From 8eb7c58dbb7b32701af113bc58722d0d1fefb1eb Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 22 Dec 2019 16:43:54 -0500 Subject: [PATCH 1/5] Remove most files from format ignore list Also moves formatting to use edition 2018, and to be done in parallel. This brings near-linear speed ups (at least with a small amount of cores). --- rustfmt.toml | 115 +++++++++++++++++----------------------- src/bootstrap/format.rs | 43 ++++++++------- 2 files changed, 73 insertions(+), 85 deletions(-) diff --git a/rustfmt.toml b/rustfmt.toml index 4e38aace15d1b..0a90c89bffe8d 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,74 +1,59 @@ -# Currently, most of the code in the compiler uses historical style. -# -# For new code, consider running rustfmt with this config (it should -# be picked up automatically). +# Run rustfmt with this config (it should be picked up automatically). version = "Two" use_small_heuristics = "Max" +merge_derives = false # by default we ignore everything in the repository # tidy only checks files which are not ignored, each entry follows gitignore style ignore = [ - # remove directories below, or opt out their subdirectories, as they are formatted - "src/bootstrap/", - "src/build_helper/", - "src/liballoc/", - "src/libarena/", - "src/libcore/", - "src/libfmt_macros/", - "src/libgraphviz/", - "src/libpanic_abort/", - "src/libpanic_unwind/", - "src/libproc_macro/", - "src/libprofiler_builtins/", - "src/librustc/", - "src/librustc_apfloat/", - "src/librustc_asan/", - "src/librustc_codegen_llvm/", - "src/librustc_codegen_ssa/", - "src/librustc_codegen_utils/", - "src/librustc_data_structures/", - "src/librustc_driver/", - "src/librustc_errors/", - "src/librustc_feature/", - "src/librustc_incremental/", - "src/librustc_index/", - "src/librustc_interface/", - "src/librustc_lexer/", - "src/librustc_lint/", - "src/librustc_llvm/", - "src/librustc_lsan/", - "src/librustc_macros/", - "src/librustc_metadata/", - "src/librustc_mir/", - "src/librustc_msan/", - "src/librustc_parse/", - "src/librustc_passes/", - "src/librustc_plugin/", - "src/librustc_plugin_impl/", - "src/librustc_privacy/", - "src/librustc_resolve/", - "src/librustc_save_analysis/", - "src/librustc_session/", - "src/librustc_target/", - "src/librustc_traits/", - "src/librustc_tsan/", - "src/librustc_typeck/", - "src/librustdoc/", - "src/libserialize/", - "src/libstd/", - "src/libsyntax/", - "src/libsyntax_expand/", - "src/libsyntax_ext/", - "src/libsyntax_pos/", - "src/libterm/", - "src/libtest/", - "src/libunwind/", - "src/rtstartup/", - "src/rustc/", - "src/rustllvm/", - "src/test/", - "src/tools/", - "src/etc", + # tests for now are not formatted, as they are sometimes pretty-printing constrained + # (and generally rustfmt can move around comments in UI-testing incompatible ways) + "src/test", + + # tidy issues (line length, etc.) + # to be fixed shortly + "src/libcore/iter/adapters/mod.rs", + "src/libcore/iter/traits/iterator.rs", + "src/librustc/hir/lowering.rs", + "src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs", + "src/librustc/lint/mod.rs", + "src/librustc/middle/resolve_lifetime.rs", + "src/librustc/traits/mod.rs", + "src/librustc/ty/constness.rs", + "src/librustc/ty/context.rs", + "src/librustc/ty/wf.rs", + "src/librustc_codegen_llvm/back/write.rs", + "src/librustc_codegen_llvm/consts.rs", + "src/librustc_codegen_llvm/debuginfo/metadata.rs", + "src/librustc_codegen_ssa/base.rs", + "src/librustc_codegen_ssa/mir/place.rs", + "src/librustc_codegen_utils/symbol_names/v0.rs", + "src/librustc_errors/emitter.rs", + "src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs", + "src/librustc_mir/borrow_check/type_check/mod.rs", + "src/librustc_mir/build/expr/as_rvalue.rs", + "src/librustc_mir/build/matches/mod.rs", + "src/librustc_mir/build/mod.rs", + "src/librustc_mir/const_eval.rs", + "src/librustc_mir/interpret/place.rs", + "src/librustc_mir/monomorphize/collector.rs", + "src/librustc_passes/ast_validation.rs", + "src/librustc_resolve/lib.rs", + "src/librustc_resolve/resolve_imports.rs", + "src/librustc_typeck/astconv.rs", + "src/librustc_typeck/check/_match.rs", + "src/librustc_typeck/check/coercion.rs", + "src/librustc_typeck/check/method/confirm.rs", + "src/librustc_typeck/check/mod.rs", + "src/librustc_typeck/check/wfcheck.rs", + "src/librustdoc/html/markdown/tests.rs", + "src/libstd/sys/sgx/abi/mem.rs", + "src/libstd/sys/unix/os.rs", + "src/libsyntax_expand/parse/lexer/tests.rs", + "src/libsyntax_expand/parse/tests.rs", + "src/libsyntax_ext/test.rs", + "src/tools/build-manifest/src/main.rs", + "src/librustc_feature", # do not format submodules "src/doc/book", diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index c8ae2f4e6888c..65b654fb51929 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -1,21 +1,17 @@ //! Runs rustfmt on the repository. use crate::Build; -use std::process::Command; +use build_helper::t; use ignore::WalkBuilder; use std::path::Path; -use build_helper::t; - -fn rustfmt(build: &Build, path: &Path, check: bool) { - let rustfmt_path = build.config.initial_rustfmt.as_ref().unwrap_or_else(|| { - eprintln!("./x.py fmt is not supported on this channel"); - std::process::exit(1); - }); +use std::process::Command; - let mut cmd = Command::new(&rustfmt_path); +fn rustfmt(src: &Path, rustfmt: &Path, path: &Path, check: bool) { + let mut cmd = Command::new(&rustfmt); // avoid the submodule config paths from coming into play, // we only allow a single global config for the workspace for now - cmd.arg("--config-path").arg(&build.src.canonicalize().unwrap()); + cmd.arg("--config-path").arg(&src.canonicalize().unwrap()); + cmd.arg("--edition").arg("2018"); cmd.arg("--unstable-features"); cmd.arg("--skip-children"); if check { @@ -51,14 +47,21 @@ pub fn format(build: &Build, check: bool) { } let ignore_fmt = ignore_fmt.build().unwrap(); - let walker = WalkBuilder::new(&build.src) - .types(matcher) - .overrides(ignore_fmt) - .build(); - for entry in walker { - let entry = t!(entry); - if entry.file_type().map_or(false, |t| t.is_file()) { - rustfmt(build, &entry.path(), check); - } - } + let rustfmt_path = build.config.initial_rustfmt.as_ref().unwrap_or_else(|| { + eprintln!("./x.py fmt is not supported on this channel"); + std::process::exit(1); + }); + let src = build.src.clone(); + let walker = WalkBuilder::new(&build.src).types(matcher).overrides(ignore_fmt).build_parallel(); + walker.run(|| { + let src = src.clone(); + let rustfmt_path = rustfmt_path.clone(); + Box::new(move |entry| { + let entry = t!(entry); + if entry.file_type().map_or(false, |t| t.is_file()) { + rustfmt(&src, &rustfmt_path, &entry.path(), check); + } + ignore::WalkState::Continue + }) + }); } From a06baa56b95674fc626b3c3fd680d6a65357fe60 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 22 Dec 2019 17:42:04 -0500 Subject: [PATCH 2/5] Format the world --- src/bootstrap/bin/llvm-config-wrapper.rs | 2 +- src/bootstrap/bin/main.rs | 2 +- src/bootstrap/bin/rustc.rs | 46 +- src/bootstrap/bin/rustdoc.rs | 16 +- src/bootstrap/bin/sccache-plus-cl.rs | 12 +- src/bootstrap/builder.rs | 128 +- src/bootstrap/builder/tests.rs | 379 +- src/bootstrap/cache.rs | 46 +- src/bootstrap/cc_detect.rs | 61 +- src/bootstrap/channel.rs | 31 +- src/bootstrap/check.rs | 89 +- src/bootstrap/clean.rs | 12 +- src/bootstrap/compile.rs | 272 +- src/bootstrap/config.rs | 69 +- src/bootstrap/dist.rs | 1010 +-- src/bootstrap/doc.rs | 163 +- src/bootstrap/flags.rs | 97 +- src/bootstrap/job.rs | 56 +- src/bootstrap/lib.rs | 251 +- src/bootstrap/metadata.rs | 25 +- src/bootstrap/native.rs | 235 +- src/bootstrap/sanity.rs | 103 +- src/bootstrap/test.rs | 488 +- src/bootstrap/tool.rs | 203 +- src/bootstrap/toolstate.rs | 65 +- src/bootstrap/util.rs | 129 +- src/build_helper/lib.rs | 75 +- src/etc/test-float-parse/long-fractions.rs | 2 +- src/etc/test-float-parse/many-digits.rs | 6 +- src/etc/test-float-parse/subnorm.rs | 2 +- src/liballoc/alloc.rs | 23 +- src/liballoc/benches/lib.rs | 4 +- src/liballoc/benches/vec.rs | 2 +- src/liballoc/borrow.rs | 35 +- src/liballoc/boxed.rs | 36 +- src/liballoc/collections/binary_heap.rs | 45 +- src/liballoc/collections/btree/map.rs | 371 +- src/liballoc/collections/btree/node.rs | 616 +- src/liballoc/collections/btree/set.rs | 247 +- src/liballoc/collections/linked_list.rs | 110 +- src/liballoc/collections/mod.rs | 12 +- src/liballoc/collections/vec_deque.rs | 250 +- src/liballoc/lib.rs | 27 +- src/liballoc/raw_vec.rs | 126 +- src/liballoc/rc.rs | 133 +- src/liballoc/rc/tests.rs | 13 +- src/liballoc/str.rs | 64 +- src/liballoc/string.rs | 113 +- src/liballoc/sync.rs | 151 +- src/liballoc/sync/tests.rs | 18 +- src/liballoc/tests/binary_heap.rs | 10 +- src/liballoc/tests/btree/map.rs | 33 +- src/liballoc/tests/btree/set.rs | 75 +- src/liballoc/tests/heap.rs | 23 +- src/liballoc/tests/lib.rs | 4 +- src/liballoc/tests/linked_list.rs | 1 - src/liballoc/tests/slice.rs | 194 +- src/liballoc/tests/str.rs | 354 +- src/liballoc/tests/string.rs | 188 +- src/liballoc/tests/vec.rs | 233 +- src/liballoc/vec.rs | 248 +- src/libarena/lib.rs | 50 +- src/libarena/tests.rs | 22 +- src/libcore/alloc.rs | 167 +- src/libcore/any.rs | 24 +- src/libcore/array/iter.rs | 54 +- src/libcore/array/mod.rs | 21 +- src/libcore/benches/pattern.rs | 1 - src/libcore/borrow.rs | 22 +- src/libcore/cell.rs | 81 +- src/libcore/cmp.rs | 190 +- src/libcore/fmt/builders.rs | 99 +- src/libcore/fmt/num.rs | 45 +- src/libcore/intrinsics.rs | 46 +- src/libcore/iter/adapters/chain.rs | 87 +- src/libcore/iter/adapters/zip.rs | 100 +- src/libcore/iter/mod.rs | 66 +- src/libcore/iter/range.rs | 29 +- src/libcore/iter/traits/marker.rs | 2 +- src/libcore/iter/traits/mod.rs | 14 +- src/libcore/lib.rs | 87 +- src/libcore/marker.rs | 69 +- src/libcore/mem/maybe_uninit.rs | 11 +- src/libcore/mem/mod.rs | 6 +- src/libcore/num/f32.rs | 9 +- src/libcore/panic.rs | 38 +- src/libcore/ptr/const_ptr.rs | 80 +- src/libcore/ptr/mod.rs | 4 +- src/libcore/ptr/mut_ptr.rs | 112 +- src/libcore/result.rs | 96 +- src/libcore/slice/mod.rs | 819 ++- src/libcore/str/lossy.rs | 48 +- src/libcore/str/mod.rs | 419 +- src/libcore/str/pattern.rs | 231 +- src/libcore/sync/atomic.rs | 136 +- src/libcore/tests/cmp.rs | 6 +- src/libcore/tests/fmt/builders.rs | 235 +- src/libcore/tests/hash/mod.rs | 3 +- src/libcore/tests/iter.rs | 304 +- src/libcore/tests/num/dec2flt/mod.rs | 6 +- src/libcore/tests/num/flt2dec/mod.rs | 1036 +-- src/libcore/tests/num/mod.rs | 243 +- src/libcore/tests/pattern.rs | 469 +- src/libcore/tests/ptr.rs | 2 +- src/libcore/tests/result.rs | 52 +- src/libfmt_macros/lib.rs | 60 +- src/libfmt_macros/tests.rs | 203 +- src/libgraphviz/lib.rs | 48 +- src/libgraphviz/tests.rs | 178 +- src/libpanic_abort/lib.rs | 63 +- src/libpanic_unwind/dwarf/eh.rs | 41 +- src/libpanic_unwind/dwarf/mod.rs | 2 +- src/libpanic_unwind/emcc.rs | 38 +- src/libpanic_unwind/gcc.rs | 31 +- src/libpanic_unwind/hermit.rs | 10 +- src/libpanic_unwind/lib.rs | 21 +- src/libpanic_unwind/seh.rs | 46 +- src/libproc_macro/bridge/buffer.rs | 20 +- src/libproc_macro/bridge/client.rs | 34 +- src/libproc_macro/bridge/closure.rs | 5 +- src/libproc_macro/bridge/handle.rs | 22 +- src/libproc_macro/bridge/mod.rs | 7 +- src/libproc_macro/bridge/server.rs | 36 +- src/libproc_macro/diagnostic.rs | 15 +- src/libproc_macro/lib.rs | 58 +- src/libprofiler_builtins/build.rs | 39 +- src/libprofiler_builtins/lib.rs | 8 +- src/librustc/arena.rs | 42 +- src/librustc/benches/lib.rs | 28 +- src/librustc/dep_graph/debug.rs | 15 +- src/librustc/dep_graph/dep_node.rs | 78 +- src/librustc/dep_graph/graph.rs | 421 +- src/librustc/dep_graph/mod.rs | 4 +- src/librustc/dep_graph/prev.rs | 20 +- src/librustc/dep_graph/query.rs | 38 +- src/librustc/dep_graph/safe.rs | 37 +- src/librustc/dep_graph/serialized.rs | 6 +- src/librustc/hir/check_attr.rs | 216 +- src/librustc/hir/def.rs | 66 +- src/librustc/hir/def_id.rs | 9 +- src/librustc/hir/intravisit.rs | 281 +- src/librustc/hir/itemlikevisit.rs | 11 +- src/librustc/hir/lowering/expr.rs | 399 +- src/librustc/hir/lowering/item.rs | 602 +- src/librustc/hir/map/blocks.rs | 132 +- src/librustc/hir/map/collector.rs | 180 +- src/librustc/hir/map/definitions.rs | 183 +- src/librustc/hir/map/hir_id_validator.rs | 106 +- src/librustc/hir/map/mod.rs | 834 +-- src/librustc/hir/mod.rs | 413 +- src/librustc/hir/pat_util.rs | 89 +- src/librustc/hir/print.rs | 619 +- src/librustc/hir/ptr.rs | 18 +- src/librustc/hir/upvars.rs | 8 +- src/librustc/ich/hcx.rs | 91 +- src/librustc/ich/impls_hir.rs | 117 +- src/librustc/ich/impls_syntax.rs | 53 +- src/librustc/ich/impls_ty.rs | 30 +- src/librustc/ich/mod.rs | 9 +- src/librustc/infer/at.rs | 239 +- src/librustc/infer/canonical/canonicalizer.rs | 122 +- src/librustc/infer/canonical/mod.rs | 126 +- .../infer/canonical/query_response.rs | 157 +- src/librustc/infer/canonical/substitute.rs | 23 +- src/librustc/infer/combine.rs | 238 +- src/librustc/infer/equate.rs | 78 +- src/librustc/infer/error_reporting/mod.rs | 324 +- .../infer/error_reporting/need_type_info.rs | 144 +- .../nice_region_error/different_lifetimes.rs | 37 +- .../nice_region_error/find_anon_type.rs | 34 +- .../error_reporting/nice_region_error/mod.rs | 14 +- .../nice_region_error/named_anon_conflict.rs | 19 +- .../nice_region_error/placeholder_error.rs | 51 +- .../nice_region_error/static_impl_trait.rs | 42 +- .../trait_impl_difference.rs | 22 +- .../error_reporting/nice_region_error/util.rs | 16 +- src/librustc/infer/error_reporting/note.rs | 738 +- src/librustc/infer/freshen.rs | 153 +- src/librustc/infer/fudge.rs | 63 +- src/librustc/infer/glb.rs | 54 +- src/librustc/infer/higher_ranked/mod.rs | 30 +- src/librustc/infer/lattice.rs | 13 +- .../infer/lexical_region_resolve/graphviz.rs | 64 +- .../infer/lexical_region_resolve/mod.rs | 23 +- src/librustc/infer/lub.rs | 54 +- src/librustc/infer/mod.rs | 229 +- src/librustc/infer/nll_relate/mod.rs | 92 +- src/librustc/infer/opaque_types/mod.rs | 132 +- src/librustc/infer/outlives/env.rs | 19 +- .../infer/outlives/free_region_map.rs | 20 +- src/librustc/infer/outlives/obligations.rs | 81 +- src/librustc/infer/outlives/verify.rs | 45 +- .../infer/region_constraints/leak_check.rs | 21 +- src/librustc/infer/region_constraints/mod.rs | 83 +- src/librustc/infer/resolve.rs | 43 +- src/librustc/infer/sub.rs | 90 +- src/librustc/infer/type_variable.rs | 92 +- src/librustc/infer/unify_key.rs | 71 +- src/librustc/lib.rs | 31 +- src/librustc/lint/builtin.rs | 45 +- src/librustc/lint/context.rs | 377 +- src/librustc/lint/internal.rs | 7 +- src/librustc/lint/levels.rs | 211 +- src/librustc/middle/cstore.rs | 61 +- src/librustc/middle/diagnostic_items.rs | 34 +- src/librustc/middle/exported_symbols.rs | 48 +- src/librustc/middle/free_region.rs | 56 +- src/librustc/middle/lang_items.rs | 14 +- src/librustc/middle/lib_features.rs | 40 +- src/librustc/middle/privacy.rs | 6 +- src/librustc/middle/reachable.rs | 203 +- src/librustc/middle/recursion_limit.rs | 2 +- src/librustc/middle/region.rs | 350 +- src/librustc/middle/stability.rs | 319 +- src/librustc/middle/weak_lang_items.rs | 14 +- src/librustc/mir/cache.rs | 54 +- src/librustc/mir/interpret/allocation.rs | 181 +- src/librustc/mir/interpret/error.rs | 420 +- src/librustc/mir/interpret/mod.rs | 91 +- src/librustc/mir/interpret/pointer.rs | 41 +- src/librustc/mir/interpret/queries.rs | 34 +- src/librustc/mir/interpret/value.rs | 102 +- src/librustc/mir/mod.rs | 238 +- src/librustc/mir/mono.rs | 228 +- src/librustc/mir/tcx.rs | 122 +- src/librustc/mir/traversal.rs | 16 +- src/librustc/mir/visit.rs | 31 +- src/librustc/query/mod.rs | 17 +- src/librustc/traits/auto_trait.rs | 185 +- src/librustc/traits/chalk_fulfill.rs | 65 +- src/librustc/traits/codegen/mod.rs | 33 +- src/librustc/traits/coherence.rs | 186 +- src/librustc/traits/engine.rs | 24 +- src/librustc/traits/error_reporting.rs | 1400 ++-- src/librustc/traits/fulfill.rs | 228 +- src/librustc/traits/object_safety.rs | 284 +- src/librustc/traits/on_unimplemented.rs | 165 +- src/librustc/traits/project.rs | 862 ++- src/librustc/traits/query/dropck_outlives.rs | 51 +- .../traits/query/evaluate_obligation.rs | 33 +- src/librustc/traits/query/method_autoderef.rs | 2 +- src/librustc/traits/query/mod.rs | 3 +- src/librustc/traits/query/normalize.rs | 19 +- .../traits/query/normalize_erasing_regions.rs | 2 +- src/librustc/traits/query/outlives_bounds.rs | 52 +- .../traits/query/type_op/ascribe_user_type.rs | 12 +- src/librustc/traits/query/type_op/custom.rs | 9 +- src/librustc/traits/query/type_op/eq.rs | 6 +- src/librustc/traits/query/type_op/mod.rs | 18 +- .../traits/query/type_op/normalize.rs | 8 +- src/librustc/traits/query/type_op/outlives.rs | 2 +- src/librustc/traits/query/type_op/subtype.rs | 11 +- src/librustc/traits/select.rs | 792 +-- src/librustc/traits/specialize/mod.rs | 213 +- .../traits/specialize/specialization_graph.rs | 114 +- src/librustc/traits/structural_impls.rs | 212 +- src/librustc/traits/util.rs | 255 +- src/librustc/ty/_match.rs | 82 +- src/librustc/ty/adjustment.rs | 18 +- src/librustc/ty/binding.rs | 2 +- src/librustc/ty/cast.rs | 9 +- src/librustc/ty/codec.rs | 81 +- src/librustc/ty/diagnostics.rs | 39 +- src/librustc/ty/erase_regions.rs | 21 +- src/librustc/ty/error.rs | 318 +- src/librustc/ty/fast_reject.rs | 65 +- src/librustc/ty/flags.rs | 46 +- src/librustc/ty/fold.rs | 235 +- .../ty/inhabitedness/def_id_forest.rs | 14 +- src/librustc/ty/inhabitedness/mod.rs | 34 +- src/librustc/ty/instance.rs | 220 +- src/librustc/ty/layout.rs | 1092 ++- src/librustc/ty/mod.rs | 837 ++- src/librustc/ty/outlives.rs | 9 +- src/librustc/ty/print/mod.rs | 153 +- src/librustc/ty/print/obsolete.rs | 11 +- src/librustc/ty/print/pretty.rs | 466 +- src/librustc/ty/query/config.rs | 20 +- src/librustc/ty/query/job.rs | 159 +- src/librustc/ty/query/keys.rs | 10 +- src/librustc/ty/query/mod.rs | 63 +- src/librustc/ty/query/on_disk_cache.rs | 222 +- src/librustc/ty/query/plumbing.rs | 192 +- src/librustc/ty/query/values.rs | 2 +- src/librustc/ty/relate.rs | 273 +- src/librustc/ty/steal.rs | 10 +- src/librustc/ty/structural_impls.rs | 425 +- src/librustc/ty/structural_match.rs | 38 +- src/librustc/ty/sty.rs | 536 +- src/librustc/ty/subst.rs | 180 +- src/librustc/ty/trait_def.rs | 63 +- src/librustc/ty/util.rs | 400 +- src/librustc/ty/walk.rs | 35 +- src/librustc/util/bug.rs | 2 +- src/librustc/util/captures.rs | 4 +- src/librustc/util/common.rs | 44 +- src/librustc/util/nodemap.rs | 2 +- src/librustc_apfloat/ieee.rs | 232 +- src/librustc_apfloat/lib.rs | 100 +- src/librustc_apfloat/ppc.rs | 59 +- src/librustc_apfloat/tests/ieee.rs | 6064 ++++------------- src/librustc_apfloat/tests/ppc.rs | 171 +- src/librustc_asan/build.rs | 2 +- src/librustc_asan/lib.rs | 8 +- src/librustc_codegen_llvm/abi.rs | 122 +- src/librustc_codegen_llvm/allocator.rs | 57 +- src/librustc_codegen_llvm/asm.rs | 69 +- src/librustc_codegen_llvm/attributes.rs | 224 +- src/librustc_codegen_llvm/back/archive.rs | 143 +- src/librustc_codegen_llvm/back/bytecode.rs | 47 +- src/librustc_codegen_llvm/back/lto.rs | 377 +- src/librustc_codegen_llvm/base.rs | 55 +- src/librustc_codegen_llvm/builder.rs | 485 +- src/librustc_codegen_llvm/callee.rs | 29 +- src/librustc_codegen_llvm/common.rs | 127 +- src/librustc_codegen_llvm/context.rs | 185 +- .../debuginfo/create_scope_map.rs | 27 +- src/librustc_codegen_llvm/debuginfo/gdb.rs | 32 +- src/librustc_codegen_llvm/debuginfo/mod.rs | 200 +- .../debuginfo/namespace.rs | 22 +- .../debuginfo/source_loc.rs | 27 +- src/librustc_codegen_llvm/debuginfo/utils.rs | 17 +- src/librustc_codegen_llvm/declare.rs | 67 +- src/librustc_codegen_llvm/intrinsic.rs | 1288 ++-- src/librustc_codegen_llvm/lib.rs | 104 +- src/librustc_codegen_llvm/llvm/archive_ro.rs | 8 +- src/librustc_codegen_llvm/llvm/diagnostic.rs | 65 +- src/librustc_codegen_llvm/llvm/ffi.rs | 1958 +++--- src/librustc_codegen_llvm/llvm/mod.rs | 41 +- src/librustc_codegen_llvm/llvm_util.rs | 85 +- src/librustc_codegen_llvm/metadata.rs | 79 +- src/librustc_codegen_llvm/mono_item.rs | 46 +- src/librustc_codegen_llvm/type_.rs | 171 +- src/librustc_codegen_llvm/type_of.rs | 191 +- src/librustc_codegen_llvm/va_arg.rs | 56 +- src/librustc_codegen_llvm/value.rs | 10 +- src/librustc_codegen_ssa/back/archive.rs | 28 +- src/librustc_codegen_ssa/back/command.rs | 26 +- src/librustc_codegen_ssa/back/link.rs | 546 +- src/librustc_codegen_ssa/back/linker.rs | 323 +- src/librustc_codegen_ssa/back/lto.rs | 4 +- src/librustc_codegen_ssa/back/mod.rs | 10 +- src/librustc_codegen_ssa/back/rpath.rs | 16 +- src/librustc_codegen_ssa/back/rpath/tests.rs | 59 +- .../back/symbol_export.rs | 137 +- src/librustc_codegen_ssa/back/write.rs | 567 +- src/librustc_codegen_ssa/common.rs | 35 +- .../debuginfo/type_names.rs | 53 +- src/librustc_codegen_ssa/glue.rs | 22 +- src/librustc_codegen_ssa/lib.rs | 62 +- src/librustc_codegen_ssa/meth.rs | 18 +- src/librustc_codegen_ssa/mir/analyze.rs | 208 +- src/librustc_codegen_ssa/mir/block.rs | 453 +- src/librustc_codegen_ssa/mir/constant.rs | 79 +- src/librustc_codegen_ssa/mir/debuginfo.rs | 85 +- src/librustc_codegen_ssa/mir/mod.rs | 316 +- src/librustc_codegen_ssa/mir/operand.rs | 202 +- src/librustc_codegen_ssa/mir/rvalue.rs | 428 +- src/librustc_codegen_ssa/mir/statement.rs | 64 +- src/librustc_codegen_ssa/mono_item.rs | 60 +- src/librustc_codegen_ssa/traits/abi.rs | 2 +- src/librustc_codegen_ssa/traits/backend.rs | 6 +- src/librustc_codegen_ssa/traits/builder.rs | 21 +- src/librustc_codegen_ssa/traits/debuginfo.rs | 2 +- src/librustc_codegen_ssa/traits/mod.rs | 4 +- src/librustc_codegen_ssa/traits/type_.rs | 2 +- src/librustc_codegen_ssa/traits/write.rs | 10 +- src/librustc_codegen_utils/codegen_backend.rs | 16 +- src/librustc_codegen_utils/lib.rs | 24 +- src/librustc_codegen_utils/link.rs | 120 +- src/librustc_codegen_utils/symbol_names.rs | 14 +- .../symbol_names/legacy.rs | 95 +- .../symbol_names_test.rs | 7 +- src/librustc_data_structures/base_n.rs | 1 - src/librustc_data_structures/base_n/tests.rs | 2 +- src/librustc_data_structures/box_region.rs | 30 +- src/librustc_data_structures/const_cstr.rs | 8 +- src/librustc_data_structures/fingerprint.rs | 9 +- src/librustc_data_structures/fx.rs | 2 +- .../graph/dominators/mod.rs | 12 +- .../graph/dominators/tests.rs | 7 +- .../graph/implementation/mod.rs | 66 +- .../graph/implementation/tests.rs | 42 +- .../graph/iterate/mod.rs | 6 +- src/librustc_data_structures/graph/mod.rs | 15 +- .../graph/reference.rs | 4 +- src/librustc_data_structures/graph/scc/mod.rs | 59 +- .../graph/scc/tests.rs | 89 +- src/librustc_data_structures/graph/tests.rs | 6 +- .../graph/vec_graph/mod.rs | 12 +- .../graph/vec_graph/tests.rs | 11 +- src/librustc_data_structures/lib.rs | 64 +- src/librustc_data_structures/macros.rs | 4 +- .../obligation_forest/mod.rs | 119 +- .../obligation_forest/tests.rs | 398 +- .../owning_ref/mod.rs | 356 +- .../owning_ref/tests.rs | 109 +- src/librustc_data_structures/profiling.rs | 71 +- src/librustc_data_structures/ptr_key.rs | 6 +- src/librustc_data_structures/sharded.rs | 35 +- src/librustc_data_structures/sip128.rs | 69 +- src/librustc_data_structures/sip128/tests.rs | 374 +- src/librustc_data_structures/small_c_str.rs | 5 +- .../snapshot_map/mod.rs | 29 +- src/librustc_data_structures/sorted_map.rs | 160 +- .../sorted_map/tests.rs | 25 +- src/librustc_data_structures/stable_hasher.rs | 148 +- src/librustc_data_structures/stable_map.rs | 3 +- src/librustc_data_structures/svh.rs | 15 +- src/librustc_data_structures/sync.rs | 28 +- src/librustc_data_structures/thin_vec.rs | 8 +- .../tiny_list/tests.rs | 32 +- .../transitive_relation.rs | 101 +- .../transitive_relation/tests.rs | 9 +- .../vec_linked_list.rs | 5 +- src/librustc_data_structures/work_queue.rs | 10 +- src/librustc_driver/lib.rs | 513 +- src/librustc_driver/pretty.rs | 212 +- .../annotate_snippet_emitter_writer.rs | 126 +- src/librustc_errors/diagnostic.rs | 154 +- src/librustc_errors/diagnostic_builder.rs | 89 +- src/librustc_errors/json.rs | 221 +- src/librustc_errors/json/tests.rs | 4 +- src/librustc_errors/lib.rs | 222 +- src/librustc_errors/lock.rs | 27 +- src/librustc_errors/snippet.rs | 30 +- src/librustc_errors/styled_buffer.rs | 29 +- src/librustc_incremental/assert_dep_graph.rs | 213 +- .../assert_module_sources.rs | 62 +- src/librustc_incremental/lib.rs | 28 +- .../persist/dirty_clean.rs | 246 +- .../persist/file_format.rs | 42 +- src/librustc_incremental/persist/fs.rs | 517 +- src/librustc_incremental/persist/fs/tests.rs | 79 +- src/librustc_incremental/persist/load.rs | 74 +- src/librustc_incremental/persist/mod.rs | 4 +- src/librustc_incremental/persist/save.rs | 141 +- .../persist/work_product.rs | 73 +- src/librustc_index/bit_set.rs | 62 +- src/librustc_index/bit_set/tests.rs | 23 +- src/librustc_index/lib.rs | 2 +- src/librustc_index/vec.rs | 71 +- src/librustc_interface/interface.rs | 85 +- src/librustc_interface/lib.rs | 5 +- src/librustc_interface/passes.rs | 351 +- src/librustc_interface/proc_macro_decls.rs | 17 +- src/librustc_interface/queries.rs | 102 +- src/librustc_interface/tests.rs | 136 +- src/librustc_interface/util.rs | 197 +- src/librustc_lexer/src/lib.rs | 18 +- src/librustc_lexer/src/unescape.rs | 9 +- src/librustc_lint/array_into_iter.rs | 14 +- src/librustc_lint/builtin.rs | 687 +- src/librustc_lint/lib.rs | 430 +- src/librustc_lint/non_ascii_idents.rs | 3 +- src/librustc_lint/nonstandard_style.rs | 98 +- src/librustc_lint/redundant_semicolon.rs | 12 +- src/librustc_lint/types.rs | 273 +- src/librustc_lint/unused.rs | 256 +- src/librustc_llvm/build.rs | 100 +- src/librustc_llvm/lib.rs | 204 +- src/librustc_lsan/build.rs | 2 +- src/librustc_lsan/lib.rs | 8 +- src/librustc_macros/src/hash_stable.rs | 70 +- src/librustc_macros/src/lib.rs | 5 +- src/librustc_macros/src/lift.rs | 33 +- src/librustc_macros/src/query.rs | 59 +- src/librustc_macros/src/symbols.rs | 26 +- src/librustc_macros/src/type_foldable.rs | 39 +- src/librustc_metadata/creader.rs | 364 +- src/librustc_metadata/dependency_format.rs | 168 +- src/librustc_metadata/dynamic_lib.rs | 71 +- src/librustc_metadata/dynamic_lib/tests.rs | 15 +- src/librustc_metadata/foreign_modules.rs | 18 +- src/librustc_metadata/lib.rs | 14 +- src/librustc_metadata/link_args.rs | 12 +- src/librustc_metadata/locator.rs | 440 +- src/librustc_metadata/native_libs.rs | 122 +- src/librustc_metadata/rmeta/decoder.rs | 609 +- .../rmeta/decoder/cstore_impl.rs | 130 +- src/librustc_metadata/rmeta/encoder.rs | 301 +- src/librustc_metadata/rmeta/mod.rs | 55 +- src/librustc_metadata/rmeta/table.rs | 53 +- src/librustc_mir/borrow_check/borrow_set.rs | 61 +- .../borrow_check/constraint_generation.rs | 73 +- .../borrow_check/constraints/graph.rs | 46 +- .../borrow_check/constraints/mod.rs | 6 +- .../diagnostics/conflict_errors.rs | 530 +- .../diagnostics/explain_borrow.rs | 148 +- .../borrow_check/diagnostics/find_use.rs | 20 +- .../borrow_check/diagnostics/mod.rs | 328 +- .../borrow_check/diagnostics/move_errors.rs | 232 +- .../diagnostics/outlives_suggestion.rs | 15 +- .../borrow_check/diagnostics/region_errors.rs | 243 +- .../borrow_check/diagnostics/region_name.rs | 166 +- .../borrow_check/diagnostics/var_name.rs | 51 +- src/librustc_mir/borrow_check/invalidation.rs | 179 +- src/librustc_mir/borrow_check/location.rs | 28 +- .../borrow_check/member_constraints.rs | 10 +- src/librustc_mir/borrow_check/mod.rs | 489 +- src/librustc_mir/borrow_check/nll.rs | 164 +- src/librustc_mir/borrow_check/path_utils.rs | 6 +- src/librustc_mir/borrow_check/place_ext.rs | 28 +- .../borrow_check/places_conflict.rs | 94 +- src/librustc_mir/borrow_check/prefixes.rs | 9 +- .../borrow_check/region_infer/dump_mir.rs | 22 +- .../borrow_check/region_infer/graphviz.rs | 9 +- .../borrow_check/region_infer/mod.rs | 94 +- .../borrow_check/region_infer/values.rs | 71 +- src/librustc_mir/borrow_check/renumber.rs | 21 +- .../type_check/constraint_conversion.rs | 59 +- .../type_check/free_region_relations.rs | 62 +- .../borrow_check/type_check/input_output.rs | 16 +- .../type_check/liveness/local_use_map.rs | 2 +- .../borrow_check/type_check/liveness/mod.rs | 12 +- .../type_check/liveness/polonius.rs | 6 +- .../borrow_check/type_check/liveness/trace.rs | 9 +- .../borrow_check/type_check/relate_tys.rs | 42 +- .../borrow_check/universal_regions.rs | 139 +- src/librustc_mir/borrow_check/used_muts.rs | 31 +- src/librustc_mir/build/block.rs | 159 +- src/librustc_mir/build/cfg.rs | 79 +- src/librustc_mir/build/expr/as_constant.rs | 27 +- src/librustc_mir/build/expr/as_operand.rs | 17 +- src/librustc_mir/build/expr/as_place.rs | 166 +- src/librustc_mir/build/expr/as_temp.rs | 46 +- src/librustc_mir/build/expr/category.rs | 3 +- src/librustc_mir/build/expr/into.rs | 139 +- src/librustc_mir/build/expr/stmt.rs | 29 +- src/librustc_mir/build/into.rs | 9 +- src/librustc_mir/build/matches/simplify.rs | 64 +- src/librustc_mir/build/matches/test.rs | 398 +- src/librustc_mir/build/matches/util.rs | 86 +- src/librustc_mir/build/misc.rs | 32 +- src/librustc_mir/build/scope.rs | 466 +- src/librustc_mir/dataflow/at_location.rs | 31 +- .../dataflow/drop_flag_effects.rs | 75 +- src/librustc_mir/dataflow/generic.rs | 38 +- src/librustc_mir/dataflow/generic/graphviz.rs | 47 +- src/librustc_mir/dataflow/graphviz.rs | 123 +- .../dataflow/impls/borrowed_locals.rs | 35 +- src/librustc_mir/dataflow/impls/borrows.rs | 123 +- .../dataflow/impls/indirect_mutation.rs | 51 +- src/librustc_mir/dataflow/impls/mod.rs | 250 +- .../dataflow/impls/storage_liveness.rs | 48 +- src/librustc_mir/dataflow/mod.rs | 249 +- .../dataflow/move_paths/builder.rs | 62 +- src/librustc_mir/dataflow/move_paths/mod.rs | 2 +- src/librustc_mir/hair/constant.rs | 20 +- src/librustc_mir/hair/cx/block.rs | 43 +- src/librustc_mir/hair/cx/expr.rs | 760 +-- src/librustc_mir/hair/cx/mod.rs | 43 +- src/librustc_mir/hair/mod.rs | 28 +- src/librustc_mir/hair/pattern/const_to_pat.rs | 158 +- src/librustc_mir/hair/pattern/mod.rs | 350 +- src/librustc_mir/hair/util.rs | 6 +- src/librustc_mir/interpret/cast.rs | 135 +- src/librustc_mir/interpret/eval_context.rs | 209 +- src/librustc_mir/interpret/intern.rs | 92 +- src/librustc_mir/interpret/intrinsics.rs | 122 +- .../interpret/intrinsics/caller_location.rs | 16 +- .../interpret/intrinsics/type_name.rs | 53 +- src/librustc_mir/interpret/machine.rs | 49 +- src/librustc_mir/interpret/memory.rs | 203 +- src/librustc_mir/interpret/mod.rs | 22 +- src/librustc_mir/interpret/operand.rs | 304 +- src/librustc_mir/interpret/operator.rs | 74 +- src/librustc_mir/interpret/snapshot.rs | 128 +- src/librustc_mir/interpret/step.rs | 63 +- src/librustc_mir/interpret/terminator.rs | 337 +- src/librustc_mir/interpret/traits.rs | 101 +- src/librustc_mir/interpret/validity.rs | 252 +- src/librustc_mir/interpret/visitor.rs | 35 +- src/librustc_mir/lib.rs | 18 +- src/librustc_mir/lints.rs | 53 +- src/librustc_mir/monomorphize/mod.rs | 4 +- src/librustc_mir/monomorphize/partitioning.rs | 271 +- src/librustc_mir/shim.rs | 545 +- src/librustc_mir/transform/add_call_guards.rs | 28 +- .../transform/add_moves_for_packed_drops.rs | 42 +- src/librustc_mir/transform/add_retag.rs | 84 +- .../transform/check_consts/mod.rs | 11 +- .../transform/check_consts/ops.rs | 144 +- .../transform/check_consts/qualifs.rs | 79 +- .../transform/check_consts/resolver.rs | 27 +- .../transform/check_consts/validation.rs | 293 +- src/librustc_mir/transform/check_unsafety.rs | 422 +- .../transform/cleanup_post_borrowck.rs | 16 +- src/librustc_mir/transform/const_prop.rs | 403 +- src/librustc_mir/transform/copy_prop.rs | 164 +- src/librustc_mir/transform/deaggregator.rs | 22 +- src/librustc_mir/transform/dump_mir.rs | 30 +- src/librustc_mir/transform/elaborate_drops.rs | 312 +- src/librustc_mir/transform/erase_regions.rs | 15 +- src/librustc_mir/transform/generator.rs | 478 +- src/librustc_mir/transform/inline.rs | 220 +- src/librustc_mir/transform/instcombine.rs | 23 +- src/librustc_mir/transform/mod.rs | 229 +- src/librustc_mir/transform/no_landing_pads.rs | 10 +- src/librustc_mir/transform/promote_consts.rs | 419 +- .../transform/qualify_min_const_fn.rs | 150 +- .../transform/remove_noop_landing_pads.rs | 62 +- src/librustc_mir/transform/rustc_peek.rs | 123 +- src/librustc_mir/transform/simplify.rs | 143 +- .../transform/simplify_branches.rs | 29 +- src/librustc_mir/transform/simplify_try.rs | 28 +- src/librustc_mir/util/aggregate.rs | 59 +- src/librustc_mir/util/alignment.rs | 8 +- src/librustc_mir/util/borrowck_errors.rs | 120 +- src/librustc_mir/util/collect_writes.rs | 19 +- src/librustc_mir/util/def_use.rs | 63 +- src/librustc_mir/util/elaborate_drops.rs | 439 +- src/librustc_mir/util/graphviz.rs | 59 +- src/librustc_mir/util/liveness.rs | 51 +- src/librustc_mir/util/mod.rs | 10 +- src/librustc_mir/util/patch.rs | 68 +- src/librustc_mir/util/pretty.rs | 116 +- src/librustc_msan/build.rs | 2 +- src/librustc_msan/lib.rs | 8 +- src/librustc_parse/config.rs | 74 +- src/librustc_parse/lexer/mod.rs | 200 +- src/librustc_parse/lexer/tokentrees.rs | 58 +- .../lexer/unescape_error_reporting.rs | 91 +- src/librustc_parse/lexer/unicode_chars.rs | 2 +- src/librustc_parse/lib.rs | 118 +- src/librustc_parse/parser/attr.rs | 69 +- src/librustc_parse/parser/diagnostics.rs | 359 +- src/librustc_parse/parser/expr.rs | 630 +- src/librustc_parse/parser/generics.rs | 113 +- src/librustc_parse/parser/item.rs | 550 +- src/librustc_parse/parser/mod.rs | 325 +- src/librustc_parse/parser/module.rs | 108 +- src/librustc_parse/parser/pat.rs | 201 +- src/librustc_parse/parser/path.rs | 132 +- src/librustc_parse/parser/stmt.rs | 112 +- src/librustc_parse/parser/ty.rs | 61 +- src/librustc_parse/validate_attr.rs | 133 +- src/librustc_passes/check_const.rs | 58 +- src/librustc_passes/dead.rs | 277 +- src/librustc_passes/entry.rs | 68 +- src/librustc_passes/hir_stats.rs | 71 +- src/librustc_passes/intrinsicck.rs | 65 +- src/librustc_passes/layout_test.rs | 14 +- src/librustc_passes/lib.rs | 12 +- src/librustc_passes/liveness.rs | 608 +- src/librustc_passes/loops.rs | 148 +- src/librustc_plugin_impl/build.rs | 26 +- src/librustc_plugin_impl/lib.rs | 1 - src/librustc_plugin_impl/load.rs | 54 +- src/librustc_privacy/lib.rs | 459 +- src/librustc_resolve/build_reduced_graph.rs | 415 +- src/librustc_resolve/check_unused.rs | 55 +- src/librustc_resolve/def_collector.rs | 109 +- src/librustc_resolve/diagnostics.rs | 594 +- src/librustc_resolve/late.rs | 547 +- src/librustc_resolve/late/diagnostics.rs | 228 +- src/librustc_resolve/macros.rs | 735 +- src/librustc_save_analysis/dump_visitor.rs | 289 +- src/librustc_save_analysis/dumper.rs | 25 +- src/librustc_save_analysis/lib.rs | 624 +- src/librustc_save_analysis/sig.rs | 185 +- src/librustc_save_analysis/span_utils.rs | 26 +- src/librustc_session/cgu_reuse_tracker.rs | 79 +- src/librustc_session/code_stats.rs | 77 +- src/librustc_session/config.rs | 345 +- src/librustc_session/filesearch.rs | 59 +- src/librustc_session/lib.rs | 4 +- src/librustc_session/lint.rs | 31 +- src/librustc_session/node_id.rs | 4 +- src/librustc_session/options.rs | 24 +- src/librustc_session/parse.rs | 46 +- src/librustc_session/search_paths.rs | 11 +- src/librustc_session/session.rs | 321 +- src/librustc_session/utils.rs | 3 +- src/librustc_target/abi/call/aarch64.rs | 41 +- src/librustc_target/abi/call/amdgpu.rs | 37 +- src/librustc_target/abi/call/arm.rs | 41 +- src/librustc_target/abi/call/hexagon.rs | 4 +- src/librustc_target/abi/call/mips.rs | 21 +- src/librustc_target/abi/call/mips64.rs | 43 +- src/librustc_target/abi/call/mod.rs | 163 +- src/librustc_target/abi/call/powerpc.rs | 4 +- src/librustc_target/abi/call/powerpc64.rs | 50 +- src/librustc_target/abi/call/s390x.rs | 31 +- src/librustc_target/abi/call/sparc.rs | 21 +- src/librustc_target/abi/call/sparc64.rs | 41 +- src/librustc_target/abi/call/wasm32.rs | 32 +- .../abi/call/wasm32_bindgen_compat.rs | 6 +- src/librustc_target/abi/call/x86.rs | 29 +- src/librustc_target/abi/call/x86_64.rs | 93 +- src/librustc_target/abi/call/x86_win64.rs | 21 +- src/librustc_target/abi/mod.rs | 205 +- src/librustc_target/lib.rs | 4 +- src/librustc_target/spec/aarch64_apple_ios.rs | 4 +- src/librustc_target/spec/aarch64_fuchsia.rs | 7 +- .../spec/aarch64_linux_android.rs | 5 +- .../spec/aarch64_pc_windows_msvc.rs | 2 +- .../spec/aarch64_unknown_freebsd.rs | 5 +- .../spec/aarch64_unknown_linux_gnu.rs | 2 +- .../spec/aarch64_unknown_linux_musl.rs | 2 +- .../spec/aarch64_unknown_netbsd.rs | 5 +- .../spec/aarch64_unknown_none.rs | 4 +- .../spec/aarch64_unknown_none_softfloat.rs | 4 +- .../spec/aarch64_uwp_windows_msvc.rs | 2 +- .../spec/aarch64_wrs_vxworks.rs | 5 +- src/librustc_target/spec/abi.rs | 58 +- src/librustc_target/spec/android_base.rs | 4 +- src/librustc_target/spec/apple_base.rs | 15 +- src/librustc_target/spec/apple_ios_base.rs | 80 +- .../spec/arm_linux_androideabi.rs | 5 +- .../spec/arm_unknown_linux_gnueabi.rs | 2 +- .../spec/arm_unknown_linux_gnueabihf.rs | 4 +- .../spec/arm_unknown_linux_musleabi.rs | 2 +- .../spec/arm_unknown_linux_musleabihf.rs | 2 +- .../spec/armebv7r_none_eabi.rs | 4 +- .../spec/armebv7r_none_eabihf.rs | 4 +- .../spec/armv4t_unknown_linux_gnueabi.rs | 4 +- .../spec/armv5te_unknown_linux_gnueabi.rs | 4 +- .../spec/armv5te_unknown_linux_musleabi.rs | 4 +- .../spec/armv6_unknown_freebsd.rs | 4 +- .../spec/armv6_unknown_netbsd_eabihf.rs | 4 +- src/librustc_target/spec/armv7_apple_ios.rs | 6 +- .../spec/armv7_linux_androideabi.rs | 8 +- .../spec/armv7_unknown_cloudabi_eabihf.rs | 5 +- .../spec/armv7_unknown_freebsd.rs | 4 +- .../spec/armv7_unknown_linux_gnueabi.rs | 4 +- .../spec/armv7_unknown_linux_gnueabihf.rs | 4 +- .../spec/armv7_unknown_linux_musleabi.rs | 4 +- .../spec/armv7_unknown_linux_musleabihf.rs | 4 +- .../spec/armv7_unknown_netbsd_eabihf.rs | 4 +- .../spec/armv7_wrs_vxworks_eabihf.rs | 4 +- src/librustc_target/spec/armv7r_none_eabi.rs | 4 +- .../spec/armv7r_none_eabihf.rs | 4 +- src/librustc_target/spec/armv7s_apple_ios.rs | 6 +- .../spec/asmjs_unknown_emscripten.rs | 6 +- src/librustc_target/spec/cloudabi_base.rs | 19 +- src/librustc_target/spec/dragonfly_base.rs | 26 +- src/librustc_target/spec/freebsd_base.rs | 26 +- src/librustc_target/spec/fuchsia_base.rs | 24 +- src/librustc_target/spec/haiku_base.rs | 4 +- src/librustc_target/spec/hermit_base.rs | 13 +- .../spec/hermit_kernel_base.rs | 13 +- .../spec/hexagon_unknown_linux_musl.rs | 15 +- src/librustc_target/spec/i386_apple_ios.rs | 8 +- src/librustc_target/spec/i686_apple_darwin.rs | 5 +- .../spec/i686_pc_windows_gnu.rs | 4 +- .../spec/i686_pc_windows_msvc.rs | 3 +- .../spec/i686_unknown_netbsd.rs | 5 +- .../spec/i686_uwp_windows_gnu.rs | 4 +- src/librustc_target/spec/l4re_base.rs | 2 +- src/librustc_target/spec/linux_base.rs | 32 +- .../spec/mips64_unknown_linux_muslabi64.rs | 5 +- .../spec/mips64el_unknown_linux_muslabi64.rs | 5 +- .../spec/mips_unknown_linux_musl.rs | 5 +- .../spec/mipsel_unknown_linux_musl.rs | 5 +- src/librustc_target/spec/mod.rs | 131 +- src/librustc_target/spec/msp430_none_elf.rs | 4 +- src/librustc_target/spec/netbsd_base.rs | 21 +- .../spec/nvptx64_nvidia_cuda.rs | 6 +- src/librustc_target/spec/openbsd_base.rs | 26 +- .../spec/powerpc64_unknown_freebsd.rs | 5 +- .../spec/powerpc64_unknown_linux_gnu.rs | 7 +- .../spec/powerpc64_unknown_linux_musl.rs | 5 +- .../spec/powerpc64_wrs_vxworks.rs | 4 +- .../spec/powerpc64le_unknown_linux_gnu.rs | 5 +- .../spec/powerpc64le_unknown_linux_musl.rs | 5 +- .../spec/powerpc_unknown_linux_gnu.rs | 5 +- .../spec/powerpc_unknown_linux_gnuspe.rs | 5 +- .../spec/powerpc_unknown_linux_musl.rs | 5 +- .../spec/powerpc_unknown_netbsd.rs | 5 +- .../spec/powerpc_wrs_vxworks.rs | 5 +- .../spec/powerpc_wrs_vxworks_spe.rs | 2 +- src/librustc_target/spec/redox_base.rs | 32 +- .../spec/riscv32i_unknown_none_elf.rs | 5 +- .../spec/riscv32imac_unknown_none_elf.rs | 5 +- .../spec/riscv32imc_unknown_none_elf.rs | 5 +- .../spec/riscv64gc_unknown_none_elf.rs | 5 +- .../spec/riscv64imac_unknown_none_elf.rs | 5 +- src/librustc_target/spec/solaris_base.rs | 2 +- .../spec/sparc64_unknown_netbsd.rs | 5 +- src/librustc_target/spec/thumb_base.rs | 4 +- .../spec/thumbv6m_none_eabi.rs | 4 +- .../spec/thumbv7a_pc_windows_msvc.rs | 9 +- .../spec/thumbv7em_none_eabi.rs | 5 +- .../spec/thumbv7em_none_eabihf.rs | 4 +- .../spec/thumbv7m_none_eabi.rs | 5 +- .../spec/thumbv7neon_linux_androideabi.rs | 8 +- .../thumbv7neon_unknown_linux_gnueabihf.rs | 4 +- .../thumbv7neon_unknown_linux_musleabihf.rs | 4 +- .../spec/thumbv8m_base_none_eabi.rs | 2 +- .../spec/thumbv8m_main_none_eabi.rs | 5 +- .../spec/thumbv8m_main_none_eabihf.rs | 2 +- src/librustc_target/spec/uefi_base.rs | 13 +- src/librustc_target/spec/vxworks_base.rs | 29 +- src/librustc_target/spec/wasm32_base.rs | 4 +- .../spec/wasm32_unknown_emscripten.rs | 25 +- .../spec/wasm32_unknown_unknown.rs | 6 +- src/librustc_target/spec/windows_base.rs | 52 +- src/librustc_target/spec/windows_msvc_base.rs | 6 +- src/librustc_target/spec/windows_uwp_base.rs | 47 +- .../spec/windows_uwp_msvc_base.rs | 16 +- .../spec/x86_64_apple_darwin.rs | 5 +- src/librustc_target/spec/x86_64_apple_ios.rs | 8 +- .../spec/x86_64_apple_ios_macabi.rs | 8 +- .../spec/x86_64_fortanix_unknown_sgx.rs | 33 +- src/librustc_target/spec/x86_64_fuchsia.rs | 2 +- .../spec/x86_64_rumprun_netbsd.rs | 5 +- .../spec/x86_64_unknown_hermit.rs | 2 +- .../spec/x86_64_unknown_hermit_kernel.rs | 4 +- .../spec/x86_64_unknown_netbsd.rs | 5 +- src/librustc_traits/chalk_context/mod.rs | 219 +- .../chalk_context/program_clauses/builtin.rs | 142 +- .../chalk_context/program_clauses/mod.rs | 121 +- .../program_clauses/primitive.rs | 66 +- .../chalk_context/resolvent_ops.rs | 97 +- src/librustc_traits/chalk_context/unify.rs | 51 +- src/librustc_traits/dropck_outlives.rs | 87 +- src/librustc_traits/evaluate_obligation.rs | 10 +- src/librustc_traits/generic_types.rs | 42 +- .../implied_outlives_bounds.rs | 57 +- src/librustc_traits/lib.rs | 9 +- src/librustc_traits/lowering/environment.rs | 135 +- src/librustc_traits/lowering/mod.rs | 157 +- .../normalize_erasing_regions.rs | 16 +- .../normalize_projection_ty.rs | 21 +- src/librustc_traits/type_op.rs | 119 +- src/librustc_tsan/build.rs | 2 +- src/librustc_tsan/lib.rs | 8 +- src/librustc_typeck/check/autoderef.rs | 148 +- src/librustc_typeck/check/callee.rs | 66 +- src/librustc_typeck/check/cast.rs | 364 +- src/librustc_typeck/check/closure.rs | 256 +- src/librustc_typeck/check/compare_method.rs | 635 +- src/librustc_typeck/check/demand.rs | 396 +- src/librustc_typeck/check/expr.rs | 700 +- .../check/generator_interior.rs | 145 +- src/librustc_typeck/check/intrinsic.rs | 561 +- src/librustc_typeck/check/method/mod.rs | 242 +- src/librustc_typeck/check/method/probe.rs | 806 ++- src/librustc_typeck/check/method/suggest.rs | 602 +- src/librustc_typeck/check/op.rs | 449 +- src/librustc_typeck/check/pat.rs | 302 +- src/librustc_typeck/check/regionck.rs | 158 +- src/librustc_typeck/check/upvar.rs | 75 +- src/librustc_typeck/check/writeback.rs | 183 +- src/librustc_typeck/check_unused.rs | 52 +- src/librustc_typeck/coherence/builtin.rs | 344 +- .../coherence/inherent_impls.rs | 386 +- .../coherence/inherent_impls_overlap.rs | 56 +- src/librustc_typeck/coherence/mod.rs | 99 +- src/librustc_typeck/coherence/orphan.rs | 79 +- src/librustc_typeck/coherence/unsafety.rs | 74 +- src/librustc_typeck/collect.rs | 823 +-- .../constrained_generic_params.rs | 34 +- src/librustc_typeck/expr_use_visitor.rs | 138 +- src/librustc_typeck/impl_wf_check.rs | 100 +- src/librustc_typeck/lib.rs | 153 +- src/librustc_typeck/mem_categorization.rs | 236 +- src/librustc_typeck/namespace.rs | 14 +- src/librustc_typeck/outlives/explicit.rs | 6 +- .../outlives/implicit_infer.rs | 32 +- src/librustc_typeck/outlives/mod.rs | 77 +- src/librustc_typeck/outlives/test.rs | 12 +- src/librustc_typeck/outlives/utils.rs | 9 +- src/librustc_typeck/structured_errors.rs | 54 +- src/librustc_typeck/variance/constraints.rs | 207 +- src/librustc_typeck/variance/mod.rs | 32 +- src/librustc_typeck/variance/solve.rs | 59 +- src/librustc_typeck/variance/terms.rs | 38 +- src/librustc_typeck/variance/test.rs | 10 +- src/librustc_typeck/variance/xform.rs | 6 +- src/librustdoc/clean/auto_trait.rs | 370 +- src/librustdoc/clean/blanket_impl.rs | 80 +- src/librustdoc/clean/cfg.rs | 96 +- src/librustdoc/clean/cfg/tests.rs | 216 +- src/librustdoc/clean/inline.rs | 257 +- src/librustdoc/clean/mod.rs | 1092 ++- src/librustdoc/clean/simplify.rs | 79 +- src/librustdoc/clean/types.rs | 438 +- src/librustdoc/clean/utils.rs | 236 +- src/librustdoc/config.rs | 129 +- src/librustdoc/core.rs | 440 +- src/librustdoc/docfs.rs | 32 +- src/librustdoc/doctree.rs | 34 +- src/librustdoc/externalfiles.rs | 52 +- src/librustdoc/fold.rs | 69 +- src/librustdoc/html/escape.rs | 4 +- src/librustdoc/html/format.rs | 539 +- src/librustdoc/html/highlight.rs | 142 +- src/librustdoc/html/item_type.rs | 246 +- src/librustdoc/html/layout.rs | 156 +- src/librustdoc/html/markdown.rs | 244 +- src/librustdoc/html/render.rs | 2705 ++++---- src/librustdoc/html/render/cache.rs | 274 +- src/librustdoc/html/render/tests.rs | 13 +- src/librustdoc/html/sources.rs | 59 +- src/librustdoc/html/toc.rs | 20 +- src/librustdoc/html/toc/tests.rs | 41 +- src/librustdoc/lib.rs | 420 +- src/librustdoc/markdown.rs | 39 +- .../passes/calculate_doc_coverage.rs | 36 +- .../passes/check_code_block_syntax.rs | 8 +- src/librustdoc/passes/collapse_docs.rs | 20 +- .../passes/collect_intra_doc_links.rs | 410 +- src/librustdoc/passes/collect_trait_impls.rs | 33 +- src/librustdoc/passes/mod.rs | 55 +- .../passes/private_items_doc_tests.rs | 4 +- src/librustdoc/passes/propagate_doc_cfg.rs | 2 +- src/librustdoc/passes/strip_hidden.rs | 4 +- src/librustdoc/passes/strip_priv_imports.rs | 4 +- src/librustdoc/passes/strip_private.rs | 4 +- src/librustdoc/passes/unindent_comments.rs | 45 +- src/librustdoc/test.rs | 253 +- src/librustdoc/test/tests.rs | 158 +- src/librustdoc/theme.rs | 68 +- src/librustdoc/theme/tests.rs | 8 +- src/librustdoc/visit_ast.rs | 353 +- src/librustdoc/visit_lib.rs | 21 +- src/libserialize/collection_impls.rs | 74 +- src/libserialize/hex.rs | 18 +- src/libserialize/hex/tests.rs | 19 +- src/libserialize/json.rs | 912 ++- src/libserialize/json/tests.rs | 53 +- src/libserialize/leb128.rs | 46 +- src/libserialize/lib.rs | 19 +- src/libserialize/opaque.rs | 26 +- src/libserialize/serialize.rs | 270 +- src/libserialize/tests/json.rs | 661 +- src/libserialize/tests/leb128.rs | 6 +- src/libserialize/tests/opaque.rs | 125 +- src/libstd/alloc.rs | 49 +- src/libstd/collections/hash/map.rs | 92 +- src/libstd/collections/hash/set.rs | 224 +- src/libstd/error.rs | 88 +- src/libstd/ffi/c_str.rs | 63 +- src/libstd/ffi/os_str.rs | 68 +- src/libstd/future.rs | 13 +- src/libstd/io/buffered.rs | 4 +- src/libstd/io/cursor.rs | 168 +- src/libstd/io/lazy.rs | 9 +- src/libstd/io/mod.rs | 3 +- src/libstd/io/stdio.rs | 137 +- src/libstd/keyword_docs.rs | 78 +- src/libstd/lib.rs | 146 +- src/libstd/net/ip.rs | 457 +- src/libstd/net/mod.rs | 30 +- src/libstd/net/parser.rs | 6 +- src/libstd/panicking.rs | 93 +- src/libstd/primitive_docs.rs | 54 +- src/libstd/sync/condvar.rs | 97 +- src/libstd/sync/mod.rs | 4 +- src/libstd/sync/mutex.rs | 62 +- src/libstd/sync/rwlock.rs | 70 +- src/libstd/sys/cloudabi/abi/cloudabi.rs | 2098 +++--- src/libstd/sys/cloudabi/condvar.rs | 42 +- src/libstd/sys/cloudabi/mod.rs | 5 +- src/libstd/sys/cloudabi/mutex.rs | 2 +- src/libstd/sys/cloudabi/rwlock.rs | 22 +- src/libstd/sys/sgx/condvar.rs | 2 +- src/libstd/sys/sgx/mod.rs | 16 +- src/libstd/sys/sgx/mutex.rs | 22 +- src/libstd/sys/sgx/rwlock.rs | 41 +- src/libstd/sys/sgx/waitqueue.rs | 115 +- src/libstd/sys/unix/args.rs | 125 +- src/libstd/sys/unix/condvar.rs | 64 +- src/libstd/sys/unix/ext/mod.rs | 31 +- src/libstd/sys/unix/ext/net.rs | 174 +- src/libstd/sys/unix/fs.rs | 453 +- src/libstd/sys/unix/mod.rs | 68 +- src/libstd/sys/unix/mutex.rs | 12 +- src/libstd/sys/unix/process/process_unix.rs | 172 +- src/libstd/sys/unix/rwlock.rs | 6 +- src/libstd/sys/unix/time.rs | 124 +- src/libstd/sys/vxworks/os.rs | 93 +- .../sys/vxworks/process/process_vxworks.rs | 54 +- src/libstd/sys/wasi/ext/io.rs | 2 +- src/libstd/sys/wasi/io.rs | 25 +- src/libstd/sys/wasi/mod.rs | 20 +- src/libstd/sys/wasm/alloc.rs | 2 +- src/libstd/sys/wasm/condvar.rs | 13 +- src/libstd/sys/wasm/condvar_atomics.rs | 2 +- src/libstd/sys/wasm/fast_thread_local.rs | 2 +- src/libstd/sys/wasm/mod.rs | 14 +- src/libstd/sys/wasm/mutex.rs | 11 +- src/libstd/sys/wasm/mutex_atomics.rs | 7 +- src/libstd/sys/wasm/rwlock.rs | 7 +- src/libstd/sys/wasm/rwlock_atomics.rs | 23 +- src/libstd/sys/windows/c.rs | 537 +- src/libstd/sys/windows/condvar.rs | 19 +- src/libstd/sys/windows/mod.rs | 102 +- src/libstd/sys/windows/mutex.rs | 24 +- src/libstd/sys/windows/net.rs | 205 +- src/libstd/sys/windows/process.rs | 159 +- src/libstd/sys/windows/rwlock.rs | 4 +- src/libstd/sys/windows/time.rs | 42 +- src/libstd/sys_common/at_exit_imp.rs | 4 +- src/libstd/sys_common/backtrace.rs | 17 +- src/libstd/sys_common/condvar.rs | 28 +- src/libstd/sys_common/mod.rs | 35 +- src/libstd/sys_common/mutex.rs | 32 +- src/libstd/sys_common/remutex.rs | 31 +- src/libstd/sys_common/rwlock.rs | 32 +- src/libstd/sys_common/thread_local.rs | 35 +- src/libstd/tests/run-time-detect.rs | 13 +- src/libstd/thread/mod.rs | 179 +- src/libsyntax/ast.rs | 258 +- src/libsyntax/attr/builtin.rs | 455 +- src/libsyntax/attr/mod.rs | 194 +- src/libsyntax/diagnostics/macros.rs | 8 +- src/libsyntax/early_buffered_lints.rs | 2 +- src/libsyntax/entry.rs | 2 +- src/libsyntax/expand/allocator.rs | 10 +- src/libsyntax/expand/mod.rs | 3 +- src/libsyntax/feature_gate/check.rs | 447 +- src/libsyntax/lib.rs | 29 +- src/libsyntax/mut_visit.rs | 212 +- src/libsyntax/print/helpers.rs | 10 +- src/libsyntax/print/pp.rs | 101 +- src/libsyntax/print/pprust.rs | 712 +- src/libsyntax/print/pprust/tests.rs | 21 +- src/libsyntax/ptr.rs | 26 +- src/libsyntax/show_span.rs | 13 +- src/libsyntax/token.rs | 236 +- src/libsyntax/tokenstream.rs | 52 +- src/libsyntax/util/classify.rs | 14 +- src/libsyntax/util/comments.rs | 48 +- src/libsyntax/util/lev_distance.rs | 56 +- src/libsyntax/util/lev_distance/tests.rs | 14 +- src/libsyntax/util/literal.rs | 112 +- src/libsyntax/util/map_in_place.rs | 22 +- src/libsyntax/util/node_count.rs | 15 +- src/libsyntax/util/parser.rs | 50 +- src/libsyntax/visit.rs | 249 +- src/libsyntax_expand/base.rs | 296 +- src/libsyntax_expand/build.rs | 408 +- src/libsyntax_expand/expand.rs | 687 +- src/libsyntax_expand/lib.rs | 8 +- src/libsyntax_expand/mbe.rs | 4 +- src/libsyntax_expand/mbe/macro_check.rs | 2 +- src/libsyntax_expand/mbe/macro_parser.rs | 136 +- src/libsyntax_expand/mbe/macro_rules.rs | 51 +- src/libsyntax_expand/mbe/quoted.rs | 24 +- src/libsyntax_expand/mut_visit/tests.rs | 44 +- src/libsyntax_expand/placeholders.rs | 212 +- src/libsyntax_expand/proc_macro.rs | 100 +- src/libsyntax_expand/proc_macro_server.rs | 69 +- src/libsyntax_expand/tests.rs | 1033 ++- src/libsyntax_expand/tokenstream/tests.rs | 4 +- src/libsyntax_ext/asm.rs | 63 +- src/libsyntax_ext/assert.rs | 65 +- src/libsyntax_ext/cfg.rs | 5 +- src/libsyntax_ext/cmdline_attrs.rs | 5 +- src/libsyntax_ext/compile_error.rs | 11 +- src/libsyntax_ext/concat.rs | 5 +- src/libsyntax_ext/concat_idents.rs | 26 +- src/libsyntax_ext/deriving/bounds.rs | 16 +- src/libsyntax_ext/deriving/clone.rs | 170 +- src/libsyntax_ext/deriving/cmp/eq.rs | 86 +- src/libsyntax_ext/deriving/cmp/ord.rs | 111 +- src/libsyntax_ext/deriving/cmp/partial_eq.rs | 53 +- src/libsyntax_ext/deriving/cmp/partial_ord.rs | 189 +- src/libsyntax_ext/deriving/debug.rs | 90 +- src/libsyntax_ext/deriving/decodable.rs | 203 +- src/libsyntax_ext/deriving/default.rs | 87 +- src/libsyntax_ext/deriving/encodable.rs | 172 +- src/libsyntax_ext/deriving/generic/mod.rs | 975 +-- src/libsyntax_ext/deriving/generic/ty.rs | 215 +- src/libsyntax_ext/deriving/hash.rs | 70 +- src/libsyntax_ext/deriving/mod.rs | 134 +- src/libsyntax_ext/env.rs | 64 +- src/libsyntax_ext/format.rs | 230 +- src/libsyntax_ext/format_foreign.rs | 179 +- .../format_foreign/printf/tests.rs | 50 +- .../format_foreign/shell/tests.rs | 5 +- src/libsyntax_ext/global_allocator.rs | 20 +- src/libsyntax_ext/global_asm.rs | 39 +- src/libsyntax_ext/lib.rs | 14 +- src/libsyntax_ext/log_syntax.rs | 11 +- src/libsyntax_ext/proc_macro_harness.rs | 231 +- src/libsyntax_ext/source_util.rs | 89 +- src/libsyntax_ext/standard_library_imports.rs | 39 +- src/libsyntax_ext/test_harness.rs | 121 +- src/libsyntax_ext/trace_macros.rs | 15 +- src/libsyntax_ext/util.rs | 4 +- src/libsyntax_pos/analyze_source_file.rs | 42 +- .../analyze_source_file/tests.rs | 47 +- src/libsyntax_pos/caching_source_map_view.rs | 27 +- src/libsyntax_pos/edition.rs | 20 +- src/libsyntax_pos/hygiene.rs | 154 +- src/libsyntax_pos/lib.rs | 298 +- src/libsyntax_pos/source_map.rs | 301 +- src/libsyntax_pos/source_map/tests.rs | 37 +- src/libsyntax_pos/span_encoding.rs | 4 +- src/libsyntax_pos/symbol.rs | 55 +- src/libsyntax_pos/tests.rs | 9 +- src/libterm/lib.rs | 16 +- src/libterm/terminfo/mod.rs | 53 +- src/libterm/terminfo/parm.rs | 246 +- src/libterm/terminfo/parm/tests.rs | 105 +- src/libterm/terminfo/parser/compiled.rs | 77 +- src/libterm/win.rs | 20 +- src/libtest/bench.rs | 36 +- src/libtest/cli.rs | 46 +- src/libtest/console.rs | 75 +- src/libtest/event.rs | 11 +- src/libtest/formatters/json.rs | 29 +- src/libtest/formatters/mod.rs | 15 +- src/libtest/formatters/pretty.rs | 32 +- src/libtest/formatters/terse.rs | 26 +- src/libtest/helpers/exit_code.rs | 2 +- src/libtest/helpers/isatty.rs | 3 +- src/libtest/helpers/mod.rs | 2 +- src/libtest/lib.rs | 135 +- src/libtest/options.rs | 5 +- src/libtest/stats/tests.rs | 11 +- src/libtest/test_result.rs | 4 +- src/libtest/tests.rs | 120 +- src/libtest/time.rs | 51 +- src/libtest/types.rs | 6 +- src/libunwind/build.rs | 6 +- src/libunwind/lib.rs | 6 +- src/libunwind/libunwind.rs | 15 +- src/rtstartup/rsbegin.rs | 10 +- src/rtstartup/rsend.rs | 4 +- src/rustc/rustc.rs | 19 +- src/tools/cargotest/main.rs | 44 +- src/tools/compiletest/src/common.rs | 2 +- src/tools/compiletest/src/errors.rs | 29 +- src/tools/compiletest/src/header.rs | 167 +- src/tools/compiletest/src/json.rs | 66 +- src/tools/compiletest/src/main.rs | 344 +- src/tools/compiletest/src/raise_fd_limit.rs | 15 +- src/tools/compiletest/src/read2.rs | 5 +- src/tools/compiletest/src/runtest.rs | 851 +-- src/tools/compiletest/src/runtest/tests.rs | 19 +- src/tools/compiletest/src/util.rs | 10 +- src/tools/error_index_generator/build.rs | 13 +- src/tools/error_index_generator/main.rs | 111 +- src/tools/linkchecker/main.rs | 168 +- src/tools/remote-test-client/src/main.rs | 162 +- src/tools/remote-test-server/src/main.rs | 49 +- src/tools/rustdoc-themes/main.rs | 14 +- src/tools/rustdoc/main.rs | 4 +- src/tools/tidy/src/bins.rs | 58 +- src/tools/tidy/src/cargo.rs | 23 +- src/tools/tidy/src/debug_artifacts.rs | 3 +- src/tools/tidy/src/deps.rs | 20 +- src/tools/tidy/src/error_codes_check.rs | 64 +- src/tools/tidy/src/errors.rs | 89 +- src/tools/tidy/src/extdeps.rs | 6 +- src/tools/tidy/src/features.rs | 408 +- src/tools/tidy/src/features/version.rs | 9 +- src/tools/tidy/src/lib.rs | 42 +- src/tools/tidy/src/main.rs | 4 +- src/tools/tidy/src/pal.rs | 72 +- src/tools/tidy/src/style.rs | 63 +- src/tools/tidy/src/ui_tests.rs | 6 +- src/tools/tidy/src/unit_tests.rs | 58 +- src/tools/tidy/src/unstable_book.rs | 62 +- src/tools/unstable-book-gen/src/main.rs | 92 +- 1160 files changed, 66321 insertions(+), 74703 deletions(-) diff --git a/src/bootstrap/bin/llvm-config-wrapper.rs b/src/bootstrap/bin/llvm-config-wrapper.rs index 5e3625eb22e52..cf77af44ff606 100644 --- a/src/bootstrap/bin/llvm-config-wrapper.rs +++ b/src/bootstrap/bin/llvm-config-wrapper.rs @@ -2,8 +2,8 @@ // `src/bootstrap/native.rs` for why this is needed when compiling LLD. use std::env; -use std::process::{self, Stdio, Command}; use std::io::{self, Write}; +use std::process::{self, Command, Stdio}; fn main() { let real_llvm_config = env::var_os("LLVM_CONFIG_REAL").unwrap(); diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs index 138b7f4b26104..b67486c9628cd 100644 --- a/src/bootstrap/bin/main.rs +++ b/src/bootstrap/bin/main.rs @@ -7,7 +7,7 @@ use std::env; -use bootstrap::{Config, Build}; +use bootstrap::{Build, Config}; fn main() { let args = env::args().skip(1).collect::>(); diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 475f2e904639c..a34ec44566bc1 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -27,9 +27,7 @@ fn main() { // Detect whether or not we're a build script depending on whether --target // is passed (a bit janky...) - let target = args.windows(2) - .find(|w| &*w[0] == "--target") - .and_then(|w| w[1].to_str()); + let target = args.windows(2).find(|w| &*w[0] == "--target").and_then(|w| w[1].to_str()); let version = args.iter().find(|w| &**w == "-vV"); let verbose = match env::var("RUSTC_VERBOSE") { @@ -57,19 +55,16 @@ fn main() { dylib_path.insert(0, PathBuf::from(&libdir)); let mut cmd = Command::new(rustc); - cmd.args(&args) - .env(bootstrap::util::dylib_path_var(), - env::join_paths(&dylib_path).unwrap()); + cmd.args(&args).env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); // Get the name of the crate we're compiling, if any. - let crate_name = args.windows(2) - .find(|args| args[0] == "--crate-name") - .and_then(|args| args[1].to_str()); + let crate_name = + args.windows(2).find(|args| args[0] == "--crate-name").and_then(|args| args[1].to_str()); if let Some(crate_name) = crate_name { if let Some(target) = env::var_os("RUSTC_TIME") { - if target == "all" || - target.into_string().unwrap().split(",").any(|c| c.trim() == crate_name) + if target == "all" + || target.into_string().unwrap().split(",").any(|c| c.trim() == crate_name) { cmd.arg("-Ztime"); } @@ -101,15 +96,22 @@ fn main() { // `compiler_builtins` are unconditionally compiled with panic=abort to // workaround undefined references to `rust_eh_unwind_resume` generated // otherwise, see issue https://github.com/rust-lang/rust/issues/43095. - if crate_name == Some("panic_abort") || - crate_name == Some("compiler_builtins") && stage != "0" { + if crate_name == Some("panic_abort") + || crate_name == Some("compiler_builtins") && stage != "0" + { cmd.arg("-C").arg("panic=abort"); } // Set various options from config.toml to configure how we're building // code. let debug_assertions = match env::var("RUSTC_DEBUG_ASSERTIONS") { - Ok(s) => if s == "true" { "y" } else { "n" }, + Ok(s) => { + if s == "true" { + "y" + } else { + "n" + } + } Err(..) => "n", }; @@ -178,17 +180,17 @@ fn main() { if env::var_os("RUSTC_PRINT_STEP_TIMINGS").is_some() { if let Some(crate_name) = crate_name { let start = Instant::now(); - let status = cmd - .status() - .unwrap_or_else(|_| panic!("\n\n failed to run {:?}", cmd)); + let status = cmd.status().unwrap_or_else(|_| panic!("\n\n failed to run {:?}", cmd)); let dur = start.elapsed(); let is_test = args.iter().any(|a| a == "--test"); - eprintln!("[RUSTC-TIMING] {} test:{} {}.{:03}", - crate_name, - is_test, - dur.as_secs(), - dur.subsec_nanos() / 1_000_000); + eprintln!( + "[RUSTC-TIMING] {} test:{} {}.{:03}", + crate_name, + is_test, + dur.as_secs(), + dur.subsec_nanos() / 1_000_000 + ); match status.code() { Some(i) => std::process::exit(i), diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index 6937fb922de48..8c8b33a4e4e0a 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -3,9 +3,9 @@ //! See comments in `src/bootstrap/rustc.rs` for more information. use std::env; -use std::process::Command; -use std::path::PathBuf; use std::ffi::OsString; +use std::path::PathBuf; +use std::process::Command; fn main() { let args = env::args_os().skip(1).collect::>(); @@ -35,8 +35,7 @@ fn main() { .arg("dox") .arg("--sysroot") .arg(&sysroot) - .env(bootstrap::util::dylib_path_var(), - env::join_paths(&dylib_path).unwrap()); + .env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); // Force all crates compiled by this compiler to (a) be unstable and (b) // allow the `rustc_private` feature to link to other unstable crates @@ -55,8 +54,7 @@ fn main() { if let Some(version) = env::var_os("RUSTDOC_CRATE_VERSION") { // This "unstable-options" can be removed when `--crate-version` is stabilized if !has_unstable { - cmd.arg("-Z") - .arg("unstable-options"); + cmd.arg("-Z").arg("unstable-options"); } cmd.arg("--crate-version").arg(version); has_unstable = true; @@ -66,8 +64,7 @@ fn main() { if let Some(_) = env::var_os("RUSTDOC_GENERATE_REDIRECT_PAGES") { // This "unstable-options" can be removed when `--generate-redirect-pages` is stabilized if !has_unstable { - cmd.arg("-Z") - .arg("unstable-options"); + cmd.arg("-Z").arg("unstable-options"); } cmd.arg("--generate-redirect-pages"); has_unstable = true; @@ -77,8 +74,7 @@ fn main() { if let Some(ref x) = env::var_os("RUSTDOC_RESOURCE_SUFFIX") { // This "unstable-options" can be removed when `--resource-suffix` is stabilized if !has_unstable { - cmd.arg("-Z") - .arg("unstable-options"); + cmd.arg("-Z").arg("unstable-options"); } cmd.arg("--resource-suffix").arg(x); } diff --git a/src/bootstrap/bin/sccache-plus-cl.rs b/src/bootstrap/bin/sccache-plus-cl.rs index f40eec83ddf32..554c2dd4d81ea 100644 --- a/src/bootstrap/bin/sccache-plus-cl.rs +++ b/src/bootstrap/bin/sccache-plus-cl.rs @@ -8,12 +8,12 @@ fn main() { env::set_var("CXX", env::var_os("SCCACHE_CXX").unwrap()); let mut cfg = cc::Build::new(); cfg.cargo_metadata(false) - .out_dir("/") - .target(&target) - .host(&target) - .opt_level(0) - .warnings(false) - .debug(false); + .out_dir("/") + .target(&target) + .host(&target) + .opt_level(0) + .warnings(false) + .debug(false); let compiler = cfg.get_compiler(); // Invoke sccache with said compiler diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index bd0462fca6dfe..a2dca66697d6d 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -24,7 +24,7 @@ use crate::native; use crate::test; use crate::tool; use crate::util::{self, add_lib_path, exe, libdir}; -use crate::{Build, DocTests, Mode, GitRepo}; +use crate::{Build, DocTests, GitRepo, Mode}; pub use crate::Compiler; @@ -122,11 +122,7 @@ impl PathSet { fn path(&self, builder: &Builder<'_>) -> PathBuf { match self { - PathSet::Set(set) => set - .iter() - .next() - .unwrap_or(&builder.build.src) - .to_path_buf(), + PathSet::Set(set) => set.iter().next().unwrap_or(&builder.build.src).to_path_buf(), PathSet::Suite(path) => PathBuf::from(path), } } @@ -180,10 +176,8 @@ impl StepDescription { } fn run(v: &[StepDescription], builder: &Builder<'_>, paths: &[PathBuf]) { - let should_runs = v - .iter() - .map(|desc| (desc.should_run)(ShouldRun::new(builder))) - .collect::>(); + let should_runs = + v.iter().map(|desc| (desc.should_run)(ShouldRun::new(builder))).collect::>(); // sanity checks on rules for (desc, should_run) in v.iter().zip(&should_runs) { @@ -280,8 +274,7 @@ impl<'a> ShouldRun<'a> { // multiple aliases for the same job pub fn paths(mut self, paths: &[&str]) -> Self { - self.paths - .insert(PathSet::Set(paths.iter().map(PathBuf::from).collect())); + self.paths.insert(PathSet::Set(paths.iter().map(PathBuf::from).collect())); self } @@ -354,11 +347,9 @@ impl<'a> Builder<'a> { tool::Miri, native::Lld ), - Kind::Check | Kind::Clippy | Kind::Fix | Kind::Format => describe!( - check::Std, - check::Rustc, - check::Rustdoc - ), + Kind::Check | Kind::Clippy | Kind::Fix | Kind::Format => { + describe!(check::Std, check::Rustc, check::Rustdoc) + } Kind::Test => describe!( crate::toolstate::ToolStateCheck, test::Tidy, @@ -549,9 +540,7 @@ impl<'a> Builder<'a> { /// obtained through this function, since it ensures that they are valid /// (i.e., built and assembled). pub fn compiler(&self, stage: u32, host: Interned) -> Compiler { - self.ensure(compile::Assemble { - target_compiler: Compiler { stage, host }, - }) + self.ensure(compile::Assemble { target_compiler: Compiler { stage, host } }) } /// Similar to `compiler`, except handles the full-bootstrap option to @@ -627,9 +616,10 @@ impl<'a> Builder<'a> { self.rustc_snapshot_libdir() } else { match self.config.libdir_relative() { - Some(relative_libdir) if compiler.stage >= 1 - => self.sysroot(compiler).join(relative_libdir), - _ => self.sysroot(compiler).join(libdir(&compiler.host)) + Some(relative_libdir) if compiler.stage >= 1 => { + self.sysroot(compiler).join(relative_libdir) + } + _ => self.sysroot(compiler).join(libdir(&compiler.host)), } } } @@ -644,9 +634,8 @@ impl<'a> Builder<'a> { libdir(&self.config.build).as_ref() } else { match self.config.libdir_relative() { - Some(relative_libdir) if compiler.stage >= 1 - => relative_libdir, - _ => libdir(&compiler.host).as_ref() + Some(relative_libdir) if compiler.stage >= 1 => relative_libdir, + _ => libdir(&compiler.host).as_ref(), } } } @@ -657,9 +646,8 @@ impl<'a> Builder<'a> { /// For example this returns `lib` on Unix and Windows. pub fn sysroot_libdir_relative(&self, compiler: Compiler) -> &Path { match self.config.libdir_relative() { - Some(relative_libdir) if compiler.stage >= 1 - => relative_libdir, - _ => Path::new("lib") + Some(relative_libdir) if compiler.stage >= 1 => relative_libdir, + _ => Path::new("lib"), } } @@ -681,9 +669,7 @@ impl<'a> Builder<'a> { if compiler.is_snapshot(self) { self.initial_rustc.clone() } else { - self.sysroot(compiler) - .join("bin") - .join(exe("rustc", &compiler.host)) + self.sysroot(compiler).join("bin").join(exe("rustc", &compiler.host)) } } @@ -740,17 +726,10 @@ impl<'a> Builder<'a> { self.clear_if_dirty(&my_out, &rustdoc); } - cargo - .env("CARGO_TARGET_DIR", out_dir) - .arg(cmd) - .arg("-Zconfig-profile"); + cargo.env("CARGO_TARGET_DIR", out_dir).arg(cmd).arg("-Zconfig-profile"); let profile_var = |name: &str| { - let profile = if self.config.rust_optimize { - "RELEASE" - } else { - "DEV" - }; + let profile = if self.config.rust_optimize { "RELEASE" } else { "DEV" }; format!("CARGO_PROFILE_{}_{}", profile, name) }; @@ -762,8 +741,7 @@ impl<'a> Builder<'a> { } if cmd != "install" { - cargo.arg("--target") - .arg(target); + cargo.arg("--target").arg(target); } else { assert_eq!(target, compiler.host); } @@ -801,14 +779,14 @@ impl<'a> Builder<'a> { } match mode { - Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {}, + Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {} Mode::Rustc | Mode::Codegen | Mode::ToolRustc => { // Build proc macros both for the host and the target if target != compiler.host && cmd != "check" { cargo.arg("-Zdual-proc-macros"); rustflags.arg("-Zdual-proc-macros"); } - }, + } } // This tells Cargo (and in turn, rustc) to output more complete @@ -884,11 +862,7 @@ impl<'a> Builder<'a> { assert!(!use_snapshot || stage == 0 || self.local_rebuild); let maybe_sysroot = self.sysroot(compiler); - let sysroot = if use_snapshot { - self.rustc_snapshot_sysroot() - } else { - &maybe_sysroot - }; + let sysroot = if use_snapshot { self.rustc_snapshot_sysroot() } else { &maybe_sysroot }; let libdir = self.rustc_libdir(compiler); // Customize the compiler we're running. Specify the compiler to cargo @@ -902,10 +876,7 @@ impl<'a> Builder<'a> { .env("RUSTC", self.out.join("bootstrap/debug/rustc")) .env("RUSTC_REAL", self.rustc(compiler)) .env("RUSTC_STAGE", stage.to_string()) - .env( - "RUSTC_DEBUG_ASSERTIONS", - self.config.rust_debug_assertions.to_string(), - ) + .env("RUSTC_DEBUG_ASSERTIONS", self.config.rust_debug_assertions.to_string()) .env("RUSTC_SYSROOT", &sysroot) .env("RUSTC_LIBDIR", &libdir) .env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc")) @@ -948,7 +919,6 @@ impl<'a> Builder<'a> { // to change a flag in a binary? if self.config.rust_rpath && util::use_host_linker(&target) { let rpath = if target.contains("apple") { - // Note that we need to take one extra step on macOS to also pass // `-Wl,-instal_name,@rpath/...` to get things to work right. To // do that we pass a weird flag to the compiler to get it to do @@ -980,8 +950,9 @@ impl<'a> Builder<'a> { let debuginfo_level = match mode { Mode::Rustc | Mode::Codegen => self.config.rust_debuginfo_level_rustc, Mode::Std => self.config.rust_debuginfo_level_std, - Mode::ToolBootstrap | Mode::ToolStd | - Mode::ToolRustc => self.config.rust_debuginfo_level_tools, + Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustc => { + self.config.rust_debuginfo_level_tools + } }; cargo.env(profile_var("DEBUG"), debuginfo_level.to_string()); @@ -1102,14 +1073,11 @@ impl<'a> Builder<'a> { cargo.env(format!("CC_{}", target), &cc); let cflags = self.cflags(target, GitRepo::Rustc).join(" "); - cargo - .env(format!("CFLAGS_{}", target), cflags.clone()); + cargo.env(format!("CFLAGS_{}", target), cflags.clone()); if let Some(ar) = self.ar(target) { let ranlib = format!("{} s", ar.display()); - cargo - .env(format!("AR_{}", target), ar) - .env(format!("RANLIB_{}", target), ranlib); + cargo.env(format!("AR_{}", target), ar).env(format!("RANLIB_{}", target), ranlib); } if let Ok(cxx) = self.cxx(target) { @@ -1120,15 +1088,14 @@ impl<'a> Builder<'a> { } } - if mode == Mode::Std - && self.config.extended - && compiler.is_final_stage(self) - { + if mode == Mode::Std && self.config.extended && compiler.is_final_stage(self) { rustflags.arg("-Zsave-analysis"); - cargo.env("RUST_SAVE_ANALYSIS_CONFIG", - "{\"output_file\": null,\"full_docs\": false,\ + cargo.env( + "RUST_SAVE_ANALYSIS_CONFIG", + "{\"output_file\": null,\"full_docs\": false,\ \"pub_only\": true,\"reachable_only\": false,\ - \"distro_crate\": true,\"signatures\": false,\"borrow_data\": false}"); + \"distro_crate\": true,\"signatures\": false,\"borrow_data\": false}", + ); } // For `cargo doc` invocations, make rustdoc print the Rust version into the docs @@ -1182,8 +1149,7 @@ impl<'a> Builder<'a> { } match (mode, self.config.rust_codegen_units_std, self.config.rust_codegen_units) { - (Mode::Std, Some(n), _) | - (_, _, Some(n)) => { + (Mode::Std, Some(n), _) | (_, _, Some(n)) => { cargo.env(profile_var("CODEGEN_UNITS"), n.to_string()); } _ => { @@ -1217,10 +1183,7 @@ impl<'a> Builder<'a> { rustflags.arg("-Cprefer-dynamic"); } - Cargo { - command: cargo, - rustflags, - } + Cargo { command: cargo, rustflags } } /// Ensure that a given step is built, returning its output. This will @@ -1231,10 +1194,7 @@ impl<'a> Builder<'a> { let mut stack = self.stack.borrow_mut(); for stack_step in stack.iter() { // should skip - if stack_step - .downcast_ref::() - .map_or(true, |stack_step| *stack_step != step) - { + if stack_step.downcast_ref::().map_or(true, |stack_step| *stack_step != step) { continue; } let mut out = String::new(); @@ -1277,11 +1237,7 @@ impl<'a> Builder<'a> { let cur_step = stack.pop().expect("step stack empty"); assert_eq!(cur_step.downcast_ref(), Some(&step)); } - self.verbose(&format!( - "{}< {:?}", - " ".repeat(self.stack.borrow().len()), - step - )); + self.verbose(&format!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step)); self.cache.put(step, out.clone()); out } @@ -1344,7 +1300,9 @@ impl Cargo { } pub fn args(&mut self, args: I) -> &mut Cargo - where I: IntoIterator, S: AsRef + where + I: IntoIterator, + S: AsRef, { for arg in args { self.arg(arg.as_ref()); diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index b9d97fb8b760a..5fefb972866a9 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -11,12 +11,10 @@ fn configure(host: &[&str], target: &[&str]) -> Config { config.skip_only_host_steps = false; config.dry_run = true; // try to avoid spurious failures in dist where we create/delete each others file - let dir = config.out.join("tmp-rustbuild-tests").join( - &thread::current() - .name() - .unwrap_or("unknown") - .replace(":", "-"), - ); + let dir = config + .out + .join("tmp-rustbuild-tests") + .join(&thread::current().name().unwrap_or("unknown").replace(":", "-")); t!(fs::create_dir_all(&dir)); config.out = dir; config.build = INTERNER.intern_str("A"); @@ -46,26 +44,15 @@ fn dist_baseline() { let a = INTERNER.intern_str("A"); - assert_eq!( - first(builder.cache.all::()), - &[dist::Docs { host: a },] - ); - assert_eq!( - first(builder.cache.all::()), - &[dist::Mingw { host: a },] - ); + assert_eq!(first(builder.cache.all::()), &[dist::Docs { host: a },]); + assert_eq!(first(builder.cache.all::()), &[dist::Mingw { host: a },]); assert_eq!( first(builder.cache.all::()), - &[dist::Rustc { - compiler: Compiler { host: a, stage: 2 } - },] + &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] ); assert_eq!( first(builder.cache.all::()), - &[dist::Std { - compiler: Compiler { host: a, stage: 1 }, - target: a, - },] + &[dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },] ); assert_eq!(first(builder.cache.all::()), &[dist::Src]); } @@ -81,10 +68,7 @@ fn dist_with_targets() { assert_eq!( first(builder.cache.all::()), - &[ - dist::Docs { host: a }, - dist::Docs { host: b }, - ] + &[dist::Docs { host: a }, dist::Docs { host: b },] ); assert_eq!( first(builder.cache.all::()), @@ -92,21 +76,13 @@ fn dist_with_targets() { ); assert_eq!( first(builder.cache.all::()), - &[dist::Rustc { - compiler: Compiler { host: a, stage: 2 } - },] + &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] ); assert_eq!( first(builder.cache.all::()), &[ - dist::Std { - compiler: Compiler { host: a, stage: 1 }, - target: a, - }, - dist::Std { - compiler: Compiler { host: a, stage: 2 }, - target: b, - }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, ] ); assert_eq!(first(builder.cache.all::()), &[dist::Src]); @@ -123,10 +99,7 @@ fn dist_with_hosts() { assert_eq!( first(builder.cache.all::()), - &[ - dist::Docs { host: a }, - dist::Docs { host: b }, - ] + &[dist::Docs { host: a }, dist::Docs { host: b },] ); assert_eq!( first(builder.cache.all::()), @@ -135,25 +108,15 @@ fn dist_with_hosts() { assert_eq!( first(builder.cache.all::()), &[ - dist::Rustc { - compiler: Compiler { host: a, stage: 2 } - }, - dist::Rustc { - compiler: Compiler { host: b, stage: 2 } - }, + dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, + dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, ] ); assert_eq!( first(builder.cache.all::()), &[ - dist::Std { - compiler: Compiler { host: a, stage: 1 }, - target: a, - }, - dist::Std { - compiler: Compiler { host: a, stage: 1 }, - target: b, - }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, ] ); assert_eq!(first(builder.cache.all::()), &[dist::Src]); @@ -172,23 +135,13 @@ fn dist_only_cross_host() { assert_eq!( first(builder.cache.all::()), - &[ - dist::Rustc { - compiler: Compiler { host: b, stage: 2 } - }, - ] + &[dist::Rustc { compiler: Compiler { host: b, stage: 2 } },] ); assert_eq!( first(builder.cache.all::()), &[ - compile::Rustc { - compiler: Compiler { host: a, stage: 0 }, - target: a, - }, - compile::Rustc { - compiler: Compiler { host: a, stage: 1 }, - target: b, - }, + compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, ] ); } @@ -205,46 +158,25 @@ fn dist_with_targets_and_hosts() { assert_eq!( first(builder.cache.all::()), - &[ - dist::Docs { host: a }, - dist::Docs { host: b }, - dist::Docs { host: c }, - ] + &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },] ); assert_eq!( first(builder.cache.all::()), - &[ - dist::Mingw { host: a }, - dist::Mingw { host: b }, - dist::Mingw { host: c }, - ] + &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },] ); assert_eq!( first(builder.cache.all::()), &[ - dist::Rustc { - compiler: Compiler { host: a, stage: 2 } - }, - dist::Rustc { - compiler: Compiler { host: b, stage: 2 } - }, + dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, + dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, ] ); assert_eq!( first(builder.cache.all::()), &[ - dist::Std { - compiler: Compiler { host: a, stage: 1 }, - target: a, - }, - dist::Std { - compiler: Compiler { host: a, stage: 1 }, - target: b, - }, - dist::Std { - compiler: Compiler { host: a, stage: 2 }, - target: c, - }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, ] ); assert_eq!(first(builder.cache.all::()), &[dist::Src]); @@ -264,36 +196,19 @@ fn dist_with_target_flag() { assert_eq!( first(builder.cache.all::()), - &[ - dist::Docs { host: a }, - dist::Docs { host: b }, - dist::Docs { host: c }, - ] + &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },] ); assert_eq!( first(builder.cache.all::()), - &[ - dist::Mingw { host: a }, - dist::Mingw { host: b }, - dist::Mingw { host: c }, - ] + &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },] ); assert_eq!(first(builder.cache.all::()), &[]); assert_eq!( first(builder.cache.all::()), &[ - dist::Std { - compiler: Compiler { host: a, stage: 1 }, - target: a, - }, - dist::Std { - compiler: Compiler { host: a, stage: 1 }, - target: b, - }, - dist::Std { - compiler: Compiler { host: a, stage: 2 }, - target: c, - }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, ] ); assert_eq!(first(builder.cache.all::()), &[]); @@ -310,10 +225,7 @@ fn dist_with_same_targets_and_hosts() { assert_eq!( first(builder.cache.all::()), - &[ - dist::Docs { host: a }, - dist::Docs { host: b }, - ] + &[dist::Docs { host: a }, dist::Docs { host: b },] ); assert_eq!( first(builder.cache.all::()), @@ -322,68 +234,35 @@ fn dist_with_same_targets_and_hosts() { assert_eq!( first(builder.cache.all::()), &[ - dist::Rustc { - compiler: Compiler { host: a, stage: 2 } - }, - dist::Rustc { - compiler: Compiler { host: b, stage: 2 } - }, + dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, + dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, ] ); assert_eq!( first(builder.cache.all::()), &[ - dist::Std { - compiler: Compiler { host: a, stage: 1 }, - target: a, - }, - dist::Std { - compiler: Compiler { host: a, stage: 1 }, - target: b, - }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, ] ); assert_eq!(first(builder.cache.all::()), &[dist::Src]); assert_eq!( first(builder.cache.all::()), &[ - compile::Std { - compiler: Compiler { host: a, stage: 0 }, - target: a, - }, - compile::Std { - compiler: Compiler { host: a, stage: 1 }, - target: a, - }, - compile::Std { - compiler: Compiler { host: a, stage: 2 }, - target: a, - }, - compile::Std { - compiler: Compiler { host: a, stage: 1 }, - target: b, - }, - compile::Std { - compiler: Compiler { host: a, stage: 2 }, - target: b, - }, + compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, ] ); assert_eq!( first(builder.cache.all::()), &[ - compile::Assemble { - target_compiler: Compiler { host: a, stage: 0 }, - }, - compile::Assemble { - target_compiler: Compiler { host: a, stage: 1 }, - }, - compile::Assemble { - target_compiler: Compiler { host: a, stage: 2 }, - }, - compile::Assemble { - target_compiler: Compiler { host: b, stage: 2 }, - }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, + compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } }, ] ); } @@ -401,76 +280,28 @@ fn build_default() { assert_eq!( first(builder.cache.all::()), &[ - compile::Std { - compiler: Compiler { host: a, stage: 0 }, - target: a, - }, - compile::Std { - compiler: Compiler { host: a, stage: 1 }, - target: a, - }, - compile::Std { - compiler: Compiler { host: a, stage: 2 }, - target: a, - }, - compile::Std { - compiler: Compiler { host: b, stage: 2 }, - target: a, - }, - compile::Std { - compiler: Compiler { host: a, stage: 1 }, - target: b, - }, - compile::Std { - compiler: Compiler { host: a, stage: 2 }, - target: b, - }, - compile::Std { - compiler: Compiler { host: b, stage: 2 }, - target: b, - }, - compile::Std { - compiler: Compiler { host: a, stage: 2 }, - target: c, - }, - compile::Std { - compiler: Compiler { host: b, stage: 2 }, - target: c, - }, + compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c }, ] ); assert!(!builder.cache.all::().is_empty()); assert_eq!( first(builder.cache.all::()), &[ - compile::Rustc { - compiler: Compiler { host: a, stage: 0 }, - target: a, - }, - compile::Rustc { - compiler: Compiler { host: a, stage: 1 }, - target: a, - }, - compile::Rustc { - compiler: Compiler { host: a, stage: 2 }, - target: a, - }, - compile::Rustc { - compiler: Compiler { host: b, stage: 2 }, - target: a, - }, - compile::Rustc { - compiler: Compiler { host: a, stage: 1 }, - target: b, - }, - compile::Rustc { - compiler: Compiler { host: a, stage: 2 }, - target: b, - }, - compile::Rustc { - compiler: Compiler { host: b, stage: 2 }, - target: b, - }, + compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: a }, + compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, + compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: b }, + compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: b }, ] ); } @@ -490,76 +321,32 @@ fn build_with_target_flag() { assert_eq!( first(builder.cache.all::()), &[ - compile::Std { - compiler: Compiler { host: a, stage: 0 }, - target: a, - }, - compile::Std { - compiler: Compiler { host: a, stage: 1 }, - target: a, - }, - compile::Std { - compiler: Compiler { host: a, stage: 2 }, - target: a, - }, - compile::Std { - compiler: Compiler { host: b, stage: 2 }, - target: a, - }, - compile::Std { - compiler: Compiler { host: a, stage: 1 }, - target: b, - }, - compile::Std { - compiler: Compiler { host: a, stage: 2 }, - target: b, - }, - compile::Std { - compiler: Compiler { host: b, stage: 2 }, - target: b, - }, - compile::Std { - compiler: Compiler { host: a, stage: 2 }, - target: c, - }, - compile::Std { - compiler: Compiler { host: b, stage: 2 }, - target: c, - }, + compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c }, ] ); assert_eq!( first(builder.cache.all::()), &[ - compile::Assemble { - target_compiler: Compiler { host: a, stage: 0 }, - }, - compile::Assemble { - target_compiler: Compiler { host: a, stage: 1 }, - }, - compile::Assemble { - target_compiler: Compiler { host: a, stage: 2 }, - }, - compile::Assemble { - target_compiler: Compiler { host: b, stage: 2 }, - }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, + compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } }, ] ); assert_eq!( first(builder.cache.all::()), &[ - compile::Rustc { - compiler: Compiler { host: a, stage: 0 }, - target: a, - }, - compile::Rustc { - compiler: Compiler { host: a, stage: 1 }, - target: a, - }, - compile::Rustc { - compiler: Compiler { host: a, stage: 1 }, - target: b, - }, + compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, ] ); } @@ -585,10 +372,8 @@ fn test_with_no_doc_stage0() { let host = INTERNER.intern_str("A"); - builder.run_step_descriptions( - &[StepDescription::from::()], - &["src/libstd".into()], - ); + builder + .run_step_descriptions(&[StepDescription::from::()], &["src/libstd".into()]); // Ensure we don't build any compiler artifacts. assert!(!builder.cache.contains::()); @@ -607,9 +392,7 @@ fn test_with_no_doc_stage0() { #[test] fn test_exclude() { let mut config = configure(&[], &[]); - config.exclude = vec![ - "src/tools/tidy".into(), - ]; + config.exclude = vec!["src/tools/tidy".into()]; config.cmd = Subcommand::Test { paths: Vec::new(), test_args: Vec::new(), diff --git a/src/bootstrap/cache.rs b/src/bootstrap/cache.rs index 4310f2c6fa140..0c16fae01bca7 100644 --- a/src/bootstrap/cache.rs +++ b/src/bootstrap/cache.rs @@ -1,6 +1,7 @@ use std::any::{Any, TypeId}; use std::borrow::Borrow; use std::cell::RefCell; +use std::cmp::{Ord, Ordering, PartialOrd}; use std::collections::HashMap; use std::convert::AsRef; use std::ffi::OsStr; @@ -11,7 +12,6 @@ use std::mem; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::sync::Mutex; -use std::cmp::{PartialOrd, Ord, Ordering}; use lazy_static::lazy_static; @@ -47,7 +47,7 @@ impl Eq for Interned {} impl PartialEq for Interned { fn eq(&self, other: &str) -> bool { - *self == other + *self == other } } impl<'a> PartialEq<&'a str> for Interned { @@ -168,24 +168,21 @@ struct TyIntern { impl Default for TyIntern { fn default() -> Self { - TyIntern { - items: Vec::new(), - set: Default::default(), - } + TyIntern { items: Vec::new(), set: Default::default() } } } impl TyIntern { fn intern_borrow(&mut self, item: &B) -> Interned where - B: Eq + Hash + ToOwned + ?Sized, + B: Eq + Hash + ToOwned + ?Sized, T: Borrow, { if let Some(i) = self.set.get(&item) { return *i; } let item = item.to_owned(); - let interned = Interned(self.items.len(), PhantomData::<*const T>); + let interned = Interned(self.items.len(), PhantomData::<*const T>); self.set.insert(item.clone(), interned); self.items.push(item); interned @@ -195,7 +192,7 @@ impl TyIntern { if let Some(i) = self.set.get(&item) { return *i; } - let interned = Interned(self.items.len(), PhantomData::<*const T>); + let interned = Interned(self.items.len(), PhantomData::<*const T>); self.set.insert(item.clone(), interned); self.items.push(item); interned @@ -235,10 +232,12 @@ lazy_static! { /// `get()` method. #[derive(Debug)] pub struct Cache( - RefCell, // actually a HashMap> - >> + RefCell< + HashMap< + TypeId, + Box, // actually a HashMap> + >, + >, ); impl Cache { @@ -249,10 +248,11 @@ impl Cache { pub fn put(&self, step: S, value: S::Output) { let mut cache = self.0.borrow_mut(); let type_id = TypeId::of::(); - let stepcache = cache.entry(type_id) - .or_insert_with(|| Box::new(HashMap::::new())) - .downcast_mut::>() - .expect("invalid type mapped"); + let stepcache = cache + .entry(type_id) + .or_insert_with(|| Box::new(HashMap::::new())) + .downcast_mut::>() + .expect("invalid type mapped"); assert!(!stepcache.contains_key(&step), "processing {:?} a second time", step); stepcache.insert(step, value); } @@ -260,10 +260,11 @@ impl Cache { pub fn get(&self, step: &S) -> Option { let mut cache = self.0.borrow_mut(); let type_id = TypeId::of::(); - let stepcache = cache.entry(type_id) - .or_insert_with(|| Box::new(HashMap::::new())) - .downcast_mut::>() - .expect("invalid type mapped"); + let stepcache = cache + .entry(type_id) + .or_insert_with(|| Box::new(HashMap::::new())) + .downcast_mut::>() + .expect("invalid type mapped"); stepcache.get(step).cloned() } } @@ -273,7 +274,8 @@ impl Cache { pub fn all(&mut self) -> Vec<(S, S::Output)> { let cache = self.0.get_mut(); let type_id = TypeId::of::(); - let mut v = cache.remove(&type_id) + let mut v = cache + .remove(&type_id) .map(|b| b.downcast::>().expect("correct type")) .map(|m| m.into_iter().collect::>()) .unwrap_or_default(); diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs index a4cb81d3d1b1b..a236edf971fcc 100644 --- a/src/bootstrap/cc_detect.rs +++ b/src/bootstrap/cc_detect.rs @@ -22,15 +22,15 @@ //! everything. use std::collections::HashSet; -use std::{env, iter}; use std::path::{Path, PathBuf}; use std::process::Command; +use std::{env, iter}; use build_helper::output; -use crate::{Build, GitRepo}; -use crate::config::Target; use crate::cache::Interned; +use crate::config::Target; +use crate::{Build, GitRepo}; // The `cc` crate doesn't provide a way to obtain a path to the detected archiver, // so use some simplified logic here. First we respect the environment variable `AR`, then @@ -64,14 +64,25 @@ fn cc2ar(cc: &Path, target: &str) -> Option { pub fn find(build: &mut Build) { // For all targets we're going to need a C compiler for building some shims // and such as well as for being a linker for Rust code. - let targets = build.targets.iter().chain(&build.hosts).cloned().chain(iter::once(build.build)) - .collect::>(); + let targets = build + .targets + .iter() + .chain(&build.hosts) + .cloned() + .chain(iter::once(build.build)) + .collect::>(); for target in targets.into_iter() { let mut cfg = cc::Build::new(); - cfg.cargo_metadata(false).opt_level(2).warnings(false).debug(false) - .target(&target).host(&build.build); + cfg.cargo_metadata(false) + .opt_level(2) + .warnings(false) + .debug(false) + .target(&target) + .host(&build.build); match build.crt_static(target) { - Some(a) => { cfg.static_crt(a); } + Some(a) => { + cfg.static_crt(a); + } None => { if target.contains("msvc") { cfg.static_crt(true); @@ -102,8 +113,13 @@ pub fn find(build: &mut Build) { // If we use llvm-libunwind, we will need a C++ compiler as well for all targets // We'll need one anyways if the target triple is also a host triple let mut cfg = cc::Build::new(); - cfg.cargo_metadata(false).opt_level(2).warnings(false).debug(false).cpp(true) - .target(&target).host(&build.build); + cfg.cargo_metadata(false) + .opt_level(2) + .warnings(false) + .debug(false) + .cpp(true) + .target(&target) + .host(&build.build); let cxx_configured = if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) { cfg.compiler(cxx); @@ -133,21 +149,24 @@ pub fn find(build: &mut Build) { } } -fn set_compiler(cfg: &mut cc::Build, - compiler: Language, - target: Interned, - config: Option<&Target>, - build: &Build) { +fn set_compiler( + cfg: &mut cc::Build, + compiler: Language, + target: Interned, + config: Option<&Target>, + build: &Build, +) { match &*target { // When compiling for android we may have the NDK configured in the // config.toml in which case we look there. Otherwise the default // compiler already takes into account the triple in question. t if t.contains("android") => { if let Some(ndk) = config.and_then(|c| c.ndk.as_ref()) { - let target = target.replace("armv7neon", "arm") - .replace("armv7", "arm") - .replace("thumbv7neon", "arm") - .replace("thumbv7", "arm"); + let target = target + .replace("armv7neon", "arm") + .replace("armv7", "arm") + .replace("thumbv7neon", "arm") + .replace("thumbv7", "arm"); let compiler = format!("{}-{}", target, compiler.clang()); cfg.compiler(ndk.join("bin").join(compiler)); } @@ -159,7 +178,7 @@ fn set_compiler(cfg: &mut cc::Build, let c = cfg.get_compiler(); let gnu_compiler = compiler.gcc(); if !c.path().ends_with(gnu_compiler) { - return + return; } let output = output(c.to_command().arg("--version")); @@ -168,7 +187,7 @@ fn set_compiler(cfg: &mut cc::Build, None => return, }; match output[i + 3..].chars().next().unwrap() { - '0' ..= '6' => {} + '0'..='6' => {} _ => return, } let alternative = format!("e{}", gnu_compiler); diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index ec4bf9a04fa94..38810237ef93c 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -29,31 +29,28 @@ impl GitInfo { pub fn new(ignore_git: bool, dir: &Path) -> GitInfo { // See if this even begins to look like a git dir if ignore_git || !dir.join(".git").exists() { - return GitInfo { inner: None } + return GitInfo { inner: None }; } // Make sure git commands work - match Command::new("git") - .arg("rev-parse") - .current_dir(dir) - .output() - { + match Command::new("git").arg("rev-parse").current_dir(dir).output() { Ok(ref out) if out.status.success() => {} _ => return GitInfo { inner: None }, } // Ok, let's scrape some info - let ver_date = output(Command::new("git").current_dir(dir) - .arg("log").arg("-1") - .arg("--date=short") - .arg("--pretty=format:%cd")); - let ver_hash = output(Command::new("git").current_dir(dir) - .arg("rev-parse").arg("HEAD")); - let short_ver_hash = output(Command::new("git") - .current_dir(dir) - .arg("rev-parse") - .arg("--short=9") - .arg("HEAD")); + let ver_date = output( + Command::new("git") + .current_dir(dir) + .arg("log") + .arg("-1") + .arg("--date=short") + .arg("--pretty=format:%cd"), + ); + let ver_hash = output(Command::new("git").current_dir(dir).arg("rev-parse").arg("HEAD")); + let short_ver_hash = output( + Command::new("git").current_dir(dir).arg("rev-parse").arg("--short=9").arg("HEAD"), + ); GitInfo { inner: Some(Info { commit_date: ver_date.trim().to_string(), diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index f5c427d870e71..d4016f16fa9d3 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -1,10 +1,10 @@ //! Implementation of compiling the compiler and standard library, in "check"-based modes. -use crate::compile::{run_cargo, std_cargo, rustc_cargo, add_to_sysroot}; -use crate::builder::{RunConfig, Builder, Kind, ShouldRun, Step}; +use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; +use crate::cache::Interned; +use crate::compile::{add_to_sysroot, run_cargo, rustc_cargo, std_cargo}; use crate::tool::{prepare_tool_cargo, SourceType}; use crate::{Compiler, Mode}; -use crate::cache::Interned; use std::path::PathBuf; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -15,7 +15,7 @@ pub struct Std { fn args(kind: Kind) -> Vec { match kind { Kind::Clippy => vec!["--".to_owned(), "--cap-lints".to_owned(), "warn".to_owned()], - _ => Vec::new() + _ => Vec::new(), } } @@ -24,7 +24,7 @@ fn cargo_subcommand(kind: Kind) -> &'static str { Kind::Check => "check", Kind::Clippy => "clippy", Kind::Fix => "fix", - _ => unreachable!() + _ => unreachable!(), } } @@ -37,9 +37,7 @@ impl Step for Std { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Std { - target: run.target, - }); + run.builder.ensure(Std { target: run.target }); } fn run(self, builder: &Builder<'_>) { @@ -50,12 +48,14 @@ impl Step for Std { std_cargo(builder, &compiler, target, &mut cargo); builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target)); - run_cargo(builder, - cargo, - args(builder.kind), - &libstd_stamp(builder, compiler, target), - vec![], - true); + run_cargo( + builder, + cargo, + args(builder.kind), + &libstd_stamp(builder, compiler, target), + vec![], + true, + ); let libdir = builder.sysroot_libdir(compiler, target); let hostdir = builder.sysroot_libdir(compiler, compiler.host); @@ -78,9 +78,7 @@ impl Step for Rustc { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rustc { - target: run.target, - }); + run.builder.ensure(Rustc { target: run.target }); } /// Builds the compiler. @@ -94,17 +92,19 @@ impl Step for Rustc { builder.ensure(Std { target }); - let mut cargo = builder.cargo(compiler, Mode::Rustc, target, - cargo_subcommand(builder.kind)); + let mut cargo = + builder.cargo(compiler, Mode::Rustc, target, cargo_subcommand(builder.kind)); rustc_cargo(builder, &mut cargo, target); builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target)); - run_cargo(builder, - cargo, - args(builder.kind), - &librustc_stamp(builder, compiler, target), - vec![], - true); + run_cargo( + builder, + cargo, + args(builder.kind), + &librustc_stamp(builder, compiler, target), + vec![], + true, + ); let libdir = builder.sysroot_libdir(compiler, target); let hostdir = builder.sysroot_libdir(compiler, compiler.host); @@ -127,9 +127,7 @@ impl Step for Rustdoc { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rustdoc { - target: run.target, - }); + run.builder.ensure(Rustdoc { target: run.target }); } fn run(self, builder: &Builder<'_>) { @@ -138,22 +136,26 @@ impl Step for Rustdoc { builder.ensure(Rustc { target }); - let cargo = prepare_tool_cargo(builder, - compiler, - Mode::ToolRustc, - target, - cargo_subcommand(builder.kind), - "src/tools/rustdoc", - SourceType::InTree, - &[]); + let cargo = prepare_tool_cargo( + builder, + compiler, + Mode::ToolRustc, + target, + cargo_subcommand(builder.kind), + "src/tools/rustdoc", + SourceType::InTree, + &[], + ); println!("Checking rustdoc artifacts ({} -> {})", &compiler.host, target); - run_cargo(builder, - cargo, - args(builder.kind), - &rustdoc_stamp(builder, compiler, target), - vec![], - true); + run_cargo( + builder, + cargo, + args(builder.kind), + &rustdoc_stamp(builder, compiler, target), + vec![], + true, + ); let libdir = builder.sysroot_libdir(compiler, target); let hostdir = builder.sysroot_libdir(compiler, compiler.host); @@ -188,6 +190,5 @@ pub fn rustdoc_stamp( compiler: Compiler, target: Interned, ) -> PathBuf { - builder.cargo_out(compiler, Mode::ToolRustc, target) - .join(".rustdoc-check.stamp") + builder.cargo_out(compiler, Mode::ToolRustc, target).join(".rustdoc-check.stamp") } diff --git a/src/bootstrap/clean.rs b/src/bootstrap/clean.rs index 73be8bfed8e88..b4e58c06fdea9 100644 --- a/src/bootstrap/clean.rs +++ b/src/bootstrap/clean.rs @@ -31,7 +31,7 @@ pub fn clean(build: &Build, all: bool) { for entry in entries { let entry = t!(entry); if entry.file_name().to_str() == Some("llvm") { - continue + continue; } let path = t!(entry.path().canonicalize()); rm_rf(&path); @@ -47,7 +47,7 @@ fn rm_rf(path: &Path) { return; } panic!("failed to get metadata for file {}: {}", path.display(), e); - }, + } Ok(metadata) => { if metadata.file_type().is_file() || metadata.file_type().is_symlink() { do_op(path, "remove file", |p| fs::remove_file(p)); @@ -58,20 +58,20 @@ fn rm_rf(path: &Path) { rm_rf(&t!(file).path()); } do_op(path, "remove dir", |p| fs::remove_dir(p)); - }, + } }; } fn do_op(path: &Path, desc: &str, mut f: F) - where F: FnMut(&Path) -> io::Result<()> +where + F: FnMut(&Path) -> io::Result<()>, { match f(path) { Ok(()) => {} // On windows we can't remove a readonly file, and git will often clone files as readonly. // As a result, we have some special logic to remove readonly files on windows. // This is also the reason that we can't use things like fs::remove_dir_all(). - Err(ref e) if cfg!(windows) && - e.kind() == ErrorKind::PermissionDenied => { + Err(ref e) if cfg!(windows) && e.kind() == ErrorKind::PermissionDenied => { let mut p = t!(path.symlink_metadata()).permissions(); p.set_readonly(false); t!(fs::set_permissions(path, p)); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 831053bc0f7e2..2d60024a22ac4 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -9,10 +9,10 @@ use std::borrow::Cow; use std::env; use std::fs; -use std::io::BufReader; use std::io::prelude::*; +use std::io::BufReader; use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio, exit}; +use std::process::{exit, Command, Stdio}; use std::str; use build_helper::{output, t, up_to_date}; @@ -20,14 +20,14 @@ use filetime::FileTime; use serde::Deserialize; use serde_json; -use crate::dist; use crate::builder::Cargo; -use crate::util::{exe, is_dylib}; -use crate::{Compiler, Mode, GitRepo}; +use crate::dist; use crate::native; +use crate::util::{exe, is_dylib}; +use crate::{Compiler, GitRepo, Mode}; -use crate::cache::{INTERNER, Interned}; -use crate::builder::{Step, RunConfig, ShouldRun, Builder, Kind}; +use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; +use crate::cache::{Interned, INTERNER}; #[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)] pub struct Std { @@ -61,11 +61,7 @@ impl Step for Std { if builder.config.keep_stage.contains(&compiler.stage) { builder.info("Warning: Using a potentially old libstd. This may not behave well."); - builder.ensure(StdLink { - compiler, - target_compiler: compiler, - target, - }); + builder.ensure(StdLink { compiler, target_compiler: compiler, target }); return; } @@ -73,10 +69,7 @@ impl Step for Std { let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); if compiler_to_use != compiler { - builder.ensure(Std { - compiler: compiler_to_use, - target, - }); + builder.ensure(Std { compiler: compiler_to_use, target }); builder.info(&format!("Uplifting stage1 std ({} -> {})", compiler_to_use.host, target)); // Even if we're not building std this stage, the new sysroot must @@ -96,14 +89,18 @@ impl Step for Std { let mut cargo = builder.cargo(compiler, Mode::Std, target, "build"); std_cargo(builder, &compiler, target, &mut cargo); - builder.info(&format!("Building stage{} std artifacts ({} -> {})", compiler.stage, - &compiler.host, target)); - run_cargo(builder, - cargo, - vec![], - &libstd_stamp(builder, compiler, target), - target_deps, - false); + builder.info(&format!( + "Building stage{} std artifacts ({} -> {})", + compiler.stage, &compiler.host, target + )); + run_cargo( + builder, + cargo, + vec![], + &libstd_stamp(builder, compiler, target), + target_deps, + false, + ); builder.ensure(StdLink { compiler: builder.compiler(compiler.stage, builder.config.build), @@ -114,19 +111,18 @@ impl Step for Std { } /// Copies third party objects needed by various targets. -fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target: Interned) - -> Vec -{ +fn copy_third_party_objects( + builder: &Builder<'_>, + compiler: &Compiler, + target: Interned, +) -> Vec { let libdir = builder.sysroot_libdir(*compiler, target); let mut target_deps = vec![]; let mut copy_and_stamp = |sourcedir: &Path, name: &str| { let target = libdir.join(name); - builder.copy( - &sourcedir.join(name), - &target, - ); + builder.copy(&sourcedir.join(name), &target); target_deps.push(target); }; @@ -162,10 +158,12 @@ fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target: /// Configure cargo to compile the standard library, adding appropriate env vars /// and such. -pub fn std_cargo(builder: &Builder<'_>, - compiler: &Compiler, - target: Interned, - cargo: &mut Cargo) { +pub fn std_cargo( + builder: &Builder<'_>, + compiler: &Compiler, + target: Interned, + cargo: &mut Cargo, +) { if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") { cargo.env("MACOSX_DEPLOYMENT_TARGET", target); } @@ -216,14 +214,14 @@ pub fn std_cargo(builder: &Builder<'_>, // missing // We also only build the runtimes when --enable-sanitizers (or its // config.toml equivalent) is used - let llvm_config = builder.ensure(native::Llvm { - target: builder.config.build, - }); + let llvm_config = builder.ensure(native::Llvm { target: builder.config.build }); cargo.env("LLVM_CONFIG", llvm_config); cargo.env("RUSTC_BUILD_SANITIZERS", "1"); } - cargo.arg("--features").arg(features) + cargo + .arg("--features") + .arg(features) .arg("--manifest-path") .arg(builder.src.join("src/libtest/Cargo.toml")); @@ -271,12 +269,10 @@ impl Step for StdLink { let compiler = self.compiler; let target_compiler = self.target_compiler; let target = self.target; - builder.info(&format!("Copying stage{} std from stage{} ({} -> {} / {})", - target_compiler.stage, - compiler.stage, - &compiler.host, - target_compiler.host, - target)); + builder.info(&format!( + "Copying stage{} std from stage{} ({} -> {} / {})", + target_compiler.stage, compiler.stage, &compiler.host, target_compiler.host, target + )); let libdir = builder.sysroot_libdir(target_compiler, target); let hostdir = builder.sysroot_libdir(target_compiler, compiler.host); add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target)); @@ -337,7 +333,7 @@ impl Step for StartupObjects { let for_compiler = self.compiler; let target = self.target; if !target.contains("windows-gnu") { - return vec![] + return vec![]; } let mut target_deps = vec![]; @@ -352,12 +348,17 @@ impl Step for StartupObjects { let dst_file = &dst_dir.join(file.to_string() + ".o"); if !up_to_date(src_file, dst_file) { let mut cmd = Command::new(&builder.initial_rustc); - builder.run(cmd.env("RUSTC_BOOTSTRAP", "1") - .arg("--cfg").arg("bootstrap") - .arg("--target").arg(target) - .arg("--emit=obj") - .arg("-o").arg(dst_file) - .arg(src_file)); + builder.run( + cmd.env("RUSTC_BOOTSTRAP", "1") + .arg("--cfg") + .arg("bootstrap") + .arg("--target") + .arg(target) + .arg("--emit=obj") + .arg("-o") + .arg(dst_file) + .arg(src_file), + ); } let target = sysroot_dir.join(file.to_string() + ".o"); @@ -366,10 +367,7 @@ impl Step for StartupObjects { } for obj in ["crt2.o", "dllcrt2.o"].iter() { - let src = compiler_file(builder, - builder.cc(target), - target, - obj); + let src = compiler_file(builder, builder.cc(target), target, obj); let target = sysroot_dir.join(obj); builder.copy(&src, &target); target_deps.push(target); @@ -414,22 +412,15 @@ impl Step for Rustc { if builder.config.keep_stage.contains(&compiler.stage) { builder.info("Warning: Using a potentially old librustc. This may not behave well."); - builder.ensure(RustcLink { - compiler, - target_compiler: compiler, - target, - }); + builder.ensure(RustcLink { compiler, target_compiler: compiler, target }); return; } let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); if compiler_to_use != compiler { - builder.ensure(Rustc { - compiler: compiler_to_use, - target, - }); - builder.info(&format!("Uplifting stage1 rustc ({} -> {})", - builder.config.build, target)); + builder.ensure(Rustc { compiler: compiler_to_use, target }); + builder + .info(&format!("Uplifting stage1 rustc ({} -> {})", builder.config.build, target)); builder.ensure(RustcLink { compiler: compiler_to_use, target_compiler: compiler, @@ -447,14 +438,18 @@ impl Step for Rustc { let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "build"); rustc_cargo(builder, &mut cargo, target); - builder.info(&format!("Building stage{} compiler artifacts ({} -> {})", - compiler.stage, &compiler.host, target)); - run_cargo(builder, - cargo, - vec![], - &librustc_stamp(builder, compiler, target), - vec![], - false); + builder.info(&format!( + "Building stage{} compiler artifacts ({} -> {})", + compiler.stage, &compiler.host, target + )); + run_cargo( + builder, + cargo, + vec![], + &librustc_stamp(builder, compiler, target), + vec![], + false, + ); // We used to build librustc_codegen_llvm as a separate step, // which produced a dylib that the compiler would dlopen() at runtime. @@ -503,19 +498,22 @@ impl Step for Rustc { } pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo, target: Interned) { - cargo.arg("--features").arg(builder.rustc_features()) - .arg("--manifest-path") - .arg(builder.src.join("src/rustc/Cargo.toml")); + cargo + .arg("--features") + .arg(builder.rustc_features()) + .arg("--manifest-path") + .arg(builder.src.join("src/rustc/Cargo.toml")); rustc_cargo_env(builder, cargo, target); } pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: Interned) { // Set some configuration variables picked up by build scripts and // the compiler alike - cargo.env("CFG_RELEASE", builder.rust_release()) - .env("CFG_RELEASE_CHANNEL", &builder.config.channel) - .env("CFG_VERSION", builder.rust_version()) - .env("CFG_PREFIX", builder.config.prefix.clone().unwrap_or_default()); + cargo + .env("CFG_RELEASE", builder.rust_release()) + .env("CFG_RELEASE_CHANNEL", &builder.config.channel) + .env("CFG_VERSION", builder.rust_version()) + .env("CFG_PREFIX", builder.config.prefix.clone().unwrap_or_default()); let libdir_relative = builder.config.libdir_relative().unwrap_or(Path::new("lib")); cargo.env("CFG_LIBDIR_RELATIVE", libdir_relative); @@ -561,14 +559,12 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: Interne } // Building with a static libstdc++ is only supported on linux right now, // not for MSVC or macOS - if builder.config.llvm_static_stdcpp && - !target.contains("freebsd") && - !target.contains("msvc") && - !target.contains("apple") { - let file = compiler_file(builder, - builder.cxx(target).unwrap(), - target, - "libstdc++.a"); + if builder.config.llvm_static_stdcpp + && !target.contains("freebsd") + && !target.contains("msvc") + && !target.contains("apple") + { + let file = compiler_file(builder, builder.cxx(target).unwrap(), target, "libstdc++.a"); cargo.env("LLVM_STATIC_STDCPP", file); } if builder.config.llvm_link_shared || builder.config.llvm_thin_lto { @@ -602,17 +598,15 @@ impl Step for RustcLink { let compiler = self.compiler; let target_compiler = self.target_compiler; let target = self.target; - builder.info(&format!("Copying stage{} rustc from stage{} ({} -> {} / {})", - target_compiler.stage, - compiler.stage, - &compiler.host, - target_compiler.host, - target)); + builder.info(&format!( + "Copying stage{} rustc from stage{} ({} -> {} / {})", + target_compiler.stage, compiler.stage, &compiler.host, target_compiler.host, target + )); add_to_sysroot( builder, &builder.sysroot_libdir(target_compiler, target), &builder.sysroot_libdir(target_compiler, compiler.host), - &librustc_stamp(builder, compiler, target) + &librustc_stamp(builder, compiler, target), ); } } @@ -706,8 +700,10 @@ impl Step for Assemble { let target_compiler = self.target_compiler; if target_compiler.stage == 0 { - assert_eq!(builder.config.build, target_compiler.host, - "Cannot obtain compiler for non-native build triple at stage 0"); + assert_eq!( + builder.config.build, target_compiler.host, + "Cannot obtain compiler for non-native build triple at stage 0" + ); // The stage 0 compiler for the build triple is always pre-built. return target_compiler; } @@ -728,23 +724,17 @@ impl Step for Assemble { // // FIXME: It may be faster if we build just a stage 1 compiler and then // use that to bootstrap this compiler forward. - let build_compiler = - builder.compiler(target_compiler.stage - 1, builder.config.build); + let build_compiler = builder.compiler(target_compiler.stage - 1, builder.config.build); // Build the libraries for this compiler to link to (i.e., the libraries // it uses at runtime). NOTE: Crates the target compiler compiles don't // link to these. (FIXME: Is that correct? It seems to be correct most // of the time but I think we do link to these for stage2/bin compilers // when not performing a full bootstrap). - builder.ensure(Rustc { - compiler: build_compiler, - target: target_compiler.host, - }); + builder.ensure(Rustc { compiler: build_compiler, target: target_compiler.host }); let lld_install = if builder.config.lld_enabled { - Some(builder.ensure(native::Lld { - target: target_compiler.host, - })) + Some(builder.ensure(native::Lld { target: target_compiler.host })) } else { None }; @@ -801,7 +791,7 @@ pub fn add_to_sysroot( builder: &Builder<'_>, sysroot_dst: &Path, sysroot_host_dst: &Path, - stamp: &Path + stamp: &Path, ) { t!(fs::create_dir_all(&sysroot_dst)); t!(fs::create_dir_all(&sysroot_host_dst)); @@ -814,14 +804,14 @@ pub fn add_to_sysroot( } } -pub fn run_cargo(builder: &Builder<'_>, - cargo: Cargo, - tail_args: Vec, - stamp: &Path, - additional_target_deps: Vec, - is_check: bool) - -> Vec -{ +pub fn run_cargo( + builder: &Builder<'_>, + cargo: Cargo, + tail_args: Vec, + stamp: &Path, + additional_target_deps: Vec, + is_check: bool, +) -> Vec { if builder.config.dry_run { return Vec::new(); } @@ -831,9 +821,12 @@ pub fn run_cargo(builder: &Builder<'_>, // `target_deps_dir` looks like $dir/$target/release/deps let target_deps_dir = target_root_dir.join("deps"); // `host_root_dir` looks like $dir/release - let host_root_dir = target_root_dir.parent().unwrap() // chop off `release` - .parent().unwrap() // chop off `$target` - .join(target_root_dir.file_name().unwrap()); + let host_root_dir = target_root_dir + .parent() + .unwrap() // chop off `release` + .parent() + .unwrap() // chop off `$target` + .join(target_root_dir.file_name().unwrap()); // Spawn Cargo slurping up its JSON output. We'll start building up the // `deps` array of all files it generated along with a `toplevel` array of @@ -844,20 +837,19 @@ pub fn run_cargo(builder: &Builder<'_>, let (filenames, crate_types) = match msg { CargoMessage::CompilerArtifact { filenames, - target: CargoTarget { - crate_types, - }, + target: CargoTarget { crate_types }, .. } => (filenames, crate_types), _ => return, }; for filename in filenames { // Skip files like executables - if !filename.ends_with(".rlib") && - !filename.ends_with(".lib") && - !filename.ends_with(".a") && - !is_dylib(&filename) && - !(is_check && filename.ends_with(".rmeta")) { + if !filename.ends_with(".rlib") + && !filename.ends_with(".lib") + && !filename.ends_with(".a") + && !is_dylib(&filename) + && !(is_check && filename.ends_with(".rmeta")) + { continue; } @@ -913,14 +905,13 @@ pub fn run_cargo(builder: &Builder<'_>, .collect::>(); for (prefix, extension, expected_len) in toplevel { let candidates = contents.iter().filter(|&&(_, ref filename, ref meta)| { - filename.starts_with(&prefix[..]) && - filename[prefix.len()..].starts_with("-") && - filename.ends_with(&extension[..]) && - meta.len() == expected_len - }); - let max = candidates.max_by_key(|&&(_, _, ref metadata)| { - FileTime::from_last_modification_time(metadata) + filename.starts_with(&prefix[..]) + && filename[prefix.len()..].starts_with("-") + && filename.ends_with(&extension[..]) + && meta.len() == expected_len }); + let max = candidates + .max_by_key(|&&(_, _, ref metadata)| FileTime::from_last_modification_time(metadata)); let path_to_add = match max { Some(triple) => triple.0.to_str().unwrap(), None => panic!("no output generated for {:?} {:?}", prefix, extension), @@ -960,7 +951,7 @@ pub fn stream_cargo( // Instruct Cargo to give us json messages on stdout, critically leaving // stderr as piped so we can get those pretty colors. let mut message_format = String::from("json-render-diagnostics"); - if let Some(s) = &builder.config.rustc_error_format { + if let Some(s) = &builder.config.rustc_error_format { message_format.push_str(",json-diagnostic-"); message_format.push_str(s); } @@ -985,17 +976,18 @@ pub fn stream_cargo( match serde_json::from_str::>(&line) { Ok(msg) => cb(msg), // If this was informational, just print it out and continue - Err(_) => println!("{}", line) + Err(_) => println!("{}", line), } } // Make sure Cargo actually succeeded after we read all of its stdout. let status = t!(child.wait()); if !status.success() { - eprintln!("command did not execute successfully: {:?}\n\ + eprintln!( + "command did not execute successfully: {:?}\n\ expected success, got: {}", - cargo, - status); + cargo, status + ); } status.success() } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 3e67734e69078..11bfc7a47cc48 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -3,20 +3,20 @@ //! This module implements parsing `config.toml` configuration files to tweak //! how the build runs. +use std::cmp; use std::collections::{HashMap, HashSet}; use std::env; use std::ffi::OsString; use std::fs; use std::path::{Path, PathBuf}; use std::process; -use std::cmp; -use build_helper::t; -use toml; -use serde::Deserialize; -use crate::cache::{INTERNER, Interned}; +use crate::cache::{Interned, INTERNER}; use crate::flags::Flags; pub use crate::flags::Subcommand; +use build_helper::t; +use serde::Deserialize; +use toml; /// Global configuration for the entire build and/or bootstrap. /// @@ -420,17 +420,22 @@ impl Config { let has_targets = !flags.target.is_empty(); config.skip_only_host_steps = !has_hosts && has_targets; - let toml = file.map(|file| { - let contents = t!(fs::read_to_string(&file)); - match toml::from_str(&contents) { - Ok(table) => table, - Err(err) => { - println!("failed to parse TOML configuration '{}': {}", - file.display(), err); - process::exit(2); + let toml = file + .map(|file| { + let contents = t!(fs::read_to_string(&file)); + match toml::from_str(&contents) { + Ok(table) => table, + Err(err) => { + println!( + "failed to parse TOML configuration '{}': {}", + file.display(), + err + ); + process::exit(2); + } } - } - }).unwrap_or_else(|| TomlConfig::default()); + }) + .unwrap_or_else(|| TomlConfig::default()); let build = toml.build.clone().unwrap_or_default(); // set by bootstrap.py @@ -441,24 +446,15 @@ impl Config { config.hosts.push(host); } } - for target in config.hosts.iter().cloned() - .chain(build.target.iter().map(|s| INTERNER.intern_str(s))) + for target in + config.hosts.iter().cloned().chain(build.target.iter().map(|s| INTERNER.intern_str(s))) { if !config.targets.contains(&target) { config.targets.push(target); } } - config.hosts = if !flags.host.is_empty() { - flags.host - } else { - config.hosts - }; - config.targets = if !flags.target.is_empty() { - flags.target - } else { - config.targets - }; - + config.hosts = if !flags.host.is_empty() { flags.host } else { config.hosts }; + config.targets = if !flags.target.is_empty() { flags.target } else { config.targets }; config.nodejs = build.nodejs.map(PathBuf::from); config.gdb = build.gdb.map(PathBuf::from); @@ -507,9 +503,7 @@ impl Config { if let Some(ref llvm) = toml.llvm { match llvm.ccache { - Some(StringOrBool::String(ref s)) => { - config.ccache = Some(s.to_string()) - } + Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()), Some(StringOrBool::Bool(true)) => { config.ccache = Some("ccache".to_string()); } @@ -574,9 +568,8 @@ impl Config { set(&mut config.rust_remap_debuginfo, rust.remap_debuginfo); if let Some(ref backends) = rust.codegen_backends { - config.rust_codegen_backends = backends.iter() - .map(|s| INTERNER.intern_str(s)) - .collect(); + config.rust_codegen_backends = + backends.iter().map(|s| INTERNER.intern_str(s)).collect(); } config.rust_codegen_units = rust.codegen_units.map(threads_from_config); @@ -634,9 +627,11 @@ impl Config { config.rust_debug_assertions = debug_assertions.unwrap_or(default); let with_defaults = |debuginfo_level_specific: Option| { - debuginfo_level_specific - .or(debuginfo_level) - .unwrap_or(if debug == Some(true) { 2 } else { 0 }) + debuginfo_level_specific.or(debuginfo_level).unwrap_or(if debug == Some(true) { + 2 + } else { + 0 + }) }; config.rust_debuginfo_level_rustc = with_defaults(debuginfo_level_rustc); config.rust_debuginfo_level_std = with_defaults(debuginfo_level_std); diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 02533944fc28f..e64d4c8637d55 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -11,18 +11,18 @@ use std::env; use std::fs; use std::io::Write; -use std::path::{PathBuf, Path}; +use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use build_helper::{output, t}; -use crate::{Compiler, Mode, LLVM_TOOLS}; -use crate::channel; -use crate::util::{is_dylib, exe, timeit}; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; +use crate::cache::{Interned, INTERNER}; +use crate::channel; use crate::compile; use crate::tool::{self, Tool}; -use crate::cache::{INTERNER, Interned}; +use crate::util::{exe, is_dylib, timeit}; +use crate::{Compiler, Mode, LLVM_TOOLS}; use time::{self, Timespec}; pub fn pkgname(builder: &Builder<'_>, component: &str) -> String { @@ -80,9 +80,7 @@ impl Step for Docs { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Docs { - host: run.target, - }); + run.builder.ensure(Docs { host: run.target }); } /// Builds the `rust-docs` installer component. @@ -110,16 +108,19 @@ impl Step for Docs { let mut cmd = rust_installer(builder); cmd.arg("generate") - .arg("--product-name=Rust-Documentation") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rust-documentation-is-installed.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", name, host)) - .arg("--component-name=rust-docs") - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--bulk-dirs=share/doc/rust/html"); + .arg("--product-name=Rust-Documentation") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=Rust-documentation-is-installed.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg(format!("--package-name={}-{}", name, host)) + .arg("--component-name=rust-docs") + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg("--bulk-dirs=share/doc/rust/html"); builder.run(&mut cmd); builder.remove_dir(&image); @@ -141,9 +142,7 @@ impl Step for RustcDocs { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(RustcDocs { - host: run.target, - }); + run.builder.ensure(RustcDocs { host: run.target }); } /// Builds the `rustc-docs` installer component. @@ -168,16 +167,19 @@ impl Step for RustcDocs { let mut cmd = rust_installer(builder); cmd.arg("generate") - .arg("--product-name=Rustc-Documentation") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rustc-documentation-is-installed.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", name, host)) - .arg("--component-name=rustc-docs") - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--bulk-dirs=share/doc/rust/html"); + .arg("--product-name=Rustc-Documentation") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=Rustc-documentation-is-installed.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg(format!("--package-name={}-{}", name, host)) + .arg("--component-name=rustc-docs") + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg("--bulk-dirs=share/doc/rust/html"); builder.info(&format!("Dist compiler docs ({})", host)); let _time = timeit(builder); @@ -192,10 +194,7 @@ fn find_files(files: &[&str], path: &[PathBuf]) -> Vec { let mut found = Vec::with_capacity(files.len()); for file in files { - let file_path = - path.iter() - .map(|dir| dir.join(file)) - .find(|p| p.exists()); + let file_path = path.iter().map(|dir| dir.join(file)).find(|p| p.exists()); if let Some(file_path) = file_path { found.push(file_path); @@ -208,7 +207,10 @@ fn find_files(files: &[&str], path: &[PathBuf]) -> Vec { } fn make_win_dist( - rust_root: &Path, plat_root: &Path, target_triple: Interned, builder: &Builder<'_> + rust_root: &Path, + plat_root: &Path, + target_triple: Interned, + builder: &Builder<'_>, ) { //Ask gcc where it keeps its stuff let mut cmd = Command::new(builder.cc(target_triple)); @@ -222,11 +224,7 @@ fn make_win_dist( let idx = line.find(':').unwrap(); let key = &line[..idx]; let trim_chars: &[_] = &[' ', '=']; - let value = - line[(idx + 1)..] - .trim_start_matches(trim_chars) - .split(';') - .map(PathBuf::from); + let value = line[(idx + 1)..].trim_start_matches(trim_chars).split(';').map(PathBuf::from); if key == "programs" { bin_path.extend(value); @@ -243,7 +241,8 @@ fn make_win_dist( rustc_dlls.push("libgcc_s_seh-1.dll"); } - let target_libs = [ //MinGW libs + let target_libs = [ + //MinGW libs "libgcc.a", "libgcc_eh.a", "libgcc_s.a", @@ -312,7 +311,7 @@ fn make_win_dist( &target_bin_dir.join("GCC-WARNING.txt"), "gcc.exe contained in this folder cannot be used for compiling C files - it is only\ used as a linker. In order to be able to compile projects containing C code use\ - the GCC provided by MinGW or Cygwin." + the GCC provided by MinGW or Cygwin.", ); //Copy platform libs to platform-specific lib directory @@ -366,15 +365,18 @@ impl Step for Mingw { let mut cmd = rust_installer(builder); cmd.arg("generate") - .arg("--product-name=Rust-MinGW") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rust-MinGW-is-installed.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", name, host)) - .arg("--component-name=rust-mingw") - .arg("--legacy-manifest-dirs=rustlib,cargo"); + .arg("--product-name=Rust-MinGW") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=Rust-MinGW-is-installed.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg(format!("--package-name={}-{}", name, host)) + .arg("--component-name=rust-mingw") + .arg("--legacy-manifest-dirs=rustlib,cargo"); builder.run(&mut cmd); t!(fs::remove_dir_all(&image)); Some(distdir(builder).join(format!("{}-{}.tar.gz", name, host))) @@ -396,9 +398,8 @@ impl Step for Rustc { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rustc { - compiler: run.builder.compiler(run.builder.top_stage, run.target), - }); + run.builder + .ensure(Rustc { compiler: run.builder.compiler(run.builder.top_stage, run.target) }); } /// Creates the `rustc` installer component. @@ -452,16 +453,20 @@ impl Step for Rustc { // Finally, wrap everything up in a nice tarball! let mut cmd = rust_installer(builder); cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rust-is-ready-to-roll.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg("--non-installed-overlay").arg(&overlay) - .arg(format!("--package-name={}-{}", name, host)) - .arg("--component-name=rustc") - .arg("--legacy-manifest-dirs=rustlib,cargo"); + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=Rust-is-ready-to-roll.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg("--non-installed-overlay") + .arg(&overlay) + .arg(format!("--package-name={}-{}", name, host)) + .arg("--component-name=rustc") + .arg("--legacy-manifest-dirs=rustlib,cargo"); builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host)); let _time = timeit(builder); @@ -508,16 +513,10 @@ impl Step for Rustc { // Copy over lld if it's there if builder.config.lld_enabled { let exe = exe("rust-lld", &compiler.host); - let src = builder.sysroot_libdir(compiler, host) - .parent() - .unwrap() - .join("bin") - .join(&exe); + let src = + builder.sysroot_libdir(compiler, host).parent().unwrap().join("bin").join(&exe); // for the rationale about this rename check `compile::copy_lld_to_sysroot` - let dst = image.join("lib/rustlib") - .join(&*host) - .join("bin") - .join(&exe); + let dst = image.join("lib/rustlib").join(&*host).join("bin").join(&exe); t!(fs::create_dir_all(&dst.parent().unwrap())); builder.copy(&src, &dst); } @@ -530,9 +529,10 @@ impl Step for Rustc { // Reproducible builds: If SOURCE_DATE_EPOCH is set, use that as the time. let time = env::var("SOURCE_DATE_EPOCH") .map(|timestamp| { - let epoch = timestamp.parse().map_err(|err| { - format!("could not parse SOURCE_DATE_EPOCH: {}", err) - }).unwrap(); + let epoch = timestamp + .parse() + .map_err(|err| format!("could not parse SOURCE_DATE_EPOCH: {}", err)) + .unwrap(); time::at(Timespec::new(epoch, 0)) }) @@ -546,16 +546,18 @@ impl Step for Rustc { let page_dst = man_dst.join(file_entry.file_name()); t!(fs::copy(&page_src, &page_dst)); // template in month/year and version number - builder.replace_in_file(&page_dst, - &[("", &month_year), - ("", channel::CFG_RELEASE_NUM)]); + builder.replace_in_file( + &page_dst, + &[ + ("", &month_year), + ("", channel::CFG_RELEASE_NUM), + ], + ); } // Debugger scripts - builder.ensure(DebuggerScripts { - sysroot: INTERNER.intern_path(image.to_owned()), - host, - }); + builder + .ensure(DebuggerScripts { sysroot: INTERNER.intern_path(image.to_owned()), host }); // Misc license info let cp = |file: &str| { @@ -600,8 +602,11 @@ impl Step for DebuggerScripts { }; if host.contains("windows-msvc") { // windbg debugger scripts - builder.install(&builder.src.join("src/etc/rust-windbg.cmd"), &sysroot.join("bin"), - 0o755); + builder.install( + &builder.src.join("src/etc/rust-windbg.cmd"), + &sysroot.join("bin"), + 0o755, + ); cp_debugger_script("natvis/intrinsic.natvis"); cp_debugger_script("natvis/liballoc.natvis"); @@ -611,17 +616,14 @@ impl Step for DebuggerScripts { cp_debugger_script("debugger_pretty_printers_common.py"); // gdb debugger scripts - builder.install(&builder.src.join("src/etc/rust-gdb"), &sysroot.join("bin"), - 0o755); - builder.install(&builder.src.join("src/etc/rust-gdbgui"), &sysroot.join("bin"), - 0o755); + builder.install(&builder.src.join("src/etc/rust-gdb"), &sysroot.join("bin"), 0o755); + builder.install(&builder.src.join("src/etc/rust-gdbgui"), &sysroot.join("bin"), 0o755); cp_debugger_script("gdb_load_rust_pretty_printers.py"); cp_debugger_script("gdb_rust_pretty_printing.py"); // lldb debugger scripts - builder.install(&builder.src.join("src/etc/rust-lldb"), &sysroot.join("bin"), - 0o755); + builder.install(&builder.src.join("src/etc/rust-lldb"), &sysroot.join("bin"), 0o755); cp_debugger_script("lldb_rust_formatters.py"); } @@ -696,18 +698,21 @@ impl Step for Std { let mut cmd = rust_installer(builder); cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=std-is-standing-at-the-ready.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", name, target)) - .arg(format!("--component-name=rust-std-{}", target)) - .arg("--legacy-manifest-dirs=rustlib,cargo"); - - builder.info(&format!("Dist std stage{} ({} -> {})", - compiler.stage, &compiler.host, target)); + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=std-is-standing-at-the-ready.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg(format!("--package-name={}-{}", name, target)) + .arg(format!("--component-name=rust-std-{}", target)) + .arg("--legacy-manifest-dirs=rustlib,cargo"); + + builder + .info(&format!("Dist std stage{} ({} -> {})", compiler.stage, &compiler.host, target)); let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); @@ -762,18 +767,23 @@ impl Step for RustcDev { let mut cmd = rust_installer(builder); cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rust-is-ready-to-develop.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", name, target)) - .arg(format!("--component-name=rustc-dev-{}", target)) - .arg("--legacy-manifest-dirs=rustlib,cargo"); - - builder.info(&format!("Dist rustc-dev stage{} ({} -> {})", - compiler.stage, &compiler.host, target)); + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=Rust-is-ready-to-develop.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg(format!("--package-name={}-{}", name, target)) + .arg(format!("--component-name=rustc-dev-{}", target)) + .arg("--legacy-manifest-dirs=rustlib,cargo"); + + builder.info(&format!( + "Dist rustc-dev stage{} ({} -> {})", + compiler.stage, &compiler.host, target + )); let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); @@ -825,8 +835,11 @@ impl Step for Analysis { let image = tmpdir(builder).join(format!("{}-{}-image", name, target)); - let src = builder.stage_out(compiler, Mode::Std) - .join(target).join(builder.cargo_dir()).join("deps"); + let src = builder + .stage_out(compiler, Mode::Std) + .join(target) + .join(builder.cargo_dir()) + .join("deps"); let image_src = src.join("save-analysis"); let dst = image.join("lib/rustlib").join(target).join("analysis"); @@ -836,15 +849,18 @@ impl Step for Analysis { let mut cmd = rust_installer(builder); cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=save-analysis-saved.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", name, target)) - .arg(format!("--component-name=rust-analysis-{}", target)) - .arg("--legacy-manifest-dirs=rustlib,cargo"); + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=save-analysis-saved.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg(format!("--package-name={}-{}", name, target)) + .arg(format!("--component-name=rust-analysis-{}", target)) + .arg("--legacy-manifest-dirs=rustlib,cargo"); builder.info("Dist analysis"); let _time = timeit(builder); @@ -861,31 +877,35 @@ fn copy_src_dirs(builder: &Builder<'_>, src_dirs: &[&str], exclude_dirs: &[&str] None => return false, }; if spath.ends_with("~") || spath.ends_with(".pyc") { - return false + return false; } const LLVM_PROJECTS: &[&str] = &[ - "llvm-project/clang", "llvm-project\\clang", - "llvm-project/libunwind", "llvm-project\\libunwind", - "llvm-project/lld", "llvm-project\\lld", - "llvm-project/lldb", "llvm-project\\lldb", - "llvm-project/llvm", "llvm-project\\llvm", - "llvm-project/compiler-rt", "llvm-project\\compiler-rt", + "llvm-project/clang", + "llvm-project\\clang", + "llvm-project/libunwind", + "llvm-project\\libunwind", + "llvm-project/lld", + "llvm-project\\lld", + "llvm-project/lldb", + "llvm-project\\lldb", + "llvm-project/llvm", + "llvm-project\\llvm", + "llvm-project/compiler-rt", + "llvm-project\\compiler-rt", ]; - if spath.contains("llvm-project") && !spath.ends_with("llvm-project") + if spath.contains("llvm-project") + && !spath.ends_with("llvm-project") && !LLVM_PROJECTS.iter().any(|path| spath.contains(path)) { return false; } - const LLVM_TEST: &[&str] = &[ - "llvm-project/llvm/test", "llvm-project\\llvm\\test", - ]; - if LLVM_TEST.iter().any(|path| spath.contains(path)) && - (spath.ends_with(".ll") || - spath.ends_with(".td") || - spath.ends_with(".s")) { - return false + const LLVM_TEST: &[&str] = &["llvm-project/llvm/test", "llvm-project\\llvm\\test"]; + if LLVM_TEST.iter().any(|path| spath.contains(path)) + && (spath.ends_with(".ll") || spath.ends_with(".td") || spath.ends_with(".s")) + { + return false; } let full_path = Path::new(dir).join(path); @@ -894,22 +914,37 @@ fn copy_src_dirs(builder: &Builder<'_>, src_dirs: &[&str], exclude_dirs: &[&str] } let excludes = [ - "CVS", "RCS", "SCCS", ".git", ".gitignore", ".gitmodules", - ".gitattributes", ".cvsignore", ".svn", ".arch-ids", "{arch}", - "=RELEASE-ID", "=meta-update", "=update", ".bzr", ".bzrignore", - ".bzrtags", ".hg", ".hgignore", ".hgrags", "_darcs", + "CVS", + "RCS", + "SCCS", + ".git", + ".gitignore", + ".gitmodules", + ".gitattributes", + ".cvsignore", + ".svn", + ".arch-ids", + "{arch}", + "=RELEASE-ID", + "=meta-update", + "=update", + ".bzr", + ".bzrignore", + ".bzrtags", + ".hg", + ".hgignore", + ".hgrags", + "_darcs", ]; - !path.iter() - .map(|s| s.to_str().unwrap()) - .any(|s| excludes.contains(&s)) + !path.iter().map(|s| s.to_str().unwrap()).any(|s| excludes.contains(&s)) } // Copy the directories using our filter for item in src_dirs { let dst = &dst_dir.join(item); t!(fs::create_dir_all(dst)); - builder.cp_filtered( - &builder.src.join(item), dst, &|path| filter_fn(exclude_dirs, item, path)); + builder + .cp_filtered(&builder.src.join(item), dst, &|path| filter_fn(exclude_dirs, item, path)); } } @@ -940,9 +975,7 @@ impl Step for Src { let dst_src = dst.join("rust"); t!(fs::create_dir_all(&dst_src)); - let src_files = [ - "Cargo.lock", - ]; + let src_files = ["Cargo.lock"]; // This is the reduced set of paths which will become the rust-src component // (essentially libstd and all of its path dependencies) let std_src_dirs = [ @@ -977,15 +1010,18 @@ impl Step for Src { // Create source tarball in rust-installer format let mut cmd = rust_installer(builder); cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Awesome-Source.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg(format!("--package-name={}", name)) - .arg("--component-name=rust-src") - .arg("--legacy-manifest-dirs=rustlib,cargo"); + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=Awesome-Source.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg(format!("--package-name={}", name)) + .arg("--component-name=rust-src") + .arg("--legacy-manifest-dirs=rustlib,cargo"); builder.info("Dist src"); let _time = timeit(builder); @@ -1036,9 +1072,7 @@ impl Step for PlainSourceTarball { "Cargo.toml", "Cargo.lock", ]; - let src_dirs = [ - "src", - ]; + let src_dirs = ["src"]; copy_src_dirs(builder, &src_dirs[..], &[], &plain_dst_src); @@ -1057,8 +1091,7 @@ impl Step for PlainSourceTarball { if builder.rust_info.is_git() { // Vendor all Cargo dependencies let mut cmd = Command::new(&builder.initial_cargo); - cmd.arg("vendor") - .current_dir(&plain_dst_src); + cmd.arg("vendor").current_dir(&plain_dst_src); builder.run(&mut cmd); } @@ -1073,10 +1106,12 @@ impl Step for PlainSourceTarball { builder.info("running installer"); let mut cmd = rust_installer(builder); cmd.arg("tarball") - .arg("--input").arg(&plain_name) - .arg("--output").arg(&tarball) - .arg("--work-dir=.") - .current_dir(tmpdir(builder)); + .arg("--input") + .arg(&plain_name) + .arg("--output") + .arg(&tarball) + .arg("--work-dir=.") + .current_dir(tmpdir(builder)); builder.info("Create plain source tarball"); let _time = timeit(builder); @@ -1095,10 +1130,10 @@ pub fn sanitize_sh(path: &Path) -> String { let mut ch = s.chars(); let drive = ch.next().unwrap_or('C'); if ch.next() != Some(':') { - return None + return None; } if ch.next() != Some('/') { - return None + return None; } Some(format!("/{}/{}", drive, &s[drive.len_utf8() + 2..])) } @@ -1154,8 +1189,7 @@ impl Step for Cargo { builder.install(&man.path(), &image.join("share/man/man1"), 0o644); } builder.install(&etc.join("_cargo"), &image.join("share/zsh/site-functions"), 0o644); - builder.copy(&etc.join("cargo.bashcomp.sh"), - &image.join("etc/bash_completion.d/cargo")); + builder.copy(&etc.join("cargo.bashcomp.sh"), &image.join("etc/bash_completion.d/cargo")); let doc = image.join("share/doc/cargo"); builder.install(&src.join("README.md"), &doc, 0o644); builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); @@ -1175,16 +1209,20 @@ impl Step for Cargo { // Generate the installer tarball let mut cmd = rust_installer(builder); cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rust-is-ready-to-roll.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg("--non-installed-overlay").arg(&overlay) - .arg(format!("--package-name={}-{}", name, target)) - .arg("--component-name=cargo") - .arg("--legacy-manifest-dirs=rustlib,cargo"); + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=Rust-is-ready-to-roll.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg("--non-installed-overlay") + .arg(&overlay) + .arg(format!("--package-name={}-{}", name, target)) + .arg("--component-name=cargo") + .arg("--legacy-manifest-dirs=rustlib,cargo"); builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target)); let _time = timeit(builder); @@ -1236,11 +1274,12 @@ impl Step for Rls { // Prepare the image directory // We expect RLS to build, because we've exited this step above if tool // state for RLS isn't testing. - let rls = builder.ensure(tool::Rls { - compiler, - target, - extra_features: Vec::new(), - }).or_else(|| { missing_tool("RLS", builder.build.config.missing_tools); None })?; + let rls = builder + .ensure(tool::Rls { compiler, target, extra_features: Vec::new() }) + .or_else(|| { + missing_tool("RLS", builder.build.config.missing_tools); + None + })?; builder.install(&rls, &image.join("bin"), 0o755); let doc = image.join("share/doc/rls"); @@ -1260,16 +1299,20 @@ impl Step for Rls { // Generate the installer tarball let mut cmd = rust_installer(builder); cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=RLS-ready-to-serve.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg("--non-installed-overlay").arg(&overlay) - .arg(format!("--package-name={}-{}", name, target)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--component-name=rls-preview"); + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=RLS-ready-to-serve.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg("--non-installed-overlay") + .arg(&overlay) + .arg(format!("--package-name={}-{}", name, target)) + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg("--component-name=rls-preview"); builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target)); let _time = timeit(builder); @@ -1321,15 +1364,18 @@ impl Step for Clippy { // Prepare the image directory // We expect clippy to build, because we've exited this step above if tool // state for clippy isn't testing. - let clippy = builder.ensure(tool::Clippy { - compiler, - target, - extra_features: Vec::new(), - }).or_else(|| { missing_tool("clippy", builder.build.config.missing_tools); None })?; - let cargoclippy = builder.ensure(tool::CargoClippy { - compiler, - target, extra_features: Vec::new() - }).or_else(|| { missing_tool("cargo clippy", builder.build.config.missing_tools); None })?; + let clippy = builder + .ensure(tool::Clippy { compiler, target, extra_features: Vec::new() }) + .or_else(|| { + missing_tool("clippy", builder.build.config.missing_tools); + None + })?; + let cargoclippy = builder + .ensure(tool::CargoClippy { compiler, target, extra_features: Vec::new() }) + .or_else(|| { + missing_tool("cargo clippy", builder.build.config.missing_tools); + None + })?; builder.install(&clippy, &image.join("bin"), 0o755); builder.install(&cargoclippy, &image.join("bin"), 0o755); @@ -1350,16 +1396,20 @@ impl Step for Clippy { // Generate the installer tarball let mut cmd = rust_installer(builder); cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=clippy-ready-to-serve.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg("--non-installed-overlay").arg(&overlay) - .arg(format!("--package-name={}-{}", name, target)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--component-name=clippy-preview"); + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=clippy-ready-to-serve.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg("--non-installed-overlay") + .arg(&overlay) + .arg(format!("--package-name={}-{}", name, target)) + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg("--component-name=clippy-preview"); builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target)); let _time = timeit(builder); @@ -1411,16 +1461,18 @@ impl Step for Miri { // Prepare the image directory // We expect miri to build, because we've exited this step above if tool // state for miri isn't testing. - let miri = builder.ensure(tool::Miri { - compiler, - target, - extra_features: Vec::new(), - }).or_else(|| { missing_tool("miri", builder.build.config.missing_tools); None })?; - let cargomiri = builder.ensure(tool::CargoMiri { - compiler, - target, - extra_features: Vec::new() - }).or_else(|| { missing_tool("cargo miri", builder.build.config.missing_tools); None })?; + let miri = builder + .ensure(tool::Miri { compiler, target, extra_features: Vec::new() }) + .or_else(|| { + missing_tool("miri", builder.build.config.missing_tools); + None + })?; + let cargomiri = builder + .ensure(tool::CargoMiri { compiler, target, extra_features: Vec::new() }) + .or_else(|| { + missing_tool("cargo miri", builder.build.config.missing_tools); + None + })?; builder.install(&miri, &image.join("bin"), 0o755); builder.install(&cargomiri, &image.join("bin"), 0o755); @@ -1441,16 +1493,20 @@ impl Step for Miri { // Generate the installer tarball let mut cmd = rust_installer(builder); cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=miri-ready-to-serve.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg("--non-installed-overlay").arg(&overlay) - .arg(format!("--package-name={}-{}", name, target)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--component-name=miri-preview"); + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=miri-ready-to-serve.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg("--non-installed-overlay") + .arg(&overlay) + .arg(format!("--package-name={}-{}", name, target)) + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg("--component-name=miri-preview"); builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target)); let _time = timeit(builder); @@ -1499,16 +1555,18 @@ impl Step for Rustfmt { builder.create_dir(&image); // Prepare the image directory - let rustfmt = builder.ensure(tool::Rustfmt { - compiler, - target, - extra_features: Vec::new(), - }).or_else(|| { missing_tool("Rustfmt", builder.build.config.missing_tools); None })?; - let cargofmt = builder.ensure(tool::Cargofmt { - compiler, - target, - extra_features: Vec::new(), - }).or_else(|| { missing_tool("Cargofmt", builder.build.config.missing_tools); None })?; + let rustfmt = builder + .ensure(tool::Rustfmt { compiler, target, extra_features: Vec::new() }) + .or_else(|| { + missing_tool("Rustfmt", builder.build.config.missing_tools); + None + })?; + let cargofmt = builder + .ensure(tool::Cargofmt { compiler, target, extra_features: Vec::new() }) + .or_else(|| { + missing_tool("Cargofmt", builder.build.config.missing_tools); + None + })?; builder.install(&rustfmt, &image.join("bin"), 0o755); builder.install(&cargofmt, &image.join("bin"), 0o755); @@ -1529,16 +1587,20 @@ impl Step for Rustfmt { // Generate the installer tarball let mut cmd = rust_installer(builder); cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=rustfmt-ready-to-fmt.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg("--non-installed-overlay").arg(&overlay) - .arg(format!("--package-name={}-{}", name, target)) - .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--component-name=rustfmt-preview"); + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=rustfmt-ready-to-fmt.") + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg("--non-installed-overlay") + .arg(&overlay) + .arg(format!("--package-name={}-{}", name, target)) + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg("--component-name=rustfmt-preview"); builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target)); let _time = timeit(builder); @@ -1580,9 +1642,7 @@ impl Step for Extended { builder.info(&format!("Dist extended stage{} ({})", compiler.stage, target)); - let rustc_installer = builder.ensure(Rustc { - compiler: builder.compiler(stage, target), - }); + let rustc_installer = builder.ensure(Rustc { compiler: builder.compiler(stage, target) }); let cargo_installer = builder.ensure(Cargo { compiler, target }); let rustfmt_installer = builder.ensure(Rustfmt { compiler, target }); let rls_installer = builder.ensure(Rls { compiler, target }); @@ -1593,11 +1653,9 @@ impl Step for Extended { let mingw_installer = builder.ensure(Mingw { host: target }); let analysis_installer = builder.ensure(Analysis { compiler, target }); - let docs_installer = builder.ensure(Docs { host: target, }); - let std_installer = builder.ensure(Std { - compiler: builder.compiler(stage, target), - target, - }); + let docs_installer = builder.ensure(Docs { host: target }); + let std_installer = + builder.ensure(Std { compiler: builder.compiler(stage, target), target }); let tmp = tmpdir(builder); let overlay = tmp.join("extended-overlay"); @@ -1648,12 +1706,16 @@ impl Step for Extended { .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-is-ready-to-roll.") - .arg("--work-dir").arg(&work) - .arg("--output-dir").arg(&distdir(builder)) + .arg("--work-dir") + .arg(&work) + .arg("--output-dir") + .arg(&distdir(builder)) .arg(format!("--package-name={}-{}", pkgname(builder, "rust"), target)) .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--input-tarballs").arg(input_tarballs) - .arg("--non-installed-overlay").arg(&overlay); + .arg("--input-tarballs") + .arg(input_tarballs) + .arg("--non-installed-overlay") + .arg(&overlay); let time = timeit(&builder); builder.run(&mut cmd); drop(time); @@ -1718,8 +1780,10 @@ impl Step for Extended { let pkgbuild = |component: &str| { let mut cmd = Command::new("pkgbuild"); - cmd.arg("--identifier").arg(format!("org.rust-lang.{}", component)) - .arg("--scripts").arg(pkg.join(component)) + cmd.arg("--identifier") + .arg(format!("org.rust-lang.{}", component)) + .arg("--scripts") + .arg(pkg.join(component)) .arg("--nopayload") .arg(pkg.join(component).with_extension("pkg")); builder.run(&mut cmd); @@ -1727,8 +1791,10 @@ impl Step for Extended { let prepare = |name: &str| { builder.create_dir(&pkg.join(name)); - builder.cp_r(&work.join(&format!("{}-{}", pkgname(builder, name), target)), - &pkg.join(name)); + builder.cp_r( + &work.join(&format!("{}-{}", pkgname(builder, name), target)), + &pkg.join(name), + ); builder.install(&etc.join("pkg/postinstall"), &pkg.join(name), 0o755); pkgbuild(name); }; @@ -1756,12 +1822,13 @@ impl Step for Extended { builder.create(&pkg.join("res/LICENSE.txt"), &license); builder.install(&etc.join("gfx/rust-logo.png"), &pkg.join("res"), 0o644); let mut cmd = Command::new("productbuild"); - cmd.arg("--distribution").arg(xform(&etc.join("pkg/Distribution.xml"))) - .arg("--resources").arg(pkg.join("res")) - .arg(distdir(builder).join(format!("{}-{}.pkg", - pkgname(builder, "rust"), - target))) - .arg("--package-path").arg(&pkg); + cmd.arg("--distribution") + .arg(xform(&etc.join("pkg/Distribution.xml"))) + .arg("--resources") + .arg(pkg.join("res")) + .arg(distdir(builder).join(format!("{}-{}.pkg", pkgname(builder, "rust"), target))) + .arg("--package-path") + .arg(&pkg); let _time = timeit(builder); builder.run(&mut cmd); } @@ -1783,9 +1850,10 @@ impl Step for Extended { } else { name.to_string() }; - builder.cp_r(&work.join(&format!("{}-{}", pkgname(builder, name), target)) - .join(dir), - &exe.join(name)); + builder.cp_r( + &work.join(&format!("{}-{}", pkgname(builder, name), target)).join(dir), + &exe.join(name), + ); builder.remove(&exe.join(name).join("manifest.in")); }; prepare("rustc"); @@ -1815,9 +1883,7 @@ impl Step for Extended { // Generate exe installer builder.info("building `exe` installer with `iscc`"); let mut cmd = Command::new("iscc"); - cmd.arg("rust.iss") - .arg("/Q") - .current_dir(&exe); + cmd.arg("rust.iss").arg("/Q").current_dir(&exe); if target.contains("windows-gnu") { cmd.arg("/dMINGW"); } @@ -1825,9 +1891,11 @@ impl Step for Extended { let time = timeit(builder); builder.run(&mut cmd); drop(time); - builder.install(&exe.join(format!("{}-{}.exe", pkgname(builder, "rust"), target)), - &distdir(builder), - 0o755); + builder.install( + &exe.join(format!("{}-{}.exe", pkgname(builder, "rust"), target)), + &distdir(builder), + 0o755, + ); // Generate msi installer let wix = PathBuf::from(env::var_os("WIX").unwrap()); @@ -1836,106 +1904,165 @@ impl Step for Extended { let light = wix.join("bin/light.exe"); let heat_flags = ["-nologo", "-gg", "-sfrag", "-srd", "-sreg"]; - builder.run(Command::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("rustc") - .args(&heat_flags) - .arg("-cg").arg("RustcGroup") - .arg("-dr").arg("Rustc") - .arg("-var").arg("var.RustcDir") - .arg("-out").arg(exe.join("RustcGroup.wxs"))); - builder.run(Command::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("rust-docs") - .args(&heat_flags) - .arg("-cg").arg("DocsGroup") - .arg("-dr").arg("Docs") - .arg("-var").arg("var.DocsDir") - .arg("-out").arg(exe.join("DocsGroup.wxs")) - .arg("-t").arg(etc.join("msi/squash-components.xsl"))); - builder.run(Command::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("cargo") - .args(&heat_flags) - .arg("-cg").arg("CargoGroup") - .arg("-dr").arg("Cargo") - .arg("-var").arg("var.CargoDir") - .arg("-out").arg(exe.join("CargoGroup.wxs")) - .arg("-t").arg(etc.join("msi/remove-duplicates.xsl"))); - builder.run(Command::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("rust-std") - .args(&heat_flags) - .arg("-cg").arg("StdGroup") - .arg("-dr").arg("Std") - .arg("-var").arg("var.StdDir") - .arg("-out").arg(exe.join("StdGroup.wxs"))); + builder.run( + Command::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rustc") + .args(&heat_flags) + .arg("-cg") + .arg("RustcGroup") + .arg("-dr") + .arg("Rustc") + .arg("-var") + .arg("var.RustcDir") + .arg("-out") + .arg(exe.join("RustcGroup.wxs")), + ); + builder.run( + Command::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rust-docs") + .args(&heat_flags) + .arg("-cg") + .arg("DocsGroup") + .arg("-dr") + .arg("Docs") + .arg("-var") + .arg("var.DocsDir") + .arg("-out") + .arg(exe.join("DocsGroup.wxs")) + .arg("-t") + .arg(etc.join("msi/squash-components.xsl")), + ); + builder.run( + Command::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("cargo") + .args(&heat_flags) + .arg("-cg") + .arg("CargoGroup") + .arg("-dr") + .arg("Cargo") + .arg("-var") + .arg("var.CargoDir") + .arg("-out") + .arg(exe.join("CargoGroup.wxs")) + .arg("-t") + .arg(etc.join("msi/remove-duplicates.xsl")), + ); + builder.run( + Command::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rust-std") + .args(&heat_flags) + .arg("-cg") + .arg("StdGroup") + .arg("-dr") + .arg("Std") + .arg("-var") + .arg("var.StdDir") + .arg("-out") + .arg(exe.join("StdGroup.wxs")), + ); if rls_installer.is_some() { - builder.run(Command::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("rls") - .args(&heat_flags) - .arg("-cg").arg("RlsGroup") - .arg("-dr").arg("Rls") - .arg("-var").arg("var.RlsDir") - .arg("-out").arg(exe.join("RlsGroup.wxs")) - .arg("-t").arg(etc.join("msi/remove-duplicates.xsl"))); + builder.run( + Command::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rls") + .args(&heat_flags) + .arg("-cg") + .arg("RlsGroup") + .arg("-dr") + .arg("Rls") + .arg("-var") + .arg("var.RlsDir") + .arg("-out") + .arg(exe.join("RlsGroup.wxs")) + .arg("-t") + .arg(etc.join("msi/remove-duplicates.xsl")), + ); } if clippy_installer.is_some() { - builder.run(Command::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("clippy") - .args(&heat_flags) - .arg("-cg").arg("ClippyGroup") - .arg("-dr").arg("Clippy") - .arg("-var").arg("var.ClippyDir") - .arg("-out").arg(exe.join("ClippyGroup.wxs")) - .arg("-t").arg(etc.join("msi/remove-duplicates.xsl"))); + builder.run( + Command::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("clippy") + .args(&heat_flags) + .arg("-cg") + .arg("ClippyGroup") + .arg("-dr") + .arg("Clippy") + .arg("-var") + .arg("var.ClippyDir") + .arg("-out") + .arg(exe.join("ClippyGroup.wxs")) + .arg("-t") + .arg(etc.join("msi/remove-duplicates.xsl")), + ); } if miri_installer.is_some() { - builder.run(Command::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("miri") - .args(&heat_flags) - .arg("-cg").arg("MiriGroup") - .arg("-dr").arg("Miri") - .arg("-var").arg("var.MiriDir") - .arg("-out").arg(exe.join("MiriGroup.wxs")) - .arg("-t").arg(etc.join("msi/remove-duplicates.xsl"))); + builder.run( + Command::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("miri") + .args(&heat_flags) + .arg("-cg") + .arg("MiriGroup") + .arg("-dr") + .arg("Miri") + .arg("-var") + .arg("var.MiriDir") + .arg("-out") + .arg(exe.join("MiriGroup.wxs")) + .arg("-t") + .arg(etc.join("msi/remove-duplicates.xsl")), + ); } - builder.run(Command::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("rust-analysis") - .args(&heat_flags) - .arg("-cg").arg("AnalysisGroup") - .arg("-dr").arg("Analysis") - .arg("-var").arg("var.AnalysisDir") - .arg("-out").arg(exe.join("AnalysisGroup.wxs")) - .arg("-t").arg(etc.join("msi/remove-duplicates.xsl"))); + builder.run( + Command::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rust-analysis") + .args(&heat_flags) + .arg("-cg") + .arg("AnalysisGroup") + .arg("-dr") + .arg("Analysis") + .arg("-var") + .arg("var.AnalysisDir") + .arg("-out") + .arg(exe.join("AnalysisGroup.wxs")) + .arg("-t") + .arg(etc.join("msi/remove-duplicates.xsl")), + ); if target.contains("windows-gnu") { - builder.run(Command::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("rust-mingw") - .args(&heat_flags) - .arg("-cg").arg("GccGroup") - .arg("-dr").arg("Gcc") - .arg("-var").arg("var.GccDir") - .arg("-out").arg(exe.join("GccGroup.wxs"))); + builder.run( + Command::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rust-mingw") + .args(&heat_flags) + .arg("-cg") + .arg("GccGroup") + .arg("-dr") + .arg("Gcc") + .arg("-var") + .arg("var.GccDir") + .arg("-out") + .arg(exe.join("GccGroup.wxs")), + ); } let candle = |input: &Path| { - let output = exe.join(input.file_stem().unwrap()) - .with_extension("wixobj"); - let arch = if target.contains("x86_64") {"x64"} else {"x86"}; + let output = exe.join(input.file_stem().unwrap()).with_extension("wixobj"); + let arch = if target.contains("x86_64") { "x64" } else { "x86" }; let mut cmd = Command::new(&candle); cmd.current_dir(&exe) .arg("-nologo") @@ -1944,8 +2071,10 @@ impl Step for Extended { .arg("-dCargoDir=cargo") .arg("-dStdDir=rust-std") .arg("-dAnalysisDir=rust-analysis") - .arg("-arch").arg(&arch) - .arg("-out").arg(&output) + .arg("-arch") + .arg(&arch) + .arg("-out") + .arg(&output) .arg(&input); add_env(builder, &mut cmd, target); @@ -1993,9 +2122,12 @@ impl Step for Extended { let filename = format!("{}-{}.msi", pkgname(builder, "rust"), target); let mut cmd = Command::new(&light); cmd.arg("-nologo") - .arg("-ext").arg("WixUIExtension") - .arg("-ext").arg("WixUtilExtension") - .arg("-out").arg(exe.join(&filename)) + .arg("-ext") + .arg("WixUIExtension") + .arg("-ext") + .arg("WixUtilExtension") + .arg("-out") + .arg(exe.join(&filename)) .arg("rust.wixobj") .arg("ui.wixobj") .arg("rustwelcomedlg.wixobj") @@ -2035,29 +2167,27 @@ impl Step for Extended { fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: Interned) { let mut parts = channel::CFG_RELEASE_NUM.split('.'); cmd.env("CFG_RELEASE_INFO", builder.rust_version()) - .env("CFG_RELEASE_NUM", channel::CFG_RELEASE_NUM) - .env("CFG_RELEASE", builder.rust_release()) - .env("CFG_VER_MAJOR", parts.next().unwrap()) - .env("CFG_VER_MINOR", parts.next().unwrap()) - .env("CFG_VER_PATCH", parts.next().unwrap()) - .env("CFG_VER_BUILD", "0") // just needed to build - .env("CFG_PACKAGE_VERS", builder.rust_package_vers()) - .env("CFG_PACKAGE_NAME", pkgname(builder, "rust")) - .env("CFG_BUILD", target) - .env("CFG_CHANNEL", &builder.config.channel); + .env("CFG_RELEASE_NUM", channel::CFG_RELEASE_NUM) + .env("CFG_RELEASE", builder.rust_release()) + .env("CFG_VER_MAJOR", parts.next().unwrap()) + .env("CFG_VER_MINOR", parts.next().unwrap()) + .env("CFG_VER_PATCH", parts.next().unwrap()) + .env("CFG_VER_BUILD", "0") // just needed to build + .env("CFG_PACKAGE_VERS", builder.rust_package_vers()) + .env("CFG_PACKAGE_NAME", pkgname(builder, "rust")) + .env("CFG_BUILD", target) + .env("CFG_CHANNEL", &builder.config.channel); if target.contains("windows-gnu") { - cmd.env("CFG_MINGW", "1") - .env("CFG_ABI", "GNU"); + cmd.env("CFG_MINGW", "1").env("CFG_ABI", "GNU"); } else { - cmd.env("CFG_MINGW", "0") - .env("CFG_ABI", "MSVC"); + cmd.env("CFG_MINGW", "0").env("CFG_ABI", "MSVC"); } if target.contains("x86_64") { - cmd.env("CFG_PLATFORM", "x64"); + cmd.env("CFG_PLATFORM", "x64"); } else { - cmd.env("CFG_PLATFORM", "x86"); + cmd.env("CFG_PLATFORM", "x86"); } } @@ -2130,17 +2260,11 @@ impl Step for HashSign { // // Note: This function does no yet support Windows but we also don't support // linking LLVM tools dynamically on Windows yet. -pub fn maybe_install_llvm_dylib(builder: &Builder<'_>, - target: Interned, - sysroot: &Path) { - let src_libdir = builder - .llvm_out(target) - .join("lib"); +pub fn maybe_install_llvm_dylib(builder: &Builder<'_>, target: Interned, sysroot: &Path) { + let src_libdir = builder.llvm_out(target).join("lib"); let dst_libdir1 = sysroot.join("lib/rustlib").join(&*target).join("lib"); - let dst_libdir2 = sysroot.join(builder.sysroot_libdir_relative(Compiler { - stage: 1, - host: target, - })); + let dst_libdir2 = + sysroot.join(builder.sysroot_libdir_relative(Compiler { stage: 1, host: target })); t!(fs::create_dir_all(&dst_libdir1)); t!(fs::create_dir_all(&dst_libdir2)); @@ -2150,7 +2274,7 @@ pub fn maybe_install_llvm_dylib(builder: &Builder<'_>, builder.install(&llvm_dylib_path, &dst_libdir1, 0o644); builder.install(&llvm_dylib_path, &dst_libdir2, 0o644); } - return + return; } // Usually libLLVM.so is a symlink to something like libLLVM-6.0.so. @@ -2159,11 +2283,9 @@ pub fn maybe_install_llvm_dylib(builder: &Builder<'_>, let llvm_dylib_path = src_libdir.join("libLLVM.so"); if llvm_dylib_path.exists() { let llvm_dylib_path = llvm_dylib_path.canonicalize().unwrap_or_else(|e| { - panic!("dist: Error calling canonicalize path `{}`: {}", - llvm_dylib_path.display(), e); + panic!("dist: Error calling canonicalize path `{}`: {}", llvm_dylib_path.display(), e); }); - builder.install(&llvm_dylib_path, &dst_libdir1, 0o644); builder.install(&llvm_dylib_path, &dst_libdir2, 0o644); } @@ -2183,9 +2305,7 @@ impl Step for LlvmTools { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(LlvmTools { - target: run.target, - }); + run.builder.ensure(LlvmTools { target: run.target }); } fn run(self, builder: &Builder<'_>) -> Option { @@ -2195,8 +2315,7 @@ impl Step for LlvmTools { /* run only if llvm-config isn't used */ if let Some(config) = builder.config.target_config.get(&target) { if let Some(ref _s) = config.llvm_config { - builder.info(&format!("Skipping LlvmTools ({}): external LLVM", - target)); + builder.info(&format!("Skipping LlvmTools ({}): external LLVM", target)); return None; } } @@ -2211,12 +2330,8 @@ impl Step for LlvmTools { drop(fs::remove_dir_all(&image)); // Prepare the image directory - let src_bindir = builder - .llvm_out(target) - .join("bin"); - let dst_bindir = image.join("lib/rustlib") - .join(&*target) - .join("bin"); + let src_bindir = builder.llvm_out(target).join("bin"); + let dst_bindir = image.join("lib/rustlib").join(&*target).join("bin"); t!(fs::create_dir_all(&dst_bindir)); for tool in LLVM_TOOLS { let exe = src_bindir.join(exe(tool, &target)); @@ -2237,15 +2352,18 @@ impl Step for LlvmTools { .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=llvm-tools-installed.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg("--non-installed-overlay").arg(&overlay) + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg("--non-installed-overlay") + .arg(&overlay) .arg(format!("--package-name={}-{}", name, target)) .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--component-name=llvm-tools-preview"); - builder.run(&mut cmd); Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target))) } @@ -2266,9 +2384,7 @@ impl Step for Lldb { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Lldb { - target: run.target, - }); + run.builder.ensure(Lldb { target: run.target }); } fn run(self, builder: &Builder<'_>) -> Option { @@ -2278,9 +2394,7 @@ impl Step for Lldb { return None; } - let bindir = builder - .llvm_out(target) - .join("bin"); + let bindir = builder.llvm_out(target).join("bin"); let lldb_exe = bindir.join(exe("lldb", &target)); if !lldb_exe.exists() { return None; @@ -2314,7 +2428,7 @@ impl Step for Lldb { if t!(entry.file_type()).is_symlink() { builder.copy_to_folder(&entry.path(), &dst); } else { - builder.install(&entry.path(), &dst, 0o755); + builder.install(&entry.path(), &dst, 0o755); } } } @@ -2333,8 +2447,7 @@ impl Step for Lldb { let entry = t!(entry); if let Ok(name) = entry.file_name().into_string() { if name.starts_with("python") { - let dst = root.join(libdir_name) - .join(entry.file_name()); + let dst = root.join(libdir_name).join(entry.file_name()); t!(fs::create_dir_all(&dst)); builder.cp_r(&entry.path(), &dst); break; @@ -2355,15 +2468,18 @@ impl Step for Lldb { .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=lldb-installed.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg("--non-installed-overlay").arg(&overlay) + .arg("--image-dir") + .arg(&image) + .arg("--work-dir") + .arg(&tmpdir(builder)) + .arg("--output-dir") + .arg(&distdir(builder)) + .arg("--non-installed-overlay") + .arg(&overlay) .arg(format!("--package-name={}-{}", name, target)) .arg("--legacy-manifest-dirs=rustlib,cargo") .arg("--component-name=lldb-preview"); - builder.run(&mut cmd); Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target))) } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 608cee0a80bfc..8cd7fc2c17257 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -10,17 +10,17 @@ use std::collections::HashSet; use std::fs; use std::io; -use std::path::{PathBuf, Path}; +use std::path::{Path, PathBuf}; use crate::Mode; use build_helper::{t, up_to_date}; -use crate::util::symlink_dir; use crate::builder::{Builder, Compiler, RunConfig, ShouldRun, Step}; -use crate::tool::{self, prepare_tool_cargo, Tool, SourceType}; +use crate::cache::{Interned, INTERNER}; use crate::compile; -use crate::cache::{INTERNER, Interned}; use crate::config::Config; +use crate::tool::{self, prepare_tool_cargo, SourceType, Tool}; +use crate::util::symlink_dir; macro_rules! book { ($($name:ident, $path:expr, $book_name:expr;)+) => { @@ -88,15 +88,11 @@ impl Step for UnstableBook { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(UnstableBook { - target: run.target, - }); + run.builder.ensure(UnstableBook { target: run.target }); } fn run(self, builder: &Builder<'_>) { - builder.ensure(UnstableBookGen { - target: self.target, - }); + builder.ensure(UnstableBookGen { target: self.target }); builder.ensure(RustbookSrc { target: self.target, name: INTERNER.intern_str("unstable-book"), @@ -121,10 +117,7 @@ impl Step for CargoBook { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(CargoBook { - target: run.target, - name: INTERNER.intern_str("cargo"), - }); + run.builder.ensure(CargoBook { target: run.target, name: INTERNER.intern_str("cargo") }); } fn run(self, builder: &Builder<'_>) { @@ -141,11 +134,7 @@ impl Step for CargoBook { let _ = fs::remove_dir_all(&out); - builder.run(builder.tool_cmd(Tool::Rustbook) - .arg("build") - .arg(&src) - .arg("-d") - .arg(out)); + builder.run(builder.tool_cmd(Tool::Rustbook).arg("build").arg(&src).arg("-d").arg(out)); } } @@ -180,16 +169,12 @@ impl Step for RustbookSrc { let rustbook = builder.tool_exe(Tool::Rustbook); let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook); if up_to_date(&src, &index) && up_to_date(&rustbook, &index) { - return + return; } builder.info(&format!("Rustbook ({}) - {}", target, name)); let _ = fs::remove_dir_all(&out); - builder.run(rustbook_cmd - .arg("build") - .arg(&src) - .arg("-d") - .arg(out)); + builder.run(rustbook_cmd.arg("build").arg(&src).arg("-d").arg(out)); } } @@ -262,10 +247,7 @@ impl Step for TheBook { }); // build the version info page and CSS - builder.ensure(Standalone { - compiler, - target, - }); + builder.ensure(Standalone { compiler, target }); // build the redirect pages builder.info(&format!("Documenting book redirect pages ({})", target)); @@ -297,13 +279,20 @@ fn invoke_rustdoc( let out = out.join("book"); - cmd.arg("--html-after-content").arg(&footer) - .arg("--html-before-content").arg(&version_info) - .arg("--html-in-header").arg(&header) + cmd.arg("--html-after-content") + .arg(&footer) + .arg("--html-before-content") + .arg(&version_info) + .arg("--html-in-header") + .arg(&header) .arg("--markdown-no-toc") - .arg("--markdown-playground-url").arg("https://play.rust-lang.org/") - .arg("-o").arg(&out).arg(&path) - .arg("--markdown-css").arg("../rust.css"); + .arg("--markdown-playground-url") + .arg("https://play.rust-lang.org/") + .arg("-o") + .arg(&out) + .arg(&path) + .arg("--markdown-css") + .arg("../rust.css"); builder.run(&mut cmd); } @@ -366,33 +355,39 @@ impl Step for Standalone { let path = file.path(); let filename = path.file_name().unwrap().to_str().unwrap(); if !filename.ends_with(".md") || filename == "README.md" { - continue + continue; } let html = out.join(filename).with_extension("html"); let rustdoc = builder.rustdoc(compiler); - if up_to_date(&path, &html) && - up_to_date(&footer, &html) && - up_to_date(&favicon, &html) && - up_to_date(&full_toc, &html) && - (builder.config.dry_run || up_to_date(&version_info, &html)) && - (builder.config.dry_run || up_to_date(&rustdoc, &html)) { - continue + if up_to_date(&path, &html) + && up_to_date(&footer, &html) + && up_to_date(&favicon, &html) + && up_to_date(&full_toc, &html) + && (builder.config.dry_run || up_to_date(&version_info, &html)) + && (builder.config.dry_run || up_to_date(&rustdoc, &html)) + { + continue; } let mut cmd = builder.rustdoc_cmd(compiler); - cmd.arg("--html-after-content").arg(&footer) - .arg("--html-before-content").arg(&version_info) - .arg("--html-in-header").arg(&favicon) - .arg("--markdown-no-toc") - .arg("--index-page").arg(&builder.src.join("src/doc/index.md")) - .arg("--markdown-playground-url").arg("https://play.rust-lang.org/") - .arg("-o").arg(&out) - .arg(&path); + cmd.arg("--html-after-content") + .arg(&footer) + .arg("--html-before-content") + .arg(&version_info) + .arg("--html-in-header") + .arg(&favicon) + .arg("--markdown-no-toc") + .arg("--index-page") + .arg(&builder.src.join("src/doc/index.md")) + .arg("--markdown-playground-url") + .arg("https://play.rust-lang.org/") + .arg("-o") + .arg(&out) + .arg(&path); if filename == "not_found.md" { - cmd.arg("--markdown-css") - .arg("https://doc.rust-lang.org/rust.css"); + cmd.arg("--markdown-css").arg("https://doc.rust-lang.org/rust.css"); } else { cmd.arg("--markdown-css").arg("rust.css"); } @@ -417,10 +412,7 @@ impl Step for Std { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Std { - stage: run.builder.top_stage, - target: run.target - }); + run.builder.ensure(Std { stage: run.builder.top_stage, target: run.target }); } /// Compile all standard library documentation. @@ -436,8 +428,7 @@ impl Step for Std { let compiler = builder.compiler(stage, builder.config.build); builder.ensure(compile::Std { compiler, target }); - let out_dir = builder.stage_out(compiler, Mode::Std) - .join(target).join("doc"); + let out_dir = builder.stage_out(compiler, Mode::Std).join(target).join("doc"); // Here what we're doing is creating a *symlink* (directory junction on // Windows) to the final output location. This is not done as an @@ -462,18 +453,21 @@ impl Step for Std { // Keep a whitelist so we do not build internal stdlib crates, these will be // build by the rustc step later if enabled. - cargo.arg("-Z").arg("unstable-options") - .arg("-p").arg(package); + cargo.arg("-Z").arg("unstable-options").arg("-p").arg(package); // Create all crate output directories first to make sure rustdoc uses // relative links. // FIXME: Cargo should probably do this itself. t!(fs::create_dir_all(out_dir.join(package))); - cargo.arg("--") - .arg("--markdown-css").arg("rust.css") - .arg("--markdown-no-toc") - .arg("--generate-redirect-pages") - .arg("--resource-suffix").arg(crate::channel::CFG_RELEASE_NUM) - .arg("--index-page").arg(&builder.src.join("src/doc/index.md")); + cargo + .arg("--") + .arg("--markdown-css") + .arg("rust.css") + .arg("--markdown-no-toc") + .arg("--generate-redirect-pages") + .arg("--resource-suffix") + .arg(crate::channel::CFG_RELEASE_NUM) + .arg("--index-page") + .arg(&builder.src.join("src/doc/index.md")); builder.run(&mut cargo.into()); }; @@ -501,10 +495,7 @@ impl Step for Rustc { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rustc { - stage: run.builder.top_stage, - target: run.target, - }); + run.builder.ensure(Rustc { stage: run.builder.top_stage, target: run.target }); } /// Generates compiler documentation. @@ -568,7 +559,7 @@ impl Step for Rustc { fn find_compiler_crates( builder: &Builder<'_>, name: &Interned, - crates: &mut HashSet> + crates: &mut HashSet>, ) { // Add current crate. crates.insert(*name); @@ -597,10 +588,7 @@ impl Step for Rustdoc { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rustdoc { - stage: run.builder.top_stage, - target: run.target, - }); + run.builder.ensure(Rustdoc { stage: run.builder.top_stage, target: run.target }); } /// Generates compiler documentation. @@ -633,9 +621,7 @@ impl Step for Rustdoc { builder.ensure(tool::Rustdoc { compiler: compiler }); // Symlink compiler docs to the output directory of rustdoc documentation. - let out_dir = builder.stage_out(compiler, Mode::ToolRustc) - .join(target) - .join("doc"); + let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target).join("doc"); t!(fs::create_dir_all(&out_dir)); t!(symlink_dir_force(&builder.config, &out, &out_dir)); @@ -648,7 +634,7 @@ impl Step for Rustdoc { "doc", "src/tools/rustdoc", SourceType::InTree, - &[] + &[], ); // Only include compiler crates, no dependencies of those, such as `libc`. @@ -676,9 +662,7 @@ impl Step for ErrorIndex { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(ErrorIndex { - target: run.target, - }); + run.builder.ensure(ErrorIndex { target: run.target }); } /// Generates the HTML rendered error-index by running the @@ -690,10 +674,7 @@ impl Step for ErrorIndex { let out = builder.doc_out(target); t!(fs::create_dir_all(&out)); let compiler = builder.compiler(2, builder.config.build); - let mut index = tool::ErrorIndex::command( - builder, - compiler, - ); + let mut index = tool::ErrorIndex::command(builder, compiler); index.arg("html"); index.arg(out.join("error-index.html")); index.arg(crate::channel::CFG_RELEASE_NUM); @@ -721,9 +702,7 @@ impl Step for UnstableBookGen { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(UnstableBookGen { - target: run.target, - }); + run.builder.ensure(UnstableBookGen { target: run.target }); } fn run(self, builder: &Builder<'_>) { @@ -751,9 +730,7 @@ fn symlink_dir_force(config: &Config, src: &Path, dst: &Path) -> io::Result<()> } else { // handle directory junctions on windows by falling back to // `remove_dir`. - fs::remove_file(dst).or_else(|_| { - fs::remove_dir(dst) - })?; + fs::remove_file(dst).or_else(|_| fs::remove_dir(dst))?; } } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index b98e2c1bf2466..ffc24367db6e9 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -88,16 +88,15 @@ pub enum Subcommand { impl Default for Subcommand { fn default() -> Subcommand { - Subcommand::Build { - paths: vec![PathBuf::from("nowhere")], - } + Subcommand::Build { paths: vec![PathBuf::from("nowhere")] } } } impl Flags { pub fn parse(args: &[String]) -> Flags { let mut extra_help = String::new(); - let mut subcommand_help = String::from("\ + let mut subcommand_help = String::from( + "\ Usage: x.py [options] [...] Subcommands: @@ -113,7 +112,7 @@ Subcommands: dist Build distribution artifacts install Install distribution artifacts -To learn more about a subcommand, run `./x.py -h`" +To learn more about a subcommand, run `./x.py -h`", ); let mut opts = Options::new(); @@ -127,12 +126,20 @@ To learn more about a subcommand, run `./x.py -h`" opts.optmulti("", "exclude", "build paths to exclude", "PATH"); opts.optopt("", "on-fail", "command to run on failure", "CMD"); opts.optflag("", "dry-run", "dry run; don't build anything"); - opts.optopt("", "stage", + opts.optopt( + "", + "stage", "stage to build (indicates compiler to use/test, e.g., stage 0 uses the \ bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)", - "N"); - opts.optmulti("", "keep-stage", "stage(s) to keep without recompiling \ - (pass multiple times to keep e.g., both stages 0 and 1)", "N"); + "N", + ); + opts.optmulti( + "", + "keep-stage", + "stage(s) to keep without recompiling \ + (pass multiple times to keep e.g., both stages 0 and 1)", + "N", + ); opts.optopt("", "src", "path to the root of the rust checkout", "DIR"); opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS"); opts.optflag("h", "help", "print this help message"); @@ -197,11 +204,7 @@ To learn more about a subcommand, run `./x.py -h`" ); opts.optflag("", "no-doc", "do not run doc tests"); opts.optflag("", "doc", "only run doc tests"); - opts.optflag( - "", - "bless", - "update all stderr/stdout files of failing ui tests", - ); + opts.optflag("", "bless", "update all stderr/stdout files of failing ui tests"); opts.optopt( "", "compare-mode", @@ -212,7 +215,7 @@ To learn more about a subcommand, run `./x.py -h`" "", "pass", "force {check,build,run}-pass tests to this mode.", - "check | build | run" + "check | build | run", ); opts.optflag( "", @@ -386,10 +389,7 @@ Arguments: _ => {} }; // Get any optional paths which occur after the subcommand - let paths = matches.free[1..] - .iter() - .map(|p| p.into()) - .collect::>(); + let paths = matches.free[1..].iter().map(|p| p.into()).collect::>(); let cfg_file = matches.opt_str("config").map(PathBuf::from).or_else(|| { if fs::metadata("config.toml").is_ok() { @@ -409,10 +409,8 @@ Arguments: extra_help.push_str(maybe_rules_help.unwrap_or_default().as_str()); } else if !(subcommand.as_str() == "clean" || subcommand.as_str() == "fmt") { extra_help.push_str( - format!( - "Run `./x.py {} -h -v` to see a list of available paths.", - subcommand - ).as_str(), + format!("Run `./x.py {} -h -v` to see a list of available paths.", subcommand) + .as_str(), ); } @@ -443,10 +441,7 @@ Arguments: DocTests::Yes }, }, - "bench" => Subcommand::Bench { - paths, - test_args: matches.opt_strs("test-args"), - }, + "bench" => Subcommand::Bench { paths, test_args: matches.opt_strs("test-args") }, "doc" => Subcommand::Doc { paths }, "clean" => { if !paths.is_empty() { @@ -454,15 +449,9 @@ Arguments: usage(1, &opts, &subcommand_help, &extra_help); } - Subcommand::Clean { - all: matches.opt_present("all"), - } - } - "fmt" => { - Subcommand::Format { - check: matches.opt_present("check"), - } + Subcommand::Clean { all: matches.opt_present("all") } } + "fmt" => Subcommand::Format { check: matches.opt_present("check") }, "dist" => Subcommand::Dist { paths }, "install" => Subcommand::Install { paths }, _ => { @@ -476,8 +465,10 @@ Arguments: dry_run: matches.opt_present("dry-run"), on_fail: matches.opt_str("on-fail"), rustc_error_format: matches.opt_str("error-format"), - keep_stage: matches.opt_strs("keep-stage") - .into_iter().map(|j| j.parse().expect("`keep-stage` should be a number")) + keep_stage: matches + .opt_strs("keep-stage") + .into_iter() + .map(|j| j.parse().expect("`keep-stage` should be a number")) .collect(), host: split(&matches.opt_strs("host")) .into_iter() @@ -504,10 +495,7 @@ impl Subcommand { pub fn test_args(&self) -> Vec<&str> { match *self { Subcommand::Test { ref test_args, .. } | Subcommand::Bench { ref test_args, .. } => { - test_args - .iter() - .flat_map(|s| s.split_whitespace()) - .collect() + test_args.iter().flat_map(|s| s.split_whitespace()).collect() } _ => Vec::new(), } @@ -515,10 +503,9 @@ impl Subcommand { pub fn rustc_args(&self) -> Vec<&str> { match *self { - Subcommand::Test { ref rustc_args, .. } => rustc_args - .iter() - .flat_map(|s| s.split_whitespace()) - .collect(), + Subcommand::Test { ref rustc_args, .. } => { + rustc_args.iter().flat_map(|s| s.split_whitespace()).collect() + } _ => Vec::new(), } } @@ -553,28 +540,21 @@ impl Subcommand { pub fn compare_mode(&self) -> Option<&str> { match *self { - Subcommand::Test { - ref compare_mode, .. - } => compare_mode.as_ref().map(|s| &s[..]), + Subcommand::Test { ref compare_mode, .. } => compare_mode.as_ref().map(|s| &s[..]), _ => None, } } pub fn pass(&self) -> Option<&str> { match *self { - Subcommand::Test { - ref pass, .. - } => pass.as_ref().map(|s| &s[..]), + Subcommand::Test { ref pass, .. } => pass.as_ref().map(|s| &s[..]), _ => None, } } } fn split(s: &[String]) -> Vec { - s.iter() - .flat_map(|s| s.split(',')) - .map(|s| s.to_string()) - .collect() + s.iter().flat_map(|s| s.split(',')).map(|s| s.to_string()).collect() } fn parse_deny_warnings(matches: &getopts::Matches) -> Option { @@ -582,12 +562,9 @@ fn parse_deny_warnings(matches: &getopts::Matches) -> Option { Some("deny") => Some(true), Some("warn") => Some(false), Some(value) => { - eprintln!( - r#"invalid value for --warnings: {:?}, expected "warn" or "deny""#, - value, - ); + eprintln!(r#"invalid value for --warnings: {:?}, expected "warn" or "deny""#, value,); process::exit(1); - }, + } None => None, } } diff --git a/src/bootstrap/job.rs b/src/bootstrap/job.rs index 6867d62a480bd..57153e2ad39f4 100644 --- a/src/bootstrap/job.rs +++ b/src/bootstrap/job.rs @@ -29,11 +29,11 @@ #![allow(nonstandard_style, dead_code)] +use crate::Build; use std::env; use std::io; use std::mem; use std::ptr; -use crate::Build; type HANDLE = *mut u8; type BOOL = i32; @@ -61,21 +61,23 @@ extern "system" { fn CreateJobObjectW(lpJobAttributes: *mut u8, lpName: *const u8) -> HANDLE; fn CloseHandle(hObject: HANDLE) -> BOOL; fn GetCurrentProcess() -> HANDLE; - fn OpenProcess(dwDesiredAccess: DWORD, - bInheritHandle: BOOL, - dwProcessId: DWORD) -> HANDLE; - fn DuplicateHandle(hSourceProcessHandle: HANDLE, - hSourceHandle: HANDLE, - hTargetProcessHandle: HANDLE, - lpTargetHandle: LPHANDLE, - dwDesiredAccess: DWORD, - bInheritHandle: BOOL, - dwOptions: DWORD) -> BOOL; + fn OpenProcess(dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwProcessId: DWORD) -> HANDLE; + fn DuplicateHandle( + hSourceProcessHandle: HANDLE, + hSourceHandle: HANDLE, + hTargetProcessHandle: HANDLE, + lpTargetHandle: LPHANDLE, + dwDesiredAccess: DWORD, + bInheritHandle: BOOL, + dwOptions: DWORD, + ) -> BOOL; fn AssignProcessToJobObject(hJob: HANDLE, hProcess: HANDLE) -> BOOL; - fn SetInformationJobObject(hJob: HANDLE, - JobObjectInformationClass: JOBOBJECTINFOCLASS, - lpJobObjectInformation: LPVOID, - cbJobObjectInformationLength: DWORD) -> BOOL; + fn SetInformationJobObject( + hJob: HANDLE, + JobObjectInformationClass: JOBOBJECTINFOCLASS, + lpJobObjectInformation: LPVOID, + cbJobObjectInformationLength: DWORD, + ) -> BOOL; fn SetErrorMode(mode: UINT) -> UINT; } @@ -132,10 +134,12 @@ pub unsafe fn setup(build: &mut Build) { info.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_PRIORITY_CLASS; info.BasicLimitInformation.PriorityClass = BELOW_NORMAL_PRIORITY_CLASS; } - let r = SetInformationJobObject(job, - JobObjectExtendedLimitInformation, - &mut info as *mut _ as LPVOID, - mem::size_of_val(&info) as DWORD); + let r = SetInformationJobObject( + job, + JobObjectExtendedLimitInformation, + &mut info as *mut _ as LPVOID, + mem::size_of_val(&info) as DWORD, + ); assert!(r != 0, "{}", io::Error::last_os_error()); // Assign our process to this job object. Note that if this fails, one very @@ -150,7 +154,7 @@ pub unsafe fn setup(build: &mut Build) { let r = AssignProcessToJobObject(job, GetCurrentProcess()); if r == 0 { CloseHandle(job); - return + return; } // If we've got a parent process (e.g., the python script that called us) @@ -169,9 +173,15 @@ pub unsafe fn setup(build: &mut Build) { let parent = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid.parse().unwrap()); assert!(!parent.is_null(), "{}", io::Error::last_os_error()); let mut parent_handle = ptr::null_mut(); - let r = DuplicateHandle(GetCurrentProcess(), job, - parent, &mut parent_handle, - 0, FALSE, DUPLICATE_SAME_ACCESS); + let r = DuplicateHandle( + GetCurrentProcess(), + job, + parent, + &mut parent_handle, + 0, + FALSE, + DUPLICATE_SAME_ACCESS, + ); // If this failed, well at least we tried! An example of DuplicateHandle // failing in the past has been when the wrong python2 package spawned this diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index ff9a55afa2957..1fee3fd9ac1d2 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -106,12 +106,12 @@ #![feature(core_intrinsics)] #![feature(drain_filter)] -use std::cell::{RefCell, Cell}; -use std::collections::{HashSet, HashMap}; +use std::cell::{Cell, RefCell}; +use std::collections::{HashMap, HashSet}; use std::env; -use std::fs::{self, OpenOptions, File}; -use std::io::{Seek, SeekFrom, Write, Read}; -use std::path::{PathBuf, Path}; +use std::fs::{self, File, OpenOptions}; +use std::io::{Read, Seek, SeekFrom, Write}; +use std::path::{Path, PathBuf}; use std::process::{self, Command}; use std::slice; use std::str; @@ -121,33 +121,31 @@ use std::os::unix::fs::symlink as symlink_file; #[cfg(windows)] use std::os::windows::fs::symlink_file; -use build_helper::{ - mtime, output, run, run_suppressed, t, try_run, try_run_suppressed, -}; +use build_helper::{mtime, output, run, run_suppressed, t, try_run, try_run_suppressed}; use filetime::FileTime; use crate::util::{exe, libdir, CiEnv}; +mod builder; +mod cache; mod cc_detect; mod channel; mod check; -mod test; mod clean; mod compile; -mod metadata; mod config; mod dist; mod doc; mod flags; +mod format; mod install; +mod metadata; mod native; mod sanity; -pub mod util; -mod builder; -mod cache; +mod test; mod tool; mod toolstate; -mod format; +pub mod util; #[cfg(windows)] mod job; @@ -163,13 +161,12 @@ mod job { #[cfg(any(target_os = "haiku", target_os = "hermit", not(any(unix, windows))))] mod job { - pub unsafe fn setup(_build: &mut crate::Build) { - } + pub unsafe fn setup(_build: &mut crate::Build) {} } +use crate::cache::{Interned, INTERNER}; pub use crate::config::Config; use crate::flags::Subcommand; -use crate::cache::{Interned, INTERNER}; const LLVM_TOOLS: &[&str] = &[ "llvm-nm", // used to inspect binaries; it shows symbol names, their sizes and visibility @@ -179,7 +176,7 @@ const LLVM_TOOLS: &[&str] = &[ "llvm-readobj", // used to get information from ELFs/objects that the other tools don't provide "llvm-size", // used to prints the size of the linker sections of a program "llvm-strip", // used to discard symbols from binary files to reduce their size - "llvm-ar" // used for creating and modifying archive files + "llvm-ar", // used for creating and modifying archive files ]; /// A structure representing a Rust compiler. @@ -258,10 +255,8 @@ pub struct Build { ci_env: CiEnv, delayed_failures: RefCell>, prerelease_version: Cell>, - tool_artifacts: RefCell, - HashMap)> - >>, + tool_artifacts: + RefCell, HashMap)>>>, } #[derive(Debug)] @@ -274,8 +269,7 @@ struct Crate { impl Crate { fn is_local(&self, build: &Build) -> bool { - self.path.starts_with(&build.config.src) && - !self.path.to_string_lossy().ends_with("_shim") + self.path.starts_with(&build.config.src) && !self.path.to_string_lossy().ends_with("_shim") } fn local_path(&self, build: &Build) -> PathBuf { @@ -316,7 +310,7 @@ impl Mode { pub fn is_tool(&self) -> bool { match self { Mode::ToolBootstrap | Mode::ToolRustc | Mode::ToolStd => true, - _ => false + _ => false, } } } @@ -331,12 +325,10 @@ impl Build { let out = config.out.clone(); let is_sudo = match env::var_os("SUDO_USER") { - Some(sudo_user) => { - match env::var_os("USER") { - Some(user) => user != sudo_user, - None => false, - } - } + Some(sudo_user) => match env::var_os("USER") { + Some(user) => user != sudo_user, + None => false, + }, None => false, }; @@ -393,11 +385,15 @@ impl Build { // If local-rust is the same major.minor as the current version, then force a // local-rebuild - let local_version_verbose = output( - Command::new(&build.initial_rustc).arg("--version").arg("--verbose")); + let local_version_verbose = + output(Command::new(&build.initial_rustc).arg("--version").arg("--verbose")); let local_release = local_version_verbose - .lines().filter(|x| x.starts_with("release:")) - .next().unwrap().trim_start_matches("release:").trim(); + .lines() + .filter(|x| x.starts_with("release:")) + .next() + .unwrap() + .trim_start_matches("release:") + .trim(); let my_version = channel::CFG_RELEASE_NUM; if local_release.split('.').take(2).eq(my_version.split('.').take(2)) { build.verbose(&format!("auto-detected local-rebuild {}", local_release)); @@ -411,9 +407,7 @@ impl Build { } pub fn build_triple(&self) -> &[Interned] { - unsafe { - slice::from_raw_parts(&self.build, 1) - } + unsafe { slice::from_raw_parts(&self.build, 1) } } /// Executes the entire build, as configured by the flags and configuration. @@ -514,7 +508,7 @@ impl Build { /// Component directory that Cargo will produce output into (e.g. /// release/debug) fn cargo_dir(&self) -> &'static str { - if self.config.rust_optimize {"release"} else {"debug"} + if self.config.rust_optimize { "release" } else { "debug" } } fn tools_dir(&self, compiler: Compiler) -> PathBuf { @@ -535,17 +529,13 @@ impl Build { Mode::ToolBootstrap => "-bootstrap-tools", Mode::ToolStd | Mode::ToolRustc => "-tools", }; - self.out.join(&*compiler.host) - .join(format!("stage{}{}", compiler.stage, suffix)) + self.out.join(&*compiler.host).join(format!("stage{}{}", compiler.stage, suffix)) } /// Returns the root output directory for all Cargo output in a given stage, /// running a particular compiler, whether or not we're building the /// standard library, and targeting the specified architecture. - fn cargo_out(&self, - compiler: Compiler, - mode: Mode, - target: Interned) -> PathBuf { + fn cargo_out(&self, compiler: Compiler, mode: Mode, target: Interned) -> PathBuf { self.stage_out(compiler, mode).join(&*target).join(self.cargo_dir()) } @@ -589,7 +579,7 @@ impl Build { fn is_rust_llvm(&self, target: Interned) -> bool { match self.config.target_config.get(&target) { Some(ref c) => c.llvm_config.is_none(), - None => true + None => true, } } @@ -607,8 +597,8 @@ impl Build { // On Fedora the system LLVM installs FileCheck in the // llvm subdirectory of the libdir. let llvm_libdir = output(Command::new(s).arg("--libdir")); - let lib_filecheck = Path::new(llvm_libdir.trim()) - .join("llvm").join(exe("FileCheck", &*target)); + let lib_filecheck = + Path::new(llvm_libdir.trim()).join("llvm").join(exe("FileCheck", &*target)); if lib_filecheck.exists() { lib_filecheck } else { @@ -667,14 +657,18 @@ impl Build { /// Runs a command, printing out nice contextual information if it fails. fn run(&self, cmd: &mut Command) { - if self.config.dry_run { return; } + if self.config.dry_run { + return; + } self.verbose(&format!("running: {:?}", cmd)); run(cmd) } /// Runs a command, printing out nice contextual information if it fails. fn run_quiet(&self, cmd: &mut Command) { - if self.config.dry_run { return; } + if self.config.dry_run { + return; + } self.verbose(&format!("running: {:?}", cmd)); run_suppressed(cmd) } @@ -683,7 +677,9 @@ impl Build { /// Exits if the command failed to execute at all, otherwise returns its /// `status.success()`. fn try_run(&self, cmd: &mut Command) -> bool { - if self.config.dry_run { return true; } + if self.config.dry_run { + return true; + } self.verbose(&format!("running: {:?}", cmd)); try_run(cmd) } @@ -692,7 +688,9 @@ impl Build { /// Exits if the command failed to execute at all, otherwise returns its /// `status.success()`. fn try_run_quiet(&self, cmd: &mut Command) -> bool { - if self.config.dry_run { return true; } + if self.config.dry_run { + return true; + } self.verbose(&format!("running: {:?}", cmd)); try_run_suppressed(cmd) } @@ -720,7 +718,9 @@ impl Build { } fn info(&self, msg: &str) { - if self.config.dry_run { return; } + if self.config.dry_run { + return; + } println!("{}", msg); } @@ -732,7 +732,7 @@ impl Build { fn debuginfo_map(&self, which: GitRepo) -> Option { if !self.config.rust_remap_debuginfo { - return None + return None; } let path = match which { @@ -755,10 +755,12 @@ impl Build { fn cflags(&self, target: Interned, which: GitRepo) -> Vec { // Filter out -O and /O (the optimization flags) that we picked up from // cc-rs because the build scripts will determine that for themselves. - let mut base = self.cc[&target].args().iter() - .map(|s| s.to_string_lossy().into_owned()) - .filter(|s| !s.starts_with("-O") && !s.starts_with("/O")) - .collect::>(); + let mut base = self.cc[&target] + .args() + .iter() + .map(|s| s.to_string_lossy().into_owned()) + .filter(|s| !s.starts_with("-O") && !s.starts_with("/O")) + .collect::>(); // If we're compiling on macOS then we add a few unconditional flags // indicating that we want libc++ (more filled out than libstdc++) and @@ -776,7 +778,7 @@ impl Build { } if let Some(map) = self.debuginfo_map(which) { - let cc = self.cc(target); + let cc = self.cc(target); if cc.ends_with("clang") || cc.ends_with("gcc") { base.push(format!("-fdebug-prefix-map={}", map)); } else if cc.ends_with("clang-cl.exe") { @@ -801,20 +803,21 @@ impl Build { fn cxx(&self, target: Interned) -> Result<&Path, String> { match self.cxx.get(&target) { Some(p) => Ok(p.path()), - None => Err(format!( - "target `{}` is not configured as a host, only as a target", - target)) + None => { + Err(format!("target `{}` is not configured as a host, only as a target", target)) + } } } /// Returns the path to the linker for the given target if it needs to be overridden. fn linker(&self, target: Interned) -> Option<&Path> { - if let Some(linker) = self.config.target_config.get(&target) - .and_then(|c| c.linker.as_ref()) { + if let Some(linker) = self.config.target_config.get(&target).and_then(|c| c.linker.as_ref()) + { Some(linker) - } else if target != self.config.build && - util::use_host_linker(&target) && - !target.contains("msvc") { + } else if target != self.config.build + && util::use_host_linker(&target) + && !target.contains("msvc") + { Some(self.cc(target)) } else { None @@ -826,14 +829,15 @@ impl Build { if target.contains("pc-windows-msvc") { Some(true) } else { - self.config.target_config.get(&target) - .and_then(|t| t.crt_static) + self.config.target_config.get(&target).and_then(|t| t.crt_static) } } /// Returns the "musl root" for this `target`, if defined fn musl_root(&self, target: Interned) -> Option<&Path> { - self.config.target_config.get(&target) + self.config + .target_config + .get(&target) .and_then(|t| t.musl_root.as_ref()) .or(self.config.musl_root.as_ref()) .map(|p| &**p) @@ -841,22 +845,20 @@ impl Build { /// Returns the sysroot for the wasi target, if defined fn wasi_root(&self, target: Interned) -> Option<&Path> { - self.config.target_config.get(&target) - .and_then(|t| t.wasi_root.as_ref()) - .map(|p| &**p) + self.config.target_config.get(&target).and_then(|t| t.wasi_root.as_ref()).map(|p| &**p) } /// Returns `true` if this is a no-std `target`, if defined fn no_std(&self, target: Interned) -> Option { - self.config.target_config.get(&target) - .map(|t| t.no_std) + self.config.target_config.get(&target).map(|t| t.no_std) } /// Returns `true` if the target will be tested using the `remote-test-client` /// and `remote-test-server` binaries. fn remote_tested(&self, target: Interned) -> bool { - self.qemu_rootfs(target).is_some() || target.contains("android") || - env::var_os("TEST_DEVICE_ADDR").is_some() + self.qemu_rootfs(target).is_some() + || target.contains("android") + || env::var_os("TEST_DEVICE_ADDR").is_some() } /// Returns the root of the "rootfs" image that this target will be using, @@ -865,9 +867,7 @@ impl Build { /// If `Some` is returned then that means that tests for this target are /// emulated with QEMU and binaries will need to be shipped to the emulator. fn qemu_rootfs(&self, target: Interned) -> Option<&Path> { - self.config.target_config.get(&target) - .and_then(|t| t.qemu_rootfs.as_ref()) - .map(|p| &**p) + self.config.target_config.get(&target).and_then(|t| t.qemu_rootfs.as_ref()).map(|p| &**p) } /// Path to the python interpreter to use @@ -899,9 +899,9 @@ impl Build { /// When all of these conditions are met the build will lift artifacts from /// the previous stage forward. fn force_use_stage1(&self, compiler: Compiler, target: Interned) -> bool { - !self.config.full_bootstrap && - compiler.stage >= 2 && - (self.hosts.iter().any(|h| *h == target) || target == self.build) + !self.config.full_bootstrap + && compiler.stage >= 2 + && (self.hosts.iter().any(|h| *h == target) || target == self.build) } /// Given `num` in the form "a.b.c" return a "release string" which @@ -912,11 +912,13 @@ impl Build { fn release(&self, num: &str) -> String { match &self.config.channel[..] { "stable" => num.to_string(), - "beta" => if self.rust_info.is_git() { - format!("{}-beta.{}", num, self.beta_prerelease_version()) - } else { - format!("{}-beta", num) - }, + "beta" => { + if self.rust_info.is_git() { + format!("{}-beta.{}", num, self.beta_prerelease_version()) + } else { + format!("{}-beta", num) + } + } "nightly" => format!("{}-nightly", num), _ => format!("{}-dev", num), } @@ -924,33 +926,21 @@ impl Build { fn beta_prerelease_version(&self) -> u32 { if let Some(s) = self.prerelease_version.get() { - return s + return s; } let beta = output( - Command::new("git") - .arg("ls-remote") - .arg("origin") - .arg("beta") - .current_dir(&self.src) + Command::new("git").arg("ls-remote").arg("origin").arg("beta").current_dir(&self.src), ); let beta = beta.trim().split_whitespace().next().unwrap(); let master = output( - Command::new("git") - .arg("ls-remote") - .arg("origin") - .arg("master") - .current_dir(&self.src) + Command::new("git").arg("ls-remote").arg("origin").arg("master").current_dir(&self.src), ); let master = master.trim().split_whitespace().next().unwrap(); // Figure out where the current beta branch started. let base = output( - Command::new("git") - .arg("merge-base") - .arg(beta) - .arg(master) - .current_dir(&self.src), + Command::new("git").arg("merge-base").arg(beta).arg(master).current_dir(&self.src), ); let base = base.trim(); @@ -1061,7 +1051,7 @@ impl Build { let prefix = "version = \""; let suffix = "\""; if line.starts_with(prefix) && line.ends_with(suffix) { - return line[prefix.len()..line.len() - suffix.len()].to_string() + return line[prefix.len()..line.len() - suffix.len()].to_string(); } } @@ -1106,7 +1096,7 @@ impl Build { // run_cargo for more information (in compile.rs). for part in contents.split(|b| *b == 0) { if part.is_empty() { - continue + continue; } let host = part[0] as char == 'h'; let path = PathBuf::from(t!(str::from_utf8(&part[1..]))); @@ -1117,9 +1107,13 @@ impl Build { /// Copies a file from `src` to `dst` pub fn copy(&self, src: &Path, dst: &Path) { - if self.config.dry_run { return; } + if self.config.dry_run { + return; + } self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst)); - if src == dst { return; } + if src == dst { + return; + } let _ = fs::remove_file(&dst); let metadata = t!(src.symlink_metadata()); if metadata.file_type().is_symlink() { @@ -1131,8 +1125,7 @@ impl Build { // just fall back to a slow `copy` operation. } else { if let Err(e) = fs::copy(src, dst) { - panic!("failed to copy `{}` to `{}`: {}", src.display(), - dst.display(), e) + panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e) } t!(fs::set_permissions(dst, metadata.permissions())); let atime = FileTime::from_last_access_time(&metadata); @@ -1144,7 +1137,9 @@ impl Build { /// Search-and-replaces within a file. (Not maximally efficiently: allocates a /// new string for each replacement.) pub fn replace_in_file(&self, path: &Path, replacements: &[(&str, &str)]) { - if self.config.dry_run { return; } + if self.config.dry_run { + return; + } let mut contents = String::new(); let mut file = t!(OpenOptions::new().read(true).write(true).open(path)); t!(file.read_to_string(&mut contents)); @@ -1159,7 +1154,9 @@ impl Build { /// Copies the `src` directory recursively to `dst`. Both are assumed to exist /// when this function is called. pub fn cp_r(&self, src: &Path, dst: &Path) { - if self.config.dry_run { return; } + if self.config.dry_run { + return; + } for f in self.read_dir(src) { let path = f.path(); let name = path.file_name().unwrap(); @@ -1210,7 +1207,9 @@ impl Build { } fn install(&self, src: &Path, dstdir: &Path, perms: u32) { - if self.config.dry_run { return; } + if self.config.dry_run { + return; + } let dst = dstdir.join(src.file_name().unwrap()); self.verbose_than(1, &format!("Install {:?} to {:?}", src, dst)); t!(fs::create_dir_all(dstdir)); @@ -1221,8 +1220,7 @@ impl Build { } let metadata = t!(src.symlink_metadata()); if let Err(e) = fs::copy(&src, &dst) { - panic!("failed to copy `{}` to `{}`: {}", src.display(), - dst.display(), e) + panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e) } t!(fs::set_permissions(&dst, metadata.permissions())); let atime = FileTime::from_last_access_time(&metadata); @@ -1233,26 +1231,34 @@ impl Build { } fn create(&self, path: &Path, s: &str) { - if self.config.dry_run { return; } + if self.config.dry_run { + return; + } t!(fs::write(path, s)); } fn read(&self, path: &Path) -> String { - if self.config.dry_run { return String::new(); } + if self.config.dry_run { + return String::new(); + } t!(fs::read_to_string(path)) } fn create_dir(&self, dir: &Path) { - if self.config.dry_run { return; } + if self.config.dry_run { + return; + } t!(fs::create_dir_all(dir)) } fn remove_dir(&self, dir: &Path) { - if self.config.dry_run { return; } + if self.config.dry_run { + return; + } t!(fs::remove_dir_all(dir)) } - fn read_dir(&self, dir: &Path) -> impl Iterator { + fn read_dir(&self, dir: &Path) -> impl Iterator { let iter = match fs::read_dir(dir) { Ok(v) => v, Err(_) if self.config.dry_run => return vec![].into_iter(), @@ -1262,7 +1268,9 @@ impl Build { } fn remove(&self, f: &Path) { - if self.config.dry_run { return; } + if self.config.dry_run { + return; + } fs::remove_file(f).unwrap_or_else(|_| panic!("failed to remove {:?}", f)); } } @@ -1275,7 +1283,6 @@ fn chmod(path: &Path, perms: u32) { #[cfg(windows)] fn chmod(_path: &Path, _perms: u32) {} - impl Compiler { pub fn with_stage(mut self, stage: u32) -> Compiler { self.stage = stage; diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index b622b3682a777..8a26adc7ed501 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -1,14 +1,14 @@ use std::collections::HashMap; -use std::process::Command; -use std::path::PathBuf; use std::collections::HashSet; +use std::path::PathBuf; +use std::process::Command; use build_helper::output; use serde::Deserialize; use serde_json; -use crate::{Build, Crate}; use crate::cache::INTERNER; +use crate::{Build, Crate}; #[derive(Deserialize)] struct Output { @@ -71,10 +71,14 @@ fn build_krate(features: &str, build: &mut Build, resolves: &mut Vec) -> ShouldRun<'_> { - run.path("src/llvm-project") - .path("src/llvm-project/llvm") - .path("src/llvm") + run.path("src/llvm-project").path("src/llvm-project/llvm").path("src/llvm") } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Llvm { - target: run.target, - }); + run.builder.ensure(Llvm { target: run.target }); } /// Compile LLVM for `target`. @@ -56,7 +52,7 @@ impl Step for Llvm { if let Some(config) = builder.config.target_config.get(&target) { if let Some(ref s) = config.llvm_config { check_llvm_version(builder, s); - return s.to_path_buf() + return s.to_path_buf(); } } @@ -69,8 +65,8 @@ impl Step for Llvm { } llvm_config_ret_dir.push("bin"); - let build_llvm_config = llvm_config_ret_dir - .join(exe("llvm-config", &*builder.config.build)); + let build_llvm_config = + llvm_config_ret_dir.join(exe("llvm-config", &*builder.config.build)); let done_stamp = out_dir.join("llvm-finished-building"); if done_stamp.exists() { @@ -112,8 +108,10 @@ impl Step for Llvm { // defaults! let llvm_targets = match &builder.config.llvm_targets { Some(s) => s, - None => "AArch64;ARM;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;\ - Sparc;SystemZ;WebAssembly;X86", + None => { + "AArch64;ARM;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;\ + Sparc;SystemZ;WebAssembly;X86" + } }; let llvm_exp_targets = match builder.config.llvm_experimental_targets { @@ -121,31 +119,31 @@ impl Step for Llvm { None => "", }; - let assertions = if builder.config.llvm_assertions {"ON"} else {"OFF"}; + let assertions = if builder.config.llvm_assertions { "ON" } else { "OFF" }; cfg.out_dir(&out_dir) - .profile(profile) - .define("LLVM_ENABLE_ASSERTIONS", assertions) - .define("LLVM_TARGETS_TO_BUILD", llvm_targets) - .define("LLVM_EXPERIMENTAL_TARGETS_TO_BUILD", llvm_exp_targets) - .define("LLVM_INCLUDE_EXAMPLES", "OFF") - .define("LLVM_INCLUDE_TESTS", "OFF") - .define("LLVM_INCLUDE_DOCS", "OFF") - .define("LLVM_INCLUDE_BENCHMARKS", "OFF") - .define("LLVM_ENABLE_ZLIB", "OFF") - .define("WITH_POLLY", "OFF") - .define("LLVM_ENABLE_TERMINFO", "OFF") - .define("LLVM_ENABLE_LIBEDIT", "OFF") - .define("LLVM_ENABLE_BINDINGS", "OFF") - .define("LLVM_ENABLE_Z3_SOLVER", "OFF") - .define("LLVM_PARALLEL_COMPILE_JOBS", builder.jobs().to_string()) - .define("LLVM_TARGET_ARCH", target.split('-').next().unwrap()) - .define("LLVM_DEFAULT_TARGET_TRIPLE", target); + .profile(profile) + .define("LLVM_ENABLE_ASSERTIONS", assertions) + .define("LLVM_TARGETS_TO_BUILD", llvm_targets) + .define("LLVM_EXPERIMENTAL_TARGETS_TO_BUILD", llvm_exp_targets) + .define("LLVM_INCLUDE_EXAMPLES", "OFF") + .define("LLVM_INCLUDE_TESTS", "OFF") + .define("LLVM_INCLUDE_DOCS", "OFF") + .define("LLVM_INCLUDE_BENCHMARKS", "OFF") + .define("LLVM_ENABLE_ZLIB", "OFF") + .define("WITH_POLLY", "OFF") + .define("LLVM_ENABLE_TERMINFO", "OFF") + .define("LLVM_ENABLE_LIBEDIT", "OFF") + .define("LLVM_ENABLE_BINDINGS", "OFF") + .define("LLVM_ENABLE_Z3_SOLVER", "OFF") + .define("LLVM_PARALLEL_COMPILE_JOBS", builder.jobs().to_string()) + .define("LLVM_TARGET_ARCH", target.split('-').next().unwrap()) + .define("LLVM_DEFAULT_TARGET_TRIPLE", target); if builder.config.llvm_thin_lto { cfg.define("LLVM_ENABLE_LTO", "Thin"); if !target.contains("apple") { - cfg.define("LLVM_ENABLE_LLD", "ON"); + cfg.define("LLVM_ENABLE_LLD", "ON"); } } @@ -212,20 +210,17 @@ impl Step for Llvm { // http://llvm.org/docs/HowToCrossCompileLLVM.html if target != builder.config.build { - builder.ensure(Llvm { - target: builder.config.build, - }); + builder.ensure(Llvm { target: builder.config.build }); // FIXME: if the llvm root for the build triple is overridden then we // should use llvm-tblgen from there, also should verify that it // actually exists most of the time in normal installs of LLVM. let host = builder.llvm_out(builder.config.build).join("bin/llvm-tblgen"); - cfg.define("CMAKE_CROSSCOMPILING", "True") - .define("LLVM_TABLEGEN", &host); + cfg.define("CMAKE_CROSSCOMPILING", "True").define("LLVM_TABLEGEN", &host); if target.contains("netbsd") { - cfg.define("CMAKE_SYSTEM_NAME", "NetBSD"); + cfg.define("CMAKE_SYSTEM_NAME", "NetBSD"); } else if target.contains("freebsd") { - cfg.define("CMAKE_SYSTEM_NAME", "FreeBSD"); + cfg.define("CMAKE_SYSTEM_NAME", "FreeBSD"); } cfg.define("LLVM_NATIVE_BUILD", builder.llvm_out(builder.config.build).join("build")); @@ -237,11 +232,8 @@ impl Step for Llvm { cfg.define("LLVM_VERSION_SUFFIX", suffix); } } else { - let mut default_suffix = format!( - "-rust-{}-{}", - channel::CFG_RELEASE_NUM, - builder.config.channel, - ); + let mut default_suffix = + format!("-rust-{}-{}", channel::CFG_RELEASE_NUM, builder.config.channel,); if let Some(sha) = llvm_info.sha_short() { default_suffix.push_str("-"); default_suffix.push_str(sha); @@ -282,7 +274,7 @@ impl Step for Llvm { fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { if !builder.config.llvm_version_check { - return + return; } if builder.config.dry_run { @@ -291,19 +283,16 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { let mut cmd = Command::new(llvm_config); let version = output(cmd.arg("--version")); - let mut parts = version.split('.').take(2) - .filter_map(|s| s.parse::().ok()); + let mut parts = version.split('.').take(2).filter_map(|s| s.parse::().ok()); if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) { if major >= 7 { - return + return; } } panic!("\n\nbad LLVM version: {}, need >=7.0\n\n", version) } -fn configure_cmake(builder: &Builder<'_>, - target: Interned, - cfg: &mut cmake::Config) { +fn configure_cmake(builder: &Builder<'_>, target: Interned, cfg: &mut cmake::Config) { // Do not print installation messages for up-to-date files. // LLVM and LLD builds can produce a lot of those and hit CI limits on log size. cfg.define("CMAKE_INSTALL_MESSAGE", "LAZY"); @@ -311,8 +300,7 @@ fn configure_cmake(builder: &Builder<'_>, if builder.config.ninja { cfg.generator("Ninja"); } - cfg.target(&target) - .host(&builder.config.build); + cfg.target(&target).host(&builder.config.build); let sanitize_cc = |cc: &Path| { if target.contains("msvc") { @@ -326,7 +314,7 @@ fn configure_cmake(builder: &Builder<'_>, // vars that we'd otherwise configure. In that case we just skip this // entirely. if target.contains("msvc") && !builder.config.ninja { - return + return; } let (cc, cxx) = match builder.config.llvm_clang_cl { @@ -335,56 +323,52 @@ fn configure_cmake(builder: &Builder<'_>, }; // Handle msvc + ninja + ccache specially (this is what the bots use) - if target.contains("msvc") && - builder.config.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"); - - cfg.define("CMAKE_C_COMPILER", sanitize_cc(&wrap_cc)) - .define("CMAKE_CXX_COMPILER", sanitize_cc(&wrap_cc)); - cfg.env("SCCACHE_PATH", - builder.config.ccache.as_ref().unwrap()) - .env("SCCACHE_TARGET", target) - .env("SCCACHE_CC", &cc) - .env("SCCACHE_CXX", &cxx); - - // Building LLVM on MSVC can be a little ludicrous at times. We're so far - // off the beaten path here that I'm not really sure this is even half - // supported any more. Here we're trying to: - // - // * Build LLVM on MSVC - // * Build LLVM with `clang-cl` instead of `cl.exe` - // * Build a project with `sccache` - // * Build for 32-bit as well - // * Build with Ninja - // - // For `cl.exe` there are different binaries to compile 32/64 bit which - // we use but for `clang-cl` there's only one which internally - // multiplexes via flags. As a result it appears that CMake's detection - // of a compiler's architecture and such on MSVC **doesn't** pass any - // custom flags we pass in CMAKE_CXX_FLAGS below. This means that if we - // use `clang-cl.exe` it's always diagnosed as a 64-bit compiler which - // definitely causes problems since all the env vars are pointing to - // 32-bit libraries. - // - // To hack around this... again... we pass an argument that's - // unconditionally passed in the sccache shim. This'll get CMake to - // correctly diagnose it's doing a 32-bit compilation and LLVM will - // internally configure itself appropriately. - if builder.config.llvm_clang_cl.is_some() && target.contains("i686") { - cfg.env("SCCACHE_EXTRA_ARGS", "-m32"); - } + if target.contains("msvc") && builder.config.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"); + + cfg.define("CMAKE_C_COMPILER", sanitize_cc(&wrap_cc)) + .define("CMAKE_CXX_COMPILER", sanitize_cc(&wrap_cc)); + cfg.env("SCCACHE_PATH", builder.config.ccache.as_ref().unwrap()) + .env("SCCACHE_TARGET", target) + .env("SCCACHE_CC", &cc) + .env("SCCACHE_CXX", &cxx); + + // Building LLVM on MSVC can be a little ludicrous at times. We're so far + // off the beaten path here that I'm not really sure this is even half + // supported any more. Here we're trying to: + // + // * Build LLVM on MSVC + // * Build LLVM with `clang-cl` instead of `cl.exe` + // * Build a project with `sccache` + // * Build for 32-bit as well + // * Build with Ninja + // + // For `cl.exe` there are different binaries to compile 32/64 bit which + // we use but for `clang-cl` there's only one which internally + // multiplexes via flags. As a result it appears that CMake's detection + // of a compiler's architecture and such on MSVC **doesn't** pass any + // custom flags we pass in CMAKE_CXX_FLAGS below. This means that if we + // use `clang-cl.exe` it's always diagnosed as a 64-bit compiler which + // definitely causes problems since all the env vars are pointing to + // 32-bit libraries. + // + // To hack around this... again... we pass an argument that's + // unconditionally passed in the sccache shim. This'll get CMake to + // correctly diagnose it's doing a 32-bit compilation and LLVM will + // internally configure itself appropriately. + if builder.config.llvm_clang_cl.is_some() && target.contains("i686") { + cfg.env("SCCACHE_EXTRA_ARGS", "-m32"); + } } else { - // If ccache is configured we inform the build a little differently how - // to invoke ccache while also invoking our compilers. - if let Some(ref ccache) = builder.config.ccache { - cfg.define("CMAKE_C_COMPILER_LAUNCHER", ccache) - .define("CMAKE_CXX_COMPILER_LAUNCHER", ccache); - } - cfg.define("CMAKE_C_COMPILER", sanitize_cc(cc)) - .define("CMAKE_CXX_COMPILER", sanitize_cc(cxx)); + // If ccache is configured we inform the build a little differently how + // to invoke ccache while also invoking our compilers. + if let Some(ref ccache) = builder.config.ccache { + cfg.define("CMAKE_C_COMPILER_LAUNCHER", ccache) + .define("CMAKE_CXX_COMPILER_LAUNCHER", ccache); + } + cfg.define("CMAKE_C_COMPILER", sanitize_cc(cc)) + .define("CMAKE_CXX_COMPILER", sanitize_cc(cxx)); } cfg.build_arg("-j").build_arg(builder.jobs().to_string()); @@ -394,10 +378,7 @@ fn configure_cmake(builder: &Builder<'_>, } cfg.define("CMAKE_C_FLAGS", cflags); let mut cxxflags = builder.cflags(target, GitRepo::Llvm).join(" "); - if builder.config.llvm_static_stdcpp && - !target.contains("msvc") && - !target.contains("netbsd") - { + if builder.config.llvm_static_stdcpp && !target.contains("msvc") && !target.contains("netbsd") { cxxflags.push_str(" -static-libstdc++"); } if let Some(ref s) = builder.config.llvm_cxxflags { @@ -455,14 +436,12 @@ impl Step for Lld { } let target = self.target; - let llvm_config = builder.ensure(Llvm { - target: self.target, - }); + let llvm_config = builder.ensure(Llvm { target: self.target }); let out_dir = builder.lld_out(target); let done_stamp = out_dir.join("lld-finished-building"); if done_stamp.exists() { - return out_dir + return out_dir; } builder.info(&format!("Building LLD for {}", target)); @@ -486,14 +465,12 @@ impl Step for Lld { // ensure we don't hit the same bugs with escaping. It means that you // can't build on a system where your paths require `\` on Windows, but // there's probably a lot of reasons you can't do that other than this. - let llvm_config_shim = env::current_exe() - .unwrap() - .with_file_name("llvm-config-wrapper"); + let llvm_config_shim = env::current_exe().unwrap().with_file_name("llvm-config-wrapper"); cfg.out_dir(&out_dir) - .profile("Release") - .env("LLVM_CONFIG_REAL", llvm_config) - .define("LLVM_CONFIG_PATH", llvm_config_shim) - .define("LLVM_INCLUDE_TESTS", "OFF"); + .profile("Release") + .env("LLVM_CONFIG_REAL", llvm_config) + .define("LLVM_CONFIG_PATH", llvm_config_shim) + .define("LLVM_INCLUDE_TESTS", "OFF"); cfg.build(); @@ -528,7 +505,7 @@ impl Step for TestHelpers { let dst = builder.test_helpers_out(target); let src = builder.src.join("src/test/auxiliary/rust_test_helpers.c"); if up_to_date(&src, &dst.join("librust_test_helpers.a")) { - return + return; } builder.info("Building test helpers"); @@ -550,13 +527,13 @@ impl Step for TestHelpers { } cfg.cargo_metadata(false) - .out_dir(&dst) - .target(&target) - .host(&builder.config.build) - .opt_level(0) - .warnings(false) - .debug(false) - .file(builder.src.join("src/test/auxiliary/rust_test_helpers.c")) - .compile("rust_test_helpers"); + .out_dir(&dst) + .target(&target) + .host(&builder.config.build) + .opt_level(0) + .warnings(false) + .debug(false) + .file(builder.src.join("src/test/auxiliary/rust_test_helpers.c")) + .compile("rust_test_helpers"); } } diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index bffe748f37cc1..8ff7056e628f3 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -10,7 +10,7 @@ use std::collections::HashMap; use std::env; -use std::ffi::{OsString, OsStr}; +use std::ffi::{OsStr, OsString}; use std::fs; use std::path::PathBuf; use std::process::Command; @@ -26,30 +26,31 @@ struct Finder { impl Finder { fn new() -> Self { - Self { - cache: HashMap::new(), - path: env::var_os("PATH").unwrap_or_default() - } + Self { cache: HashMap::new(), path: env::var_os("PATH").unwrap_or_default() } } fn maybe_have>(&mut self, cmd: S) -> Option { let cmd: OsString = cmd.as_ref().into(); let path = &self.path; - self.cache.entry(cmd.clone()).or_insert_with(|| { - for path in env::split_paths(path) { - let target = path.join(&cmd); - let mut cmd_exe = cmd.clone(); - cmd_exe.push(".exe"); - - if target.is_file() // some/path/git + self.cache + .entry(cmd.clone()) + .or_insert_with(|| { + for path in env::split_paths(path) { + let target = path.join(&cmd); + let mut cmd_exe = cmd.clone(); + cmd_exe.push(".exe"); + + if target.is_file() // some/path/git || path.join(&cmd_exe).exists() // some/path/git.exe - || target.join(&cmd_exe).exists() // some/path/git/git.exe - { - return Some(target); + || target.join(&cmd_exe).exists() + // some/path/git/git.exe + { + return Some(target); + } } - } - None - }).clone() + None + }) + .clone() } fn must_have>(&mut self, cmd: S) -> PathBuf { @@ -77,11 +78,17 @@ pub fn check(build: &mut Build) { } // We need cmake, but only if we're actually building LLVM or sanitizers. - let building_llvm = build.hosts.iter() - .map(|host| build.config.target_config - .get(host) - .map(|config| config.llvm_config.is_none()) - .unwrap_or(true)) + let building_llvm = build + .hosts + .iter() + .map(|host| { + build + .config + .target_config + .get(host) + .map(|config| config.llvm_config.is_none()) + .unwrap_or(true) + }) .any(|build_llvm_ourselves| build_llvm_ourselves); if building_llvm || build.config.sanitizers { cmd_finder.must_have("cmake"); @@ -119,17 +126,29 @@ pub fn check(build: &mut Build) { } } - build.config.python = build.config.python.take().map(|p| cmd_finder.must_have(p)) + build.config.python = build + .config + .python + .take() + .map(|p| cmd_finder.must_have(p)) .or_else(|| cmd_finder.maybe_have("python2.7")) .or_else(|| cmd_finder.maybe_have("python2")) .or_else(|| env::var_os("BOOTSTRAP_PYTHON").map(PathBuf::from)) // set by bootstrap.py .or_else(|| Some(cmd_finder.must_have("python"))); - build.config.nodejs = build.config.nodejs.take().map(|p| cmd_finder.must_have(p)) + build.config.nodejs = build + .config + .nodejs + .take() + .map(|p| cmd_finder.must_have(p)) .or_else(|| cmd_finder.maybe_have("node")) .or_else(|| cmd_finder.maybe_have("nodejs")); - build.config.gdb = build.config.gdb.take().map(|p| cmd_finder.must_have(p)) + build.config.gdb = build + .config + .gdb + .take() + .map(|p| cmd_finder.must_have(p)) .or_else(|| cmd_finder.maybe_have("gdb")); // We're gonna build some custom C code here and there, host triples @@ -169,15 +188,13 @@ pub fn check(build: &mut Build) { for target in &build.targets { // Can't compile for iOS unless we're on macOS - if target.contains("apple-ios") && - !build.build.contains("apple-darwin") { + if target.contains("apple-ios") && !build.build.contains("apple-darwin") { panic!("the iOS target is only supported on macOS"); } if target.contains("-none-") || target.contains("nvptx") { if build.no_std(*target).is_none() { - let target = build.config.target_config.entry(target.clone()) - .or_default(); + let target = build.config.target_config.entry(target.clone()).or_default(); target.no_std = true; } @@ -192,22 +209,20 @@ pub fn check(build: &mut Build) { // If this is a native target (host is also musl) and no musl-root is given, // fall back to the system toolchain in /usr before giving up if build.musl_root(*target).is_none() && build.config.build == *target { - let target = build.config.target_config.entry(target.clone()) - .or_default(); + let target = build.config.target_config.entry(target.clone()).or_default(); target.musl_root = Some("/usr".into()); } match build.musl_root(*target) { Some(root) => { if fs::metadata(root.join("lib/libc.a")).is_err() { - panic!("couldn't find libc.a in musl dir: {}", - root.join("lib").display()); + panic!("couldn't find libc.a in musl dir: {}", root.join("lib").display()); } } - None => { - panic!("when targeting MUSL either the rust.musl-root \ + None => panic!( + "when targeting MUSL either the rust.musl-root \ option or the target.$TARGET.musl-root option must \ - be specified in config.toml") - } + be specified in config.toml" + ), } } @@ -217,7 +232,8 @@ pub fn check(build: &mut Build) { // Studio, so detect that here and error. let out = output(Command::new("cmake").arg("--help")); if !out.contains("Visual Studio") { - panic!(" + panic!( + " cmake does not support Visual Studio generators. This is likely due to it being an msys/cygwin build of cmake, @@ -228,7 +244,8 @@ If you are building under msys2 try installing the mingw-w64-x86_64-cmake package instead of cmake: $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake -"); +" + ); } } } @@ -240,8 +257,10 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake if build.config.channel == "stable" { let stage0 = t!(fs::read_to_string(build.src.join("src/stage0.txt"))); if stage0.contains("\ndev:") { - panic!("bootstrapping from a dev compiler in a stable release, but \ - should only be bootstrapping from a released compiler!"); + panic!( + "bootstrapping from a dev compiler in a stable release, but \ + should only be bootstrapping from a released compiler!" + ); } } } diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 17aea17e69e0b..58dc8ffc17da2 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -19,11 +19,11 @@ use crate::compile; use crate::dist; use crate::flags::Subcommand; use crate::native; -use crate::tool::{self, Tool, SourceType}; +use crate::tool::{self, SourceType, Tool}; use crate::toolstate::ToolState; use crate::util::{self, dylib_path, dylib_path_var}; use crate::Crate as CargoCrate; -use crate::{DocTests, Mode, GitRepo, envify}; +use crate::{envify, DocTests, GitRepo, Mode}; const ADB_TEST_DIR: &str = "/data/tmp/work"; @@ -115,16 +115,13 @@ impl Step for Linkcheck { let _time = util::timeit(&builder); try_run( builder, - builder - .tool_cmd(Tool::Linkchecker) - .arg(builder.out.join(host).join("doc")), + builder.tool_cmd(Tool::Linkchecker).arg(builder.out.join(host).join("doc")), ); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let builder = run.builder; - run.path("src/tools/linkchecker") - .default_condition(builder.config.docs) + run.path("src/tools/linkchecker").default_condition(builder.config.docs) } fn make_run(run: RunConfig<'_>) { @@ -147,10 +144,7 @@ impl Step for Cargotest { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Cargotest { - stage: run.builder.top_stage, - host: run.target, - }); + run.builder.ensure(Cargotest { stage: run.builder.top_stage, host: run.target }); } /// Runs the `cargotest` tool as compiled in `stage` by the `host` compiler. @@ -159,10 +153,7 @@ impl Step for Cargotest { /// test` to ensure that we don't regress the test suites there. fn run(self, builder: &Builder<'_>) { let compiler = builder.compiler(self.stage, self.host); - builder.ensure(compile::Rustc { - compiler, - target: compiler.host, - }); + builder.ensure(compile::Rustc { compiler, target: compiler.host }); // Note that this is a short, cryptic, and not scoped directory name. This // is currently to minimize the length of path on Windows where we otherwise @@ -197,28 +188,24 @@ impl Step for Cargo { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Cargo { - stage: run.builder.top_stage, - host: run.target, - }); + run.builder.ensure(Cargo { stage: run.builder.top_stage, host: run.target }); } /// Runs `cargo test` for `cargo` packaged with Rust. fn run(self, builder: &Builder<'_>) { let compiler = builder.compiler(self.stage, self.host); - builder.ensure(tool::Cargo { + builder.ensure(tool::Cargo { compiler, target: self.host }); + let mut cargo = tool::prepare_tool_cargo( + builder, compiler, - target: self.host, - }); - let mut cargo = tool::prepare_tool_cargo(builder, - compiler, - Mode::ToolRustc, - self.host, - "test", - "src/tools/cargo", - SourceType::Submodule, - &[]); + Mode::ToolRustc, + self.host, + "test", + "src/tools/cargo", + SourceType::Submodule, + &[], + ); if !builder.fail_fast { cargo.arg("--no-fail-fast"); @@ -254,10 +241,7 @@ impl Step for Rls { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rls { - stage: run.builder.top_stage, - host: run.target, - }); + run.builder.ensure(Rls { stage: run.builder.top_stage, host: run.target }); } /// Runs `cargo test` for the rls. @@ -266,28 +250,26 @@ impl Step for Rls { let host = self.host; let compiler = builder.compiler(stage, host); - let build_result = builder.ensure(tool::Rls { - compiler, - target: self.host, - extra_features: Vec::new(), - }); + let build_result = + builder.ensure(tool::Rls { compiler, target: self.host, extra_features: Vec::new() }); if build_result.is_none() { eprintln!("failed to test rls: could not build"); return; } - let mut cargo = tool::prepare_tool_cargo(builder, - compiler, - Mode::ToolRustc, - host, - "test", - "src/tools/rls", - SourceType::Submodule, - &[]); + let mut cargo = tool::prepare_tool_cargo( + builder, + compiler, + Mode::ToolRustc, + host, + "test", + "src/tools/rls", + SourceType::Submodule, + &[], + ); builder.add_rustc_lib_path(compiler, &mut cargo); - cargo.arg("--") - .args(builder.config.cmd.test_args()); + cargo.arg("--").args(builder.config.cmd.test_args()); if try_run(builder, &mut cargo.into()) { builder.save_toolstate("rls", ToolState::TestPass); @@ -310,10 +292,7 @@ impl Step for Rustfmt { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rustfmt { - stage: run.builder.top_stage, - host: run.target, - }); + run.builder.ensure(Rustfmt { stage: run.builder.top_stage, host: run.target }); } /// Runs `cargo test` for rustfmt. @@ -332,14 +311,16 @@ impl Step for Rustfmt { return; } - let mut cargo = tool::prepare_tool_cargo(builder, - compiler, - Mode::ToolRustc, - host, - "test", - "src/tools/rustfmt", - SourceType::Submodule, - &[]); + let mut cargo = tool::prepare_tool_cargo( + builder, + compiler, + Mode::ToolRustc, + host, + "test", + "src/tools/rustfmt", + SourceType::Submodule, + &[], + ); let dir = testdir(builder, compiler.host); t!(fs::create_dir_all(&dir)); @@ -368,10 +349,7 @@ impl Step for Miri { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Miri { - stage: run.builder.top_stage, - host: run.target, - }); + run.builder.ensure(Miri { stage: run.builder.top_stage, host: run.target }); } /// Runs `cargo test` for miri. @@ -380,11 +358,8 @@ impl Step for Miri { let host = self.host; let compiler = builder.compiler(stage, host); - let miri = builder.ensure(tool::Miri { - compiler, - target: self.host, - extra_features: Vec::new(), - }); + let miri = + builder.ensure(tool::Miri { compiler, target: self.host, extra_features: Vec::new() }); if let Some(miri) = miri { let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "install"); cargo.arg("xargo"); @@ -407,12 +382,7 @@ impl Step for Miri { SourceType::Submodule, &[], ); - cargo - .arg("--bin") - .arg("cargo-miri") - .arg("--") - .arg("miri") - .arg("setup"); + cargo.arg("--bin").arg("cargo-miri").arg("--").arg("miri").arg("setup"); // Tell `cargo miri` not to worry about the sysroot mismatch (we built with // stage1 but run with stage2). @@ -441,7 +411,8 @@ impl Step for Miri { String::new() } else { builder.verbose(&format!("running: {:?}", cargo)); - let out = cargo.output() + let out = cargo + .output() .expect("We already ran `cargo miri setup` before and that worked"); assert!(out.status.success(), "`cargo miri setup` returned with non-0 exit code"); // Output is "\n". @@ -497,9 +468,7 @@ impl Step for CompiletestTest { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(CompiletestTest { - host: run.target, - }); + run.builder.ensure(CompiletestTest { host: run.target }); } /// Runs `cargo test` for compiletest. @@ -507,14 +476,16 @@ impl Step for CompiletestTest { let host = self.host; let compiler = builder.compiler(0, host); - let cargo = tool::prepare_tool_cargo(builder, - compiler, - Mode::ToolBootstrap, - host, - "test", - "src/tools/compiletest", - SourceType::InTree, - &[]); + let cargo = tool::prepare_tool_cargo( + builder, + compiler, + Mode::ToolBootstrap, + host, + "test", + "src/tools/compiletest", + SourceType::InTree, + &[], + ); try_run(builder, &mut cargo.into()); } @@ -536,10 +507,7 @@ impl Step for Clippy { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Clippy { - stage: run.builder.top_stage, - host: run.target, - }); + run.builder.ensure(Clippy { stage: run.builder.top_stage, host: run.target }); } /// Runs `cargo test` for clippy. @@ -554,22 +522,22 @@ impl Step for Clippy { extra_features: Vec::new(), }); if let Some(clippy) = clippy { - let mut cargo = tool::prepare_tool_cargo(builder, - compiler, - Mode::ToolRustc, - host, - "test", - "src/tools/clippy", - SourceType::Submodule, - &[]); + let mut cargo = tool::prepare_tool_cargo( + builder, + compiler, + Mode::ToolRustc, + host, + "test", + "src/tools/clippy", + SourceType::Submodule, + &[], + ); // clippy tests need to know about the stage sysroot cargo.env("SYSROOT", builder.sysroot(compiler)); cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler)); cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler)); - let host_libs = builder - .stage_out(compiler, Mode::ToolRustc) - .join(builder.cargo_dir()); + let host_libs = builder.stage_out(compiler, Mode::ToolRustc).join(builder.cargo_dir()); let target_libs = builder .stage_out(compiler, Mode::ToolRustc) .join(&self.host) @@ -623,19 +591,10 @@ impl Step for RustdocTheme { let rustdoc = builder.out.join("bootstrap/debug/rustdoc"); let mut cmd = builder.tool_cmd(Tool::RustdocTheme); cmd.arg(rustdoc.to_str().unwrap()) - .arg( - builder - .src - .join("src/librustdoc/html/static/themes") - .to_str() - .unwrap(), - ) + .arg(builder.src.join("src/librustdoc/html/static/themes").to_str().unwrap()) .env("RUSTC_STAGE", self.compiler.stage.to_string()) .env("RUSTC_SYSROOT", builder.sysroot(self.compiler)) - .env( - "RUSTDOC_LIBDIR", - builder.sysroot_libdir(self.compiler, self.compiler.host), - ) + .env("RUSTDOC_LIBDIR", builder.sysroot_libdir(self.compiler, self.compiler.host)) .env("CFG_RELEASE_CHANNEL", &builder.config.channel) .env("RUSTDOC_REAL", builder.rustdoc(self.compiler)) .env("RUSTDOC_CRATE_VERSION", builder.rust_version()) @@ -663,25 +622,17 @@ impl Step for RustdocJSStd { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(RustdocJSStd { - host: run.host, - target: run.target, - }); + run.builder.ensure(RustdocJSStd { host: run.host, target: run.target }); } fn run(self, builder: &Builder<'_>) { if let Some(ref nodejs) = builder.config.nodejs { let mut command = Command::new(nodejs); command.args(&["src/tools/rustdoc-js-std/tester.js", &*self.host]); - builder.ensure(crate::doc::Std { - target: self.target, - stage: builder.top_stage, - }); + builder.ensure(crate::doc::Std { target: self.target, stage: builder.top_stage }); builder.run(&mut command); } else { - builder.info( - "No nodejs found, skipping \"src/test/rustdoc-js-std\" tests" - ); + builder.info("No nodejs found, skipping \"src/test/rustdoc-js-std\" tests"); } } } @@ -704,11 +655,7 @@ impl Step for RustdocJSNotStd { fn make_run(run: RunConfig<'_>) { let compiler = run.builder.compiler(run.builder.top_stage, run.host); - run.builder.ensure(RustdocJSNotStd { - host: run.host, - target: run.target, - compiler, - }); + run.builder.ensure(RustdocJSNotStd { host: run.host, target: run.target, compiler }); } fn run(self, builder: &Builder<'_>) { @@ -722,9 +669,7 @@ impl Step for RustdocJSNotStd { compare_mode: None, }); } else { - builder.info( - "No nodejs found, skipping \"src/test/rustdoc-js\" tests" - ); + builder.info("No nodejs found, skipping \"src/test/rustdoc-js\" tests"); } } } @@ -747,11 +692,7 @@ impl Step for RustdocUi { fn make_run(run: RunConfig<'_>) { let compiler = run.builder.compiler(run.builder.top_stage, run.host); - run.builder.ensure(RustdocUi { - host: run.host, - target: run.target, - compiler, - }); + run.builder.ensure(RustdocUi { host: run.host, target: run.target, compiler }); } fn run(self, builder: &Builder<'_>) { @@ -818,37 +759,55 @@ fn testdir(builder: &Builder<'_>, host: Interned) -> PathBuf { macro_rules! default_test { ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }) => { test!($name { path: $path, mode: $mode, suite: $suite, default: true, host: false }); - } + }; } macro_rules! default_test_with_compare_mode { ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, compare_mode: $compare_mode:expr }) => { - test_with_compare_mode!($name { path: $path, mode: $mode, suite: $suite, default: true, - host: false, compare_mode: $compare_mode }); - } + test_with_compare_mode!($name { + path: $path, + mode: $mode, + suite: $suite, + default: true, + host: false, + compare_mode: $compare_mode + }); + }; } macro_rules! host_test { ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }) => { test!($name { path: $path, mode: $mode, suite: $suite, default: true, host: true }); - } + }; } macro_rules! test { ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, default: $default:expr, host: $host:expr }) => { - test_definitions!($name { path: $path, mode: $mode, suite: $suite, default: $default, - host: $host, compare_mode: None }); - } + test_definitions!($name { + path: $path, + mode: $mode, + suite: $suite, + default: $default, + host: $host, + compare_mode: None + }); + }; } macro_rules! test_with_compare_mode { ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, default: $default:expr, host: $host:expr, compare_mode: $compare_mode:expr }) => { - test_definitions!($name { path: $path, mode: $mode, suite: $suite, default: $default, - host: $host, compare_mode: Some($compare_mode) }); - } + test_definitions!($name { + path: $path, + mode: $mode, + suite: $suite, + default: $default, + host: $host, + compare_mode: Some($compare_mode) + }); + }; } macro_rules! test_definitions { @@ -878,10 +837,7 @@ macro_rules! test_definitions { fn make_run(run: RunConfig<'_>) { let compiler = run.builder.compiler(run.builder.top_stage, run.host); - run.builder.ensure($name { - compiler, - target: run.target, - }); + run.builder.ensure($name { compiler, target: run.target }); } fn run(self, builder: &Builder<'_>) { @@ -895,7 +851,7 @@ macro_rules! test_definitions { }) } } - } + }; } default_test_with_compare_mode!(Ui { @@ -911,11 +867,7 @@ default_test!(CompileFail { suite: "compile-fail" }); -default_test!(RunFail { - path: "src/test/run-fail", - mode: "run-fail", - suite: "run-fail" -}); +default_test!(RunFail { path: "src/test/run-fail", mode: "run-fail", suite: "run-fail" }); default_test!(RunPassValgrind { path: "src/test/run-pass-valgrind", @@ -923,17 +875,9 @@ default_test!(RunPassValgrind { suite: "run-pass-valgrind" }); -default_test!(MirOpt { - path: "src/test/mir-opt", - mode: "mir-opt", - suite: "mir-opt" -}); +default_test!(MirOpt { path: "src/test/mir-opt", mode: "mir-opt", suite: "mir-opt" }); -default_test!(Codegen { - path: "src/test/codegen", - mode: "codegen", - suite: "codegen" -}); +default_test!(Codegen { path: "src/test/codegen", mode: "codegen", suite: "codegen" }); default_test!(CodegenUnits { path: "src/test/codegen-units", @@ -947,29 +891,13 @@ default_test!(Incremental { suite: "incremental" }); -default_test!(Debuginfo { - path: "src/test/debuginfo", - mode: "debuginfo", - suite: "debuginfo" -}); +default_test!(Debuginfo { path: "src/test/debuginfo", mode: "debuginfo", suite: "debuginfo" }); -host_test!(UiFullDeps { - path: "src/test/ui-fulldeps", - mode: "ui", - suite: "ui-fulldeps" -}); +host_test!(UiFullDeps { path: "src/test/ui-fulldeps", mode: "ui", suite: "ui-fulldeps" }); -host_test!(Rustdoc { - path: "src/test/rustdoc", - mode: "rustdoc", - suite: "rustdoc" -}); +host_test!(Rustdoc { path: "src/test/rustdoc", mode: "rustdoc", suite: "rustdoc" }); -host_test!(Pretty { - path: "src/test/pretty", - mode: "pretty", - suite: "pretty" -}); +host_test!(Pretty { path: "src/test/pretty", mode: "pretty", suite: "pretty" }); test!(RunFailPretty { path: "src/test/run-fail/pretty", mode: "pretty", @@ -985,11 +913,7 @@ test!(RunPassValgrindPretty { host: true }); -default_test!(RunMake { - path: "src/test/run-make", - mode: "run-make", - suite: "run-make" -}); +default_test!(RunMake { path: "src/test/run-make", mode: "run-make", suite: "run-make" }); host_test!(RunMakeFullDeps { path: "src/test/run-make-fulldeps", @@ -997,11 +921,7 @@ host_test!(RunMakeFullDeps { suite: "run-make-fulldeps" }); -default_test!(Assembly { - path: "src/test/assembly", - mode: "assembly", - suite: "assembly" -}); +default_test!(Assembly { path: "src/test/assembly", mode: "assembly", suite: "assembly" }); #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] struct Compiletest { @@ -1048,10 +968,8 @@ impl Step for Compiletest { }); } - builder.ensure(dist::DebuggerScripts { - sysroot: builder.sysroot(compiler), - host: target, - }); + builder + .ensure(dist::DebuggerScripts { sysroot: builder.sysroot(compiler), host: target }); } if suite.ends_with("fulldeps") { @@ -1077,10 +995,8 @@ impl Step for Compiletest { // compiletest currently has... a lot of arguments, so let's just pass all // of them! - cmd.arg("--compile-lib-path") - .arg(builder.rustc_libdir(compiler)); - cmd.arg("--run-lib-path") - .arg(builder.sysroot_libdir(compiler, target)); + cmd.arg("--compile-lib-path").arg(builder.rustc_libdir(compiler)); + cmd.arg("--run-lib-path").arg(builder.sysroot_libdir(compiler, target)); cmd.arg("--rustc-path").arg(builder.rustc(compiler)); let is_rustdoc = suite.ends_with("rustdoc-ui") || suite.ends_with("rustdoc-js"); @@ -1091,33 +1007,25 @@ impl Step for Compiletest { || (mode == "ui" && is_rustdoc) || mode == "js-doc-test" { - cmd.arg("--rustdoc-path") - .arg(builder.rustdoc(compiler)); + cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler)); } - cmd.arg("--src-base") - .arg(builder.src.join("src/test").join(suite)); - cmd.arg("--build-base") - .arg(testdir(builder, compiler.host).join(suite)); - cmd.arg("--stage-id") - .arg(format!("stage{}-{}", compiler.stage, target)); + cmd.arg("--src-base").arg(builder.src.join("src/test").join(suite)); + cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite)); + cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target)); cmd.arg("--mode").arg(mode); cmd.arg("--target").arg(target); cmd.arg("--host").arg(&*compiler.host); - cmd.arg("--llvm-filecheck") - .arg(builder.llvm_filecheck(builder.config.build)); + cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.build)); if builder.config.cmd.bless() { cmd.arg("--bless"); } - let compare_mode = builder.config.cmd.compare_mode().or_else(|| { - if builder.config.test_compare_mode { - self.compare_mode - } else { - None - } - }); + let compare_mode = + builder.config.cmd.compare_mode().or_else(|| { + if builder.config.test_compare_mode { self.compare_mode } else { None } + }); if let Some(ref pass) = builder.config.cmd.pass() { cmd.arg("--pass"); @@ -1128,11 +1036,7 @@ impl Step for Compiletest { cmd.arg("--nodejs").arg(nodejs); } - let mut flags = if is_rustdoc { - Vec::new() - } else { - vec!["-Crpath".to_string()] - }; + let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] }; if !is_rustdoc { if builder.config.rust_optimize_tests { flags.push("-O".to_string()); @@ -1147,17 +1051,11 @@ impl Step for Compiletest { } let mut hostflags = flags.clone(); - hostflags.push(format!( - "-Lnative={}", - builder.test_helpers_out(compiler.host).display() - )); + hostflags.push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display())); cmd.arg("--host-rustcflags").arg(hostflags.join(" ")); let mut targetflags = flags; - targetflags.push(format!( - "-Lnative={}", - builder.test_helpers_out(target).display() - )); + targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display())); cmd.arg("--target-rustcflags").arg(targetflags.join(" ")); cmd.arg("--docck-python").arg(builder.python()); @@ -1178,9 +1076,10 @@ impl Step for Compiletest { let run = |cmd: &mut Command| { cmd.output().map(|output| { String::from_utf8_lossy(&output.stdout) - .lines().next().unwrap_or_else(|| { - panic!("{:?} failed {:?}", cmd, output) - }).to_string() + .lines() + .next() + .unwrap_or_else(|| panic!("{:?} failed {:?}", cmd, output)) + .to_string() }) }; let lldb_exe = if builder.config.lldb_enabled { @@ -1192,7 +1091,7 @@ impl Step for Compiletest { let lldb_version = Command::new(&lldb_exe) .arg("--version") .output() - .map(|output| { String::from_utf8_lossy(&output.stdout).to_string() }) + .map(|output| String::from_utf8_lossy(&output.stdout).to_string()) .ok(); if let Some(ref vers) = lldb_version { cmd.arg("--lldb-version").arg(vers); @@ -1216,11 +1115,9 @@ impl Step for Compiletest { // Get test-args by striping suite path let mut test_args: Vec<&str> = paths .iter() - .map(|p| { - match p.strip_prefix(".") { - Ok(path) => path, - Err(_) => p, - } + .map(|p| match p.strip_prefix(".") { + Ok(path) => path, + Err(_) => p, }) .filter(|p| p.starts_with(suite_path) && (p.is_dir() || p.is_file())) .filter_map(|p| { @@ -1250,9 +1147,7 @@ impl Step for Compiletest { } if builder.config.llvm_enabled() { - let llvm_config = builder.ensure(native::Llvm { - target: builder.config.build, - }); + let llvm_config = builder.ensure(native::Llvm { target: builder.config.build }); if !builder.config.dry_run { let llvm_version = output(Command::new(&llvm_config).arg("--version")); cmd.arg("--llvm-version").arg(llvm_version); @@ -1282,23 +1177,24 @@ impl Step for Compiletest { // The llvm/bin directory contains many useful cross-platform // tools. Pass the path to run-make tests so they can use them. - let llvm_bin_path = llvm_config.parent() + let llvm_bin_path = llvm_config + .parent() .expect("Expected llvm-config to be contained in directory"); assert!(llvm_bin_path.is_dir()); cmd.arg("--llvm-bin-dir").arg(llvm_bin_path); // If LLD is available, add it to the PATH if builder.config.lld_enabled { - let lld_install_root = builder.ensure(native::Lld { - target: builder.config.build, - }); + let lld_install_root = + builder.ensure(native::Lld { target: builder.config.build }); let lld_bin_path = lld_install_root.join("bin"); let old_path = env::var_os("PATH").unwrap_or_default(); - let new_path = env::join_paths(std::iter::once(lld_bin_path) - .chain(env::split_paths(&old_path))) - .expect("Could not add LLD bin path to PATH"); + let new_path = env::join_paths( + std::iter::once(lld_bin_path).chain(env::split_paths(&old_path)), + ) + .expect("Could not add LLD bin path to PATH"); cmd.env("PATH", new_path); } } @@ -1318,8 +1214,7 @@ impl Step for Compiletest { } if builder.remote_tested(target) { - cmd.arg("--remote-test-client") - .arg(builder.tool_exe(Tool::RemoteTestClient)); + cmd.arg("--remote-test-client").arg(builder.tool_exe(Tool::RemoteTestClient)); } // Running a C compiler on MSVC requires a few env vars to be set, to be @@ -1349,7 +1244,6 @@ impl Step for Compiletest { std::fs::create_dir_all(&tmp).unwrap(); cmd.env("RUST_TEST_TMPDIR", tmp); - cmd.arg("--adb-path").arg("adb"); cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR); if target.contains("android") { @@ -1409,10 +1303,7 @@ impl Step for DocTest { fn run(self, builder: &Builder<'_>) { let compiler = self.compiler; - builder.ensure(compile::Std { - compiler, - target: compiler.host, - }); + builder.ensure(compile::Std { compiler, target: compiler.host }); // Do a breadth-first traversal of the `src/doc` directory and just run // tests for all files that end in `*.md` @@ -1516,9 +1407,8 @@ impl Step for ErrorIndex { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(ErrorIndex { - compiler: run.builder.compiler(run.builder.top_stage, run.host), - }); + run.builder + .ensure(ErrorIndex { compiler: run.builder.compiler(run.builder.top_stage, run.host) }); } /// Runs the error index generator tool to execute the tests located in the error @@ -1530,10 +1420,7 @@ impl Step for ErrorIndex { fn run(self, builder: &Builder<'_>) { let compiler = self.compiler; - builder.ensure(compile::Std { - compiler, - target: compiler.host, - }); + builder.ensure(compile::Std { compiler, target: compiler.host }); let dir = testdir(builder, compiler.host); t!(fs::create_dir_all(&dir)); @@ -1543,9 +1430,7 @@ impl Step for ErrorIndex { builder, builder.compiler(compiler.stage, builder.config.build), ); - tool.arg("markdown") - .arg(&output) - .env("CFG_BUILD", &builder.config.build); + tool.arg("markdown").arg(&output).env("CFG_BUILD", &builder.config.build); builder.info(&format!("Testing error-index stage{}", compiler.stage)); let _time = util::timeit(&builder); @@ -1825,23 +1710,12 @@ impl Step for Crate { if target.contains("emscripten") { cargo.env( format!("CARGO_TARGET_{}_RUNNER", envify(&target)), - builder - .config - .nodejs - .as_ref() - .expect("nodejs not configured"), + builder.config.nodejs.as_ref().expect("nodejs not configured"), ); } else if target.starts_with("wasm32") { - let node = builder - .config - .nodejs - .as_ref() - .expect("nodejs not configured"); - let runner = format!( - "{} {}/src/etc/wasm32-shim.js", - node.display(), - builder.src.display() - ); + let node = builder.config.nodejs.as_ref().expect("nodejs not configured"); + let runner = + format!("{} {}/src/etc/wasm32-shim.js", node.display(), builder.src.display()); cargo.env(format!("CARGO_TARGET_{}_RUNNER", envify(&target)), &runner); } else if builder.remote_tested(target) { cargo.env( @@ -1879,10 +1753,7 @@ impl Step for CrateRustdoc { let test_kind = builder.kind.into(); - builder.ensure(CrateRustdoc { - host: run.host, - test_kind, - }); + builder.ensure(CrateRustdoc { host: run.host, test_kind }); } fn run(self, builder: &Builder<'_>) { @@ -1892,14 +1763,16 @@ impl Step for CrateRustdoc { let target = compiler.host; builder.ensure(compile::Rustc { compiler, target }); - let mut cargo = tool::prepare_tool_cargo(builder, - compiler, - Mode::ToolRustc, - target, - test_kind.subcommand(), - "src/tools/rustdoc", - SourceType::InTree, - &[]); + let mut cargo = tool::prepare_tool_cargo( + builder, + compiler, + Mode::ToolRustc, + target, + test_kind.subcommand(), + "src/tools/rustdoc", + SourceType::InTree, + &[], + ); if test_kind.subcommand() == "test" && !builder.fail_fast { cargo.arg("--no-fail-fast"); } @@ -1961,18 +1834,13 @@ impl Step for RemoteCopyLibs { builder.info(&format!("REMOTE copy libs to emulator ({})", target)); t!(fs::create_dir_all(builder.out.join("tmp"))); - let server = builder.ensure(tool::RemoteTestServer { - compiler: compiler.with_stage(0), - target, - }); + let server = + builder.ensure(tool::RemoteTestServer { compiler: compiler.with_stage(0), target }); // Spawn the emulator and wait for it to come online let tool = builder.tool_exe(Tool::RemoteTestClient); let mut cmd = Command::new(&tool); - cmd.arg("spawn-emulator") - .arg(target) - .arg(&server) - .arg(builder.out.join("tmp")); + cmd.arg("spawn-emulator").arg(target).arg(&server).arg(builder.out.join("tmp")); if let Some(rootfs) = builder.qemu_rootfs(target) { cmd.arg(rootfs); } @@ -2027,9 +1895,7 @@ impl Step for Distcheck { .current_dir(&dir), ); builder.run( - Command::new(build_helper::make(&builder.config.build)) - .arg("check") - .current_dir(&dir), + Command::new(build_helper::make(&builder.config.build)).arg("check").current_dir(&dir), ); // Now make sure that rust-src has all of libstd's dependencies diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 815498047fd5d..9fd20386e367b 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -1,20 +1,20 @@ -use std::fs; +use std::collections::HashSet; use std::env; +use std::fs; use std::path::PathBuf; -use std::process::{Command, exit}; -use std::collections::HashSet; +use std::process::{exit, Command}; use build_helper::t; -use crate::Mode; -use crate::Compiler; -use crate::builder::{Step, RunConfig, ShouldRun, Builder, Cargo as CargoCommand}; -use crate::util::{exe, add_lib_path, CiEnv}; -use crate::compile; -use crate::channel::GitInfo; -use crate::channel; +use crate::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step}; use crate::cache::Interned; +use crate::channel; +use crate::channel::GitInfo; +use crate::compile; use crate::toolstate::ToolState; +use crate::util::{add_lib_path, exe, CiEnv}; +use crate::Compiler; +use crate::Mode; #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub enum SourceType { @@ -53,14 +53,10 @@ impl Step for ToolBuild { let is_optional_tool = self.is_optional_tool; match self.mode { - Mode::ToolRustc => { - builder.ensure(compile::Rustc { compiler, target }) - } - Mode::ToolStd => { - builder.ensure(compile::Std { compiler, target }) - } + Mode::ToolRustc => builder.ensure(compile::Rustc { compiler, target }), + Mode::ToolStd => builder.ensure(compile::Std { compiler, target }), Mode::ToolBootstrap => {} // uses downloaded stage0 compiler libs - _ => panic!("unexpected Mode for tool build") + _ => panic!("unexpected Mode for tool build"), } let cargo = prepare_tool_cargo( @@ -79,12 +75,7 @@ impl Step for ToolBuild { let is_expected = compile::stream_cargo(builder, cargo, vec![], &mut |msg| { // Only care about big things like the RLS/Cargo for now match tool { - | "rls" - | "cargo" - | "clippy-driver" - | "miri" - | "rustfmt" - => {} + "rls" | "cargo" | "clippy-driver" | "miri" | "rustfmt" => {} _ => return, } @@ -94,9 +85,7 @@ impl Step for ToolBuild { features, filenames, target: _, - } => { - (package_id, features, filenames) - } + } => (package_id, features, filenames), _ => return, }; let features = features.iter().map(|s| s.to_string()).collect::>(); @@ -105,7 +94,7 @@ impl Step for ToolBuild { let val = (tool, PathBuf::from(&*path), features.clone()); // we're only interested in deduplicating rlibs for now if val.1.extension().and_then(|s| s.to_str()) != Some("rlib") { - continue + continue; } // Don't worry about compiles that turn out to be host @@ -132,9 +121,7 @@ impl Step for ToolBuild { // already listed then we need to see if we reused the same // artifact or produced a duplicate. let mut artifacts = builder.tool_artifacts.borrow_mut(); - let prev_artifacts = artifacts - .entry(target) - .or_default(); + let prev_artifacts = artifacts.entry(target).or_default(); let prev = match prev_artifacts.get(&*id) { Some(prev) => prev, None => { @@ -160,21 +147,21 @@ impl Step for ToolBuild { // ... and otherwise this looks like we duplicated some sort of // compilation, so record it to generate an error later. - duplicates.push(( - id.to_string(), - val, - prev.clone(), - )); + duplicates.push((id.to_string(), val, prev.clone())); } }); if is_expected && !duplicates.is_empty() { - println!("duplicate artifacts found when compiling a tool, this \ + println!( + "duplicate artifacts found when compiling a tool, this \ typically means that something was recompiled because \ a transitive dependency has different features activated \ - than in a previous build:\n"); - println!("the following dependencies are duplicated although they \ - have the same features enabled:"); + than in a previous build:\n" + ); + println!( + "the following dependencies are duplicated although they \ + have the same features enabled:" + ); for (id, cur, prev) in duplicates.drain_filter(|(_, cur, prev)| cur.2 == prev.2) { println!(" {}", id); // same features @@ -185,24 +172,33 @@ impl Step for ToolBuild { println!(" {}", id); let cur_features: HashSet<_> = cur.2.into_iter().collect(); let prev_features: HashSet<_> = prev.2.into_iter().collect(); - println!(" `{}` additionally enabled features {:?} at {:?}", - cur.0, &cur_features - &prev_features, cur.1); - println!(" `{}` additionally enabled features {:?} at {:?}", - prev.0, &prev_features - &cur_features, prev.1); + println!( + " `{}` additionally enabled features {:?} at {:?}", + cur.0, + &cur_features - &prev_features, + cur.1 + ); + println!( + " `{}` additionally enabled features {:?} at {:?}", + prev.0, + &prev_features - &cur_features, + prev.1 + ); } println!(); - println!("to fix this you will probably want to edit the local \ + println!( + "to fix this you will probably want to edit the local \ src/tools/rustc-workspace-hack/Cargo.toml crate, as \ that will update the dependency graph to ensure that \ - these crates all share the same feature set"); + these crates all share the same feature set" + ); panic!("tools should not compile multiple copies of the same crate"); } - builder.save_toolstate(tool, if is_expected { - ToolState::TestFail - } else { - ToolState::BuildFail - }); + builder.save_toolstate( + tool, + if is_expected { ToolState::TestFail } else { ToolState::BuildFail }, + ); if !is_expected { if !is_optional_tool { @@ -211,8 +207,8 @@ impl Step for ToolBuild { None } } else { - let cargo_out = builder.cargo_out(compiler, self.mode, target) - .join(exe(tool, &compiler.host)); + let cargo_out = + builder.cargo_out(compiler, self.mode, target).join(exe(tool, &compiler.host)); let bin = builder.tools_dir(compiler).join(exe(tool, &compiler.host)); builder.copy(&cargo_out, &bin); Some(bin) @@ -240,12 +236,12 @@ pub fn prepare_tool_cargo( let mut features = extra_features.iter().cloned().collect::>(); if builder.build.config.cargo_native_static { - if path.ends_with("cargo") || - path.ends_with("rls") || - path.ends_with("clippy") || - path.ends_with("miri") || - path.ends_with("rustbook") || - path.ends_with("rustfmt") + if path.ends_with("cargo") + || path.ends_with("rls") + || path.ends_with("clippy") + || path.ends_with("miri") + || path.ends_with("rustbook") + || path.ends_with("rustfmt") { cargo.env("LIBZ_SYS_STATIC", "1"); features.push("rustc-workspace-hack/all-static".to_string()); @@ -395,9 +391,7 @@ pub struct ErrorIndex { impl ErrorIndex { pub fn command(builder: &Builder<'_>, compiler: Compiler) -> Command { - let mut cmd = Command::new(builder.ensure(ErrorIndex { - compiler - })); + let mut cmd = Command::new(builder.ensure(ErrorIndex { compiler })); add_lib_path( vec![PathBuf::from(&builder.sysroot_libdir(compiler, compiler.host))], &mut cmd, @@ -417,22 +411,23 @@ impl Step for ErrorIndex { // Compile the error-index in the same stage as rustdoc to avoid // recompiling rustdoc twice if we can. let stage = if run.builder.top_stage >= 2 { run.builder.top_stage } else { 0 }; - run.builder.ensure(ErrorIndex { - compiler: run.builder.compiler(stage, run.builder.config.build), - }); + run.builder + .ensure(ErrorIndex { compiler: run.builder.compiler(stage, run.builder.config.build) }); } fn run(self, builder: &Builder<'_>) -> PathBuf { - builder.ensure(ToolBuild { - compiler: self.compiler, - target: self.compiler.host, - tool: "error_index_generator", - mode: Mode::ToolRustc, - path: "src/tools/error_index_generator", - is_optional_tool: false, - source_type: SourceType::InTree, - extra_features: Vec::new(), - }).expect("expected to build -- essential tool") + builder + .ensure(ToolBuild { + compiler: self.compiler, + target: self.compiler.host, + tool: "error_index_generator", + mode: Mode::ToolRustc, + path: "src/tools/error_index_generator", + is_optional_tool: false, + source_type: SourceType::InTree, + extra_features: Vec::new(), + }) + .expect("expected to build -- essential tool") } } @@ -457,16 +452,18 @@ impl Step for RemoteTestServer { } fn run(self, builder: &Builder<'_>) -> PathBuf { - builder.ensure(ToolBuild { - compiler: self.compiler, - target: self.target, - tool: "remote-test-server", - mode: Mode::ToolStd, - path: "src/tools/remote-test-server", - is_optional_tool: false, - source_type: SourceType::InTree, - extra_features: Vec::new(), - }).expect("expected to build -- essential tool") + builder + .ensure(ToolBuild { + compiler: self.compiler, + target: self.target, + tool: "remote-test-server", + mode: Mode::ToolStd, + path: "src/tools/remote-test-server", + is_optional_tool: false, + source_type: SourceType::InTree, + extra_features: Vec::new(), + }) + .expect("expected to build -- essential tool") } } @@ -487,9 +484,8 @@ impl Step for Rustdoc { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rustdoc { - compiler: run.builder.compiler(run.builder.top_stage, run.host), - }); + run.builder + .ensure(Rustdoc { compiler: run.builder.compiler(run.builder.top_stage, run.host) }); } fn run(self, builder: &Builder<'_>) -> PathBuf { @@ -525,14 +521,17 @@ impl Step for Rustdoc { &[], ); - builder.info(&format!("Building rustdoc for stage{} ({})", - target_compiler.stage, target_compiler.host)); + builder.info(&format!( + "Building rustdoc for stage{} ({})", + target_compiler.stage, target_compiler.host + )); builder.run(&mut cargo.into()); // Cargo adds a number of paths to the dylib search path on windows, which results in // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" // rustdoc a different name. - let tool_rustdoc = builder.cargo_out(build_compiler, Mode::ToolRustc, target) + let tool_rustdoc = builder + .cargo_out(build_compiler, Mode::ToolRustc, target) .join(exe("rustdoc_tool_binary", &target_compiler.host)); // don't create a stage0-sysroot/bin directory. @@ -574,16 +573,18 @@ impl Step for Cargo { } fn run(self, builder: &Builder<'_>) -> PathBuf { - builder.ensure(ToolBuild { - compiler: self.compiler, - target: self.target, - tool: "cargo", - mode: Mode::ToolRustc, - path: "src/tools/cargo", - is_optional_tool: false, - source_type: SourceType::Submodule, - extra_features: Vec::new(), - }).expect("expected to build -- essential tool") + builder + .ensure(ToolBuild { + compiler: self.compiler, + target: self.target, + tool: "cargo", + mode: Mode::ToolRustc, + path: "src/tools/cargo", + is_optional_tool: false, + source_type: SourceType::Submodule, + extra_features: Vec::new(), + }) + .expect("expected to build -- essential tool") } } @@ -682,7 +683,7 @@ impl<'a> Builder<'a> { let curpaths = env::split_paths(&curpaths).collect::>(); for &(ref k, ref v) in self.cc[&compiler.host].env() { if k != "PATH" { - continue + continue; } for path in env::split_paths(v) { if !curpaths.contains(&path) { diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index a90f69d597de8..b068c8200acec 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -1,14 +1,14 @@ -use serde::{Deserialize, Serialize}; +use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use build_helper::t; -use std::time; -use std::fs; -use std::io::{Seek, SeekFrom}; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use crate::builder::{Builder, RunConfig, ShouldRun, Step}; +use std::env; use std::fmt; -use std::process::Command; +use std::fs; +use std::io::{Seek, SeekFrom}; use std::path::PathBuf; -use std::env; +use std::process::Command; +use std::time; // Each cycle is 42 days long (6 weeks); the last week is 35..=42 then. const BETA_WEEK_START: u64 = 35; @@ -38,11 +38,15 @@ pub enum ToolState { impl fmt::Display for ToolState { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", match self { - ToolState::TestFail => "test-fail", - ToolState::TestPass => "test-pass", - ToolState::BuildFail => "build-fail", - }) + write!( + f, + "{}", + match self { + ToolState::TestFail => "test-fail", + ToolState::TestPass => "test-pass", + ToolState::BuildFail => "build-fail", + } + ) } } @@ -120,9 +124,7 @@ fn check_changed_files(toolstates: &HashMap, ToolState>) { let output = t!(String::from_utf8(output.stdout)); for (tool, submodule) in STABLE_TOOLS.iter().chain(NIGHTLY_TOOLS.iter()) { - let changed = output.lines().any(|l| { - l.starts_with("M") && l.ends_with(submodule) - }); + let changed = output.lines().any(|l| l.starts_with("M") && l.ends_with(submodule)); eprintln!("Verifying status of {}...", tool); if !changed { continue; @@ -179,8 +181,10 @@ impl Step for ToolStateCheck { eprintln!("error: Tool `{}` should be test-pass but is {}", tool, state); } else if in_beta_week { did_error = true; - eprintln!("error: Tool `{}` should be test-pass but is {} during beta week.", - tool, state); + eprintln!( + "error: Tool `{}` should be test-pass but is {} during beta week.", + tool, state + ); } } } @@ -210,11 +214,8 @@ impl Builder<'_> { // Ensure the parent directory always exists t!(std::fs::create_dir_all(parent)); } - let mut file = t!(fs::OpenOptions::new() - .create(true) - .write(true) - .read(true) - .open(path)); + let mut file = + t!(fs::OpenOptions::new().create(true).write(true).read(true).open(path)); serde_json::from_reader(&mut file).unwrap_or_default() } else { @@ -233,11 +234,8 @@ impl Builder<'_> { // Ensure the parent directory always exists t!(std::fs::create_dir_all(parent)); } - let mut file = t!(fs::OpenOptions::new() - .create(true) - .read(true) - .write(true) - .open(path)); + let mut file = + t!(fs::OpenOptions::new().create(true).read(true).write(true).open(path)); let mut current_toolstates: HashMap, ToolState> = serde_json::from_reader(&mut file).unwrap_or_default(); @@ -275,10 +273,7 @@ impl Builder<'_> { /// /// * See /// if a private email by GitHub is wanted. -fn commit_toolstate_change( - current_toolstate: &ToolstateData, - in_beta_week: bool, -) { +fn commit_toolstate_change(current_toolstate: &ToolstateData, in_beta_week: bool) { fn git_config(key: &str, value: &str) { let status = Command::new("git").arg("config").arg("--global").arg(key).arg(value).status(); let success = match status { @@ -303,7 +298,8 @@ fn commit_toolstate_change( let git_credential_path = PathBuf::from(t!(env::var("HOME"))).join(".git-credentials"); t!(fs::write(&git_credential_path, credential)); - let status = Command::new("git").arg("clone") + let status = Command::new("git") + .arg("clone") .arg("--depth=1") .arg(t!(env::var("TOOLSTATE_REPO"))) .status(); @@ -402,10 +398,7 @@ fn change_toolstate( std::process::exit(1); } - let commit = t!(std::process::Command::new("git") - .arg("rev-parse") - .arg("HEAD") - .output()); + let commit = t!(std::process::Command::new("git").arg("rev-parse").arg("HEAD").output()); let commit = t!(String::from_utf8(commit.stdout)); let toolstate_serialized = t!(serde_json::to_string(¤t_toolstate)); diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 085742b011c84..5fd25981851d4 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -4,36 +4,28 @@ //! not a lot of interesting happenings here unfortunately. use std::env; -use std::str; use std::fs; use std::io; use std::path::{Path, PathBuf}; use std::process::Command; +use std::str; use std::time::Instant; use build_helper::t; -use crate::config::Config; use crate::builder::Builder; use crate::cache::Interned; +use crate::config::Config; /// Returns the `name` as the filename of a static library for `target`. pub fn staticlib(name: &str, target: &str) -> String { - if target.contains("windows") { - format!("{}.lib", name) - } else { - format!("lib{}.a", name) - } + if target.contains("windows") { format!("{}.lib", name) } else { format!("lib{}.a", name) } } /// Given an executable called `name`, return the filename for the /// executable for a particular target. pub fn exe(name: &str, target: &str) -> String { - if target.contains("windows") { - format!("{}.exe", name) - } else { - name.to_string() - } + if target.contains("windows") { format!("{}.exe", name) } else { name.to_string() } } /// Returns `true` if the file name given looks like a dynamic library. @@ -44,7 +36,7 @@ pub fn is_dylib(name: &str) -> bool { /// Returns the corresponding relative library directory that the compiler's /// dylibs will be found in. pub fn libdir(target: &str) -> &'static str { - if target.contains("windows") {"bin"} else {"lib"} + if target.contains("windows") { "bin" } else { "lib" } } /// Adds a list of lookup paths to `cmd`'s dynamic library lookup path. @@ -106,9 +98,7 @@ impl Drop for TimeIt { fn drop(&mut self) { let time = self.1.elapsed(); if !self.0 { - println!("\tfinished in {}.{:03}", - time.as_secs(), - time.subsec_nanos() / 1_000_000); + println!("\tfinished in {}.{:03}", time.as_secs(), time.subsec_nanos() / 1_000_000); } } } @@ -116,7 +106,9 @@ impl Drop for TimeIt { /// Symlinks two directories, using junctions on Windows and normal symlinks on /// Unix. pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { - if config.dry_run { return Ok(()); } + if config.dry_run { + return Ok(()); + } let _ = fs::remove_dir(dest); return symlink_dir_inner(src, dest); @@ -136,9 +128,9 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { #[cfg(windows)] #[allow(nonstandard_style)] fn symlink_dir_inner(target: &Path, junction: &Path) -> io::Result<()> { - use std::ptr; use std::ffi::OsStr; use std::os::windows::ffi::OsStrExt; + use std::ptr; const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024; const GENERIC_WRITE: DWORD = 0x40000000; @@ -174,22 +166,25 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { } extern "system" { - fn CreateFileW(lpFileName: LPCWSTR, - dwDesiredAccess: DWORD, - dwShareMode: DWORD, - lpSecurityAttributes: LPSECURITY_ATTRIBUTES, - dwCreationDisposition: DWORD, - dwFlagsAndAttributes: DWORD, - hTemplateFile: HANDLE) - -> HANDLE; - fn DeviceIoControl(hDevice: HANDLE, - dwIoControlCode: DWORD, - lpInBuffer: LPVOID, - nInBufferSize: DWORD, - lpOutBuffer: LPVOID, - nOutBufferSize: DWORD, - lpBytesReturned: LPDWORD, - lpOverlapped: LPOVERLAPPED) -> BOOL; + fn CreateFileW( + lpFileName: LPCWSTR, + dwDesiredAccess: DWORD, + dwShareMode: DWORD, + lpSecurityAttributes: LPSECURITY_ATTRIBUTES, + dwCreationDisposition: DWORD, + dwFlagsAndAttributes: DWORD, + hTemplateFile: HANDLE, + ) -> HANDLE; + fn DeviceIoControl( + hDevice: HANDLE, + dwIoControlCode: DWORD, + lpInBuffer: LPVOID, + nInBufferSize: DWORD, + lpOutBuffer: LPVOID, + nOutBufferSize: DWORD, + lpBytesReturned: LPDWORD, + lpOverlapped: LPOVERLAPPED, + ) -> BOOL; fn CloseHandle(hObject: HANDLE) -> BOOL; } @@ -207,17 +202,18 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { let path = to_u16s(junction)?; unsafe { - let h = CreateFileW(path.as_ptr(), - GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - ptr::null_mut(), - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, - ptr::null_mut()); + let h = CreateFileW( + path.as_ptr(), + GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + ptr::null_mut(), + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, + ptr::null_mut(), + ); let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - let db = data.as_mut_ptr() - as *mut REPARSE_MOUNTPOINT_DATA_BUFFER; + let db = data.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER; let buf = &mut (*db).ReparseTarget as *mut u16; let mut i = 0; // FIXME: this conversion is very hacky @@ -232,23 +228,21 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { (*db).ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; (*db).ReparseTargetMaximumLength = (i * 2) as WORD; (*db).ReparseTargetLength = ((i - 1) * 2) as WORD; - (*db).ReparseDataLength = - (*db).ReparseTargetLength as DWORD + 12; + (*db).ReparseDataLength = (*db).ReparseTargetLength as DWORD + 12; let mut ret = 0; - let res = DeviceIoControl(h as *mut _, - FSCTL_SET_REPARSE_POINT, - data.as_ptr() as *mut _, - (*db).ReparseDataLength + 8, - ptr::null_mut(), 0, - &mut ret, - ptr::null_mut()); - - let out = if res == 0 { - Err(io::Error::last_os_error()) - } else { - Ok(()) - }; + let res = DeviceIoControl( + h as *mut _, + FSCTL_SET_REPARSE_POINT, + data.as_ptr() as *mut _, + (*db).ReparseDataLength + 8, + ptr::null_mut(), + 0, + &mut ret, + ptr::null_mut(), + ); + + let out = if res == 0 { Err(io::Error::last_os_error()) } else { Ok(()) }; CloseHandle(h); out } @@ -299,8 +293,11 @@ pub fn forcing_clang_based_tests() -> bool { "0" | "no" | "off" => false, other => { // Let's make sure typos don't go unnoticed - panic!("Unrecognized option '{}' set in \ - RUSTBUILD_FORCE_CLANG_BASED_TESTS", other) + panic!( + "Unrecognized option '{}' set in \ + RUSTBUILD_FORCE_CLANG_BASED_TESTS", + other + ) } } } else { @@ -311,11 +308,9 @@ pub fn forcing_clang_based_tests() -> bool { pub fn use_host_linker(target: &Interned) -> bool { // FIXME: this information should be gotten by checking the linker flavor // of the rustc target - !( - target.contains("emscripten") || - target.contains("wasm32") || - target.contains("nvptx") || - target.contains("fortanix") || - target.contains("fuchsia") - ) + !(target.contains("emscripten") + || target.contains("wasm32") + || target.contains("nvptx") + || target.contains("fortanix") + || target.contains("fuchsia")) } diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index bb94fb2b755f5..3f42533238a89 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -1,9 +1,9 @@ use std::fs::File; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; +use std::thread; use std::time::{SystemTime, UNIX_EPOCH}; use std::{env, fs}; -use std::thread; /// A helper macro to `unwrap` a result except also print out details like: /// @@ -64,10 +64,7 @@ pub fn run(cmd: &mut Command) { pub fn try_run(cmd: &mut Command) -> bool { let status = match cmd.status() { Ok(status) => status, - Err(e) => fail(&format!( - "failed to execute command: {:?}\nerror: {}", - cmd, e - )), + Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), }; if !status.success() { println!( @@ -88,10 +85,7 @@ pub fn run_suppressed(cmd: &mut Command) { pub fn try_run_suppressed(cmd: &mut Command) -> bool { let output = match cmd.output() { Ok(status) => status, - Err(e) => fail(&format!( - "failed to execute command: {:?}\nerror: {}", - cmd, e - )), + Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), }; if !output.status.success() { println!( @@ -119,8 +113,10 @@ pub fn gnu_target(target: &str) -> &str { } pub fn make(host: &str) -> PathBuf { - if host.contains("dragonfly") || host.contains("freebsd") - || host.contains("netbsd") || host.contains("openbsd") + if host.contains("dragonfly") + || host.contains("freebsd") + || host.contains("netbsd") + || host.contains("openbsd") { PathBuf::from("gmake") } else { @@ -131,10 +127,7 @@ pub fn make(host: &str) -> PathBuf { pub fn output(cmd: &mut Command) -> String { let output = match cmd.stderr(Stdio::inherit()).output() { Ok(status) => status, - Err(e) => fail(&format!( - "failed to execute command: {:?}\nerror: {}", - cmd, e - )), + Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), }; if !output.status.success() { panic!( @@ -147,7 +140,8 @@ pub fn output(cmd: &mut Command) -> String { } pub fn rerun_if_changed_anything_in_dir(dir: &Path) { - let mut stack = dir.read_dir() + let mut stack = dir + .read_dir() .unwrap() .map(|e| e.unwrap()) .filter(|e| &*e.file_name() != ".git") @@ -164,9 +158,7 @@ pub fn rerun_if_changed_anything_in_dir(dir: &Path) { /// Returns the last-modified time for `path`, or zero if it doesn't exist. pub fn mtime(path: &Path) -> SystemTime { - fs::metadata(path) - .and_then(|f| f.modified()) - .unwrap_or(UNIX_EPOCH) + fs::metadata(path).and_then(|f| f.modified()).unwrap_or(UNIX_EPOCH) } /// Returns `true` if `dst` is up to date given that the file or files in `src` @@ -205,7 +197,7 @@ impl NativeLibBoilerplate { /// ensure it's linked against correctly. pub fn fixup_sanitizer_lib_name(&self, sanitizer_name: &str) { if env::var("TARGET").unwrap() != "x86_64-apple-darwin" { - return + return; } let dir = self.out_dir.join("build/lib/darwin"); @@ -248,8 +240,8 @@ pub fn native_lib_boilerplate( ) -> Result { rerun_if_changed_anything_in_dir(src_dir); - let out_dir = env::var_os("RUSTBUILD_NATIVE_DIR").unwrap_or_else(|| - env::var_os("OUT_DIR").unwrap()); + let out_dir = + env::var_os("RUSTBUILD_NATIVE_DIR").unwrap_or_else(|| env::var_os("OUT_DIR").unwrap()); let out_dir = PathBuf::from(out_dir).join(out_name); t!(fs::create_dir_all(&out_dir)); if link_name.contains('=') { @@ -257,36 +249,26 @@ pub fn native_lib_boilerplate( } else { println!("cargo:rustc-link-lib=static={}", link_name); } - println!( - "cargo:rustc-link-search=native={}", - out_dir.join(search_subdir).display() - ); + println!("cargo:rustc-link-search=native={}", out_dir.join(search_subdir).display()); let timestamp = out_dir.join("rustbuild.timestamp"); if !up_to_date(Path::new("build.rs"), ×tamp) || !up_to_date(src_dir, ×tamp) { - Ok(NativeLibBoilerplate { - src_dir: src_dir.to_path_buf(), - out_dir, - }) + Ok(NativeLibBoilerplate { src_dir: src_dir.to_path_buf(), out_dir }) } else { Err(()) } } -pub fn sanitizer_lib_boilerplate(sanitizer_name: &str) - -> Result<(NativeLibBoilerplate, String), ()> -{ +pub fn sanitizer_lib_boilerplate( + sanitizer_name: &str, +) -> Result<(NativeLibBoilerplate, String), ()> { let (link_name, search_path, apple) = match &*env::var("TARGET").unwrap() { - "x86_64-unknown-linux-gnu" => ( - format!("clang_rt.{}-x86_64", sanitizer_name), - "build/lib/linux", - false, - ), - "x86_64-apple-darwin" => ( - format!("clang_rt.{}_osx_dynamic", sanitizer_name), - "build/lib/darwin", - true, - ), + "x86_64-unknown-linux-gnu" => { + (format!("clang_rt.{}-x86_64", sanitizer_name), "build/lib/linux", false) + } + "x86_64-apple-darwin" => { + (format!("clang_rt.{}_osx_dynamic", sanitizer_name), "build/lib/darwin", true) + } _ => return Err(()), }; let to_link = if apple { @@ -297,12 +279,7 @@ pub fn sanitizer_lib_boilerplate(sanitizer_name: &str) // This env var is provided by rustbuild to tell us where `compiler-rt` // lives. let dir = env::var_os("RUST_COMPILER_RT_ROOT").unwrap(); - let lib = native_lib_boilerplate( - dir.as_ref(), - sanitizer_name, - &to_link, - search_path, - )?; + let lib = native_lib_boilerplate(dir.as_ref(), sanitizer_name, &to_link, search_path)?; Ok((lib, link_name)) } diff --git a/src/etc/test-float-parse/long-fractions.rs b/src/etc/test-float-parse/long-fractions.rs index 55e4f07cd0cc3..60cf85c4a60cf 100644 --- a/src/etc/test-float-parse/long-fractions.rs +++ b/src/etc/test-float-parse/long-fractions.rs @@ -1,7 +1,7 @@ mod _common; -use std::char; use _common::validate; +use std::char; fn main() { for n in 0..10 { diff --git a/src/etc/test-float-parse/many-digits.rs b/src/etc/test-float-parse/many-digits.rs index 76da818c7091f..599986e20dd0b 100644 --- a/src/etc/test-float-parse/many-digits.rs +++ b/src/etc/test-float-parse/many-digits.rs @@ -2,10 +2,10 @@ extern crate rand; mod _common; -use std::char; -use rand::{IsaacRng, Rng, SeedableRng}; -use rand::distributions::{Range, Sample}; use _common::{validate, SEED}; +use rand::distributions::{Range, Sample}; +use rand::{IsaacRng, Rng, SeedableRng}; +use std::char; fn main() { let mut rnd = IsaacRng::from_seed(&SEED); diff --git a/src/etc/test-float-parse/subnorm.rs b/src/etc/test-float-parse/subnorm.rs index 448482c6eb817..ba68d31e4ed7e 100644 --- a/src/etc/test-float-parse/subnorm.rs +++ b/src/etc/test-float-parse/subnorm.rs @@ -1,7 +1,7 @@ mod _common; -use std::mem::transmute; use _common::validate; +use std::mem::transmute; fn main() { for bits in 0u32..(1 << 21) { diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index 9bc76f51570e1..0c0dc928b95df 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -24,10 +24,7 @@ extern "Rust" { #[rustc_allocator_nounwind] fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize); #[rustc_allocator_nounwind] - fn __rust_realloc(ptr: *mut u8, - old_size: usize, - align: usize, - new_size: usize) -> *mut u8; + fn __rust_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8; #[rustc_allocator_nounwind] fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8; } @@ -178,12 +175,12 @@ unsafe impl Alloc for Global { } #[inline] - unsafe fn realloc(&mut self, - ptr: NonNull, - layout: Layout, - new_size: usize) - -> Result, AllocErr> - { + unsafe fn realloc( + &mut self, + ptr: NonNull, + layout: Layout, + new_size: usize, + ) -> Result, AllocErr> { NonNull::new(realloc(ptr.as_ptr(), layout, new_size)).ok_or(AllocErr) } @@ -204,11 +201,7 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { } else { let layout = Layout::from_size_align_unchecked(size, align); let ptr = alloc(layout); - if !ptr.is_null() { - ptr - } else { - handle_alloc_error(layout) - } + if !ptr.is_null() { ptr } else { handle_alloc_error(layout) } } } diff --git a/src/liballoc/benches/lib.rs b/src/liballoc/benches/lib.rs index 9acda886064ce..951477a24c8ed 100644 --- a/src/liballoc/benches/lib.rs +++ b/src/liballoc/benches/lib.rs @@ -6,8 +6,8 @@ extern crate test; mod btree; mod linked_list; -mod string; -mod str; mod slice; +mod str; +mod string; mod vec; mod vec_deque; diff --git a/src/liballoc/benches/vec.rs b/src/liballoc/benches/vec.rs index 590c49f4ef500..a3da9e80cd0fc 100644 --- a/src/liballoc/benches/vec.rs +++ b/src/liballoc/benches/vec.rs @@ -1,5 +1,5 @@ +use std::iter::{repeat, FromIterator}; use test::Bencher; -use std::iter::{FromIterator, repeat}; #[bench] fn bench_new(b: &mut Bencher) { diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index fc96045196846..51c233a21f1a4 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -16,8 +16,9 @@ use Cow::*; #[stable(feature = "rust1", since = "1.0.0")] impl<'a, B: ?Sized> Borrow for Cow<'a, B> - where B: ToOwned, - ::Owned: 'a +where + B: ToOwned, + ::Owned: 'a, { fn borrow(&self) -> &B { &**self @@ -69,9 +70,7 @@ pub trait ToOwned { /// let mut v: Vec = Vec::new(); /// [1, 2][..].clone_into(&mut v); /// ``` - #[unstable(feature = "toowned_clone_into", - reason = "recently added", - issue = "41263")] + #[unstable(feature = "toowned_clone_into", reason = "recently added", issue = "41263")] fn clone_into(&self, target: &mut Self::Owned) { *target = self.to_owned(); } @@ -79,7 +78,8 @@ pub trait ToOwned { #[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for T - where T: Clone +where + T: Clone, { type Owned = T; fn to_owned(&self) -> T { @@ -169,17 +169,16 @@ impl ToOwned for T /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub enum Cow<'a, B: ?Sized + 'a> - where B: ToOwned +where + B: ToOwned, { /// Borrowed data. #[stable(feature = "rust1", since = "1.0.0")] - Borrowed(#[stable(feature = "rust1", since = "1.0.0")] - &'a B), + Borrowed(#[stable(feature = "rust1", since = "1.0.0")] &'a B), /// Owned data. #[stable(feature = "rust1", since = "1.0.0")] - Owned(#[stable(feature = "rust1", since = "1.0.0")] - ::Owned), + Owned(#[stable(feature = "rust1", since = "1.0.0")] ::Owned), } #[stable(feature = "rust1", since = "1.0.0")] @@ -335,7 +334,8 @@ impl Eq for Cow<'_, B> where B: Eq + ToOwned {} #[stable(feature = "rust1", since = "1.0.0")] impl Ord for Cow<'_, B> - where B: Ord + ToOwned +where + B: Ord + ToOwned, { #[inline] fn cmp(&self, other: &Self) -> Ordering { @@ -345,8 +345,9 @@ impl Ord for Cow<'_, B> #[stable(feature = "rust1", since = "1.0.0")] impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq> for Cow<'a, B> - where B: PartialEq + ToOwned, - C: ToOwned +where + B: PartialEq + ToOwned, + C: ToOwned, { #[inline] fn eq(&self, other: &Cow<'b, C>) -> bool { @@ -356,7 +357,8 @@ impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq> for Cow<'a, B> #[stable(feature = "rust1", since = "1.0.0")] impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> - where B: PartialOrd + ToOwned +where + B: PartialOrd + ToOwned, { #[inline] fn partial_cmp(&self, other: &Cow<'a, B>) -> Option { @@ -403,7 +405,8 @@ where #[stable(feature = "rust1", since = "1.0.0")] impl Hash for Cow<'_, B> - where B: Hash + ToOwned +where + B: Hash + ToOwned, { #[inline] fn hash(&self, state: &mut H) { diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 3e4005acaf35c..cc01de08cafb7 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -134,21 +134,21 @@ use core::convert::{From, TryFrom}; use core::fmt; use core::future::Future; use core::hash::{Hash, Hasher}; -use core::iter::{Iterator, FromIterator, FusedIterator}; +use core::iter::{FromIterator, FusedIterator, Iterator}; use core::marker::{Unpin, Unsize}; use core::mem; -use core::pin::Pin; use core::ops::{ - CoerceUnsized, DispatchFromDyn, Deref, DerefMut, Receiver, Generator, GeneratorState + CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver, }; +use core::pin::Pin; use core::ptr::{self, NonNull, Unique}; use core::slice; use core::task::{Context, Poll}; -use crate::alloc::{self, Global, Alloc}; -use crate::vec::Vec; +use crate::alloc::{self, Alloc, Global}; use crate::raw_vec::RawVec; use crate::str::from_boxed_utf8_unchecked; +use crate::vec::Vec; /// A pointer type for heap allocation. /// @@ -196,12 +196,10 @@ impl Box { pub fn new_uninit() -> Box> { let layout = alloc::Layout::new::>(); if layout.size() == 0 { - return Box(NonNull::dangling().into()) + return Box(NonNull::dangling().into()); } - let ptr = unsafe { - Global.alloc(layout) - .unwrap_or_else(|_| alloc::handle_alloc_error(layout)) - }; + let ptr = + unsafe { Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)) }; Box(ptr.cast().into()) } @@ -269,9 +267,7 @@ impl Box<[T]> { NonNull::dangling() } else { unsafe { - Global.alloc(layout) - .unwrap_or_else(|_| alloc::handle_alloc_error(layout)) - .cast() + Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)).cast() } }; let slice = unsafe { slice::from_raw_parts_mut(ptr.as_ptr(), len) }; @@ -532,7 +528,7 @@ impl Box { #[inline] pub fn leak<'a>(b: Box) -> &'a mut T where - T: 'a // Technically not needed, but kept to be explicit. + T: 'a, // Technically not needed, but kept to be explicit. { unsafe { &mut *Box::into_raw(b) } } @@ -625,15 +621,12 @@ impl Clone for Box { } } - #[stable(feature = "box_slice_clone", since = "1.3.0")] impl Clone for Box { fn clone(&self) -> Self { // this makes a copy of the data let buf: Box<[u8]> = self.as_bytes().into(); - unsafe { - from_boxed_utf8_unchecked(buf) - } + unsafe { from_boxed_utf8_unchecked(buf) } } } @@ -1053,10 +1046,7 @@ impl FromIterator for Box<[A]> { #[stable(feature = "box_slice_clone", since = "1.3.0")] impl Clone for Box<[T]> { fn clone(&self) -> Self { - let mut new = BoxBuilder { - data: RawVec::with_capacity(self.len()), - len: 0, - }; + let mut new = BoxBuilder { data: RawVec::with_capacity(self.len()), len: 0 }; let mut target = new.data.ptr(); @@ -1152,7 +1142,7 @@ impl AsMut for Box { * could have a method to project a Pin from it. */ #[stable(feature = "pin", since = "1.33.0")] -impl Unpin for Box { } +impl Unpin for Box {} #[unstable(feature = "generator_trait", issue = "43122")] impl Generator for Box { diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index fda6f090fd779..0148711bb8625 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -145,11 +145,11 @@ #![allow(missing_docs)] #![stable(feature = "rust1", since = "1.0.0")] -use core::ops::{Deref, DerefMut}; +use core::fmt; use core::iter::{FromIterator, FusedIterator, TrustedLen}; -use core::mem::{swap, size_of, ManuallyDrop}; +use core::mem::{size_of, swap, ManuallyDrop}; +use core::ops::{Deref, DerefMut}; use core::ptr; -use core::fmt; use crate::slice; use crate::vec::{self, Vec}; @@ -267,9 +267,7 @@ pub struct PeekMut<'a, T: 'a + Ord> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for PeekMut<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("PeekMut") - .field(&self.heap.data[0]) - .finish() + f.debug_tuple("PeekMut").field(&self.heap.data[0]).finish() } } @@ -404,14 +402,7 @@ impl BinaryHeap { /// Cost is O(1) in the worst case. #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] pub fn peek_mut(&mut self) -> Option> { - if self.is_empty() { - None - } else { - Some(PeekMut { - heap: self, - sift: true, - }) - } + if self.is_empty() { None } else { Some(PeekMut { heap: self, sift: true }) } } /// Removes the greatest item from the binary heap and returns it, or `None` if it @@ -674,9 +665,7 @@ impl BinaryHeap { #[inline] #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] pub fn drain_sorted(&mut self) -> DrainSorted<'_, T> { - DrainSorted { - inner: self, - } + DrainSorted { inner: self } } } @@ -718,9 +707,7 @@ impl BinaryHeap { /// ``` #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")] pub fn into_iter_sorted(self) -> IntoIterSorted { - IntoIterSorted { - inner: self, - } + IntoIterSorted { inner: self } } /// Returns the greatest item in the binary heap, or `None` if it is empty. @@ -857,7 +844,7 @@ impl BinaryHeap { /// assert!(heap.capacity() >= 10); /// ``` #[inline] - #[unstable(feature = "shrink_to", reason = "new API", issue="56431")] + #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")] pub fn shrink_to(&mut self, min_capacity: usize) { self.data.shrink_to(min_capacity) } @@ -991,11 +978,7 @@ impl<'a, T> Hole<'a, T> { debug_assert!(pos < data.len()); // SAFE: pos should be inside the slice let elt = ptr::read(data.get_unchecked(pos)); - Hole { - data, - elt: ManuallyDrop::new(elt), - pos, - } + Hole { data, elt: ManuallyDrop::new(elt), pos } } #[inline] @@ -1059,9 +1042,7 @@ pub struct Iter<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Iter<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Iter") - .field(&self.iter.as_slice()) - .finish() + f.debug_tuple("Iter").field(&self.iter.as_slice()).finish() } } @@ -1127,9 +1108,7 @@ pub struct IntoIter { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("IntoIter") - .field(&self.iter.as_slice()) - .finish() + f.debug_tuple("IntoIter").field(&self.iter.as_slice()).finish() } } @@ -1281,7 +1260,7 @@ impl Iterator for DrainSorted<'_, T> { } #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] -impl ExactSizeIterator for DrainSorted<'_, T> { } +impl ExactSizeIterator for DrainSorted<'_, T> {} #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] impl FusedIterator for DrainSorted<'_, T> {} diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 5b48b594ff907..7d0a862d79e48 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -2,17 +2,17 @@ use core::borrow::Borrow; use core::cmp::Ordering; use core::fmt::Debug; use core::hash::{Hash, Hasher}; -use core::iter::{FromIterator, Peekable, FusedIterator}; +use core::iter::{FromIterator, FusedIterator, Peekable}; use core::marker::PhantomData; use core::ops::Bound::{Excluded, Included, Unbounded}; use core::ops::{Index, RangeBounds}; use core::{fmt, intrinsics, mem, ptr}; -use super::node::{self, Handle, NodeRef, marker, InsertResult::*, ForceResult::*}; +use super::node::{self, marker, ForceResult::*, Handle, InsertResult::*, NodeRef}; use super::search::{self, SearchResult::*}; -use UnderflowResult::*; use Entry::*; +use UnderflowResult::*; /// A map based on a B-Tree. /// @@ -138,16 +138,15 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for BTreeMap { impl Clone for BTreeMap { fn clone(&self) -> BTreeMap { fn clone_subtree<'a, K: Clone, V: Clone>( - node: node::NodeRef, K, V, marker::LeafOrInternal> + node: node::NodeRef, K, V, marker::LeafOrInternal>, ) -> BTreeMap - where K: 'a, V: 'a, + where + K: 'a, + V: 'a, { match node.force() { Leaf(leaf) => { - let mut out_tree = BTreeMap { - root: node::Root::new_leaf(), - length: 0, - }; + let mut out_tree = BTreeMap { root: node::Root::new_leaf(), length: 0 }; { let mut out_node = match out_tree.root.as_mut().force() { @@ -203,10 +202,7 @@ impl Clone for BTreeMap { if self.is_empty() { // Ideally we'd call `BTreeMap::new` here, but that has the `K: // Ord` constraint, which this method lacks. - BTreeMap { - root: node::Root::shared_empty_root(), - length: 0, - } + BTreeMap { root: node::Root::shared_empty_root(), length: 0 } } else { clone_subtree(self.root.as_ref()) } @@ -214,8 +210,9 @@ impl Clone for BTreeMap { } impl super::Recover for BTreeMap - where K: Borrow + Ord, - Q: Ord +where + K: Borrow + Ord, + Q: Ord, { type Key = K; @@ -228,15 +225,11 @@ impl super::Recover for BTreeMap fn take(&mut self, key: &Q) -> Option { match search::search_tree(self.root.as_mut(), key) { - Found(handle) => { - Some(OccupiedEntry { - handle, - length: &mut self.length, - _marker: PhantomData, - } - .remove_kv() - .0) - } + Found(handle) => Some( + OccupiedEntry { handle, length: &mut self.length, _marker: PhantomData } + .remove_kv() + .0, + ), GoDown(_) => None, } } @@ -246,13 +239,8 @@ impl super::Recover for BTreeMap match search::search_tree::, K, (), K>(self.root.as_mut(), &key) { Found(handle) => Some(mem::replace(handle.into_kv_mut().0, key)), GoDown(handle) => { - VacantEntry { - key, - handle, - length: &mut self.length, - _marker: PhantomData, - } - .insert(()); + VacantEntry { key, handle, length: &mut self.length, _marker: PhantomData } + .insert(()); None } } @@ -310,10 +298,7 @@ pub struct IntoIter { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let range = Range { - front: self.front.reborrow(), - back: self.back.reborrow(), - }; + let range = Range { front: self.front.reborrow(), back: self.back.reborrow() }; f.debug_list().entries(range).finish() } } @@ -408,10 +393,7 @@ pub struct RangeMut<'a, K: 'a, V: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for RangeMut<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let range = Range { - front: self.front.reborrow(), - back: self.back.reborrow(), - }; + let range = Range { front: self.front.reborrow(), back: self.back.reborrow() }; f.debug_list().entries(range).finish() } } @@ -426,25 +408,19 @@ impl fmt::Debug for RangeMut<'_, K, V> { pub enum Entry<'a, K: 'a, V: 'a> { /// A vacant entry. #[stable(feature = "rust1", since = "1.0.0")] - Vacant(#[stable(feature = "rust1", since = "1.0.0")] - VacantEntry<'a, K, V>), + Vacant(#[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V>), /// An occupied entry. #[stable(feature = "rust1", since = "1.0.0")] - Occupied(#[stable(feature = "rust1", since = "1.0.0")] - OccupiedEntry<'a, K, V>), + Occupied(#[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V>), } -#[stable(feature= "debug_btree_map", since = "1.12.0")] +#[stable(feature = "debug_btree_map", since = "1.12.0")] impl Debug for Entry<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - Vacant(ref v) => f.debug_tuple("Entry") - .field(v) - .finish(), - Occupied(ref o) => f.debug_tuple("Entry") - .field(o) - .finish(), + Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(), + Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(), } } } @@ -463,12 +439,10 @@ pub struct VacantEntry<'a, K: 'a, V: 'a> { _marker: PhantomData<&'a mut (K, V)>, } -#[stable(feature= "debug_btree_map", since = "1.12.0")] +#[stable(feature = "debug_btree_map", since = "1.12.0")] impl Debug for VacantEntry<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("VacantEntry") - .field(self.key()) - .finish() + f.debug_tuple("VacantEntry").field(self.key()).finish() } } @@ -486,13 +460,10 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> { _marker: PhantomData<&'a mut (K, V)>, } -#[stable(feature= "debug_btree_map", since = "1.12.0")] +#[stable(feature = "debug_btree_map", since = "1.12.0")] impl Debug for OccupiedEntry<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("OccupiedEntry") - .field("key", self.key()) - .field("value", self.get()) - .finish() + f.debug_struct("OccupiedEntry").field("key", self.key()).field("value", self.get()).finish() } } @@ -519,10 +490,7 @@ impl BTreeMap { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> BTreeMap { - BTreeMap { - root: node::Root::shared_empty_root(), - length: 0, - } + BTreeMap { root: node::Root::shared_empty_root(), length: 0 } } /// Clears the map, removing all values. @@ -563,8 +531,9 @@ impl BTreeMap { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self, key: &Q) -> Option<&V> - where K: Borrow, - Q: Ord + where + K: Borrow, + Q: Ord, { match search::search_tree(self.root.as_ref(), key) { Found(handle) => Some(handle.into_kv().1), @@ -589,8 +558,9 @@ impl BTreeMap { /// ``` #[stable(feature = "map_get_key_value", since = "1.40.0")] pub fn get_key_value(&self, k: &Q) -> Option<(&K, &V)> - where K: Borrow, - Q: Ord + where + K: Borrow, + Q: Ord, { match search::search_tree(self.root.as_ref(), k) { Found(handle) => Some(handle.into_kv()), @@ -617,7 +587,9 @@ impl BTreeMap { /// ``` #[unstable(feature = "map_first_last", issue = "62924")] pub fn first_key_value(&self) -> Option<(&K, &V)> - where T: Ord, K: Borrow + where + T: Ord, + K: Borrow, { let front = first_leaf_edge(self.root.as_ref()); front.right_kv().ok().map(Handle::into_kv) @@ -644,15 +616,17 @@ impl BTreeMap { /// ``` #[unstable(feature = "map_first_last", issue = "62924")] pub fn first_entry(&mut self) -> Option> - where T: Ord, K: Borrow + where + T: Ord, + K: Borrow, { match self.length { 0 => None, _ => Some(OccupiedEntry { - handle: self.root.as_mut().first_kv(), - length: &mut self.length, - _marker: PhantomData, - }), + handle: self.root.as_mut().first_kv(), + length: &mut self.length, + _marker: PhantomData, + }), } } @@ -674,7 +648,9 @@ impl BTreeMap { /// ``` #[unstable(feature = "map_first_last", issue = "62924")] pub fn last_key_value(&self) -> Option<(&K, &V)> - where T: Ord, K: Borrow + where + T: Ord, + K: Borrow, { let back = last_leaf_edge(self.root.as_ref()); back.left_kv().ok().map(Handle::into_kv) @@ -701,15 +677,17 @@ impl BTreeMap { /// ``` #[unstable(feature = "map_first_last", issue = "62924")] pub fn last_entry(&mut self) -> Option> - where T: Ord, K: Borrow + where + T: Ord, + K: Borrow, { match self.length { 0 => None, _ => Some(OccupiedEntry { - handle: self.root.as_mut().last_kv(), - length: &mut self.length, - _marker: PhantomData, - }), + handle: self.root.as_mut().last_kv(), + length: &mut self.length, + _marker: PhantomData, + }), } } @@ -732,8 +710,9 @@ impl BTreeMap { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains_key(&self, key: &Q) -> bool - where K: Borrow, - Q: Ord + where + K: Borrow, + Q: Ord, { self.get(key).is_some() } @@ -760,8 +739,9 @@ impl BTreeMap { // See `get` for implementation notes, this is basically a copy-paste with mut's added #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> - where K: Borrow, - Q: Ord + where + K: Borrow, + Q: Ord, { match search::search_tree(self.root.as_mut(), key) { Found(handle) => Some(handle.into_kv_mut().1), @@ -826,18 +806,14 @@ impl BTreeMap { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, key: &Q) -> Option - where K: Borrow, - Q: Ord + where + K: Borrow, + Q: Ord, { match search::search_tree(self.root.as_mut(), key) { - Found(handle) => { - Some(OccupiedEntry { - handle, - length: &mut self.length, - _marker: PhantomData, - } - .remove()) - } + Found(handle) => Some( + OccupiedEntry { handle, length: &mut self.length, _marker: PhantomData }.remove(), + ), GoDown(_) => None, } } @@ -886,10 +862,7 @@ impl BTreeMap { // First, we merge `self` and `other` into a sorted sequence in linear time. let self_iter = mem::take(self).into_iter(); let other_iter = mem::take(other).into_iter(); - let iter = MergeIter { - left: self_iter.peekable(), - right: other_iter.peekable(), - }; + let iter = MergeIter { left: self_iter.peekable(), right: other_iter.peekable() }; // Second, we build a tree from the sorted sequence in linear time. self.from_sorted_iter(iter); @@ -927,13 +900,16 @@ impl BTreeMap { /// ``` #[stable(feature = "btree_range", since = "1.17.0")] pub fn range(&self, range: R) -> Range<'_, K, V> - where T: Ord, K: Borrow, R: RangeBounds + where + T: Ord, + K: Borrow, + R: RangeBounds, { let root1 = self.root.as_ref(); let root2 = self.root.as_ref(); let (f, b) = range_search(root1, root2, range); - Range { front: f, back: b} + Range { front: f, back: b } } /// Constructs a mutable double-ended iterator over a sub-range of elements in the map. @@ -968,17 +944,16 @@ impl BTreeMap { /// ``` #[stable(feature = "btree_range", since = "1.17.0")] pub fn range_mut(&mut self, range: R) -> RangeMut<'_, K, V> - where T: Ord, K: Borrow, R: RangeBounds + where + T: Ord, + K: Borrow, + R: RangeBounds, { let root1 = self.root.as_mut(); let root2 = unsafe { ptr::read(&root1) }; let (f, b) = range_search(root1, root2, range); - RangeMut { - front: f, - back: b, - _marker: PhantomData, - } + RangeMut { front: f, back: b, _marker: PhantomData } } /// Gets the given key's corresponding entry in the map for in-place manipulation. @@ -1005,19 +980,10 @@ impl BTreeMap { self.ensure_root_is_owned(); match search::search_tree(self.root.as_mut(), &key) { Found(handle) => { - Occupied(OccupiedEntry { - handle, - length: &mut self.length, - _marker: PhantomData, - }) + Occupied(OccupiedEntry { handle, length: &mut self.length, _marker: PhantomData }) } GoDown(handle) => { - Vacant(VacantEntry { - key, - handle, - length: &mut self.length, - _marker: PhantomData, - }) + Vacant(VacantEntry { key, handle, length: &mut self.length, _marker: PhantomData }) } } } @@ -1124,7 +1090,8 @@ impl BTreeMap { /// ``` #[stable(feature = "btree_split_off", since = "1.11.0")] pub fn split_off(&mut self, key: &Q) -> Self - where K: Borrow + where + K: Borrow, { if self.is_empty() { return Self::new(); @@ -1182,10 +1149,10 @@ impl BTreeMap { /// Calculates the number of elements if it is incorrect. fn recalc_length(&mut self) { - fn dfs<'a, K, V>( - node: NodeRef, K, V, marker::LeafOrInternal> - ) -> usize - where K: 'a, V: 'a + fn dfs<'a, K, V>(node: NodeRef, K, V, marker::LeafOrInternal>) -> usize + where + K: 'a, + V: 'a, { let mut res = node.len(); @@ -1338,10 +1305,7 @@ impl ExactSizeIterator for Iter<'_, K, V> { #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Iter<'_, K, V> { fn clone(&self) -> Self { - Iter { - range: self.range.clone(), - length: self.length, - } + Iter { range: self.range.clone(), length: self.length } } } @@ -1410,11 +1374,7 @@ impl IntoIterator for BTreeMap { let len = self.length; mem::forget(self); - IntoIter { - front: first_leaf_edge(root1), - back: last_leaf_edge(root2), - length: len, - } + IntoIter { front: first_leaf_edge(root1), back: last_leaf_edge(root2), length: len } } } @@ -1619,11 +1579,7 @@ impl<'a, K, V> Iterator for Range<'a, K, V> { type Item = (&'a K, &'a V); fn next(&mut self) -> Option<(&'a K, &'a V)> { - if self.front == self.back { - None - } else { - unsafe { Some(self.next_unchecked()) } - } + if self.front == self.back { None } else { unsafe { Some(self.next_unchecked()) } } } fn last(mut self) -> Option<(&'a K, &'a V)> { @@ -1700,11 +1656,7 @@ impl<'a, K, V> Range<'a, K, V> { #[stable(feature = "btree_range", since = "1.17.0")] impl<'a, K, V> DoubleEndedIterator for Range<'a, K, V> { fn next_back(&mut self) -> Option<(&'a K, &'a V)> { - if self.front == self.back { - None - } else { - unsafe { Some(self.next_back_unchecked()) } - } + if self.front == self.back { None } else { unsafe { Some(self.next_back_unchecked()) } } } } @@ -1746,10 +1698,7 @@ impl FusedIterator for Range<'_, K, V> {} #[stable(feature = "btree_range", since = "1.17.0")] impl Clone for Range<'_, K, V> { fn clone(&self) -> Self { - Range { - front: self.front, - back: self.back, - } + Range { front: self.front, back: self.back } } } @@ -1758,11 +1707,7 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> { type Item = (&'a K, &'a mut V); fn next(&mut self) -> Option<(&'a K, &'a mut V)> { - if self.front == self.back { - None - } else { - unsafe { Some(self.next_unchecked()) } - } + if self.front == self.back { None } else { unsafe { Some(self.next_unchecked()) } } } fn last(mut self) -> Option<(&'a K, &'a mut V)> { @@ -1809,11 +1754,7 @@ impl<'a, K, V> RangeMut<'a, K, V> { #[stable(feature = "btree_range", since = "1.17.0")] impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> { fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> { - if self.front == self.back { - None - } else { - unsafe { Some(self.next_back_unchecked()) } - } + if self.front == self.back { None } else { unsafe { Some(self.next_back_unchecked()) } } } } @@ -1934,8 +1875,9 @@ impl Debug for BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] impl Index<&Q> for BTreeMap - where K: Borrow, - Q: Ord +where + K: Borrow, + Q: Ord, { type Output = V; @@ -1950,9 +1892,9 @@ impl Index<&Q> for BTreeMap } } -fn first_leaf_edge - (mut node: NodeRef) - -> Handle, marker::Edge> { +fn first_leaf_edge( + mut node: NodeRef, +) -> Handle, marker::Edge> { loop { match node.force() { Leaf(leaf) => return leaf.first_edge(), @@ -1963,9 +1905,9 @@ fn first_leaf_edge } } -fn last_leaf_edge - (mut node: NodeRef) - -> Handle, marker::Edge> { +fn last_leaf_edge( + mut node: NodeRef, +) -> Handle, marker::Edge> { loop { match node.force() { Leaf(leaf) => return leaf.last_edge(), @@ -1979,20 +1921,28 @@ fn last_leaf_edge fn range_search>( root1: NodeRef, root2: NodeRef, - range: R -)-> (Handle, marker::Edge>, - Handle, marker::Edge>) - where Q: Ord, K: Borrow + range: R, +) -> ( + Handle, marker::Edge>, + Handle, marker::Edge>, +) +where + Q: Ord, + K: Borrow, { match (range.start_bound(), range.end_bound()) { - (Excluded(s), Excluded(e)) if s==e => - panic!("range start and end are equal and excluded in BTreeMap"), - (Included(s), Included(e)) | - (Included(s), Excluded(e)) | - (Excluded(s), Included(e)) | - (Excluded(s), Excluded(e)) if s>e => - panic!("range start is greater than range end in BTreeMap"), - _ => {}, + (Excluded(s), Excluded(e)) if s == e => { + panic!("range start and end are equal and excluded in BTreeMap") + } + (Included(s), Included(e)) + | (Included(s), Excluded(e)) + | (Excluded(s), Included(e)) + | (Excluded(s), Excluded(e)) + if s > e => + { + panic!("range start is greater than range end in BTreeMap") + } + _ => {} }; let mut min_node = root1; @@ -2004,11 +1954,17 @@ fn range_search>( loop { let min_edge = match (min_found, range.start_bound()) { (false, Included(key)) => match search::search_linear(&min_node, key) { - (i, true) => { min_found = true; i }, + (i, true) => { + min_found = true; + i + } (i, false) => i, }, (false, Excluded(key)) => match search::search_linear(&min_node, key) { - (i, true) => { min_found = true; i+1 }, + (i, true) => { + min_found = true; + i + 1 + } (i, false) => i, }, (_, Unbounded) => 0, @@ -2018,11 +1974,17 @@ fn range_search>( let max_edge = match (max_found, range.end_bound()) { (false, Included(key)) => match search::search_linear(&max_node, key) { - (i, true) => { max_found = true; i+1 }, + (i, true) => { + max_found = true; + i + 1 + } (i, false) => i, }, (false, Excluded(key)) => match search::search_linear(&max_node, key) { - (i, true) => { max_found = true; i }, + (i, true) => { + max_found = true; + i + } (i, false) => i, }, (_, Unbounded) => max_node.keys().len(), @@ -2031,8 +1993,12 @@ fn range_search>( }; if !diverged { - if max_edge < min_edge { panic!("Ord is ill-defined in BTreeMap range") } - if min_edge != max_edge { diverged = true; } + if max_edge < min_edge { + panic!("Ord is ill-defined in BTreeMap range") + } + if min_edge != max_edge { + diverged = true; + } } let front = Handle::new_edge(min_node, min_edge); @@ -2040,11 +2006,11 @@ fn range_search>( match (front.force(), back.force()) { (Leaf(f), Leaf(b)) => { return (f, b); - }, + } (Internal(min_int), Internal(max_int)) => { min_node = min_int.descend(); max_node = max_int.descend(); - }, + } _ => unreachable!("BTreeMap has different depths"), }; } @@ -2321,13 +2287,14 @@ impl<'a, K: Ord, V> Entry<'a, K, V> { /// ``` #[stable(feature = "entry_and_modify", since = "1.26.0")] pub fn and_modify(self, f: F) -> Self - where F: FnOnce(&mut V) + where + F: FnOnce(&mut V), { match self { Occupied(mut entry) => { f(entry.get_mut()); Occupied(entry) - }, + } Vacant(entry) => Vacant(entry), } } @@ -2354,7 +2321,6 @@ impl<'a, K: Ord, V: Default> Entry<'a, K, V> { Vacant(entry) => entry.insert(Default::default()), } } - } impl<'a, K: Ord, V> VacantEntry<'a, K, V> { @@ -2433,17 +2399,15 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> { loop { match cur_parent { - Ok(parent) => { - match parent.insert(ins_k, ins_v, ins_edge) { - Fit(_) => return unsafe { &mut *out_ptr }, - Split(left, k, v, right) => { - ins_k = k; - ins_v = v; - ins_edge = right; - cur_parent = left.ascend().map_err(|n| n.into_root_mut()); - } + Ok(parent) => match parent.insert(ins_k, ins_v, ins_edge) { + Fit(_) => return unsafe { &mut *out_ptr }, + Split(left, k, v, right) => { + ins_k = k; + ins_v = v; + ins_edge = right; + cur_parent = left.ascend().map_err(|n| n.into_root_mut()); } - } + }, Err(root) => { root.push_level().push(ins_k, ins_v, ins_edge); return unsafe { &mut *out_ptr }; @@ -2669,8 +2633,9 @@ enum UnderflowResult<'a, K, V> { Stole(NodeRef, K, V, marker::Internal>), } -fn handle_underfull_node(node: NodeRef, K, V, marker::LeafOrInternal>) - -> UnderflowResult<'_, K, V> { +fn handle_underfull_node( + node: NodeRef, K, V, marker::LeafOrInternal>, +) -> UnderflowResult<'_, K, V> { let parent = if let Ok(parent) = node.ascend() { parent } else { @@ -2679,14 +2644,12 @@ fn handle_underfull_node(node: NodeRef, K, V, marker::Leaf let (is_left, mut handle) = match parent.left_kv() { Ok(left) => (true, left), - Err(parent) => { - match parent.right_kv() { - Ok(right) => (false, right), - Err(parent) => { - return EmptyParent(parent.into_node()); - } + Err(parent) => match parent.right_kv() { + Ok(right) => (false, right), + Err(parent) => { + return EmptyParent(parent.into_node()); } - } + }, }; if handle.can_merge() { diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index ab010b35f6ad1..53c2c29a9b659 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -33,10 +33,10 @@ use core::marker::PhantomData; use core::mem::{self, MaybeUninit}; -use core::ptr::{self, Unique, NonNull}; +use core::ptr::{self, NonNull, Unique}; use core::slice; -use crate::alloc::{Global, Alloc, Layout}; +use crate::alloc::{Alloc, Global, Layout}; use crate::boxed::Box; const B: usize = 6; @@ -110,7 +110,7 @@ impl LeafNode { vals: [MaybeUninit::UNINIT; CAPACITY], parent: ptr::null(), parent_idx: MaybeUninit::uninit(), - len: 0 + len: 0, } } } @@ -127,12 +127,8 @@ unsafe impl Sync for NodeHeader<(), ()> {} // An empty node used as a placeholder for the root node, to avoid allocations. // We use just a header in order to save space, since no operation on an empty tree will // ever take a pointer past the first key. -static EMPTY_ROOT_NODE: NodeHeader<(), ()> = NodeHeader { - parent: ptr::null(), - parent_idx: MaybeUninit::uninit(), - len: 0, - keys_start: [], -}; +static EMPTY_ROOT_NODE: NodeHeader<(), ()> = + NodeHeader { parent: ptr::null(), parent_idx: MaybeUninit::uninit(), len: 0, keys_start: [] }; /// The underlying representation of internal nodes. As with `LeafNode`s, these should be hidden /// behind `BoxedNode`s to prevent dropping uninitialized keys and values. Any pointer to an @@ -157,10 +153,7 @@ impl InternalNode { /// `len` of 0), there must be one initialized and valid edge. This function does not set up /// such an edge. unsafe fn new() -> Self { - InternalNode { - data: LeafNode::new(), - edges: [MaybeUninit::UNINIT; 2*B] - } + InternalNode { data: LeafNode::new(), edges: [MaybeUninit::UNINIT; 2 * B] } } } @@ -169,7 +162,7 @@ impl InternalNode { /// of nodes is actually behind the box, and, partially due to this lack of information, has no /// destructor. struct BoxedNode { - ptr: Unique> + ptr: Unique>, } impl BoxedNode { @@ -196,11 +189,11 @@ impl BoxedNode { /// and must be cleaned up manually. pub struct Root { node: BoxedNode, - height: usize + height: usize, } -unsafe impl Sync for Root { } -unsafe impl Send for Root { } +unsafe impl Sync for Root {} +unsafe impl Send for Root {} impl Root { pub fn is_shared_root(&self) -> bool { @@ -211,7 +204,7 @@ impl Root { Root { node: unsafe { BoxedNode::from_ptr(NonNull::new_unchecked( - &EMPTY_ROOT_NODE as *const _ as *const LeafNode as *mut _ + &EMPTY_ROOT_NODE as *const _ as *const LeafNode as *mut _, )) }, height: 0, @@ -219,14 +212,10 @@ impl Root { } pub fn new_leaf() -> Self { - Root { - node: BoxedNode::from_leaf(Box::new(unsafe { LeafNode::new() })), - height: 0 - } + Root { node: BoxedNode::from_leaf(Box::new(unsafe { LeafNode::new() })), height: 0 } } - pub fn as_ref(&self) - -> NodeRef, K, V, marker::LeafOrInternal> { + pub fn as_ref(&self) -> NodeRef, K, V, marker::LeafOrInternal> { NodeRef { height: self.height, node: self.node.as_ptr(), @@ -235,8 +224,7 @@ impl Root { } } - pub fn as_mut(&mut self) - -> NodeRef, K, V, marker::LeafOrInternal> { + pub fn as_mut(&mut self) -> NodeRef, K, V, marker::LeafOrInternal> { NodeRef { height: self.height, node: self.node.as_ptr(), @@ -245,8 +233,7 @@ impl Root { } } - pub fn into_ref(self) - -> NodeRef { + pub fn into_ref(self) -> NodeRef { NodeRef { height: self.height, node: self.node.as_ptr(), @@ -257,8 +244,7 @@ impl Root { /// Adds a new internal node with a single edge, pointing to the previous root, and make that /// new node the root. This increases the height by 1 and is the opposite of `pop_level`. - pub fn push_level(&mut self) - -> NodeRef, K, V, marker::Internal> { + pub fn push_level(&mut self) -> NodeRef, K, V, marker::Internal> { debug_assert!(!self.is_shared_root()); let mut new_node = Box::new(unsafe { InternalNode::new() }); new_node.edges[0].write(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }); @@ -270,7 +256,7 @@ impl Root { height: self.height, node: self.node.as_ptr(), root: self as *mut _, - _marker: PhantomData + _marker: PhantomData, }; unsafe { @@ -290,14 +276,14 @@ impl Root { let top = self.node.ptr; self.node = unsafe { - BoxedNode::from_ptr(self.as_mut() - .cast_unchecked::() - .first_edge() - .descend() - .node) + BoxedNode::from_ptr( + self.as_mut().cast_unchecked::().first_edge().descend().node, + ) }; self.height -= 1; - unsafe { (*self.as_mut().as_leaf_mut()).parent = ptr::null(); } + unsafe { + (*self.as_mut().as_leaf_mut()).parent = ptr::null(); + } unsafe { Global.dealloc(NonNull::from(top).cast(), Layout::new::>()); @@ -332,43 +318,34 @@ pub struct NodeRef { node: NonNull>, // This is null unless the borrow type is `Mut` root: *const Root, - _marker: PhantomData<(BorrowType, Type)> + _marker: PhantomData<(BorrowType, Type)>, } -impl<'a, K: 'a, V: 'a, Type> Copy for NodeRef, K, V, Type> { } +impl<'a, K: 'a, V: 'a, Type> Copy for NodeRef, K, V, Type> {} impl<'a, K: 'a, V: 'a, Type> Clone for NodeRef, K, V, Type> { fn clone(&self) -> Self { *self } } -unsafe impl Sync - for NodeRef { } +unsafe impl Sync for NodeRef {} -unsafe impl<'a, K: Sync + 'a, V: Sync + 'a, Type> Send - for NodeRef, K, V, Type> { } -unsafe impl<'a, K: Send + 'a, V: Send + 'a, Type> Send - for NodeRef, K, V, Type> { } -unsafe impl Send - for NodeRef { } +unsafe impl<'a, K: Sync + 'a, V: Sync + 'a, Type> Send for NodeRef, K, V, Type> {} +unsafe impl<'a, K: Send + 'a, V: Send + 'a, Type> Send for NodeRef, K, V, Type> {} +unsafe impl Send for NodeRef {} impl NodeRef { fn as_internal(&self) -> &InternalNode { - unsafe { - &*(self.node.as_ptr() as *mut InternalNode) - } + unsafe { &*(self.node.as_ptr() as *mut InternalNode) } } } impl<'a, K, V> NodeRef, K, V, marker::Internal> { fn as_internal_mut(&mut self) -> &mut InternalNode { - unsafe { - &mut *(self.node.as_ptr() as *mut InternalNode) - } + unsafe { &mut *(self.node.as_ptr() as *mut InternalNode) } } } - impl NodeRef { /// Finds the length of the node. This is the number of keys or values. In an /// internal node, the number of edges is `len() + 1`. @@ -385,22 +362,12 @@ impl NodeRef { /// Removes any static information about whether this node is a `Leaf` or an /// `Internal` node. pub fn forget_type(self) -> NodeRef { - NodeRef { - height: self.height, - node: self.node, - root: self.root, - _marker: PhantomData - } + NodeRef { height: self.height, node: self.node, root: self.root, _marker: PhantomData } } /// Temporarily takes out another, immutable reference to the same node. fn reborrow(&self) -> NodeRef, K, V, Type> { - NodeRef { - height: self.height, - node: self.node, - root: self.root, - _marker: PhantomData - } + NodeRef { height: self.height, node: self.node, root: self.root, _marker: PhantomData } } /// Assert that this is indeed a proper leaf node, and not the shared root. @@ -409,9 +376,7 @@ impl NodeRef { } fn as_header(&self) -> &NodeHeader { - unsafe { - &*(self.node.as_ptr() as *const NodeHeader) - } + unsafe { &*(self.node.as_ptr() as *const NodeHeader) } } pub fn is_shared_root(&self) -> bool { @@ -433,17 +398,9 @@ impl NodeRef { /// /// `edge.descend().ascend().unwrap()` and `node.ascend().unwrap().descend()` should /// both, upon success, do nothing. - pub fn ascend(self) -> Result< - Handle< - NodeRef< - BorrowType, - K, V, - marker::Internal - >, - marker::Edge - >, - Self - > { + pub fn ascend( + self, + ) -> Result, marker::Edge>, Self> { let parent_as_leaf = self.as_header().parent as *const LeafNode; if let Some(non_zero) = NonNull::new(parent_as_leaf as *mut _) { Ok(Handle { @@ -451,10 +408,10 @@ impl NodeRef { height: self.height + 1, node: non_zero, root: self.root, - _marker: PhantomData + _marker: PhantomData, }, idx: unsafe { usize::from(*self.as_header().parent_idx.as_ptr()) }, - _marker: PhantomData + _marker: PhantomData, }) } else { Err(self) @@ -488,16 +445,9 @@ impl NodeRef { /// Similar to `ascend`, gets a reference to a node's parent node, but also /// deallocate the current node in the process. This is unsafe because the /// current node will still be accessible despite being deallocated. - pub unsafe fn deallocate_and_ascend(self) -> Option< - Handle< - NodeRef< - marker::Owned, - K, V, - marker::Internal - >, - marker::Edge - > - > { + pub unsafe fn deallocate_and_ascend( + self, + ) -> Option, marker::Edge>> { debug_assert!(!self.is_shared_root()); let node = self.node; let ret = self.ascend().ok(); @@ -510,16 +460,9 @@ impl NodeRef { /// Similar to `ascend`, gets a reference to a node's parent node, but also /// deallocate the current node in the process. This is unsafe because the /// current node will still be accessible despite being deallocated. - pub unsafe fn deallocate_and_ascend(self) -> Option< - Handle< - NodeRef< - marker::Owned, - K, V, - marker::Internal - >, - marker::Edge - > - > { + pub unsafe fn deallocate_and_ascend( + self, + ) -> Option, marker::Edge>> { let node = self.node; let ret = self.ascend().ok(); Global.dealloc(node.cast(), Layout::new::>()); @@ -530,15 +473,8 @@ impl NodeRef { impl<'a, K, V, Type> NodeRef, K, V, Type> { /// Unsafely asserts to the compiler some static information about whether this /// node is a `Leaf`. - unsafe fn cast_unchecked(&mut self) - -> NodeRef, K, V, NewType> { - - NodeRef { - height: self.height, - node: self.node, - root: self.root, - _marker: PhantomData - } + unsafe fn cast_unchecked(&mut self) -> NodeRef, K, V, NewType> { + NodeRef { height: self.height, node: self.node, root: self.root, _marker: PhantomData } } /// Temporarily takes out another, mutable reference to the same node. Beware, as @@ -552,12 +488,7 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { // FIXME(@gereeter) consider adding yet another type parameter to `NodeRef` that restricts // the use of `ascend` and `into_root_mut` on reborrowed pointers, preventing this unsafety. unsafe fn reborrow_mut(&mut self) -> NodeRef, K, V, Type> { - NodeRef { - height: self.height, - node: self.node, - root: self.root, - _marker: PhantomData - } + NodeRef { height: self.height, node: self.node, root: self.root, _marker: PhantomData } } /// Returns a raw ptr to avoid asserting exclusive access to the entire node. @@ -612,21 +543,14 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { assert!(mem::size_of::>() == mem::size_of::>()); let header = self.as_header() as *const _ as *const NodeHeader; let keys = unsafe { &(*header).keys_start as *const _ as *const K }; - unsafe { - slice::from_raw_parts(keys, self.len()) - } + unsafe { slice::from_raw_parts(keys, self.len()) } } } fn into_val_slice(self) -> &'a [V] { debug_assert!(!self.is_shared_root()); // We cannot be the root, so `as_leaf` is okay - unsafe { - slice::from_raw_parts( - MaybeUninit::first_ptr(&self.as_leaf().vals), - self.len() - ) - } + unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().vals), self.len()) } } fn into_slices(self) -> (&'a [K], &'a [V]) { @@ -639,9 +563,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { /// Gets a mutable reference to the root itself. This is useful primarily when the /// height of the tree needs to be adjusted. Never call this on a reborrowed pointer. pub fn into_root_mut(self) -> &'a mut Root { - unsafe { - &mut *(self.root as *mut Root) - } + unsafe { &mut *(self.root as *mut Root) } } fn into_key_slice_mut(mut self) -> &'a mut [K] { @@ -653,7 +575,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { unsafe { slice::from_raw_parts_mut( MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).keys), - self.len() + self.len(), ) } } @@ -664,7 +586,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { unsafe { slice::from_raw_parts_mut( MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).vals), - self.len() + self.len(), ) } } @@ -679,14 +601,10 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { unsafe { let len = self.len(); let leaf = self.as_leaf_mut(); - let keys = slice::from_raw_parts_mut( - MaybeUninit::first_ptr_mut(&mut (*leaf).keys), - len - ); - let vals = slice::from_raw_parts_mut( - MaybeUninit::first_ptr_mut(&mut (*leaf).vals), - len - ); + let keys = + slice::from_raw_parts_mut(MaybeUninit::first_ptr_mut(&mut (*leaf).keys), len); + let vals = + slice::from_raw_parts_mut(MaybeUninit::first_ptr_mut(&mut (*leaf).vals), len); (keys, vals) } } @@ -769,10 +687,10 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { slice_insert( slice::from_raw_parts_mut( MaybeUninit::first_ptr_mut(&mut self.as_internal_mut().edges), - self.len()+1 + self.len() + 1, ), 0, - edge.node + edge.node, ); (*self.as_leaf_mut()).len += 1; @@ -797,9 +715,8 @@ impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { let edge = match self.reborrow_mut().force() { ForceResult::Leaf(_) => None, ForceResult::Internal(internal) => { - let edge = ptr::read( - internal.as_internal().edges.get_unchecked(idx + 1).as_ptr() - ); + let edge = + ptr::read(internal.as_internal().edges.get_unchecked(idx + 1).as_ptr()); let mut new_root = Root { node: edge, height: internal.height - 1 }; (*new_root.as_mut().as_leaf_mut()).parent = ptr::null(); Some(new_root) @@ -828,9 +745,9 @@ impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { let edge = slice_remove( slice::from_raw_parts_mut( MaybeUninit::first_ptr_mut(&mut internal.as_internal_mut().edges), - old_len+1 + old_len + 1, ), - 0 + 0, ); let mut new_root = Root { node: edge, height: internal.height - 1 }; @@ -851,32 +768,31 @@ impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { } fn into_kv_pointers_mut(mut self) -> (*mut K, *mut V) { - ( - self.keys_mut().as_mut_ptr(), - self.vals_mut().as_mut_ptr() - ) + (self.keys_mut().as_mut_ptr(), self.vals_mut().as_mut_ptr()) } } impl NodeRef { /// Checks whether a node is an `Internal` node or a `Leaf` node. - pub fn force(self) -> ForceResult< + pub fn force( + self, + ) -> ForceResult< NodeRef, - NodeRef + NodeRef, > { if self.height == 0 { ForceResult::Leaf(NodeRef { height: self.height, node: self.node, root: self.root, - _marker: PhantomData + _marker: PhantomData, }) } else { ForceResult::Internal(NodeRef { height: self.height, node: self.node, root: self.root, - _marker: PhantomData + _marker: PhantomData, }) } } @@ -893,10 +809,10 @@ impl NodeRef { pub struct Handle { node: Node, idx: usize, - _marker: PhantomData + _marker: PhantomData, } -impl Copy for Handle { } +impl Copy for Handle {} // We don't need the full generality of `#[derive(Clone)]`, as the only time `Node` will be // `Clone`able is when it is an immutable reference and therefore `Copy`. impl Clone for Handle { @@ -918,11 +834,7 @@ impl Handle, mar // Necessary for correctness, but in a private module debug_assert!(idx < node.len()); - Handle { - node, - idx, - _marker: PhantomData - } + Handle { node, idx, _marker: PhantomData } } pub fn left_edge(self) -> Handle, marker::Edge> { @@ -935,32 +847,24 @@ impl Handle, mar } impl PartialEq - for Handle, HandleType> { - + for Handle, HandleType> +{ fn eq(&self, other: &Self) -> bool { self.node.node == other.node.node && self.idx == other.idx } } impl - Handle, HandleType> { - + Handle, HandleType> +{ /// Temporarily takes out another, immutable handle on the same location. - pub fn reborrow(&self) - -> Handle, K, V, NodeType>, HandleType> { - + pub fn reborrow(&self) -> Handle, K, V, NodeType>, HandleType> { // We can't use Handle::new_kv or Handle::new_edge because we don't know our type - Handle { - node: self.node.reborrow(), - idx: self.idx, - _marker: PhantomData - } + Handle { node: self.node.reborrow(), idx: self.idx, _marker: PhantomData } } } -impl<'a, K, V, NodeType, HandleType> - Handle, K, V, NodeType>, HandleType> { - +impl<'a, K, V, NodeType, HandleType> Handle, K, V, NodeType>, HandleType> { /// Temporarily takes out another, mutable handle on the same location. Beware, as /// this method is very dangerous, doubly so since it may not immediately appear /// dangerous. @@ -971,52 +875,30 @@ impl<'a, K, V, NodeType, HandleType> /// of a reborrowed handle, out of bounds. // FIXME(@gereeter) consider adding yet another type parameter to `NodeRef` that restricts // the use of `ascend` and `into_root_mut` on reborrowed pointers, preventing this unsafety. - pub unsafe fn reborrow_mut(&mut self) - -> Handle, K, V, NodeType>, HandleType> { - + pub unsafe fn reborrow_mut( + &mut self, + ) -> Handle, K, V, NodeType>, HandleType> { // We can't use Handle::new_kv or Handle::new_edge because we don't know our type - Handle { - node: self.node.reborrow_mut(), - idx: self.idx, - _marker: PhantomData - } + Handle { node: self.node.reborrow_mut(), idx: self.idx, _marker: PhantomData } } } -impl - Handle, marker::Edge> { - +impl Handle, marker::Edge> { /// Creates a new handle to an edge in `node`. `idx` must be less than or equal to /// `node.len()`. pub fn new_edge(node: NodeRef, idx: usize) -> Self { // Necessary for correctness, but in a private module debug_assert!(idx <= node.len()); - Handle { - node, - idx, - _marker: PhantomData - } + Handle { node, idx, _marker: PhantomData } } - pub fn left_kv(self) - -> Result, marker::KV>, Self> { - - if self.idx > 0 { - Ok(Handle::new_kv(self.node, self.idx - 1)) - } else { - Err(self) - } + pub fn left_kv(self) -> Result, marker::KV>, Self> { + if self.idx > 0 { Ok(Handle::new_kv(self.node, self.idx - 1)) } else { Err(self) } } - pub fn right_kv(self) - -> Result, marker::KV>, Self> { - - if self.idx < self.node.len() { - Ok(Handle::new_kv(self.node, self.idx)) - } else { - Err(self) - } + pub fn right_kv(self) -> Result, marker::KV>, Self> { + if self.idx < self.node.len() { Ok(Handle::new_kv(self.node, self.idx)) } else { Err(self) } } } @@ -1045,9 +927,7 @@ impl<'a, K, V> Handle, K, V, marker::Leaf>, marker::Edge /// this edge. This method splits the node if there isn't enough room. /// /// The returned pointer points to the inserted value. - pub fn insert(mut self, key: K, val: V) - -> (InsertResult<'a, K, V, marker::Leaf>, *mut V) { - + pub fn insert(mut self, key: K, val: V) -> (InsertResult<'a, K, V, marker::Leaf>, *mut V) { if self.node.len() < CAPACITY { let ptr = self.insert_fit(key, val); (InsertResult::Fit(Handle::new_kv(self.node, self.idx)), ptr) @@ -1055,15 +935,14 @@ impl<'a, K, V> Handle, K, V, marker::Leaf>, marker::Edge let middle = Handle::new_kv(self.node, B); let (mut left, k, v, mut right) = middle.split(); let ptr = if self.idx <= B { - unsafe { - Handle::new_edge(left.reborrow_mut(), self.idx).insert_fit(key, val) - } + unsafe { Handle::new_edge(left.reborrow_mut(), self.idx).insert_fit(key, val) } } else { unsafe { Handle::new_edge( right.as_mut().cast_unchecked::(), - self.idx - (B + 1) - ).insert_fit(key, val) + self.idx - (B + 1), + ) + .insert_fit(key, val) } }; (InsertResult::Split(left, k, v, right), ptr) @@ -1086,9 +965,9 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: /// Unsafely asserts to the compiler some static information about whether the underlying /// node of this handle is a `Leaf`. - unsafe fn cast_unchecked(&mut self) - -> Handle, K, V, NewType>, marker::Edge> { - + unsafe fn cast_unchecked( + &mut self, + ) -> Handle, K, V, NewType>, marker::Edge> { Handle::new_edge(self.node.cast_unchecked(), self.idx) } @@ -1107,13 +986,13 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: slice_insert( slice::from_raw_parts_mut( MaybeUninit::first_ptr_mut(&mut self.node.as_internal_mut().edges), - self.node.len() + self.node.len(), ), self.idx + 1, - edge.node + edge.node, ); - for i in (self.idx+1)..(self.node.len()+1) { + for i in (self.idx + 1)..(self.node.len() + 1) { Handle::new_edge(self.node.reborrow_mut(), i).correct_parent_link(); } } @@ -1122,9 +1001,12 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: /// Inserts a new key/value pair and an edge that will go to the right of that new pair /// between this edge and the key/value pair to the right of this edge. This method splits /// the node if there isn't enough room. - pub fn insert(mut self, key: K, val: V, edge: Root) - -> InsertResult<'a, K, V, marker::Internal> { - + pub fn insert( + mut self, + key: K, + val: V, + edge: Root, + ) -> InsertResult<'a, K, V, marker::Internal> { // Necessary for correctness, but this is an internal module debug_assert!(edge.height == self.node.height - 1); @@ -1142,8 +1024,9 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: unsafe { Handle::new_edge( right.as_mut().cast_unchecked::(), - self.idx - (B + 1) - ).insert_fit(key, val, edge); + self.idx - (B + 1), + ) + .insert_fit(key, val, edge); } } InsertResult::Split(left, k, v, right) @@ -1151,9 +1034,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: } } -impl - Handle, marker::Edge> { - +impl Handle, marker::Edge> { /// Finds the node pointed to by this edge. /// /// `edge.descend().ascend().unwrap()` and `node.ascend().unwrap().descend()` should @@ -1165,30 +1046,22 @@ impl (&*self.node.as_internal().edges.get_unchecked(self.idx).as_ptr()).as_ptr() }, root: self.node.root, - _marker: PhantomData + _marker: PhantomData, } } } -impl<'a, K: 'a, V: 'a, NodeType> - Handle, K, V, NodeType>, marker::KV> { - +impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeType>, marker::KV> { pub fn into_kv(self) -> (&'a K, &'a V) { let (keys, vals) = self.node.into_slices(); - unsafe { - (keys.get_unchecked(self.idx), vals.get_unchecked(self.idx)) - } + unsafe { (keys.get_unchecked(self.idx), vals.get_unchecked(self.idx)) } } } -impl<'a, K: 'a, V: 'a, NodeType> - Handle, K, V, NodeType>, marker::KV> { - +impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeType>, marker::KV> { pub fn into_kv_mut(self) -> (&'a mut K, &'a mut V) { let (keys, vals) = self.node.into_slices_mut(); - unsafe { - (keys.get_unchecked_mut(self.idx), vals.get_unchecked_mut(self.idx)) - } + unsafe { (keys.get_unchecked_mut(self.idx), vals.get_unchecked_mut(self.idx)) } } } @@ -1209,8 +1082,7 @@ impl<'a, K, V> Handle, K, V, marker::Leaf>, marker::KV> /// - The key and value pointed to by this handle and extracted. /// - All the key/value pairs to the right of this handle are put into a newly /// allocated node. - pub fn split(mut self) - -> (NodeRef, K, V, marker::Leaf>, K, V, Root) { + pub fn split(mut self) -> (NodeRef, K, V, marker::Leaf>, K, V, Root) { debug_assert!(!self.node.is_shared_root()); unsafe { let mut new_node = Box::new(LeafNode::new()); @@ -1223,32 +1095,26 @@ impl<'a, K, V> Handle, K, V, marker::Leaf>, marker::KV> ptr::copy_nonoverlapping( self.node.keys().as_ptr().add(self.idx + 1), new_node.keys.as_mut_ptr() as *mut K, - new_len + new_len, ); ptr::copy_nonoverlapping( self.node.vals().as_ptr().add(self.idx + 1), new_node.vals.as_mut_ptr() as *mut V, - new_len + new_len, ); (*self.node.as_leaf_mut()).len = self.idx as u16; new_node.len = new_len as u16; - ( - self.node, - k, v, - Root { - node: BoxedNode::from_leaf(new_node), - height: 0 - } - ) + (self.node, k, v, Root { node: BoxedNode::from_leaf(new_node), height: 0 }) } } /// Removes the key/value pair pointed to by this handle, returning the edge between the /// now adjacent key/value pairs to the left and right of this handle. - pub fn remove(mut self) - -> (Handle, K, V, marker::Leaf>, marker::Edge>, K, V) { + pub fn remove( + mut self, + ) -> (Handle, K, V, marker::Leaf>, marker::Edge>, K, V) { debug_assert!(!self.node.is_shared_root()); unsafe { let k = slice_remove(self.node.keys_mut(), self.idx); @@ -1267,8 +1133,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: /// - The key and value pointed to by this handle and extracted. /// - All the edges and key/value pairs to the right of this handle are put into /// a newly allocated node. - pub fn split(mut self) - -> (NodeRef, K, V, marker::Internal>, K, V, Root) { + pub fn split(mut self) -> (NodeRef, K, V, marker::Internal>, K, V, Root) { unsafe { let mut new_node = Box::new(InternalNode::new()); @@ -1281,36 +1146,29 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: ptr::copy_nonoverlapping( self.node.keys().as_ptr().add(self.idx + 1), new_node.data.keys.as_mut_ptr() as *mut K, - new_len + new_len, ); ptr::copy_nonoverlapping( self.node.vals().as_ptr().add(self.idx + 1), new_node.data.vals.as_mut_ptr() as *mut V, - new_len + new_len, ); ptr::copy_nonoverlapping( self.node.as_internal().edges.as_ptr().add(self.idx + 1), new_node.edges.as_mut_ptr(), - new_len + 1 + new_len + 1, ); (*self.node.as_leaf_mut()).len = self.idx as u16; new_node.data.len = new_len as u16; - let mut new_root = Root { - node: BoxedNode::from_internal(new_node), - height, - }; + let mut new_root = Root { node: BoxedNode::from_internal(new_node), height }; - for i in 0..(new_len+1) { + for i in 0..(new_len + 1) { Handle::new_edge(new_root.as_mut().cast_unchecked(), i).correct_parent_link(); } - ( - self.node, - k, v, - new_root - ) + (self.node, k, v, new_root) } } @@ -1318,17 +1176,10 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: /// a node to hold the combination of the nodes to the left and right of this handle along /// with the key/value pair at this handle. pub fn can_merge(&self) -> bool { - ( - self.reborrow() - .left_edge() - .descend() - .len() - + self.reborrow() - .right_edge() - .descend() - .len() - + 1 - ) <= CAPACITY + (self.reborrow().left_edge().descend().len() + + self.reborrow().right_edge().descend().len() + + 1) + <= CAPACITY } /// Combines the node immediately to the left of this handle, the key/value pair pointed @@ -1336,8 +1187,9 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: /// child of the underlying node, returning an edge referencing that new child. /// /// Assumes that this edge `.can_merge()`. - pub fn merge(mut self) - -> Handle, K, V, marker::Internal>, marker::Edge> { + pub fn merge( + mut self, + ) -> Handle, K, V, marker::Internal>, marker::Edge> { let self1 = unsafe { ptr::read(&self) }; let self2 = unsafe { ptr::read(&self) }; let mut left_node = self1.left_edge().descend(); @@ -1349,23 +1201,27 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: debug_assert!(left_len + right_len + 1 <= CAPACITY); unsafe { - ptr::write(left_node.keys_mut().get_unchecked_mut(left_len), - slice_remove(self.node.keys_mut(), self.idx)); + ptr::write( + left_node.keys_mut().get_unchecked_mut(left_len), + slice_remove(self.node.keys_mut(), self.idx), + ); ptr::copy_nonoverlapping( right_node.keys().as_ptr(), left_node.keys_mut().as_mut_ptr().add(left_len + 1), - right_len + right_len, + ); + ptr::write( + left_node.vals_mut().get_unchecked_mut(left_len), + slice_remove(self.node.vals_mut(), self.idx), ); - ptr::write(left_node.vals_mut().get_unchecked_mut(left_len), - slice_remove(self.node.vals_mut(), self.idx)); ptr::copy_nonoverlapping( right_node.vals().as_ptr(), left_node.vals_mut().as_mut_ptr().add(left_len + 1), - right_len + right_len, ); slice_remove(&mut self.node.as_internal_mut().edges, self.idx + 1); - for i in self.idx+1..self.node.len() { + for i in self.idx + 1..self.node.len() { Handle::new_edge(self.node.reborrow_mut(), i).correct_parent_link(); } (*self.node.as_leaf_mut()).len -= 1; @@ -1375,30 +1231,23 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: if self.node.height > 1 { ptr::copy_nonoverlapping( right_node.cast_unchecked().as_internal().edges.as_ptr(), - left_node.cast_unchecked() - .as_internal_mut() - .edges - .as_mut_ptr() - .add(left_len + 1), - right_len + 1 + left_node + .cast_unchecked() + .as_internal_mut() + .edges + .as_mut_ptr() + .add(left_len + 1), + right_len + 1, ); - for i in left_len+1..left_len+right_len+2 { - Handle::new_edge( - left_node.cast_unchecked().reborrow_mut(), - i - ).correct_parent_link(); + for i in left_len + 1..left_len + right_len + 2 { + Handle::new_edge(left_node.cast_unchecked().reborrow_mut(), i) + .correct_parent_link(); } - Global.dealloc( - right_node.node.cast(), - Layout::new::>(), - ); + Global.dealloc(right_node.node.cast(), Layout::new::>()); } else { - Global.dealloc( - right_node.node.cast(), - Layout::new::>(), - ); + Global.dealloc(right_node.node.cast(), Layout::new::>()); } Handle::new_edge(self.node, self.idx) @@ -1417,7 +1266,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: match self.reborrow_mut().right_edge().descend().force() { ForceResult::Leaf(mut leaf) => leaf.push_front(k, v), - ForceResult::Internal(mut internal) => internal.push_front(k, v, edge.unwrap()) + ForceResult::Internal(mut internal) => internal.push_front(k, v, edge.unwrap()), } } } @@ -1434,7 +1283,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: match self.reborrow_mut().left_edge().descend().force() { ForceResult::Leaf(mut leaf) => leaf.push(k, v), - ForceResult::Internal(mut internal) => internal.push(k, v, edge.unwrap()) + ForceResult::Internal(mut internal) => internal.push(k, v, edge.unwrap()), } } } @@ -1463,12 +1312,8 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: }; // Make room for stolen elements in the right child. - ptr::copy(right_kv.0, - right_kv.0.add(count), - right_len); - ptr::copy(right_kv.1, - right_kv.1.add(count), - right_len); + ptr::copy(right_kv.0, right_kv.0.add(count), right_len); + ptr::copy(right_kv.1, right_kv.1.add(count), right_len); // Move elements from the left child to the right one. move_kv(left_kv, new_left_len + 1, right_kv, 0, count - 1); @@ -1487,15 +1332,15 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: (ForceResult::Internal(left), ForceResult::Internal(mut right)) => { // Make room for stolen edges. let right_edges = right.reborrow_mut().as_internal_mut().edges.as_mut_ptr(); - ptr::copy(right_edges, - right_edges.add(count), - right_len + 1); + ptr::copy(right_edges, right_edges.add(count), right_len + 1); right.correct_childrens_parent_links(count, count + right_len + 1); move_edges(left, new_left_len + 1, right, 0, count); - }, - (ForceResult::Leaf(_), ForceResult::Leaf(_)) => { } - _ => { unreachable!(); } + } + (ForceResult::Leaf(_), ForceResult::Leaf(_)) => {} + _ => { + unreachable!(); + } } } } @@ -1533,12 +1378,8 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: move_kv(right_kv, count - 1, parent_kv, 0, 1); // Fix right indexing - ptr::copy(right_kv.0.add(count), - right_kv.0, - new_right_len); - ptr::copy(right_kv.1.add(count), - right_kv.1, - new_right_len); + ptr::copy(right_kv.0.add(count), right_kv.0, new_right_len); + ptr::copy(right_kv.1.add(count), right_kv.1, new_right_len); } (*left_node.reborrow_mut().as_leaf_mut()).len += count as u16; @@ -1550,64 +1391,60 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: // Fix right indexing. let right_edges = right.reborrow_mut().as_internal_mut().edges.as_mut_ptr(); - ptr::copy(right_edges.add(count), - right_edges, - new_right_len + 1); + ptr::copy(right_edges.add(count), right_edges, new_right_len + 1); right.correct_childrens_parent_links(0, new_right_len + 1); - }, - (ForceResult::Leaf(_), ForceResult::Leaf(_)) => { } - _ => { unreachable!(); } + } + (ForceResult::Leaf(_), ForceResult::Leaf(_)) => {} + _ => { + unreachable!(); + } } } } } unsafe fn move_kv( - source: (*mut K, *mut V), source_offset: usize, - dest: (*mut K, *mut V), dest_offset: usize, - count: usize) -{ - ptr::copy_nonoverlapping(source.0.add(source_offset), - dest.0.add(dest_offset), - count); - ptr::copy_nonoverlapping(source.1.add(source_offset), - dest.1.add(dest_offset), - count); + source: (*mut K, *mut V), + source_offset: usize, + dest: (*mut K, *mut V), + dest_offset: usize, + count: usize, +) { + ptr::copy_nonoverlapping(source.0.add(source_offset), dest.0.add(dest_offset), count); + ptr::copy_nonoverlapping(source.1.add(source_offset), dest.1.add(dest_offset), count); } // Source and destination must have the same height. unsafe fn move_edges( - mut source: NodeRef, K, V, marker::Internal>, source_offset: usize, - mut dest: NodeRef, K, V, marker::Internal>, dest_offset: usize, - count: usize) -{ + mut source: NodeRef, K, V, marker::Internal>, + source_offset: usize, + mut dest: NodeRef, K, V, marker::Internal>, + dest_offset: usize, + count: usize, +) { let source_ptr = source.as_internal_mut().edges.as_mut_ptr(); let dest_ptr = dest.as_internal_mut().edges.as_mut_ptr(); - ptr::copy_nonoverlapping(source_ptr.add(source_offset), - dest_ptr.add(dest_offset), - count); + ptr::copy_nonoverlapping(source_ptr.add(source_offset), dest_ptr.add(dest_offset), count); dest.correct_childrens_parent_links(dest_offset, dest_offset + count); } impl - Handle, HandleType> { - + Handle, HandleType> +{ /// Checks whether the underlying node is an `Internal` node or a `Leaf` node. - pub fn force(self) -> ForceResult< + pub fn force( + self, + ) -> ForceResult< Handle, HandleType>, - Handle, HandleType> + Handle, HandleType>, > { match self.node.force() { - ForceResult::Leaf(node) => ForceResult::Leaf(Handle { - node, - idx: self.idx, - _marker: PhantomData - }), - ForceResult::Internal(node) => ForceResult::Internal(Handle { - node, - idx: self.idx, - _marker: PhantomData - }) + ForceResult::Leaf(node) => { + ForceResult::Leaf(Handle { node, idx: self.idx, _marker: PhantomData }) + } + ForceResult::Internal(node) => { + ForceResult::Internal(Handle { node, idx: self.idx, _marker: PhantomData }) + } } } } @@ -1615,8 +1452,10 @@ impl impl<'a, K, V> Handle, K, V, marker::LeafOrInternal>, marker::Edge> { /// Move the suffix after `self` from one node to another one. `right` must be empty. /// The first edge of `right` remains unchanged. - pub fn move_suffix(&mut self, - right: &mut NodeRef, K, V, marker::LeafOrInternal>) { + pub fn move_suffix( + &mut self, + right: &mut NodeRef, K, V, marker::LeafOrInternal>, + ) { unsafe { let left_new_len = self.idx; let mut left_node = self.reborrow_mut().into_node(); @@ -1630,7 +1469,6 @@ impl<'a, K, V> Handle, K, V, marker::LeafOrInternal>, ma let left_kv = left_node.reborrow_mut().into_kv_pointers_mut(); let right_kv = right_node.reborrow_mut().into_kv_pointers_mut(); - move_kv(left_kv, left_new_len, right_kv, 0, right_new_len); (*left_node.reborrow_mut().as_leaf_mut()).len = left_new_len as u16; @@ -1639,9 +1477,11 @@ impl<'a, K, V> Handle, K, V, marker::LeafOrInternal>, ma match (left_node.force(), right_node.force()) { (ForceResult::Internal(left), ForceResult::Internal(right)) => { move_edges(left, left_new_len + 1, right, 1, right_new_len); - }, - (ForceResult::Leaf(_), ForceResult::Leaf(_)) => { } - _ => { unreachable!(); } + } + (ForceResult::Leaf(_), ForceResult::Leaf(_)) => {} + _ => { + unreachable!(); + } } } } @@ -1649,44 +1489,36 @@ impl<'a, K, V> Handle, K, V, marker::LeafOrInternal>, ma pub enum ForceResult { Leaf(Leaf), - Internal(Internal) + Internal(Internal), } pub enum InsertResult<'a, K, V, Type> { Fit(Handle, K, V, Type>, marker::KV>), - Split(NodeRef, K, V, Type>, K, V, Root) + Split(NodeRef, K, V, Type>, K, V, Root), } pub mod marker { use core::marker::PhantomData; - pub enum Leaf { } - pub enum Internal { } - pub enum LeafOrInternal { } + pub enum Leaf {} + pub enum Internal {} + pub enum LeafOrInternal {} - pub enum Owned { } + pub enum Owned {} pub struct Immut<'a>(PhantomData<&'a ()>); pub struct Mut<'a>(PhantomData<&'a mut ()>); - pub enum KV { } - pub enum Edge { } + pub enum KV {} + pub enum Edge {} } unsafe fn slice_insert(slice: &mut [T], idx: usize, val: T) { - ptr::copy( - slice.as_ptr().add(idx), - slice.as_mut_ptr().add(idx + 1), - slice.len() - idx - ); + ptr::copy(slice.as_ptr().add(idx), slice.as_mut_ptr().add(idx + 1), slice.len() - idx); ptr::write(slice.get_unchecked_mut(idx), val); } unsafe fn slice_remove(slice: &mut [T], idx: usize) -> T { let ret = ptr::read(slice.get_unchecked(idx)); - ptr::copy( - slice.as_ptr().add(idx + 1), - slice.as_mut_ptr().add(idx), - slice.len() - idx - 1 - ); + ptr::copy(slice.as_ptr().add(idx + 1), slice.as_mut_ptr().add(idx), slice.len() - idx - 1); ret } diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs index 85b93e0eda45b..282d163141bc8 100644 --- a/src/liballoc/collections/btree/set.rs +++ b/src/liballoc/collections/btree/set.rs @@ -2,14 +2,14 @@ // to TreeMap use core::borrow::Borrow; -use core::cmp::Ordering::{Less, Greater, Equal}; +use core::cmp::Ordering::{Equal, Greater, Less}; use core::cmp::{max, min}; use core::fmt::{self, Debug}; -use core::iter::{Peekable, FromIterator, FusedIterator}; -use core::ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds}; +use core::iter::{FromIterator, FusedIterator, Peekable}; +use core::ops::{BitAnd, BitOr, BitXor, RangeBounds, Sub}; -use crate::collections::btree_map::{self, BTreeMap, Keys}; use super::Recover; +use crate::collections::btree_map::{self, BTreeMap, Keys}; // FIXME(conventions): implement bounded iterators @@ -77,9 +77,7 @@ pub struct Iter<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Iter<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Iter") - .field(&self.iter.clone()) - .finish() + f.debug_tuple("Iter").field(&self.iter.clone()).finish() } } @@ -114,8 +112,9 @@ pub struct Range<'a, T: 'a> { /// and crucially for SymmetricDifference, nexts() reports on both sides. #[derive(Clone)] struct MergeIterInner - where I: Iterator, - I::Item: Copy, +where + I: Iterator, + I::Item: Copy, { a: I, b: I, @@ -129,8 +128,9 @@ enum MergeIterPeeked { } impl MergeIterInner - where I: ExactSizeIterator + FusedIterator, - I::Item: Copy + Ord, +where + I: ExactSizeIterator + FusedIterator, + I::Item: Copy + Ord, { fn new(a: I, b: I) -> Self { MergeIterInner { a, b, peeked: None } @@ -169,14 +169,12 @@ impl MergeIterInner } impl Debug for MergeIterInner - where I: Iterator + Debug, - I::Item: Copy + Debug, +where + I: Iterator + Debug, + I::Item: Copy + Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("MergeIterInner") - .field(&self.a) - .field(&self.b) - .finish() + f.debug_tuple("MergeIterInner").field(&self.a).field(&self.b).finish() } } @@ -328,7 +326,10 @@ impl BTreeSet { /// ``` #[stable(feature = "btree_range", since = "1.17.0")] pub fn range(&self, range: R) -> Range<'_, T> - where K: Ord, T: Borrow, R: RangeBounds + where + K: Ord, + T: Borrow, + R: RangeBounds, { Range { iter: self.map.range(range) } } @@ -355,24 +356,18 @@ impl BTreeSet { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn difference<'a>(&'a self, other: &'a BTreeSet) -> Difference<'a, T> { - let (self_min, self_max) = if let (Some(self_min), Some(self_max)) = - (self.first(), self.last()) - { - (self_min, self_max) - } else { - return Difference { - inner: DifferenceInner::Iterate(self.iter()), + let (self_min, self_max) = + if let (Some(self_min), Some(self_max)) = (self.first(), self.last()) { + (self_min, self_max) + } else { + return Difference { inner: DifferenceInner::Iterate(self.iter()) }; }; - }; - let (other_min, other_max) = if let (Some(other_min), Some(other_max)) = - (other.first(), other.last()) - { - (other_min, other_max) - } else { - return Difference { - inner: DifferenceInner::Iterate(self.iter()), + let (other_min, other_max) = + if let (Some(other_min), Some(other_max)) = (other.first(), other.last()) { + (other_min, other_max) + } else { + return Difference { inner: DifferenceInner::Iterate(self.iter()) }; }; - }; Difference { inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) { (Greater, _) | (_, Less) => DifferenceInner::Iterate(self.iter()), @@ -387,10 +382,7 @@ impl BTreeSet { DifferenceInner::Iterate(self_iter) } _ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { - DifferenceInner::Search { - self_iter: self.iter(), - other_set: other, - } + DifferenceInner::Search { self_iter: self.iter(), other_set: other } } _ => DifferenceInner::Stitch { self_iter: self.iter(), @@ -421,9 +413,10 @@ impl BTreeSet { /// assert_eq!(sym_diff, [1, 3]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn symmetric_difference<'a>(&'a self, - other: &'a BTreeSet) - -> SymmetricDifference<'a, T> { + pub fn symmetric_difference<'a>( + &'a self, + other: &'a BTreeSet, + ) -> SymmetricDifference<'a, T> { SymmetricDifference(MergeIterInner::new(self.iter(), other.iter())) } @@ -449,45 +442,30 @@ impl BTreeSet { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn intersection<'a>(&'a self, other: &'a BTreeSet) -> Intersection<'a, T> { - let (self_min, self_max) = if let (Some(self_min), Some(self_max)) = - (self.first(), self.last()) - { - (self_min, self_max) - } else { - return Intersection { - inner: IntersectionInner::Answer(None), + let (self_min, self_max) = + if let (Some(self_min), Some(self_max)) = (self.first(), self.last()) { + (self_min, self_max) + } else { + return Intersection { inner: IntersectionInner::Answer(None) }; }; - }; - let (other_min, other_max) = if let (Some(other_min), Some(other_max)) = - (other.first(), other.last()) - { - (other_min, other_max) - } else { - return Intersection { - inner: IntersectionInner::Answer(None), + let (other_min, other_max) = + if let (Some(other_min), Some(other_max)) = (other.first(), other.last()) { + (other_min, other_max) + } else { + return Intersection { inner: IntersectionInner::Answer(None) }; }; - }; Intersection { inner: match (self_min.cmp(other_max), self_max.cmp(other_min)) { (Greater, _) | (_, Less) => IntersectionInner::Answer(None), (Equal, _) => IntersectionInner::Answer(Some(self_min)), (_, Equal) => IntersectionInner::Answer(Some(self_max)), _ if self.len() <= other.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { - IntersectionInner::Search { - small_iter: self.iter(), - large_set: other, - } + IntersectionInner::Search { small_iter: self.iter(), large_set: other } } _ if other.len() <= self.len() / ITER_PERFORMANCE_TIPPING_SIZE_DIFF => { - IntersectionInner::Search { - small_iter: other.iter(), - large_set: self, - } + IntersectionInner::Search { small_iter: other.iter(), large_set: self } } - _ => IntersectionInner::Stitch { - a: self.iter(), - b: other.iter(), - }, + _ => IntersectionInner::Stitch { a: self.iter(), b: other.iter() }, }, } } @@ -549,8 +527,9 @@ impl BTreeSet { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains(&self, value: &Q) -> bool - where T: Borrow, - Q: Ord + where + T: Borrow, + Q: Ord, { self.map.contains_key(value) } @@ -572,8 +551,9 @@ impl BTreeSet { /// ``` #[stable(feature = "set_recovery", since = "1.9.0")] pub fn get(&self, value: &Q) -> Option<&T> - where T: Borrow, - Q: Ord + where + T: Borrow, + Q: Ord, { Recover::get(&self.map, value) } @@ -624,20 +604,18 @@ impl BTreeSet { if self.len() > other.len() { return false; } - let (self_min, self_max) = if let (Some(self_min), Some(self_max)) = - (self.first(), self.last()) - { - (self_min, self_max) - } else { - return true; // self is empty - }; - let (other_min, other_max) = if let (Some(other_min), Some(other_max)) = - (other.first(), other.last()) - { - (other_min, other_max) - } else { - return false; // other is empty - }; + let (self_min, self_max) = + if let (Some(self_min), Some(self_max)) = (self.first(), self.last()) { + (self_min, self_max) + } else { + return true; // self is empty + }; + let (other_min, other_max) = + if let (Some(other_min), Some(other_max)) = (other.first(), other.last()) { + (other_min, other_max) + } else { + return false; // other is empty + }; let mut self_iter = self.iter(); match self_min.cmp(other_min) { Less => return false, @@ -855,8 +833,9 @@ impl BTreeSet { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, value: &Q) -> bool - where T: Borrow, - Q: Ord + where + T: Borrow, + Q: Ord, { self.map.remove(value).is_some() } @@ -878,8 +857,9 @@ impl BTreeSet { /// ``` #[stable(feature = "set_recovery", since = "1.9.0")] pub fn take(&mut self, value: &Q) -> Option - where T: Borrow, - Q: Ord + where + T: Borrow, + Q: Ord, { Recover::take(&mut self.map, value) } @@ -947,7 +927,10 @@ impl BTreeSet { /// assert!(b.contains(&41)); /// ``` #[stable(feature = "btree_split_off", since = "1.11.0")] - pub fn split_off(&mut self, key: &Q) -> Self where T: Borrow { + pub fn split_off(&mut self, key: &Q) -> Self + where + T: Borrow, + { BTreeSet { map: self.map.split_off(key) } } } @@ -1213,7 +1196,9 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { } #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for Iter<'_, T> { - fn len(&self) -> usize { self.iter.len() } + fn len(&self) -> usize { + self.iter.len() + } } #[stable(feature = "fused", since = "1.26.0")] @@ -1238,7 +1223,9 @@ impl DoubleEndedIterator for IntoIter { } #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for IntoIter { - fn len(&self) -> usize { self.iter.len() } + fn len(&self) -> usize { + self.iter.len() + } } #[stable(feature = "fused", since = "1.26.0")] @@ -1279,20 +1266,13 @@ impl Clone for Difference<'_, T> { fn clone(&self) -> Self { Difference { inner: match &self.inner { - DifferenceInner::Stitch { - self_iter, - other_iter, - } => DifferenceInner::Stitch { + DifferenceInner::Stitch { self_iter, other_iter } => DifferenceInner::Stitch { self_iter: self_iter.clone(), other_iter: other_iter.clone(), }, - DifferenceInner::Search { - self_iter, - other_set, - } => DifferenceInner::Search { - self_iter: self_iter.clone(), - other_set, - }, + DifferenceInner::Search { self_iter, other_set } => { + DifferenceInner::Search { self_iter: self_iter.clone(), other_set } + } DifferenceInner::Iterate(iter) => DifferenceInner::Iterate(iter.clone()), }, } @@ -1304,16 +1284,10 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> { fn next(&mut self) -> Option<&'a T> { match &mut self.inner { - DifferenceInner::Stitch { - self_iter, - other_iter, - } => { + DifferenceInner::Stitch { self_iter, other_iter } => { let mut self_next = self_iter.next()?; loop { - match other_iter - .peek() - .map_or(Less, |other_next| self_next.cmp(other_next)) - { + match other_iter.peek().map_or(Less, |other_next| self_next.cmp(other_next)) { Less => return Some(self_next), Equal => { self_next = self_iter.next()?; @@ -1325,10 +1299,7 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> { } } } - DifferenceInner::Search { - self_iter, - other_set, - } => loop { + DifferenceInner::Search { self_iter, other_set } => loop { let self_next = self_iter.next()?; if !other_set.contains(&self_next) { return Some(self_next); @@ -1340,14 +1311,10 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> { fn size_hint(&self) -> (usize, Option) { let (self_len, other_len) = match &self.inner { - DifferenceInner::Stitch { - self_iter, - other_iter, - } => (self_iter.len(), other_iter.len()), - DifferenceInner::Search { - self_iter, - other_set, - } => (self_iter.len(), other_set.len()), + DifferenceInner::Stitch { self_iter, other_iter } => { + (self_iter.len(), other_iter.len()) + } + DifferenceInner::Search { self_iter, other_set } => (self_iter.len(), other_set.len()), DifferenceInner::Iterate(iter) => (iter.len(), 0), }; (self_len.saturating_sub(other_len), Some(self_len)) @@ -1393,20 +1360,12 @@ impl Clone for Intersection<'_, T> { fn clone(&self) -> Self { Intersection { inner: match &self.inner { - IntersectionInner::Stitch { - a, - b, - } => IntersectionInner::Stitch { - a: a.clone(), - b: b.clone(), - }, - IntersectionInner::Search { - small_iter, - large_set, - } => IntersectionInner::Search { - small_iter: small_iter.clone(), - large_set, - }, + IntersectionInner::Stitch { a, b } => { + IntersectionInner::Stitch { a: a.clone(), b: b.clone() } + } + IntersectionInner::Search { small_iter, large_set } => { + IntersectionInner::Search { small_iter: small_iter.clone(), large_set } + } IntersectionInner::Answer(answer) => IntersectionInner::Answer(*answer), }, } @@ -1418,10 +1377,7 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> { fn next(&mut self) -> Option<&'a T> { match &mut self.inner { - IntersectionInner::Stitch { - a, - b, - } => { + IntersectionInner::Stitch { a, b } => { let mut a_next = a.next()?; let mut b_next = b.next()?; loop { @@ -1432,10 +1388,7 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> { } } } - IntersectionInner::Search { - small_iter, - large_set, - } => loop { + IntersectionInner::Search { small_iter, large_set } => loop { let small_next = small_iter.next()?; if large_set.contains(&small_next) { return Some(small_next); diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 5a6d4ee2aea93..4931093c55c99 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -14,14 +14,14 @@ use core::cmp::Ordering; use core::fmt; -use core::hash::{Hasher, Hash}; +use core::hash::{Hash, Hasher}; use core::iter::{FromIterator, FusedIterator}; use core::marker::PhantomData; use core::mem; use core::ptr::NonNull; -use crate::boxed::Box; use super::SpecExtend; +use crate::boxed::Box; #[cfg(test)] mod tests; @@ -66,9 +66,7 @@ pub struct Iter<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Iter<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Iter") - .field(&self.len) - .finish() + f.debug_tuple("Iter").field(&self.len).finish() } } @@ -101,10 +99,7 @@ pub struct IterMut<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for IterMut<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("IterMut") - .field(&self.list) - .field(&self.len) - .finish() + f.debug_tuple("IterMut").field(&self.list).field(&self.len).finish() } } @@ -124,19 +119,13 @@ pub struct IntoIter { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("IntoIter") - .field(&self.list) - .finish() + f.debug_tuple("IntoIter").field(&self.list).finish() } } impl Node { fn new(element: T) -> Self { - Node { - next: None, - prev: None, - element, - } + Node { next: None, prev: None, element } } fn into_element(self: Box) -> T { @@ -278,12 +267,7 @@ impl LinkedList { #[rustc_const_stable(feature = "const_linked_list_new", since = "1.32.0")] #[stable(feature = "rust1", since = "1.0.0")] pub const fn new() -> Self { - LinkedList { - head: None, - tail: None, - len: 0, - marker: PhantomData, - } + LinkedList { head: None, tail: None, len: 0, marker: PhantomData } } /// Moves all elements from `other` to the end of the list. @@ -357,12 +341,7 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn iter(&self) -> Iter<'_, T> { - Iter { - head: self.head, - tail: self.tail, - len: self.len, - marker: PhantomData, - } + Iter { head: self.head, tail: self.tail, len: self.len, marker: PhantomData } } /// Provides a forward iterator with mutable references. @@ -391,12 +370,7 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn iter_mut(&mut self) -> IterMut<'_, T> { - IterMut { - head: self.head, - tail: self.tail, - len: self.len, - list: self, - } + IterMut { head: self.head, tail: self.tail, len: self.len, list: self } } /// Returns `true` if the `LinkedList` is empty. @@ -491,7 +465,8 @@ impl LinkedList { /// ``` #[stable(feature = "linked_list_contains", since = "1.12.0")] pub fn contains(&self, x: &T) -> bool - where T: PartialEq + where + T: PartialEq, { self.iter().any(|e| e == x) } @@ -513,9 +488,7 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn front(&self) -> Option<&T> { - unsafe { - self.head.as_ref().map(|node| &node.as_ref().element) - } + unsafe { self.head.as_ref().map(|node| &node.as_ref().element) } } /// Provides a mutable reference to the front element, or `None` if the list @@ -541,9 +514,7 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn front_mut(&mut self) -> Option<&mut T> { - unsafe { - self.head.as_mut().map(|node| &mut node.as_mut().element) - } + unsafe { self.head.as_mut().map(|node| &mut node.as_mut().element) } } /// Provides a reference to the back element, or `None` if the list is @@ -563,9 +534,7 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn back(&self) -> Option<&T> { - unsafe { - self.tail.as_ref().map(|node| &node.as_ref().element) - } + unsafe { self.tail.as_ref().map(|node| &node.as_ref().element) } } /// Provides a mutable reference to the back element, or `None` if the list @@ -591,9 +560,7 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn back_mut(&mut self) -> Option<&mut T> { - unsafe { - self.tail.as_mut().map(|node| &mut node.as_mut().element) - } + unsafe { self.tail.as_mut().map(|node| &mut node.as_mut().element) } } /// Adds an element first in the list. @@ -790,19 +757,14 @@ impl LinkedList { /// ``` #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F> - where F: FnMut(&mut T) -> bool + where + F: FnMut(&mut T) -> bool, { // avoid borrow issues. let it = self.head; let old_len = self.len; - DrainFilter { - list: self, - it: it, - pred: filter, - idx: 0, - old_len: old_len, - } + DrainFilter { list: self, it: it, pred: filter, idx: 0, old_len: old_len } } } @@ -960,9 +922,11 @@ impl IterMut<'_, T> { /// } /// ``` #[inline] - #[unstable(feature = "linked_list_extras", - reason = "this is probably better handled by a cursor type -- we'll see", - issue = "27794")] + #[unstable( + feature = "linked_list_extras", + reason = "this is probably better handled by a cursor type -- we'll see", + issue = "27794" + )] pub fn insert_next(&mut self, element: T) { match self.head { // `push_back` is okay with aliasing `element` references @@ -1008,16 +972,16 @@ impl IterMut<'_, T> { /// assert_eq!(it.next().unwrap(), &2); /// ``` #[inline] - #[unstable(feature = "linked_list_extras", - reason = "this is probably better handled by a cursor type -- we'll see", - issue = "27794")] + #[unstable( + feature = "linked_list_extras", + reason = "this is probably better handled by a cursor type -- we'll see", + issue = "27794" + )] pub fn peek_next(&mut self) -> Option<&mut T> { if self.len == 0 { None } else { - unsafe { - self.head.as_mut().map(|node| &mut node.as_mut().element) - } + unsafe { self.head.as_mut().map(|node| &mut node.as_mut().element) } } } } @@ -1025,7 +989,8 @@ impl IterMut<'_, T> { /// An iterator produced by calling `drain_filter` on LinkedList. #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] pub struct DrainFilter<'a, T: 'a, F: 'a> - where F: FnMut(&mut T) -> bool, +where + F: FnMut(&mut T) -> bool, { list: &'a mut LinkedList, it: Option>>, @@ -1036,7 +1001,8 @@ pub struct DrainFilter<'a, T: 'a, F: 'a> #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] impl Iterator for DrainFilter<'_, T, F> - where F: FnMut(&mut T) -> bool, +where + F: FnMut(&mut T) -> bool, { type Item = T; @@ -1064,7 +1030,8 @@ impl Iterator for DrainFilter<'_, T, F> #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] impl Drop for DrainFilter<'_, T, F> - where F: FnMut(&mut T) -> bool, +where + F: FnMut(&mut T) -> bool, { fn drop(&mut self) { self.for_each(drop); @@ -1073,12 +1040,11 @@ impl Drop for DrainFilter<'_, T, F> #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] impl fmt::Debug for DrainFilter<'_, T, F> - where F: FnMut(&mut T) -> bool +where + F: FnMut(&mut T) -> bool, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("DrainFilter") - .field(&self.list) - .finish() + f.debug_tuple("DrainFilter").field(&self.list).finish() } } diff --git a/src/liballoc/collections/mod.rs b/src/liballoc/collections/mod.rs index 390a48180c0a6..0bb62373fab1e 100644 --- a/src/liballoc/collections/mod.rs +++ b/src/liballoc/collections/mod.rs @@ -45,7 +45,7 @@ use crate::alloc::{Layout, LayoutErr}; /// The error type for `try_reserve` methods. #[derive(Clone, PartialEq, Eq, Debug)] -#[unstable(feature = "try_reserve", reason = "new API", issue="48043")] +#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")] pub enum TryReserveError { /// Error due to the computed capacity exceeding the collection's maximum /// (usually `isize::MAX` bytes). @@ -57,15 +57,19 @@ pub enum TryReserveError { layout: Layout, #[doc(hidden)] - #[unstable(feature = "container_error_extra", issue = "none", reason = "\ + #[unstable( + feature = "container_error_extra", + issue = "none", + reason = "\ Enable exposing the allocator’s custom error value \ if an associated type is added in the future: \ - https://github.com/rust-lang/wg-allocators/issues/23")] + https://github.com/rust-lang/wg-allocators/issues/23" + )] non_exhaustive: (), }, } -#[unstable(feature = "try_reserve", reason = "new API", issue="48043")] +#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")] impl From for TryReserveError { #[inline] fn from(_: LayoutErr) -> Self { diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 913613653a67d..9d2eec94a0c02 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -10,13 +10,13 @@ use core::array::LengthAtMost32; use core::cmp::{self, Ordering}; use core::fmt; +use core::hash::{Hash, Hasher}; use core::iter::{once, repeat_with, FromIterator, FusedIterator}; use core::mem::{self, replace}; use core::ops::Bound::{Excluded, Included, Unbounded}; use core::ops::{Index, IndexMut, RangeBounds, Try}; use core::ptr::{self, NonNull}; use core::slice; -use core::hash::{Hash, Hasher}; use crate::collections::TryReserveError; use crate::raw_vec::RawVec; @@ -89,13 +89,12 @@ impl<'a, 'b, T> PairSlices<'a, 'b, T> { !self.b0.is_empty() } - fn remainder(self) -> impl Iterator { + fn remainder(self) -> impl Iterator { once(self.b0).chain(once(self.b1)) } } -impl<'a, 'b, T> Iterator for PairSlices<'a, 'b, T> -{ +impl<'a, 'b, T> Iterator for PairSlices<'a, 'b, T> { type Item = (&'a mut [T], &'b [T]); fn next(&mut self) -> Option { // Get next part length @@ -247,41 +246,45 @@ impl VecDeque { /// Copies a contiguous block of memory len long from src to dst #[inline] unsafe fn copy(&self, dst: usize, src: usize, len: usize) { - debug_assert!(dst + len <= self.cap(), - "cpy dst={} src={} len={} cap={}", - dst, - src, - len, - self.cap()); - debug_assert!(src + len <= self.cap(), - "cpy dst={} src={} len={} cap={}", - dst, - src, - len, - self.cap()); - ptr::copy(self.ptr().add(src), - self.ptr().add(dst), - len); + debug_assert!( + dst + len <= self.cap(), + "cpy dst={} src={} len={} cap={}", + dst, + src, + len, + self.cap() + ); + debug_assert!( + src + len <= self.cap(), + "cpy dst={} src={} len={} cap={}", + dst, + src, + len, + self.cap() + ); + ptr::copy(self.ptr().add(src), self.ptr().add(dst), len); } /// Copies a contiguous block of memory len long from src to dst #[inline] unsafe fn copy_nonoverlapping(&self, dst: usize, src: usize, len: usize) { - debug_assert!(dst + len <= self.cap(), - "cno dst={} src={} len={} cap={}", - dst, - src, - len, - self.cap()); - debug_assert!(src + len <= self.cap(), - "cno dst={} src={} len={} cap={}", - dst, - src, - len, - self.cap()); - ptr::copy_nonoverlapping(self.ptr().add(src), - self.ptr().add(dst), - len); + debug_assert!( + dst + len <= self.cap(), + "cno dst={} src={} len={} cap={}", + dst, + src, + len, + self.cap() + ); + debug_assert!( + src + len <= self.cap(), + "cno dst={} src={} len={} cap={}", + dst, + src, + len, + self.cap() + ); + ptr::copy_nonoverlapping(self.ptr().add(src), self.ptr().add(dst), len); } /// Copies a potentially wrapping block of memory len long from src to dest. @@ -292,12 +295,14 @@ impl VecDeque { fn diff(a: usize, b: usize) -> usize { if a <= b { b - a } else { a - b } } - debug_assert!(cmp::min(diff(dst, src), self.cap() - diff(dst, src)) + len <= self.cap(), - "wrc dst={} src={} len={} cap={}", - dst, - src, - len, - self.cap()); + debug_assert!( + cmp::min(diff(dst, src), self.cap() - diff(dst, src)) + len <= self.cap(), + "wrc dst={} src={} len={} cap={}", + dst, + src, + len, + self.cap() + ); if src == dst || len == 0 { return; @@ -475,11 +480,7 @@ impl VecDeque { let cap = cmp::max(capacity + 1, MINIMUM_CAPACITY + 1).next_power_of_two(); assert!(cap > capacity, "capacity overflow"); - VecDeque { - tail: 0, - head: 0, - buf: RawVec::with_capacity(cap), - } + VecDeque { tail: 0, head: 0, buf: RawVec::with_capacity(cap) } } /// Retrieves an element in the `VecDeque` by index. @@ -565,10 +566,7 @@ impl VecDeque { assert!(j < self.len()); let ri = self.wrap_add(self.tail, i); let rj = self.wrap_add(self.tail, j); - unsafe { - ptr::swap(self.ptr().add(ri), - self.ptr().add(rj)) - } + unsafe { ptr::swap(self.ptr().add(ri), self.ptr().add(rj)) } } /// Returns the number of elements the `VecDeque` can hold without @@ -635,7 +633,8 @@ impl VecDeque { pub fn reserve(&mut self, additional: usize) { let old_cap = self.cap(); let used_cap = self.len() + 1; - let new_cap = used_cap.checked_add(additional) + let new_cap = used_cap + .checked_add(additional) .and_then(|needed_cap| needed_cap.checked_next_power_of_two()) .expect("capacity overflow"); @@ -683,8 +682,8 @@ impl VecDeque { /// } /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?"); /// ``` - #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] - pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> { + #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")] + pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> { self.try_reserve(additional) } @@ -721,11 +720,12 @@ impl VecDeque { /// } /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?"); /// ``` - #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] + #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")] pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> { let old_cap = self.cap(); let used_cap = self.len() + 1; - let new_cap = used_cap.checked_add(additional) + let new_cap = used_cap + .checked_add(additional) .and_then(|needed_cap| needed_cap.checked_next_power_of_two()) .ok_or(TryReserveError::CapacityOverflow)?; @@ -781,16 +781,14 @@ impl VecDeque { /// buf.shrink_to(0); /// assert!(buf.capacity() >= 4); /// ``` - #[unstable(feature = "shrink_to", reason = "new API", issue="56431")] + #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")] pub fn shrink_to(&mut self, min_capacity: usize) { assert!(self.capacity() >= min_capacity, "Tried to shrink to a larger capacity"); // +1 since the ringbuffer always leaves one space empty // len + 1 can't overflow for an existing, well-formed ringbuffer. - let target_cap = cmp::max( - cmp::max(min_capacity, self.len()) + 1, - MINIMUM_CAPACITY + 1 - ).next_power_of_two(); + let target_cap = cmp::max(cmp::max(min_capacity, self.len()) + 1, MINIMUM_CAPACITY + 1) + .next_power_of_two(); if target_cap < self.cap() { // There are three cases of interest: @@ -913,11 +911,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn iter(&self) -> Iter<'_, T> { - Iter { - tail: self.tail, - head: self.head, - ring: unsafe { self.buffer_as_slice() }, - } + Iter { tail: self.tail, head: self.head, ring: unsafe { self.buffer_as_slice() } } } /// Returns a front-to-back iterator that returns mutable references. @@ -939,11 +933,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn iter_mut(&mut self) -> IterMut<'_, T> { - IterMut { - tail: self.tail, - head: self.head, - ring: unsafe { self.buffer_as_mut_slice() }, - } + IterMut { tail: self.tail, head: self.head, ring: unsafe { self.buffer_as_mut_slice() } } } /// Returns a pair of slices which contain, in order, the contents of the @@ -1073,7 +1063,8 @@ impl VecDeque { #[inline] #[stable(feature = "drain", since = "1.6.0")] pub fn drain(&mut self, range: R) -> Drain<'_, T> - where R: RangeBounds + where + R: RangeBounds, { // Memory safety // @@ -1089,12 +1080,12 @@ impl VecDeque { let start = match range.start_bound() { Included(&n) => n, Excluded(&n) => n + 1, - Unbounded => 0, + Unbounded => 0, }; let end = match range.end_bound() { Included(&n) => n + 1, Excluded(&n) => n, - Unbounded => len, + Unbounded => len, }; assert!(start <= end, "drain lower bound was too large"); assert!(end <= len, "drain upper bound was too large"); @@ -1174,7 +1165,8 @@ impl VecDeque { /// ``` #[stable(feature = "vec_deque_contains", since = "1.12.0")] pub fn contains(&self, x: &T) -> bool - where T: PartialEq + where + T: PartialEq, { let (a, b) = self.as_slices(); a.contains(x) || b.contains(x) @@ -1197,11 +1189,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn front(&self) -> Option<&T> { - if !self.is_empty() { - Some(&self[0]) - } else { - None - } + if !self.is_empty() { Some(&self[0]) } else { None } } /// Provides a mutable reference to the front element, or `None` if the @@ -1225,11 +1213,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn front_mut(&mut self) -> Option<&mut T> { - if !self.is_empty() { - Some(&mut self[0]) - } else { - None - } + if !self.is_empty() { Some(&mut self[0]) } else { None } } /// Provides a reference to the back element, or `None` if the `VecDeque` is @@ -1249,11 +1233,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn back(&self) -> Option<&T> { - if !self.is_empty() { - Some(&self[self.len() - 1]) - } else { - None - } + if !self.is_empty() { Some(&self[self.len() - 1]) } else { None } } /// Provides a mutable reference to the back element, or `None` if the @@ -1278,11 +1258,7 @@ impl VecDeque { #[stable(feature = "rust1", since = "1.0.0")] pub fn back_mut(&mut self) -> Option<&mut T> { let len = self.len(); - if !self.is_empty() { - Some(&mut self[len - 1]) - } else { - None - } + if !self.is_empty() { Some(&mut self[len - 1]) } else { None } } /// Removes the first element and returns it, or `None` if the `VecDeque` is @@ -1897,22 +1873,24 @@ impl VecDeque { // `at` lies in the first half. let amount_in_first = first_len - at; - ptr::copy_nonoverlapping(first_half.as_ptr().add(at), - other.ptr(), - amount_in_first); + ptr::copy_nonoverlapping(first_half.as_ptr().add(at), other.ptr(), amount_in_first); // just take all of the second half. - ptr::copy_nonoverlapping(second_half.as_ptr(), - other.ptr().add(amount_in_first), - second_len); + ptr::copy_nonoverlapping( + second_half.as_ptr(), + other.ptr().add(amount_in_first), + second_len, + ); } else { // `at` lies in the second half, need to factor in the elements we skipped // in the first half. let offset = at - first_len; let amount_in_second = second_len - offset; - ptr::copy_nonoverlapping(second_half.as_ptr().add(offset), - other.ptr(), - amount_in_second); + ptr::copy_nonoverlapping( + second_half.as_ptr().add(offset), + other.ptr(), + amount_in_second, + ); } } @@ -1979,7 +1957,8 @@ impl VecDeque { /// ``` #[stable(feature = "vec_deque_retain", since = "1.4.0")] pub fn retain(&mut self, mut f: F) - where F: FnMut(&T) -> bool + where + F: FnMut(&T) -> bool, { let len = self.len(); let mut del = 0; @@ -2034,7 +2013,7 @@ impl VecDeque { /// assert_eq!(buf, [5, 10, 101, 102, 103]); /// ``` #[stable(feature = "vec_resize_with", since = "1.33.0")] - pub fn resize_with(&mut self, new_len: usize, generator: impl FnMut()->T) { + pub fn resize_with(&mut self, new_len: usize, generator: impl FnMut() -> T) { let len = self.len(); if new_len > len { @@ -2250,10 +2229,7 @@ pub struct Iter<'a, T: 'a> { impl fmt::Debug for Iter<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail); - f.debug_tuple("Iter") - .field(&front) - .field(&back) - .finish() + f.debug_tuple("Iter").field(&front).field(&back).finish() } } @@ -2261,11 +2237,7 @@ impl fmt::Debug for Iter<'_, T> { #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Iter<'_, T> { fn clone(&self) -> Self { - Iter { - ring: self.ring, - tail: self.tail, - head: self.head, - } + Iter { ring: self.ring, tail: self.tail, head: self.head } } } @@ -2290,7 +2262,8 @@ impl<'a, T> Iterator for Iter<'a, T> { } fn fold(self, mut accum: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc + where + F: FnMut(Acc, Self::Item) -> Acc, { let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail); accum = front.iter().fold(accum, &mut f); @@ -2350,7 +2323,8 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { } fn rfold(self, mut accum: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc + where + F: FnMut(Acc, Self::Item) -> Acc, { let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail); accum = back.iter().rfold(accum, &mut f); @@ -2392,7 +2366,6 @@ impl ExactSizeIterator for Iter<'_, T> { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Iter<'_, T> {} - /// A mutable iterator over the elements of a `VecDeque`. /// /// This `struct` is created by the [`iter_mut`] method on [`VecDeque`]. See its @@ -2411,10 +2384,7 @@ pub struct IterMut<'a, T: 'a> { impl fmt::Debug for IterMut<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let (front, back) = RingSlices::ring_slices(&*self.ring, self.head, self.tail); - f.debug_tuple("IterMut") - .field(&front) - .field(&back) - .finish() + f.debug_tuple("IterMut").field(&front).field(&back).finish() } } @@ -2443,7 +2413,8 @@ impl<'a, T> Iterator for IterMut<'a, T> { } fn fold(self, mut accum: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc + where + F: FnMut(Acc, Self::Item) -> Acc, { let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail); accum = front.iter_mut().fold(accum, &mut f); @@ -2482,7 +2453,8 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { } fn rfold(self, mut accum: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc + where + F: FnMut(Acc, Self::Item) -> Acc, { let (front, back) = RingSlices::ring_slices(self.ring, self.head, self.tail); accum = back.iter_mut().rfold(accum, &mut f); @@ -2516,9 +2488,7 @@ pub struct IntoIter { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("IntoIter") - .field(&self.inner) - .finish() + f.debug_tuple("IntoIter").field(&self.inner).finish() } } @@ -2575,10 +2545,10 @@ pub struct Drain<'a, T: 'a> { impl fmt::Debug for Drain<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Drain") - .field(&self.after_tail) - .field(&self.after_head) - .field(&self.iter) - .finish() + .field(&self.after_tail) + .field(&self.after_head) + .field(&self.iter) + .finish() } } @@ -2835,7 +2805,9 @@ impl Extend for VecDeque { let head = self.head; self.head = self.wrap_add(self.head, 1); - unsafe { self.buffer_write(head, element); } + unsafe { + self.buffer_write(head, element); + } } } } @@ -2873,17 +2845,15 @@ impl From> for VecDeque { // We need to extend the buf if it's not a power of two, too small // or doesn't have at least one free space - if !buf.capacity().is_power_of_two() || (buf.capacity() < (MINIMUM_CAPACITY + 1)) || - (buf.capacity() == len) { + if !buf.capacity().is_power_of_two() + || (buf.capacity() < (MINIMUM_CAPACITY + 1)) + || (buf.capacity() == len) + { let cap = cmp::max(buf.capacity() + 1, MINIMUM_CAPACITY + 1).next_power_of_two(); buf.reserve_exact(len, cap - len); } - VecDeque { - tail: 0, - head: len, - buf, - } + VecDeque { tail: 0, head: len, buf } } } } @@ -2936,9 +2906,7 @@ impl From> for Vec { // do this in at most three copy moves. if (cap - tail) > head { // right hand block is the long one; move that enough for the left - ptr::copy(buf.add(tail), - buf.add(tail - head), - cap - tail); + ptr::copy(buf.add(tail), buf.add(tail - head), cap - tail); // copy left in the end ptr::copy(buf, buf.add(cap - head), head); // shift the new thing to the start @@ -2976,10 +2944,8 @@ impl From> for Vec { let n_ops = right_edge - left_edge; left_edge += n_ops; right_edge += right_offset + 1; - } } - } let out = Vec::from_raw_parts(buf, len, cap); mem::forget(other); diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index b549fa1ef4fc9..fdabf109b2ead 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -58,22 +58,21 @@ #![allow(unused_attributes)] #![stable(feature = "alloc", since = "1.36.0")] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", - issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", - test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))] +#![doc( + html_root_url = "https://doc.rust-lang.org/nightly/", + issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", + test(no_crate_inject, attr(allow(unused_variables), deny(warnings))) +)] #![no_std] #![needs_allocator] - #![warn(deprecated_in_future)] #![warn(missing_docs)] #![warn(missing_debug_implementations)] #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings #![allow(explicit_outlives_requirements)] #![allow(incomplete_features)] - #![cfg_attr(not(test), feature(generator_trait))] #![cfg_attr(test, feature(test))] - #![feature(allocator_api)] #![feature(allow_internal_unstable)] #![feature(arbitrary_self_types)] @@ -150,19 +149,19 @@ pub mod boxed; mod boxed { pub use std::boxed::Box; } -#[cfg(test)] -mod tests; -pub mod collections; -#[cfg(target_has_atomic = "ptr")] -pub mod sync; -pub mod rc; -pub mod raw_vec; -pub mod prelude; pub mod borrow; +pub mod collections; pub mod fmt; +pub mod prelude; +pub mod raw_vec; +pub mod rc; pub mod slice; pub mod str; pub mod string; +#[cfg(target_has_atomic = "ptr")] +pub mod sync; +#[cfg(test)] +mod tests; pub mod vec; #[cfg(not(test))] diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 444450f6628ef..86aed612efe04 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -7,9 +7,9 @@ use core::ops::Drop; use core::ptr::{self, NonNull, Unique}; use core::slice; -use crate::alloc::{Alloc, Layout, Global, AllocErr, handle_alloc_error}; -use crate::collections::TryReserveError::{self, *}; +use crate::alloc::{handle_alloc_error, Alloc, AllocErr, Global, Layout}; use crate::boxed::Box; +use crate::collections::TryReserveError::{self, *}; #[cfg(test)] mod tests; @@ -55,11 +55,7 @@ impl RawVec { let cap = if mem::size_of::() == 0 { core::usize::MAX } else { 0 }; // `Unique::empty()` doubles as "unallocated" and "zero-sized allocation". - RawVec { - ptr: Unique::empty(), - cap, - a, - } + RawVec { ptr: Unique::empty(), cap, a } } /// Like `with_capacity`, but parameterized over the choice of @@ -89,22 +85,14 @@ impl RawVec { } else { let align = mem::align_of::(); let layout = Layout::from_size_align(alloc_size, align).unwrap(); - let result = if zeroed { - a.alloc_zeroed(layout) - } else { - a.alloc(layout) - }; + let result = if zeroed { a.alloc_zeroed(layout) } else { a.alloc(layout) }; match result { Ok(ptr) => ptr.cast(), Err(_) => handle_alloc_error(layout), } }; - RawVec { - ptr: ptr.into(), - cap: capacity, - a, - } + RawVec { ptr: ptr.into(), cap: capacity, a } } } } @@ -168,11 +156,7 @@ impl RawVec { /// The `capacity` cannot exceed `isize::MAX` (only a concern on 32-bit systems). /// If the `ptr` and `capacity` come from a `RawVec` created via `a`, then this is guaranteed. pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, a: A) -> Self { - RawVec { - ptr: Unique::new_unchecked(ptr), - cap: capacity, - a, - } + RawVec { ptr: Unique::new_unchecked(ptr), cap: capacity, a } } } @@ -185,11 +169,7 @@ impl RawVec { /// The `capacity` cannot exceed `isize::MAX` (only a concern on 32-bit systems). /// If the `ptr` and `capacity` come from a `RawVec`, then this is guaranteed. pub unsafe fn from_raw_parts(ptr: *mut T, capacity: usize) -> Self { - RawVec { - ptr: Unique::new_unchecked(ptr), - cap: capacity, - a: Global, - } + RawVec { ptr: Unique::new_unchecked(ptr), cap: capacity, a: Global } } /// Converts a `Box<[T]>` into a `RawVec`. @@ -215,11 +195,7 @@ impl RawVec { /// This will always be `usize::MAX` if `T` is zero-sized. #[inline(always)] pub fn capacity(&self) -> usize { - if mem::size_of::() == 0 { - !0 - } else { - self.cap - } + if mem::size_of::() == 0 { !0 } else { self.cap } } /// Returns a shared reference to the allocator backing this `RawVec`. @@ -319,14 +295,13 @@ impl RawVec { let new_cap = 2 * self.cap; let new_size = new_cap * elem_size; alloc_guard(new_size).unwrap_or_else(|_| capacity_overflow()); - let ptr_res = self.a.realloc(NonNull::from(self.ptr).cast(), - cur, - new_size); + let ptr_res = self.a.realloc(NonNull::from(self.ptr).cast(), cur, new_size); match ptr_res { Ok(ptr) => (new_cap, ptr.cast().into()), - Err(_) => handle_alloc_error( - Layout::from_size_align_unchecked(new_size, cur.align()) - ), + Err(_) => handle_alloc_error(Layout::from_size_align_unchecked( + new_size, + cur.align(), + )), } } None => { @@ -386,17 +361,17 @@ impl RawVec { self.cap = new_cap; true } - Err(_) => { - false - } + Err(_) => false, } } } /// The same as `reserve_exact`, but returns on errors instead of panicking or aborting. - pub fn try_reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) - -> Result<(), TryReserveError> { - + pub fn try_reserve_exact( + &mut self, + used_capacity: usize, + needed_extra_capacity: usize, + ) -> Result<(), TryReserveError> { self.reserve_internal(used_capacity, needed_extra_capacity, Fallible, Exact) } @@ -425,18 +400,20 @@ impl RawVec { Err(CapacityOverflow) => capacity_overflow(), Err(AllocError { .. }) => unreachable!(), Ok(()) => { /* yay */ } - } - } + } + } /// Calculates the buffer's new size given that it'll hold `used_capacity + /// needed_extra_capacity` elements. This logic is used in amortized reserve methods. /// Returns `(new_capacity, new_alloc_size)`. - fn amortized_new_size(&self, used_capacity: usize, needed_extra_capacity: usize) - -> Result { - + fn amortized_new_size( + &self, + used_capacity: usize, + needed_extra_capacity: usize, + ) -> Result { // Nothing we can really do about these checks, sadly. - let required_cap = used_capacity.checked_add(needed_extra_capacity) - .ok_or(CapacityOverflow)?; + let required_cap = + used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?; // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`. let double_cap = self.cap * 2; // `double_cap` guarantees exponential growth. @@ -444,8 +421,11 @@ impl RawVec { } /// The same as `reserve`, but returns on errors instead of panicking or aborting. - pub fn try_reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize) - -> Result<(), TryReserveError> { + pub fn try_reserve( + &mut self, + used_capacity: usize, + needed_extra_capacity: usize, + ) -> Result<(), TryReserveError> { self.reserve_internal(used_capacity, needed_extra_capacity, Fallible, Amortized) } @@ -543,7 +523,8 @@ impl RawVec { return false; } - let new_cap = self.amortized_new_size(used_capacity, needed_extra_capacity) + let new_cap = self + .amortized_new_size(used_capacity, needed_extra_capacity) .unwrap_or_else(|_| capacity_overflow()); // Here, `cap < used_capacity + needed_extra_capacity <= new_cap` @@ -554,15 +535,15 @@ impl RawVec { // FIXME: may crash and burn on over-reserve alloc_guard(new_layout.size()).unwrap_or_else(|_| capacity_overflow()); match self.a.grow_in_place( - NonNull::from(self.ptr).cast(), old_layout, new_layout.size(), + NonNull::from(self.ptr).cast(), + old_layout, + new_layout.size(), ) { Ok(_) => { self.cap = new_cap; true } - Err(_) => { - false - } + Err(_) => false, } } } @@ -615,13 +596,11 @@ impl RawVec { let new_size = elem_size * amount; let align = mem::align_of::(); let old_layout = Layout::from_size_align_unchecked(old_size, align); - match self.a.realloc(NonNull::from(self.ptr).cast(), - old_layout, - new_size) { + match self.a.realloc(NonNull::from(self.ptr).cast(), old_layout, new_size) { Ok(p) => self.ptr = p.cast().into(), - Err(_) => handle_alloc_error( - Layout::from_size_align_unchecked(new_size, align) - ), + Err(_) => { + handle_alloc_error(Layout::from_size_align_unchecked(new_size, align)) + } } } self.cap = amount; @@ -665,7 +644,9 @@ impl RawVec { // Nothing we can really do about these checks, sadly. let new_cap = match strategy { - Exact => used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?, + Exact => { + used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)? + } Amortized => self.amortized_new_size(used_capacity, needed_extra_capacity)?, }; let new_layout = Layout::array::(new_cap).map_err(|_| CapacityOverflow)?; @@ -682,10 +663,12 @@ impl RawVec { let ptr = match (res, fallibility) { (Err(AllocErr), Infallible) => handle_alloc_error(new_layout), - (Err(AllocErr), Fallible) => return Err(TryReserveError::AllocError { - layout: new_layout, - non_exhaustive: (), - }), + (Err(AllocErr), Fallible) => { + return Err(TryReserveError::AllocError { + layout: new_layout, + non_exhaustive: (), + }); + } (Ok(ptr), _) => ptr, }; @@ -695,7 +678,6 @@ impl RawVec { Ok(()) } } - } impl RawVec { @@ -733,7 +715,9 @@ impl RawVec { unsafe impl<#[may_dangle] T, A: Alloc> Drop for RawVec { /// Frees the memory owned by the `RawVec` *without* trying to drop its contents. fn drop(&mut self) { - unsafe { self.dealloc_buffer(); } + unsafe { + self.dealloc_buffer(); + } } } diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index fd26621051981..3080a8bf45966 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -239,20 +239,20 @@ use core::array::LengthAtMost32; use core::borrow; use core::cell::Cell; use core::cmp::Ordering; +use core::convert::{From, TryFrom}; use core::fmt; use core::hash::{Hash, Hasher}; use core::intrinsics::abort; use core::iter; -use core::marker::{self, Unpin, Unsize, PhantomData}; +use core::marker::{self, PhantomData, Unpin, Unsize}; use core::mem::{self, align_of, align_of_val, forget, size_of_val}; -use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}; +use core::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver}; use core::pin::Pin; use core::ptr::{self, NonNull}; use core::slice::{self, from_raw_parts_mut}; -use core::convert::{From, TryFrom}; use core::usize; -use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; +use crate::alloc::{box_free, handle_alloc_error, Alloc, Global, Layout}; use crate::string::String; use crate::vec::Vec; @@ -296,10 +296,7 @@ impl, U: ?Sized> DispatchFromDyn> for Rc {} impl Rc { fn from_inner(ptr: NonNull>) -> Self { - Self { - ptr, - phantom: PhantomData, - } + Self { ptr, phantom: PhantomData } } unsafe fn from_ptr(ptr: *mut RcBox) -> Self { @@ -354,10 +351,9 @@ impl Rc { #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_uninit() -> Rc> { unsafe { - Rc::from_ptr(Rc::allocate_for_layout( - Layout::new::(), - |mem| mem as *mut RcBox>, - )) + Rc::from_ptr(Rc::allocate_for_layout(Layout::new::(), |mem| { + mem as *mut RcBox> + })) } } @@ -466,9 +462,7 @@ impl Rc<[T]> { /// ``` #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_uninit_slice(len: usize) -> Rc<[mem::MaybeUninit]> { - unsafe { - Rc::from_ptr(Rc::allocate_for_slice(len)) - } + unsafe { Rc::from_ptr(Rc::allocate_for_slice(len)) } } } @@ -733,13 +727,7 @@ impl Rc { #[inline] #[stable(feature = "rc_unique", since = "1.4.0")] pub fn get_mut(this: &mut Self) -> Option<&mut T> { - if Rc::is_unique(this) { - unsafe { - Some(Rc::get_mut_unchecked(this)) - } - } else { - None - } + if Rc::is_unique(this) { unsafe { Some(Rc::get_mut_unchecked(this)) } } else { None } } /// Returns a mutable reference into the given `Rc`, @@ -872,9 +860,7 @@ impl Rc { // reference count is guaranteed to be 1 at this point, and we required // the `Rc` itself to be `mut`, so we're returning the only possible // reference to the allocation. - unsafe { - &mut this.ptr.as_mut().value - } + unsafe { &mut this.ptr.as_mut().value } } } @@ -918,19 +904,16 @@ impl Rc { /// and must return back a (potentially fat)-pointer for the `RcBox`. unsafe fn allocate_for_layout( value_layout: Layout, - mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox + mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox, ) -> *mut RcBox { // Calculate layout using the given value layout. // Previously, layout was calculated on the expression // `&*(ptr as *const RcBox)`, but this created a misaligned // reference (see #54908). - let layout = Layout::new::>() - .extend(value_layout).unwrap().0 - .pad_to_align(); + let layout = Layout::new::>().extend(value_layout).unwrap().0.pad_to_align(); // Allocate for the layout. - let mem = Global.alloc(layout) - .unwrap_or_else(|_| handle_alloc_error(layout)); + let mem = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout)); // Initialize the RcBox let inner = mem_to_rcbox(mem.as_ptr()); @@ -945,10 +928,9 @@ impl Rc { /// Allocates an `RcBox` with sufficient space for an unsized inner value unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox { // Allocate for the `RcBox` using the given value. - Self::allocate_for_layout( - Layout::for_value(&*ptr), - |mem| set_data_ptr(ptr as *mut T, mem) as *mut RcBox, - ) + Self::allocate_for_layout(Layout::for_value(&*ptr), |mem| { + set_data_ptr(ptr as *mut T, mem) as *mut RcBox + }) } fn from_box(v: Box) -> Rc { @@ -963,7 +945,8 @@ impl Rc { ptr::copy_nonoverlapping( bptr as *const T as *const u8, &mut (*ptr).value as *mut _ as *mut u8, - value_size); + value_size, + ); // Free the allocation without dropping its contents box_free(box_unique); @@ -976,10 +959,9 @@ impl Rc { impl Rc<[T]> { /// Allocates an `RcBox<[T]>` with the given length. unsafe fn allocate_for_slice(len: usize) -> *mut RcBox<[T]> { - Self::allocate_for_layout( - Layout::array::(len).unwrap(), - |mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut RcBox<[T]>, - ) + Self::allocate_for_layout(Layout::array::(len).unwrap(), |mem| { + ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut RcBox<[T]> + }) } } @@ -999,10 +981,7 @@ impl Rc<[T]> { unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> { let ptr = Self::allocate_for_slice(v.len()); - ptr::copy_nonoverlapping( - v.as_ptr(), - &mut (*ptr).value as *mut [T] as *mut T, - v.len()); + ptr::copy_nonoverlapping(v.as_ptr(), &mut (*ptr).value as *mut [T] as *mut T, v.len()); Self::from_ptr(ptr) } @@ -1040,12 +1019,7 @@ impl Rc<[T]> { // Pointer to first element let elems = &mut (*ptr).value as *mut [T] as *mut T; - let mut guard = Guard { - mem: NonNull::new_unchecked(mem), - elems, - layout, - n_elems: 0, - }; + let mut guard = Guard { mem: NonNull::new_unchecked(mem), elems, layout, n_elems: 0 }; for (i, item) in iter.enumerate() { ptr::write(elems.add(i), item); @@ -1067,9 +1041,7 @@ trait RcFromSlice { impl RcFromSlice for Rc<[T]> { #[inline] default fn from_slice(v: &[T]) -> Self { - unsafe { - Self::from_iter_exact(v.iter().cloned(), v.len()) - } + unsafe { Self::from_iter_exact(v.iter().cloned(), v.len()) } } } @@ -1543,13 +1515,14 @@ impl> RcFromIter for Rc<[T]> { } } -impl> RcFromIter for Rc<[T]> { +impl> RcFromIter for Rc<[T]> { default fn from_iter(iter: I) -> Self { // This is the case for a `TrustedLen` iterator. let (low, high) = iter.size_hint(); if let Some(high) = high { debug_assert_eq!( - low, high, + low, + high, "TrustedLen iterator's size hint is not exact: {:?}", (low, high) ); @@ -1641,9 +1614,7 @@ impl Weak { /// ``` #[stable(feature = "downgraded_weak", since = "1.10.0")] pub fn new() -> Weak { - Weak { - ptr: NonNull::new(usize::MAX as *mut RcBox).expect("MAX is not 0"), - } + Weak { ptr: NonNull::new(usize::MAX as *mut RcBox).expect("MAX is not 0") } } /// Returns a raw pointer to the object `T` pointed to by this `Weak`. @@ -1781,9 +1752,7 @@ impl Weak { let offset = data_offset(ptr); let fake_ptr = ptr as *mut RcBox; let ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); - Weak { - ptr: NonNull::new(ptr).expect("Invalid pointer passed to from_raw"), - } + Weak { ptr: NonNull::new(ptr).expect("Invalid pointer passed to from_raw") } } } } @@ -1838,11 +1807,7 @@ impl Weak { /// [`Weak::new`]: #method.new #[stable(feature = "weak_counts", since = "1.41.0")] pub fn strong_count(&self) -> usize { - if let Some(inner) = self.inner() { - inner.strong() - } else { - 0 - } + if let Some(inner) = self.inner() { inner.strong() } else { 0 } } /// Gets the number of `Weak` pointers pointing to this allocation. @@ -1850,24 +1815,22 @@ impl Weak { /// If no strong pointers remain, this will return zero. #[stable(feature = "weak_counts", since = "1.41.0")] pub fn weak_count(&self) -> usize { - self.inner().map(|inner| { - if inner.strong() > 0 { - inner.weak() - 1 // subtract the implicit weak ptr - } else { - 0 - } - }).unwrap_or(0) + self.inner() + .map(|inner| { + if inner.strong() > 0 { + inner.weak() - 1 // subtract the implicit weak ptr + } else { + 0 + } + }) + .unwrap_or(0) } /// Returns `None` when the pointer is dangling and there is no allocated `RcBox` /// (i.e., when this `Weak` was created by `Weak::new`). #[inline] fn inner(&self) -> Option<&RcBox> { - if is_dangling(self.ptr) { - None - } else { - Some(unsafe { self.ptr.as_ref() }) - } + if is_dangling(self.ptr) { None } else { Some(unsafe { self.ptr.as_ref() }) } } /// Returns `true` if the two `Weak`s point to the same allocation (similar to @@ -2035,7 +1998,9 @@ trait RcBoxPtr { // nevertheless, we insert an abort here to hint LLVM at // an otherwise missed optimization. if strong == 0 || strong == usize::max_value() { - unsafe { abort(); } + unsafe { + abort(); + } } self.inner().strong.set(strong + 1); } @@ -2059,7 +2024,9 @@ trait RcBoxPtr { // nevertheless, we insert an abort here to hint LLVM at // an otherwise missed optimization. if weak == 0 || weak == usize::max_value() { - unsafe { abort(); } + unsafe { + abort(); + } } self.inner().weak.set(weak + 1); } @@ -2073,9 +2040,7 @@ trait RcBoxPtr { impl RcBoxPtr for Rc { #[inline(always)] fn inner(&self) -> &RcBox { - unsafe { - self.ptr.as_ref() - } + unsafe { self.ptr.as_ref() } } } @@ -2101,7 +2066,7 @@ impl AsRef for Rc { } #[stable(feature = "pin", since = "1.33.0")] -impl Unpin for Rc { } +impl Unpin for Rc {} unsafe fn data_offset(ptr: *const T) -> isize { // Align the unsized value to the end of the `RcBox`. diff --git a/src/liballoc/rc/tests.rs b/src/liballoc/rc/tests.rs index bf5c85a5c5960..56788bb56d550 100644 --- a/src/liballoc/rc/tests.rs +++ b/src/liballoc/rc/tests.rs @@ -2,11 +2,11 @@ use super::*; use std::boxed::Box; use std::cell::RefCell; -use std::option::Option::{self, None, Some}; -use std::result::Result::{Err, Ok}; -use std::mem::drop; use std::clone::Clone; use std::convert::{From, TryInto}; +use std::mem::drop; +use std::option::Option::{self, None, Some}; +use std::result::Result::{Err, Ok}; #[test] fn test_clone() { @@ -341,11 +341,8 @@ fn test_clone_from_slice_panic() { } } - let s: &[Fail] = &[ - Fail(0, "foo".to_string()), - Fail(1, "bar".to_string()), - Fail(2, "baz".to_string()), - ]; + let s: &[Fail] = + &[Fail(0, "foo".to_string()), Fail(1, "bar".to_string()), Fail(2, "baz".to_string())]; // Should panic, but not cause memory corruption let _r: Rc<[Fail]> = Rc::from(s); diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 83816d8b954c4..843a2f1f8e9fc 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -23,16 +23,15 @@ //! ``` #![stable(feature = "rust1", since = "1.0.0")] - // Many of the usings in this module are only used in the test configuration. // It's cleaner to just turn off the unused_imports warning than to fix them. #![allow(unused_imports)] use core::borrow::{Borrow, BorrowMut}; -use core::str::pattern::{Pattern, Searcher, ReverseSearcher, DoubleEndedSearcher}; +use core::iter::FusedIterator; use core::mem; use core::ptr; -use core::iter::FusedIterator; +use core::str::pattern::{DoubleEndedSearcher, Pattern, ReverseSearcher, Searcher}; use core::unicode::conversions; use crate::borrow::ToOwned; @@ -42,34 +41,34 @@ use crate::string::String; use crate::vec::Vec; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{FromStr, Utf8Error}; -#[allow(deprecated)] +pub use core::str::pattern; +#[stable(feature = "encode_utf16", since = "1.8.0")] +pub use core::str::EncodeUtf16; +#[stable(feature = "split_ascii_whitespace", since = "1.34.0")] +pub use core::str::SplitAsciiWhitespace; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{Lines, LinesAny}; +pub use core::str::SplitWhitespace; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{Split, RSplit}; +pub use core::str::{from_utf8, from_utf8_mut, Bytes, CharIndices, Chars}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{SplitN, RSplitN}; +pub use core::str::{from_utf8_unchecked, from_utf8_unchecked_mut, ParseBoolError}; +#[stable(feature = "str_escape", since = "1.34.0")] +pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{SplitTerminator, RSplitTerminator}; +pub use core::str::{FromStr, Utf8Error}; +#[allow(deprecated)] #[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{Matches, RMatches}; +pub use core::str::{Lines, LinesAny}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::str::{MatchIndices, RMatchIndices}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{from_utf8, from_utf8_mut, Chars, CharIndices, Bytes}; +pub use core::str::{Matches, RMatches}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{from_utf8_unchecked, from_utf8_unchecked_mut, ParseBoolError}; +pub use core::str::{RSplit, Split}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::SplitWhitespace; +pub use core::str::{RSplitN, SplitN}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::pattern; -#[stable(feature = "encode_utf16", since = "1.8.0")] -pub use core::str::EncodeUtf16; -#[stable(feature = "split_ascii_whitespace", since = "1.34.0")] -pub use core::str::SplitAsciiWhitespace; -#[stable(feature = "str_escape", since = "1.34.0")] -pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode}; +pub use core::str::{RSplitTerminator, SplitTerminator}; /// Note: `str` in `Concat` is not meaningful here. /// This type parameter of the trait only exists to enable another impl. @@ -87,9 +86,7 @@ impl> Join<&str> for [S] { type Output = String; fn join(slice: &Self, sep: &str) -> String { - unsafe { - String::from_utf8_unchecked( join_generic_copy(slice, sep.as_bytes()) ) - } + unsafe { String::from_utf8_unchecked(join_generic_copy(slice, sep.as_bytes())) } } } @@ -123,10 +120,10 @@ macro_rules! spezialize_for_lengths { macro_rules! copy_slice_and_advance { ($target:expr, $bytes:expr) => { let len = $bytes.len(); - let (head, tail) = {$target}.split_at_mut(len); + let (head, tail) = { $target }.split_at_mut(len); head.copy_from_slice($bytes); $target = tail; - } + }; } // Optimized join implementation that works for both Vec (T: Copy) and String's inner vec @@ -156,11 +153,12 @@ where // if the `len` calculation overflows, we'll panic // we would have run out of memory anyway and the rest of the function requires // the entire Vec pre-allocated for safety - let len = sep_len.checked_mul(iter.len()).and_then(|n| { - slice.iter() - .map(|s| s.borrow().as_ref().len()) - .try_fold(n, usize::checked_add) - }).expect("attempt to join into collection with len > usize::MAX"); + let len = sep_len + .checked_mul(iter.len()) + .and_then(|n| { + slice.iter().map(|s| s.borrow().as_ref().len()).try_fold(n, usize::checked_add) + }) + .expect("attempt to join into collection with len > usize::MAX"); // crucial for safety let mut result = Vec::with_capacity(len); @@ -390,13 +388,13 @@ impl str { // See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992 // for the definition of `Final_Sigma`. debug_assert!('Σ'.len_utf8() == 2); - let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev()) && - !case_ignoreable_then_cased(from[i + 2..].chars()); + let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev()) + && !case_ignoreable_then_cased(from[i + 2..].chars()); to.push_str(if is_word_final { "ς" } else { "σ" }); } fn case_ignoreable_then_cased>(iter: I) -> bool { - use core::unicode::derived_property::{Cased, Case_Ignorable}; + use core::unicode::derived_property::{Case_Ignorable, Cased}; match iter.skip_while(|&c| Case_Ignorable(c)).next() { Some(c) => Cased(c), None => false, diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index f880f5915a36a..96f871d889708 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -50,15 +50,15 @@ use core::char::{decode_utf16, REPLACEMENT_CHARACTER}; use core::fmt; use core::hash; use core::iter::{FromIterator, FusedIterator}; -use core::ops::{self, Add, AddAssign, Index, IndexMut, RangeBounds}; use core::ops::Bound::{Excluded, Included, Unbounded}; +use core::ops::{self, Add, AddAssign, Index, IndexMut, RangeBounds}; use core::ptr; -use core::str::{pattern::Pattern, lossy}; +use core::str::{lossy, pattern::Pattern}; use crate::borrow::{Cow, ToOwned}; -use crate::collections::TryReserveError; use crate::boxed::Box; -use crate::str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars}; +use crate::collections::TryReserveError; +use crate::str::{self, from_boxed_utf8_unchecked, Chars, FromStr, Utf8Error}; use crate::vec::Vec; /// A UTF-8 encoded, growable string. @@ -491,12 +491,7 @@ impl String { pub fn from_utf8(vec: Vec) -> Result { match str::from_utf8(&vec) { Ok(..) => Ok(String { vec }), - Err(e) => { - Err(FromUtf8Error { - bytes: vec, - error: e, - }) - } + Err(e) => Err(FromUtf8Error { bytes: vec, error: e }), } } @@ -985,7 +980,7 @@ impl String { /// } /// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?"); /// ``` - #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] + #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")] pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> { self.vec.try_reserve(additional) } @@ -1023,8 +1018,8 @@ impl String { /// } /// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?"); /// ``` - #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] - pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> { + #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")] + pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> { self.vec.try_reserve_exact(additional) } @@ -1072,7 +1067,7 @@ impl String { /// assert!(s.capacity() >= 3); /// ``` #[inline] - #[unstable(feature = "shrink_to", reason = "new API", issue="56431")] + #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")] pub fn shrink_to(&mut self, min_capacity: usize) { self.vec.shrink_to(min_capacity) } @@ -1222,9 +1217,7 @@ impl String { let next = idx + ch.len_utf8(); let len = self.len(); unsafe { - ptr::copy(self.vec.as_ptr().add(next), - self.vec.as_mut_ptr().add(idx), - len - next); + ptr::copy(self.vec.as_ptr().add(next), self.vec.as_mut_ptr().add(idx), len - next); self.vec.set_len(len - (next - idx)); } ch @@ -1258,25 +1251,26 @@ impl String { #[inline] #[stable(feature = "string_retain", since = "1.26.0")] pub fn retain(&mut self, mut f: F) - where F: FnMut(char) -> bool + where + F: FnMut(char) -> bool, { let len = self.len(); let mut del_bytes = 0; let mut idx = 0; while idx < len { - let ch = unsafe { - self.get_unchecked(idx..len).chars().next().unwrap() - }; + let ch = unsafe { self.get_unchecked(idx..len).chars().next().unwrap() }; let ch_len = ch.len_utf8(); if !f(ch) { del_bytes += ch_len; } else if del_bytes > 0 { unsafe { - ptr::copy(self.vec.as_ptr().add(idx), - self.vec.as_mut_ptr().add(idx - del_bytes), - ch_len); + ptr::copy( + self.vec.as_ptr().add(idx), + self.vec.as_mut_ptr().add(idx - del_bytes), + ch_len, + ); } } @@ -1285,7 +1279,9 @@ impl String { } if del_bytes > 0 { - unsafe { self.vec.set_len(len - del_bytes); } + unsafe { + self.vec.set_len(len - del_bytes); + } } } @@ -1331,12 +1327,8 @@ impl String { let amt = bytes.len(); self.vec.reserve(amt); - ptr::copy(self.vec.as_ptr().add(idx), - self.vec.as_mut_ptr().add(idx + amt), - len - idx); - ptr::copy(bytes.as_ptr(), - self.vec.as_mut_ptr().add(idx), - amt); + ptr::copy(self.vec.as_ptr().add(idx), self.vec.as_mut_ptr().add(idx + amt), len - idx); + ptr::copy(bytes.as_ptr(), self.vec.as_mut_ptr().add(idx), amt); self.vec.set_len(len + amt); } @@ -1531,7 +1523,8 @@ impl String { /// ``` #[stable(feature = "drain", since = "1.6.0")] pub fn drain(&mut self, range: R) -> Drain<'_> - where R: RangeBounds + where + R: RangeBounds, { // Memory safety // @@ -1557,12 +1550,7 @@ impl String { // slicing does the appropriate bounds checks let chars_iter = self[start..end].chars(); - Drain { - start, - end, - iter: chars_iter, - string: self_ptr, - } + Drain { start, end, iter: chars_iter, string: self_ptr } } /// Removes the specified range in the string, @@ -1591,7 +1579,8 @@ impl String { /// ``` #[stable(feature = "splice", since = "1.27.0")] pub fn replace_range(&mut self, range: R, replace_with: &str) - where R: RangeBounds + where + R: RangeBounds, { // Memory safety // @@ -1599,19 +1588,17 @@ impl String { // of the vector version. The data is just plain bytes. match range.start_bound() { - Included(&n) => assert!(self.is_char_boundary(n)), - Excluded(&n) => assert!(self.is_char_boundary(n + 1)), - Unbounded => {}, + Included(&n) => assert!(self.is_char_boundary(n)), + Excluded(&n) => assert!(self.is_char_boundary(n + 1)), + Unbounded => {} }; match range.end_bound() { - Included(&n) => assert!(self.is_char_boundary(n + 1)), - Excluded(&n) => assert!(self.is_char_boundary(n)), - Unbounded => {}, + Included(&n) => assert!(self.is_char_boundary(n + 1)), + Excluded(&n) => assert!(self.is_char_boundary(n)), + Unbounded => {} }; - unsafe { - self.as_mut_vec() - }.splice(range, replace_with.bytes()); + unsafe { self.as_mut_vec() }.splice(range, replace_with.bytes()); } /// Converts this `String` into a [`Box`]`<`[`str`]`>`. @@ -1840,9 +1827,11 @@ impl<'a> Extend> for String { } /// A convenience impl that delegates to the impl for `&str` -#[unstable(feature = "pattern", - reason = "API not fully fleshed out and ready to be stabilized", - issue = "27721")] +#[unstable( + feature = "pattern", + reason = "API not fully fleshed out and ready to be stabilized", + issue = "27721" +)] impl<'a, 'b> Pattern<'a> for &'b String { type Searcher = <&'b str as Pattern<'a>>::Searcher; @@ -1879,21 +1868,28 @@ macro_rules! impl_eq { #[allow(unused_lifetimes)] impl<'a, 'b> PartialEq<$rhs> for $lhs { #[inline] - fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&self[..], &other[..]) } + fn eq(&self, other: &$rhs) -> bool { + PartialEq::eq(&self[..], &other[..]) + } #[inline] - fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&self[..], &other[..]) } + fn ne(&self, other: &$rhs) -> bool { + PartialEq::ne(&self[..], &other[..]) + } } #[stable(feature = "rust1", since = "1.0.0")] #[allow(unused_lifetimes)] impl<'a, 'b> PartialEq<$lhs> for $rhs { #[inline] - fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&self[..], &other[..]) } + fn eq(&self, other: &$lhs) -> bool { + PartialEq::eq(&self[..], &other[..]) + } #[inline] - fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&self[..], &other[..]) } + fn ne(&self, other: &$lhs) -> bool { + PartialEq::ne(&self[..], &other[..]) + } } - - } + }; } impl_eq! { String, str } @@ -2134,7 +2130,6 @@ impl FromStr for String { } } - /// A trait for converting a value to a `String`. /// /// This trait is automatically implemented for any type which implements the @@ -2175,7 +2170,7 @@ impl ToString for T { use fmt::Write; let mut buf = String::new(); buf.write_fmt(format_args!("{}", self)) - .expect("a Display implementation returned an error unexpectedly"); + .expect("a Display implementation returned an error unexpectedly"); buf.shrink_to_fit(); buf } diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 3343384754f51..dc53ad2840727 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -8,24 +8,24 @@ use core::any::Any; use core::array::LengthAtMost32; -use core::sync::atomic; -use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst}; use core::borrow; -use core::fmt; use core::cmp::Ordering; -use core::iter; +use core::convert::{From, TryFrom}; +use core::fmt; +use core::hash::{Hash, Hasher}; use core::intrinsics::abort; +use core::iter; +use core::marker::{PhantomData, Unpin, Unsize}; use core::mem::{self, align_of, align_of_val, size_of_val}; -use core::ops::{Deref, Receiver, CoerceUnsized, DispatchFromDyn}; +use core::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver}; use core::pin::Pin; use core::ptr::{self, NonNull}; -use core::marker::{Unpin, Unsize, PhantomData}; -use core::hash::{Hash, Hasher}; -use core::{isize, usize}; -use core::convert::{From, TryFrom}; use core::slice::{self, from_raw_parts_mut}; +use core::sync::atomic; +use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst}; +use core::{isize, usize}; -use crate::alloc::{Global, Alloc, Layout, box_free, handle_alloc_error}; +use crate::alloc::{box_free, handle_alloc_error, Alloc, Global, Layout}; use crate::boxed::Box; use crate::rc::is_dangling; use crate::string::String; @@ -211,10 +211,7 @@ impl, U: ?Sized> DispatchFromDyn> for Arc {} impl Arc { fn from_inner(ptr: NonNull>) -> Self { - Self { - ptr, - phantom: PhantomData, - } + Self { ptr, phantom: PhantomData } } unsafe fn from_ptr(ptr: *mut ArcInner) -> Self { @@ -334,10 +331,9 @@ impl Arc { #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_uninit() -> Arc> { unsafe { - Arc::from_ptr(Arc::allocate_for_layout( - Layout::new::(), - |mem| mem as *mut ArcInner>, - )) + Arc::from_ptr(Arc::allocate_for_layout(Layout::new::(), |mem| { + mem as *mut ArcInner> + })) } } @@ -446,9 +442,7 @@ impl Arc<[T]> { /// ``` #[unstable(feature = "new_uninit", issue = "63291")] pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit]> { - unsafe { - Arc::from_ptr(Arc::allocate_for_slice(len)) - } + unsafe { Arc::from_ptr(Arc::allocate_for_slice(len)) } } } @@ -772,18 +766,15 @@ impl Arc { /// and must return back a (potentially fat)-pointer for the `ArcInner`. unsafe fn allocate_for_layout( value_layout: Layout, - mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner + mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner, ) -> *mut ArcInner { // Calculate layout using the given value layout. // Previously, layout was calculated on the expression // `&*(ptr as *const ArcInner)`, but this created a misaligned // reference (see #54908). - let layout = Layout::new::>() - .extend(value_layout).unwrap().0 - .pad_to_align(); + let layout = Layout::new::>().extend(value_layout).unwrap().0.pad_to_align(); - let mem = Global.alloc(layout) - .unwrap_or_else(|_| handle_alloc_error(layout)); + let mem = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout)); // Initialize the ArcInner let inner = mem_to_arcinner(mem.as_ptr()); @@ -798,10 +789,9 @@ impl Arc { /// Allocates an `ArcInner` with sufficient space for an unsized inner value. unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner { // Allocate for the `ArcInner` using the given value. - Self::allocate_for_layout( - Layout::for_value(&*ptr), - |mem| set_data_ptr(ptr as *mut T, mem) as *mut ArcInner, - ) + Self::allocate_for_layout(Layout::for_value(&*ptr), |mem| { + set_data_ptr(ptr as *mut T, mem) as *mut ArcInner + }) } fn from_box(v: Box) -> Arc { @@ -816,7 +806,8 @@ impl Arc { ptr::copy_nonoverlapping( bptr as *const T as *const u8, &mut (*ptr).data as *mut _ as *mut u8, - value_size); + value_size, + ); // Free the allocation without dropping its contents box_free(box_unique); @@ -829,10 +820,9 @@ impl Arc { impl Arc<[T]> { /// Allocates an `ArcInner<[T]>` with the given length. unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[T]> { - Self::allocate_for_layout( - Layout::array::(len).unwrap(), - |mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut ArcInner<[T]>, - ) + Self::allocate_for_layout(Layout::array::(len).unwrap(), |mem| { + ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut ArcInner<[T]> + }) } } @@ -852,10 +842,7 @@ impl Arc<[T]> { unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> { let ptr = Self::allocate_for_slice(v.len()); - ptr::copy_nonoverlapping( - v.as_ptr(), - &mut (*ptr).data as *mut [T] as *mut T, - v.len()); + ptr::copy_nonoverlapping(v.as_ptr(), &mut (*ptr).data as *mut [T] as *mut T, v.len()); Self::from_ptr(ptr) } @@ -893,12 +880,7 @@ impl Arc<[T]> { // Pointer to first element let elems = &mut (*ptr).data as *mut [T] as *mut T; - let mut guard = Guard { - mem: NonNull::new_unchecked(mem), - elems, - layout, - n_elems: 0, - }; + let mut guard = Guard { mem: NonNull::new_unchecked(mem), elems, layout, n_elems: 0 }; for (i, item) in iter.enumerate() { ptr::write(elems.add(i), item); @@ -920,9 +902,7 @@ trait ArcFromSlice { impl ArcFromSlice for Arc<[T]> { #[inline] default fn from_slice(v: &[T]) -> Self { - unsafe { - Self::from_iter_exact(v.iter().cloned(), v.len()) - } + unsafe { Self::from_iter_exact(v.iter().cloned(), v.len()) } } } @@ -1079,9 +1059,7 @@ impl Arc { // As with `get_mut()`, the unsafety is ok because our reference was // either unique to begin with, or became one upon cloning the contents. - unsafe { - &mut this.ptr.as_mut().data - } + unsafe { &mut this.ptr.as_mut().data } } } @@ -1121,9 +1099,7 @@ impl Arc { // reference count is guaranteed to be 1 at this point, and we required // the Arc itself to be `mut`, so we're returning the only possible // reference to the inner data. - unsafe { - Some(Arc::get_mut_unchecked(this)) - } + unsafe { Some(Arc::get_mut_unchecked(this)) } } else { None } @@ -1317,9 +1293,7 @@ impl Weak { /// ``` #[stable(feature = "downgraded_weak", since = "1.10.0")] pub fn new() -> Weak { - Weak { - ptr: NonNull::new(usize::MAX as *mut ArcInner).expect("MAX is not 0"), - } + Weak { ptr: NonNull::new(usize::MAX as *mut ArcInner).expect("MAX is not 0") } } /// Returns a raw pointer to the object `T` pointed to by this `Weak`. @@ -1458,9 +1432,7 @@ impl Weak { let offset = data_offset(ptr); let fake_ptr = ptr as *mut ArcInner; let ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); - Weak { - ptr: NonNull::new(ptr).expect("Invalid pointer passed to from_raw"), - } + Weak { ptr: NonNull::new(ptr).expect("Invalid pointer passed to from_raw") } } } } @@ -1531,11 +1503,7 @@ impl Weak { /// [`Weak::new`]: #method.new #[stable(feature = "weak_counts", since = "1.41.0")] pub fn strong_count(&self) -> usize { - if let Some(inner) = self.inner() { - inner.strong.load(SeqCst) - } else { - 0 - } + if let Some(inner) = self.inner() { inner.strong.load(SeqCst) } else { 0 } } /// Gets an approximation of the number of `Weak` pointers pointing to this @@ -1553,31 +1521,29 @@ impl Weak { /// [`Weak::new`]: #method.new #[stable(feature = "weak_counts", since = "1.41.0")] pub fn weak_count(&self) -> usize { - self.inner().map(|inner| { - let weak = inner.weak.load(SeqCst); - let strong = inner.strong.load(SeqCst); - if strong == 0 { - 0 - } else { - // Since we observed that there was at least one strong pointer - // after reading the weak count, we know that the implicit weak - // reference (present whenever any strong references are alive) - // was still around when we observed the weak count, and can - // therefore safely subtract it. - weak - 1 - } - }).unwrap_or(0) + self.inner() + .map(|inner| { + let weak = inner.weak.load(SeqCst); + let strong = inner.strong.load(SeqCst); + if strong == 0 { + 0 + } else { + // Since we observed that there was at least one strong pointer + // after reading the weak count, we know that the implicit weak + // reference (present whenever any strong references are alive) + // was still around when we observed the weak count, and can + // therefore safely subtract it. + weak - 1 + } + }) + .unwrap_or(0) } /// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`, /// (i.e., when this `Weak` was created by `Weak::new`). #[inline] fn inner(&self) -> Option<&ArcInner> { - if is_dangling(self.ptr) { - None - } else { - Some(unsafe { self.ptr.as_ref() }) - } + if is_dangling(self.ptr) { None } else { Some(unsafe { self.ptr.as_ref() }) } } /// Returns `true` if the two `Weak`s point to the same allocation (similar to @@ -1722,17 +1688,11 @@ impl Drop for Weak { // weak count can only be locked if there was precisely one weak ref, // meaning that drop could only subsequently run ON that remaining weak // ref, which can only happen after the lock is released. - let inner = if let Some(inner) = self.inner() { - inner - } else { - return - }; + let inner = if let Some(inner) = self.inner() { inner } else { return }; if inner.weak.fetch_sub(1, Release) == 1 { atomic::fence(Acquire); - unsafe { - Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref())) - } + unsafe { Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref())) } } } } @@ -2110,7 +2070,8 @@ impl> ArcFromIter for Arc<[T]> { let (low, high) = iter.size_hint(); if let Some(high) = high { debug_assert_eq!( - low, high, + low, + high, "TrustedLen iterator's size hint is not exact: {:?}", (low, high) ); @@ -2155,7 +2116,7 @@ impl AsRef for Arc { } #[stable(feature = "pin", since = "1.33.0")] -impl Unpin for Arc { } +impl Unpin for Arc {} /// Computes the offset of the data field within `ArcInner`. unsafe fn data_offset(ptr: *const T) -> isize { diff --git a/src/liballoc/sync/tests.rs b/src/liballoc/sync/tests.rs index 8f516129cd00f..edc2820ee22f1 100644 --- a/src/liballoc/sync/tests.rs +++ b/src/liballoc/sync/tests.rs @@ -2,14 +2,17 @@ use super::*; use std::boxed::Box; use std::clone::Clone; -use std::sync::mpsc::channel; +use std::convert::{From, TryInto}; use std::mem::drop; use std::ops::Drop; use std::option::Option::{self, None, Some}; -use std::sync::atomic::{self, Ordering::{Acquire, SeqCst}}; -use std::thread; +use std::sync::atomic::{ + self, + Ordering::{Acquire, SeqCst}, +}; +use std::sync::mpsc::channel; use std::sync::Mutex; -use std::convert::{From, TryInto}; +use std::thread; use crate::vec::Vec; @@ -394,11 +397,8 @@ fn test_clone_from_slice_panic() { } } - let s: &[Fail] = &[ - Fail(0, "foo".to_string()), - Fail(1, "bar".to_string()), - Fail(2, "baz".to_string()), - ]; + let s: &[Fail] = + &[Fail(0, "foo".to_string()), Fail(1, "bar".to_string()), Fail(2, "baz".to_string())]; // Should panic, but not cause memory corruption let _r: Arc<[Fail]> = Arc::from(s); diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index a896a1064d9e1..f49ca7139212f 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -1,5 +1,5 @@ -use std::collections::BinaryHeap; use std::collections::binary_heap::{Drain, PeekMut}; +use std::collections::BinaryHeap; use std::iter::TrustedLen; #[test] @@ -349,10 +349,10 @@ fn assert_covariance() { #[test] #[cfg(not(target_os = "emscripten"))] fn panic_safe() { + use rand::{seq::SliceRandom, thread_rng}; use std::cmp; use std::panic::{self, AssertUnwindSafe}; use std::sync::atomic::{AtomicUsize, Ordering}; - use rand::{thread_rng, seq::SliceRandom}; static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); @@ -389,10 +389,8 @@ fn panic_safe() { for i in 1..=DATASZ { DROP_COUNTER.store(0, Ordering::SeqCst); - let mut panic_ords: Vec<_> = data.iter() - .filter(|&&x| x != i) - .map(|&x| PanicOrd(x, false)) - .collect(); + let mut panic_ords: Vec<_> = + data.iter().filter(|&&x| x != i).map(|&x| PanicOrd(x, false)).collect(); let panic_item = PanicOrd(i, true); // heapify the sane items diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index 27843aeaeb0c8..3177f19927eda 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -1,8 +1,8 @@ -use std::collections::BTreeMap; use std::collections::btree_map::Entry::{Occupied, Vacant}; +use std::collections::BTreeMap; +use std::iter::FromIterator; use std::ops::Bound::{self, Excluded, Included, Unbounded}; use std::rc::Rc; -use std::iter::FromIterator; use super::DeterministicRng; @@ -101,7 +101,8 @@ fn test_iter() { let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); fn test(size: usize, mut iter: T) - where T: Iterator + where + T: Iterator, { for i in 0..size { assert_eq!(iter.size_hint(), (size - i, Some(size - i))); @@ -126,7 +127,8 @@ fn test_iter_rev() { let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); fn test(size: usize, mut iter: T) - where T: Iterator + where + T: Iterator, { for i in 0..size { assert_eq!(iter.size_hint(), (size - i, Some(size - i))); @@ -165,7 +167,8 @@ fn test_iter_mixed() { let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); fn test(size: usize, mut iter: T) - where T: Iterator + DoubleEndedIterator + where + T: Iterator + DoubleEndedIterator, { for i in 0..size / 4 { assert_eq!(iter.size_hint(), (size - i * 2, Some(size - i * 2))); @@ -207,8 +210,9 @@ fn test_range_inclusive() { let map: BTreeMap<_, _> = (0..=size).map(|i| (i, i)).collect(); fn check<'a, L, R>(lhs: L, rhs: R) - where L: IntoIterator, - R: IntoIterator, + where + L: IntoIterator, + R: IntoIterator, { let lhs: Vec<_> = lhs.into_iter().collect(); let rhs: Vec<_> = rhs.into_iter().collect(); @@ -313,7 +317,7 @@ fn test_range_borrowed_key() { map.insert("coyote".to_string(), 3); map.insert("dingo".to_string(), 4); // NOTE: would like to use simply "b".."d" here... - let mut iter = map.range::((Included("b"),Excluded("d"))); + let mut iter = map.range::((Included("b"), Excluded("d"))); assert_eq!(iter.next(), Some((&"baboon".to_string(), &2))); assert_eq!(iter.next(), Some((&"coyote".to_string(), &3))); assert_eq!(iter.next(), None); @@ -408,7 +412,6 @@ fn test_entry() { assert_eq!(map.get(&1).unwrap(), &100); assert_eq!(map.len(), 6); - // Existing key (update) match map.entry(2) { Vacant(_) => unreachable!(), @@ -430,7 +433,6 @@ fn test_entry() { assert_eq!(map.get(&3), None); assert_eq!(map.len(), 5); - // Inexistent key (insert) match map.entry(10) { Occupied(_) => unreachable!(), @@ -555,7 +557,7 @@ fn test_clone() { #[test] #[allow(dead_code)] fn test_variance() { - use std::collections::btree_map::{Iter, IntoIter, Range, Keys, Values}; + use std::collections::btree_map::{IntoIter, Iter, Keys, Range, Values}; fn map_key<'new>(v: BTreeMap<&'static str, ()>) -> BTreeMap<&'new str, ()> { v @@ -649,7 +651,6 @@ fn test_first_last_entry() { assert_eq!(a.last_entry().unwrap().key(), &1); } - macro_rules! create_append_test { ($name:ident, $len:expr) => { #[test] @@ -661,7 +662,7 @@ macro_rules! create_append_test { let mut b = BTreeMap::new(); for i in 5..$len { - b.insert(i, 2*i); + b.insert(i, 2 * i); } a.append(&mut b); @@ -673,12 +674,12 @@ macro_rules! create_append_test { if i < 5 { assert_eq!(a[&i], i); } else { - assert_eq!(a[&i], 2*i); + assert_eq!(a[&i], 2 * i); } } - assert_eq!(a.remove(&($len-1)), Some(2*($len-1))); - assert_eq!(a.insert($len-1, 20), None); + assert_eq!(a.remove(&($len - 1)), Some(2 * ($len - 1))); + assert_eq!(a.insert($len - 1, 20), None); } }; } diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs index 13cd26280227e..ed29ed62b1b3e 100644 --- a/src/liballoc/tests/btree/set.rs +++ b/src/liballoc/tests/btree/set.rs @@ -32,7 +32,8 @@ fn test_hash() { } fn check(a: &[i32], b: &[i32], expected: &[i32], f: F) - where F: FnOnce(&BTreeSet, &BTreeSet, &mut dyn FnMut(&i32) -> bool) -> bool +where + F: FnOnce(&BTreeSet, &BTreeSet, &mut dyn FnMut(&i32) -> bool) -> bool, { let mut set_a = BTreeSet::new(); let mut set_b = BTreeSet::new(); @@ -45,15 +46,13 @@ fn check(a: &[i32], b: &[i32], expected: &[i32], f: F) } let mut i = 0; - f(&set_a, - &set_b, - &mut |&x| { - if i < expected.len() { - assert_eq!(x, expected[i]); - } - i += 1; - true - }); + f(&set_a, &set_b, &mut |&x| { + if i < expected.len() { + assert_eq!(x, expected[i]); + } + i += 1; + true + }); assert_eq!(i, expected.len()); } @@ -68,11 +67,10 @@ fn test_intersection() { check_intersection(&[], &[1, 2, 3], &[]); check_intersection(&[2], &[1, 2, 3], &[2]); check_intersection(&[1, 2, 3], &[2], &[2]); - check_intersection(&[11, 1, 3, 77, 103, 5, -5], - &[2, 11, 77, -9, -42, 5, 3], - &[3, 5, 11, 77]); + check_intersection(&[11, 1, 3, 77, 103, 5, -5], &[2, 11, 77, -9, -42, 5, 3], &[3, 5, 11, 77]); - if cfg!(miri) { // Miri is too slow + if cfg!(miri) { + // Miri is too slow return; } @@ -87,9 +85,7 @@ fn test_intersection() { check_intersection(&large, &[99], &[99]); check_intersection(&[100], &large, &[]); check_intersection(&large, &[100], &[]); - check_intersection(&[11, 5000, 1, 3, 77, 8924], - &large, - &[1, 3, 11, 77]); + check_intersection(&[11, 5000, 1, 3, 77, 8924], &large, &[1, 3, 11, 77]); } #[test] @@ -121,11 +117,14 @@ fn test_difference() { check_difference(&[1, 3, 5, 9, 11], &[3, 6, 9], &[1, 5, 11]); check_difference(&[1, 3, 5, 9, 11], &[0, 1], &[3, 5, 9, 11]); check_difference(&[1, 3, 5, 9, 11], &[11, 12], &[1, 3, 5, 9]); - check_difference(&[-5, 11, 22, 33, 40, 42], - &[-12, -5, 14, 23, 34, 38, 39, 50], - &[11, 22, 33, 40, 42]); - - if cfg!(miri) { // Miri is too slow + check_difference( + &[-5, 11, 22, 33, 40, 42], + &[-12, -5, 14, 23, 34, 38, 39, 50], + &[11, 22, 33, 40, 42], + ); + + if cfg!(miri) { + // Miri is too slow return; } @@ -135,9 +134,7 @@ fn test_difference() { check_difference(&[0], &large, &[]); check_difference(&[99], &large, &[]); check_difference(&[100], &large, &[100]); - check_difference(&[11, 5000, 1, 3, 77, 8924], - &large, - &[5000, 8924]); + check_difference(&[11, 5000, 1, 3, 77, 8924], &large, &[5000, 8924]); check_difference(&large, &[], &large); check_difference(&large, &[-1], &large); check_difference(&large, &[100], &large); @@ -216,9 +213,7 @@ fn test_symmetric_difference() { check_symmetric_difference(&[], &[], &[]); check_symmetric_difference(&[1, 2, 3], &[2], &[1, 3]); check_symmetric_difference(&[2], &[1, 2, 3], &[1, 3]); - check_symmetric_difference(&[1, 3, 5, 9, 11], - &[-2, 3, 9, 14, 22], - &[-2, 1, 5, 11, 14, 22]); + check_symmetric_difference(&[1, 3, 5, 9, 11], &[-2, 3, 9, 14, 22], &[-2, 1, 5, 11, 14, 22]); } #[test] @@ -242,9 +237,11 @@ fn test_union() { check_union(&[], &[], &[]); check_union(&[1, 2, 3], &[2], &[1, 2, 3]); check_union(&[2], &[1, 2, 3], &[1, 2, 3]); - check_union(&[1, 3, 5, 9, 11, 16, 19, 24], - &[-2, 1, 5, 9, 13, 19], - &[-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]); + check_union( + &[1, 3, 5, 9, 11, 16, 19, 24], + &[-2, 1, 5, 9, 13, 19], + &[-2, 1, 3, 5, 9, 11, 13, 16, 19, 24], + ); } #[test] @@ -285,14 +282,14 @@ fn test_is_subset() { assert_eq!(is_subset(&[1, 2], &[1]), false); assert_eq!(is_subset(&[1, 2], &[1, 2]), true); assert_eq!(is_subset(&[1, 2], &[2, 3]), false); - assert_eq!(is_subset(&[-5, 11, 22, 33, 40, 42], - &[-12, -5, 11, 14, 22, 23, 33, 34, 38, 39, 40, 42]), - true); - assert_eq!(is_subset(&[-5, 11, 22, 33, 40, 42], - &[-12, -5, 11, 14, 22, 23, 34, 38]), - false); - - if cfg!(miri) { // Miri is too slow + assert_eq!( + is_subset(&[-5, 11, 22, 33, 40, 42], &[-12, -5, 11, 14, 22, 23, 33, 34, 38, 39, 40, 42]), + true + ); + assert_eq!(is_subset(&[-5, 11, 22, 33, 40, 42], &[-12, -5, 11, 14, 22, 23, 34, 38]), false); + + if cfg!(miri) { + // Miri is too slow return; } diff --git a/src/liballoc/tests/heap.rs b/src/liballoc/tests/heap.rs index 904b3e7e1b07c..43cd7187823f0 100644 --- a/src/liballoc/tests/heap.rs +++ b/src/liballoc/tests/heap.rs @@ -1,4 +1,4 @@ -use std::alloc::{Global, Alloc, Layout, System}; +use std::alloc::{Alloc, Global, Layout, System}; /// Issue #45955 and #62251. #[test] @@ -12,16 +12,23 @@ fn std_heap_overaligned_request() { } fn check_overalign_requests(mut allocator: T) { - for &align in &[4, 8, 16, 32] { // less than and bigger than `MIN_ALIGN` - for &size in &[align/2, align-1] { // size less than alignment + for &align in &[4, 8, 16, 32] { + // less than and bigger than `MIN_ALIGN` + for &size in &[align / 2, align - 1] { + // size less than alignment let iterations = 128; unsafe { - let pointers: Vec<_> = (0..iterations).map(|_| { - allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap() - }).collect(); + let pointers: Vec<_> = (0..iterations) + .map(|_| { + allocator.alloc(Layout::from_size_align(size, align).unwrap()).unwrap() + }) + .collect(); for &ptr in &pointers { - assert_eq!((ptr.as_ptr() as usize) % align, 0, - "Got a pointer less aligned than requested") + assert_eq!( + (ptr.as_ptr() as usize) % align, + 0, + "Got a pointer less aligned than requested" + ) } // Clean up diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 605e0ef55d707..3fdee8bbfdf10 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -12,8 +12,8 @@ #![feature(binary_heap_into_iter_sorted)] #![feature(binary_heap_drain_sorted)] -use std::hash::{Hash, Hasher}; use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; mod arc; mod binary_heap; @@ -27,8 +27,8 @@ mod rc; mod slice; mod str; mod string; -mod vec_deque; mod vec; +mod vec_deque; fn hash(t: &T) -> u64 { let mut s = DefaultHasher::new(); diff --git a/src/liballoc/tests/linked_list.rs b/src/liballoc/tests/linked_list.rs index 54a77d643cbe3..b7736515b262a 100644 --- a/src/liballoc/tests/linked_list.rs +++ b/src/liballoc/tests/linked_list.rs @@ -531,7 +531,6 @@ fn drain_filter_complex() { } } - #[test] fn test_drop() { static mut DROPS: i32 = 0; diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index ec45de7c79e28..51ddb5e7a4ec6 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -3,11 +3,11 @@ use std::cmp::Ordering::{self, Equal, Greater, Less}; use std::mem; use std::panic; use std::rc::Rc; -use std::sync::atomic::{Ordering::Relaxed, AtomicUsize}; +use std::sync::atomic::{AtomicUsize, Ordering::Relaxed}; -use rand::{Rng, RngCore, thread_rng}; -use rand::seq::SliceRandom; use rand::distributions::Standard; +use rand::seq::SliceRandom; +use rand::{thread_rng, Rng, RngCore}; fn square(n: usize) -> usize { n * n @@ -231,7 +231,6 @@ fn test_slice_to() { assert_eq!(&vec[..0], b); } - #[test] fn test_pop() { let mut v = vec![5]; @@ -395,10 +394,8 @@ fn test_sort() { for len in (2..25).chain(500..510) { for &modulus in &[5, 10, 100, 1000] { for _ in 0..10 { - let orig: Vec<_> = rng.sample_iter::(&Standard) - .map(|x| x % modulus) - .take(len) - .collect(); + let orig: Vec<_> = + rng.sample_iter::(&Standard).map(|x| x % modulus).take(len).collect(); // Sort in default order. let mut v = orig.clone(); @@ -543,7 +540,7 @@ fn test_rotate_left() { // non-small prime rotation, has a few rounds of swapping v = (389..1000).chain(0..389).collect(); - v.rotate_left(1000-389); + v.rotate_left(1000 - 389); assert_eq!(v, expected); } @@ -697,7 +694,7 @@ macro_rules! assert_order { (Equal, $a:expr, $b:expr) => { assert_eq!($a.cmp($b), Equal); assert_eq!($a, $b); - } + }; } #[test] @@ -714,7 +711,6 @@ fn test_total_ord_u8() { assert_order!(Greater, &[2u8, 2][..], &c[..]); } - #[test] fn test_total_ord_i32() { let c = &[1, 2, 3]; @@ -804,7 +800,6 @@ fn test_mut_iterator() { #[test] fn test_rev_iterator() { - let xs = [1, 2, 5, 10, 11]; let ys = [11, 10, 5, 2, 1]; let mut i = 0; @@ -827,15 +822,13 @@ fn test_mut_rev_iterator() { #[test] fn test_move_iterator() { let xs = vec![1, 2, 3, 4, 5]; - assert_eq!(xs.into_iter().fold(0, |a: usize, b: usize| 10 * a + b), - 12345); + assert_eq!(xs.into_iter().fold(0, |a: usize, b: usize| 10 * a + b), 12345); } #[test] fn test_move_rev_iterator() { let xs = vec![1, 2, 3, 4, 5]; - assert_eq!(xs.into_iter().rev().fold(0, |a: usize, b: usize| 10 * a + b), - 54321); + assert_eq!(xs.into_iter().rev().fold(0, |a: usize, b: usize| 10 * a + b), 54321); } #[test] @@ -879,11 +872,9 @@ fn test_splitnator_mut() { let xs = &mut [1, 2, 3, 4, 5]; let splits: &[&mut [_]] = &[&mut [1, 2, 3, 4, 5]]; - assert_eq!(xs.splitn_mut(1, |x| *x % 2 == 0).collect::>(), - splits); + assert_eq!(xs.splitn_mut(1, |x| *x % 2 == 0).collect::>(), splits); let splits: &[&mut [_]] = &[&mut [1], &mut [3, 4, 5]]; - assert_eq!(xs.splitn_mut(2, |x| *x % 2 == 0).collect::>(), - splits); + assert_eq!(xs.splitn_mut(2, |x| *x % 2 == 0).collect::>(), splits); let splits: &[&mut [_]] = &[&mut [], &mut [], &mut [], &mut [4, 5]]; assert_eq!(xs.splitn_mut(4, |_| true).collect::>(), splits); @@ -1055,11 +1046,11 @@ fn test_reverse_part() { #[test] fn test_show() { macro_rules! test_show_vec { - ($x:expr, $x_str:expr) => ({ + ($x:expr, $x_str:expr) => {{ let (x, x_str) = ($x, $x_str); assert_eq!(format!("{:?}", x), x_str); assert_eq!(format!("{:?}", x), x_str); - }) + }}; } let empty = Vec::::new(); test_show_vec!(empty, "[]"); @@ -1083,7 +1074,7 @@ fn test_vec_default() { ($ty:ty) => {{ let v: $ty = Default::default(); assert!(v.is_empty()); - }} + }}; } t!(&[i32]); @@ -1406,8 +1397,8 @@ fn test_box_slice_clone() { #[allow(unused_must_use)] // here, we care about the side effects of `.clone()` #[cfg_attr(target_os = "emscripten", ignore)] fn test_box_slice_clone_panics() { - use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; + use std::sync::Arc; struct Canary { count: Arc, @@ -1426,32 +1417,23 @@ fn test_box_slice_clone_panics() { panic!() } - Canary { - count: self.count.clone(), - panics: self.panics, - } + Canary { count: self.count.clone(), panics: self.panics } } } let drop_count = Arc::new(AtomicUsize::new(0)); - let canary = Canary { - count: drop_count.clone(), - panics: false, - }; - let panic = Canary { - count: drop_count.clone(), - panics: true, - }; + let canary = Canary { count: drop_count.clone(), panics: false }; + let panic = Canary { count: drop_count.clone(), panics: true }; std::panic::catch_unwind(move || { - // When xs is dropped, +5. - let xs = vec![canary.clone(), canary.clone(), canary.clone(), panic, canary] - .into_boxed_slice(); + // When xs is dropped, +5. + let xs = + vec![canary.clone(), canary.clone(), canary.clone(), panic, canary].into_boxed_slice(); - // When panic is cloned, +3. - xs.clone(); - }) - .unwrap_err(); + // When panic is cloned, +3. + xs.clone(); + }) + .unwrap_err(); // Total = 8 assert_eq!(drop_count.load(Ordering::SeqCst), 8); @@ -1485,26 +1467,86 @@ const MAX_LEN: usize = 80; static DROP_COUNTS: [AtomicUsize; MAX_LEN] = [ // FIXME(RFC 1109): AtomicUsize is not Copy. - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), + AtomicUsize::new(0), ]; static VERSIONS: AtomicUsize = AtomicUsize::new(0); @@ -1551,7 +1593,10 @@ macro_rules! test { // Work out the total number of comparisons required to sort // this array... let mut count = 0usize; - $input.to_owned().$func(|a, b| { count += 1; a.cmp(b) }); + $input.to_owned().$func(|a, b| { + count += 1; + a.cmp(b) + }); // ... and then panic on each and every single one. for panic_countdown in 0..count { @@ -1579,15 +1624,13 @@ macro_rules! test { // what we expect (i.e., the contents of `v`). for (i, c) in DROP_COUNTS.iter().enumerate().take(len) { let count = c.load(Relaxed); - assert!(count == 1, - "found drop count == {} for i == {}, len == {}", - count, i, len); + assert!(count == 1, "found drop count == {} for i == {}, len == {}", count, i, len); } // Check that the most recent versions of values were dropped. assert_eq!(VERSIONS.load(Relaxed), 0); } - } + }; } thread_local!(static SILENCE_PANIC: Cell = Cell::new(false)); @@ -1618,12 +1661,10 @@ fn panic_safe() { for &modulus in moduli { for &has_runs in &[false, true] { let mut input = (0..len) - .map(|id| { - DropCounter { - x: rng.next_u32() % modulus, - id: id, - version: Cell::new(0), - } + .map(|id| DropCounter { + x: rng.next_u32() % modulus, + id: id, + version: Cell::new(0), }) .collect::>(); @@ -1658,8 +1699,5 @@ fn repeat_generic_slice() { assert_eq!([1, 2].repeat(2), vec![1, 2, 1, 2]); assert_eq!([1, 2, 3, 4].repeat(0), vec![]); assert_eq!([1, 2, 3, 4].repeat(1), vec![1, 2, 3, 4]); - assert_eq!( - [1, 2, 3, 4].repeat(3), - vec![1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4] - ); + assert_eq!([1, 2, 3, 4].repeat(3), vec![1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]); } diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index 1b011242d0137..d3c72615696d5 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -13,9 +13,9 @@ fn test_le() { #[test] fn test_find() { assert_eq!("hello".find('l'), Some(2)); - assert_eq!("hello".find(|c:char| c == 'o'), Some(4)); + assert_eq!("hello".find(|c: char| c == 'o'), Some(4)); assert!("hello".find('x').is_none()); - assert!("hello".find(|c:char| c == 'x').is_none()); + assert!("hello".find(|c: char| c == 'x').is_none()); assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30)); assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30)); } @@ -23,9 +23,9 @@ fn test_find() { #[test] fn test_rfind() { assert_eq!("hello".rfind('l'), Some(3)); - assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4)); + assert_eq!("hello".rfind(|c: char| c == 'o'), Some(4)); assert!("hello".rfind('x').is_none()); - assert!("hello".rfind(|c:char| c == 'x').is_none()); + assert!("hello".rfind(|c: char| c == 'x').is_none()); assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30)); assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30)); } @@ -65,7 +65,7 @@ fn test_find_str() { assert_eq!(data[0..43].find(""), Some(0)); assert_eq!(data[6..43].find(""), Some(6 - 6)); - assert_eq!(data[0..43].find("ประ"), Some( 0)); + assert_eq!(data[0..43].find("ประ"), Some(0)); assert_eq!(data[0..43].find("ทศไ"), Some(12)); assert_eq!(data[0..43].find("ย中"), Some(24)); assert_eq!(data[0..43].find("iệt"), Some(34)); @@ -81,10 +81,7 @@ fn test_find_str() { let string = "Việt Namacbaabcaabaaba"; for (i, ci) in string.char_indices() { let ip = i + ci.len_utf8(); - for j in string[ip..].char_indices() - .map(|(i, _)| i) - .chain(Some(string.len() - ip)) - { + for j in string[ip..].char_indices().map(|(i, _)| i).chain(Some(string.len() - ip)) { let pat = &string[i..ip + j]; assert!(match string.find(pat) { None => false, @@ -98,15 +95,15 @@ fn test_find_str() { } } -fn s(x: &str) -> String { x.to_string() } +fn s(x: &str) -> String { + x.to_string() +} macro_rules! test_concat { - ($expected: expr, $string: expr) => { - { - let s: String = $string.concat(); - assert_eq!($expected, s); - } - } + ($expected: expr, $string: expr) => {{ + let s: String = $string.concat(); + assert_eq!($expected, s); + }}; } #[test] @@ -125,12 +122,10 @@ fn test_concat_for_different_lengths() { } macro_rules! test_join { - ($expected: expr, $string: expr, $delim: expr) => { - { - let s = $string.join($delim); - assert_eq!($expected, s); - } - } + ($expected: expr, $string: expr, $delim: expr) => {{ + let s = $string.join($delim); + assert_eq!($expected, s); + }}; } #[test] @@ -168,9 +163,9 @@ fn test_join_for_different_lengths_with_long_separator() { #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn test_unsafe_slice() { - assert_eq!("ab", unsafe {"abc".get_unchecked(0..2)}); - assert_eq!("bc", unsafe {"abc".get_unchecked(1..3)}); - assert_eq!("", unsafe {"abc".get_unchecked(1..1)}); + assert_eq!("ab", unsafe { "abc".get_unchecked(0..2) }); + assert_eq!("bc", unsafe { "abc".get_unchecked(1..3) }); + assert_eq!("", unsafe { "abc".get_unchecked(1..1) }); fn a_million_letter_a() -> String { let mut i = 0; let mut rs = String::new(); @@ -190,8 +185,7 @@ fn test_unsafe_slice() { rs } let letters = a_million_letter_a(); - assert_eq!(half_a_million_letter_a(), - unsafe { letters.get_unchecked(0..500000)}); + assert_eq!(half_a_million_letter_a(), unsafe { letters.get_unchecked(0..500000) }); } #[test] @@ -304,8 +298,7 @@ mod slice_index { // // This is not suitable for testing failure on invalid inputs. macro_rules! assert_range_eq { - ($s:expr, $range:expr, $expected:expr) - => { + ($s:expr, $range:expr, $expected:expr) => { let mut s: String = $s.to_owned(); let mut expected: String = $expected.to_owned(); { @@ -316,7 +309,8 @@ mod slice_index { assert_eq!(s.get($range), Some(expected), "(in assertion for: get)"); unsafe { assert_eq!( - s.get_unchecked($range), expected, + s.get_unchecked($range), + expected, "(in assertion for: get_unchecked)", ); } @@ -325,22 +319,21 @@ mod slice_index { let s: &mut str = &mut s; let expected: &mut str = &mut expected; + assert_eq!(&mut s[$range], expected, "(in assertion for: index_mut)",); assert_eq!( - &mut s[$range], expected, - "(in assertion for: index_mut)", - ); - assert_eq!( - s.get_mut($range), Some(&mut expected[..]), + s.get_mut($range), + Some(&mut expected[..]), "(in assertion for: get_mut)", ); unsafe { assert_eq!( - s.get_unchecked_mut($range), expected, + s.get_unchecked_mut($range), + expected, "(in assertion for: get_unchecked_mut)", ); } } - } + }; } // Make sure the macro can actually detect bugs, @@ -460,15 +453,15 @@ mod slice_index { assert_range_eq!(data, 30..33, "华"); /*0: 中 - 3: 华 - 6: V - 7: i - 8: ệ - 11: t - 12: - 13: N - 14: a - 15: m */ + 3: 华 + 6: V + 7: i + 8: ệ + 11: t + 12: + 13: N + 14: a + 15: m */ let ss = "中华Việt Nam"; assert_range_eq!(ss, 3..6, "华"); assert_range_eq!(ss, 6..16, "Việt Nam"); @@ -660,13 +653,13 @@ mod slice_index { // check the panic includes the prefix of the sliced string #[test] - #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")] + #[should_panic(expected = "byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")] fn test_slice_fail_truncated_1() { &LOREM_PARAGRAPH[..1024]; } // check the truncation in the panic message #[test] - #[should_panic(expected="luctus, im`[...]")] + #[should_panic(expected = "luctus, im`[...]")] fn test_slice_fail_truncated_2() { &LOREM_PARAGRAPH[..1024]; } @@ -712,8 +705,12 @@ fn test_is_char_boundary() { // ensure character locations are boundaries and continuation bytes are not assert!(s.is_char_boundary(i), "{} is a char boundary in {:?}", i, s); for j in 1..ch.len_utf8() { - assert!(!s.is_char_boundary(i + j), - "{} should not be a char boundary in {:?}", i + j, s); + assert!( + !s.is_char_boundary(i + j), + "{} should not be a char boundary in {:?}", + i + j, + s + ); } } } @@ -846,7 +843,7 @@ fn from_utf8_error() { let error = from_utf8($input).unwrap_err(); assert_eq!(error.valid_up_to(), $expected_valid_up_to); assert_eq!(error.error_len(), $expected_error_len); - } + }; } test!(b"A\xC3\xA9 \xFF ", 4, Some(1)); test!(b"A\xC3\xA9 \x80 ", 4, Some(1)); @@ -873,9 +870,8 @@ fn from_utf8_error() { fn test_as_bytes() { // no null let v = [ - 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, - 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, - 109 + 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, 184, 173, 229, 141, 142, + 86, 105, 225, 187, 135, 116, 32, 78, 97, 109, ]; let b: &[u8] = &[]; assert_eq!("".as_bytes(), b); @@ -1010,8 +1006,10 @@ fn test_escape_debug() { assert_eq!("\u{10000}\u{10ffff}".escape_debug().to_string(), "\u{10000}\\u{10ffff}"); assert_eq!("ab\u{200b}".escape_debug().to_string(), "ab\\u{200b}"); assert_eq!("\u{10d4ea}\r".escape_debug().to_string(), "\\u{10d4ea}\\r"); - assert_eq!("\u{301}a\u{301}bé\u{e000}".escape_debug().to_string(), - "\\u{301}a\u{301}bé\\u{e000}"); + assert_eq!( + "\u{301}a\u{301}bé\u{e000}".escape_debug().to_string(), + "\\u{301}a\u{301}bé\\u{e000}" + ); } #[test] @@ -1040,7 +1038,7 @@ fn test_total_ord() { #[test] fn test_iterator() { let s = "ศไทย中华Việt Nam"; - let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; + let v = ['ศ', 'ไ', 'ท', 'ย', '中', '华', 'V', 'i', 'ệ', 't', ' ', 'N', 'a', 'm']; let mut pos = 0; let it = s.chars(); @@ -1056,7 +1054,7 @@ fn test_iterator() { #[test] fn test_rev_iterator() { let s = "ศไทย中华Việt Nam"; - let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ']; + let v = ['m', 'a', 'N', ' ', 't', 'ệ', 'i', 'V', '华', '中', 'ย', 'ท', 'ไ', 'ศ']; let mut pos = 0; let it = s.chars().rev(); @@ -1097,7 +1095,7 @@ fn test_iterator_clone() { let s = "ศไทย中华Việt Nam"; let mut it = s.chars(); it.next(); - assert!(it.clone().zip(it).all(|(x,y)| x == y)); + assert!(it.clone().zip(it).all(|(x, y)| x == y)); } #[test] @@ -1122,9 +1120,8 @@ fn test_chars_debug() { fn test_bytesator() { let s = "ศไทย中华Việt Nam"; let v = [ - 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, - 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, - 109 + 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, 184, 173, 229, 141, 142, + 86, 105, 225, 187, 135, 116, 32, 78, 97, 109, ]; let mut pos = 0; @@ -1138,9 +1135,8 @@ fn test_bytesator() { fn test_bytes_revator() { let s = "ศไทย中华Việt Nam"; let v = [ - 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, - 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, - 109 + 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, 184, 173, 229, 141, 142, + 86, 105, 225, 187, 135, 116, 32, 78, 97, 109, ]; let mut pos = v.len(); @@ -1154,9 +1150,8 @@ fn test_bytes_revator() { fn test_bytesator_nth() { let s = "ศไทย中华Việt Nam"; let v = [ - 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, - 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, - 109 + 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, 184, 173, 229, 141, 142, + 86, 105, 225, 187, 135, 116, 32, 78, 97, 109, ]; let mut b = s.bytes(); @@ -1185,7 +1180,7 @@ fn test_bytesator_last() { fn test_char_indicesator() { let s = "ศไทย中华Việt Nam"; let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27]; - let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m']; + let v = ['ศ', 'ไ', 'ท', 'ย', '中', '华', 'V', 'i', 'ệ', 't', ' ', 'N', 'a', 'm']; let mut pos = 0; let it = s.char_indices(); @@ -1202,7 +1197,7 @@ fn test_char_indicesator() { fn test_char_indices_revator() { let s = "ศไทย中华Việt Nam"; let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0]; - let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ']; + let v = ['m', 'a', 'N', ' ', 't', 'ệ', 'i', 'V', '华', '中', 'ย', 'ท', 'ไ', 'ศ']; let mut pos = 0; let it = s.char_indices().rev(); @@ -1314,10 +1309,10 @@ fn test_splitator() { t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]); t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]); t("", ".", &[""]); - t("zz", "zz", &["",""]); + t("zz", "zz", &["", ""]); t("ok", "z", &["ok"]); - t("zzz", "zz", &["","z"]); - t("zzzzz", "zz", &["","","z"]); + t("zzz", "zz", &["", "z"]); + t("zzzzz", "zz", &["", "", "z"]); } #[test] @@ -1383,7 +1378,7 @@ fn test_bool_from_str() { fn check_contains_all_substrings(s: &str) { assert!(s.contains("")); for i in 0..s.len() { - for j in i+1..=s.len() { + for j in i + 1..=s.len() { assert!(s.contains(&s[i..j])); } } @@ -1405,7 +1400,6 @@ fn strslice_issue_16878() { assert!(!"00abc01234567890123456789abc".contains("bcabc")); } - #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn test_strslice_contains() { @@ -1440,14 +1434,14 @@ fn test_split_char_iterator() { let data = "\nMäry häd ä little lämb\nLittle lämb\n"; let split: Vec<&str> = data.split(' ').collect(); - assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!(split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); let mut rsplit: Vec<&str> = data.split(' ').rev().collect(); rsplit.reverse(); assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); let split: Vec<&str> = data.split(|c: char| c == ' ').collect(); - assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!(split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect(); rsplit.reverse(); @@ -1455,14 +1449,14 @@ fn test_split_char_iterator() { // Unicode let split: Vec<&str> = data.split('ä').collect(); - assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!(split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); let mut rsplit: Vec<&str> = data.split('ä').rev().collect(); rsplit.reverse(); assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); let split: Vec<&str> = data.split(|c: char| c == 'ä').collect(); - assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!(split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect(); rsplit.reverse(); @@ -1484,8 +1478,7 @@ fn test_rev_split_char_iterator_no_trailing() { #[test] fn test_utf16_code_units() { - assert_eq!("é\u{1F4A9}".encode_utf16().collect::>(), - [0xE9, 0xD83D, 0xDCA9]) + assert_eq!("é\u{1F4A9}".encode_utf16().collect::>(), [0xE9, 0xD83D, 0xDCA9]) } #[test] @@ -1521,26 +1514,16 @@ fn contains_weird_cases() { #[test] fn trim_ws() { - assert_eq!(" \t a \t ".trim_start_matches(|c: char| c.is_whitespace()), - "a \t "); - assert_eq!(" \t a \t ".trim_end_matches(|c: char| c.is_whitespace()), - " \t a"); - assert_eq!(" \t a \t ".trim_start_matches(|c: char| c.is_whitespace()), - "a \t "); - assert_eq!(" \t a \t ".trim_end_matches(|c: char| c.is_whitespace()), - " \t a"); - assert_eq!(" \t a \t ".trim_matches(|c: char| c.is_whitespace()), - "a"); - assert_eq!(" \t \t ".trim_start_matches(|c: char| c.is_whitespace()), - ""); - assert_eq!(" \t \t ".trim_end_matches(|c: char| c.is_whitespace()), - ""); - assert_eq!(" \t \t ".trim_start_matches(|c: char| c.is_whitespace()), - ""); - assert_eq!(" \t \t ".trim_end_matches(|c: char| c.is_whitespace()), - ""); - assert_eq!(" \t \t ".trim_matches(|c: char| c.is_whitespace()), - ""); + assert_eq!(" \t a \t ".trim_start_matches(|c: char| c.is_whitespace()), "a \t "); + assert_eq!(" \t a \t ".trim_end_matches(|c: char| c.is_whitespace()), " \t a"); + assert_eq!(" \t a \t ".trim_start_matches(|c: char| c.is_whitespace()), "a \t "); + assert_eq!(" \t a \t ".trim_end_matches(|c: char| c.is_whitespace()), " \t a"); + assert_eq!(" \t a \t ".trim_matches(|c: char| c.is_whitespace()), "a"); + assert_eq!(" \t \t ".trim_start_matches(|c: char| c.is_whitespace()), ""); + assert_eq!(" \t \t ".trim_end_matches(|c: char| c.is_whitespace()), ""); + assert_eq!(" \t \t ".trim_start_matches(|c: char| c.is_whitespace()), ""); + assert_eq!(" \t \t ".trim_end_matches(|c: char| c.is_whitespace()), ""); + assert_eq!(" \t \t ".trim_matches(|c: char| c.is_whitespace()), ""); } #[test] @@ -1616,8 +1599,8 @@ fn test_repeat() { } mod pattern { - use std::str::pattern::{Pattern, Searcher, ReverseSearcher}; - use std::str::pattern::SearchStep::{self, Match, Reject, Done}; + use std::str::pattern::SearchStep::{self, Done, Match, Reject}; + use std::str::pattern::{Pattern, ReverseSearcher, Searcher}; macro_rules! make_test { ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => { @@ -1641,12 +1624,12 @@ mod pattern { rev: bool, pat: impl Pattern<'a, Searcher: ReverseSearcher<'a>>, haystack: &'a str, - right: Vec + right: Vec, ) { let mut searcher = pat.into_searcher(haystack); let mut v = vec![]; loop { - match if !rev {searcher.next()} else {searcher.next_back()} { + match if !rev { searcher.next() } else { searcher.next_back() } { Match(a, b) => v.push(Match(a, b)), Reject(a, b) => v.push(Reject(a, b)), Done => break, @@ -1661,8 +1644,7 @@ mod pattern { for (i, e) in right.iter().enumerate() { match *e { - Match(a, b) | Reject(a, b) - if a <= b && a == first_index => { + Match(a, b) | Reject(a, b) if a <= b && a == first_index => { first_index = b; } _ => { @@ -1683,77 +1665,88 @@ mod pattern { assert_eq!(v, right); } - make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [ - Reject(0, 1), - Match (1, 3), - Reject(3, 4), - Match (4, 6), - Reject(6, 7), - ]); - make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [ - Reject(0, 1), - Match (1, 3), - Reject(3, 4), - Match (4, 6), - Match (6, 8), - Reject(8, 9), - ]); - make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [ - Match (0, 0), - Reject(0, 1), - Match (1, 1), - Reject(1, 2), - Match (2, 2), - Reject(2, 3), - Match (3, 3), - Reject(3, 4), - Match (4, 4), - Reject(4, 5), - Match (5, 5), - Reject(5, 6), - Match (6, 6), - Reject(6, 7), - Match (7, 7), - ]); - make_test!(str_searcher_multibyte_haystack, " ", "├──", [ - Reject(0, 3), - Reject(3, 6), - Reject(6, 9), - ]); - make_test!(str_searcher_empty_needle_multibyte_haystack, "", "├──", [ - Match (0, 0), - Reject(0, 3), - Match (3, 3), - Reject(3, 6), - Match (6, 6), - Reject(6, 9), - Match (9, 9), - ]); - make_test!(str_searcher_empty_needle_empty_haystack, "", "", [ - Match(0, 0), - ]); - make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [ - ]); - make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [ - Reject(0, 1), - Match (1, 2), - Match (2, 3), - Reject(3, 4), - Match (4, 5), - Match (5, 6), - Reject(6, 7), - ]); - make_test!(char_searcher_multibyte_haystack, ' ', "├──", [ - Reject(0, 3), - Reject(3, 6), - Reject(6, 9), - ]); - make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [ - Reject(0, 1), - Reject(1, 2), - Reject(2, 3), - ]); - + make_test!( + str_searcher_ascii_haystack, + "bb", + "abbcbbd", + [Reject(0, 1), Match(1, 3), Reject(3, 4), Match(4, 6), Reject(6, 7),] + ); + make_test!( + str_searcher_ascii_haystack_seq, + "bb", + "abbcbbbbd", + [Reject(0, 1), Match(1, 3), Reject(3, 4), Match(4, 6), Match(6, 8), Reject(8, 9),] + ); + make_test!( + str_searcher_empty_needle_ascii_haystack, + "", + "abbcbbd", + [ + Match(0, 0), + Reject(0, 1), + Match(1, 1), + Reject(1, 2), + Match(2, 2), + Reject(2, 3), + Match(3, 3), + Reject(3, 4), + Match(4, 4), + Reject(4, 5), + Match(5, 5), + Reject(5, 6), + Match(6, 6), + Reject(6, 7), + Match(7, 7), + ] + ); + make_test!( + str_searcher_multibyte_haystack, + " ", + "├──", + [Reject(0, 3), Reject(3, 6), Reject(6, 9),] + ); + make_test!( + str_searcher_empty_needle_multibyte_haystack, + "", + "├──", + [ + Match(0, 0), + Reject(0, 3), + Match(3, 3), + Reject(3, 6), + Match(6, 6), + Reject(6, 9), + Match(9, 9), + ] + ); + make_test!(str_searcher_empty_needle_empty_haystack, "", "", [Match(0, 0),]); + make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", []); + make_test!( + char_searcher_ascii_haystack, + 'b', + "abbcbbd", + [ + Reject(0, 1), + Match(1, 2), + Match(2, 3), + Reject(3, 4), + Match(4, 5), + Match(5, 6), + Reject(6, 7), + ] + ); + make_test!( + char_searcher_multibyte_haystack, + ' ', + "├──", + [Reject(0, 3), Reject(3, 6), Reject(6, 9),] + ); + make_test!( + char_searcher_short_haystack, + '\u{1F4A9}', + "* \t", + [Reject(0, 1), Reject(1, 2), Reject(2, 3),] + ); } macro_rules! generate_iterator_test { @@ -1850,7 +1843,10 @@ generate_iterator_test! { fn different_str_pattern_forwarding_lifetimes() { use std::str::pattern::Pattern; - fn foo<'a, P>(p: P) where for<'b> &'b P: Pattern<'a> { + fn foo<'a, P>(p: P) + where + for<'b> &'b P: Pattern<'a>, + { for _ in 0..3 { "asdf".find(&p); } diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index fe7b4ff24b8c9..dd44495845961 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -1,9 +1,12 @@ use std::borrow::Cow; use std::collections::TryReserveError::*; use std::mem::size_of; -use std::{usize, isize}; +use std::{isize, usize}; -pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { +pub trait IntoCow<'a, B: ?Sized> +where + B: ToOwned, +{ fn into_cow(self) -> Cow<'a, B>; } @@ -43,8 +46,7 @@ fn test_from_utf8() { assert_eq!(String::from_utf8(xs).unwrap(), String::from("hello")); let xs = "ศไทย中华Việt Nam".as_bytes().to_vec(); - assert_eq!(String::from_utf8(xs).unwrap(), - String::from("ศไทย中华Việt Nam")); + assert_eq!(String::from_utf8(xs).unwrap(), String::from("ศไทย中华Việt Nam")); let xs = b"hello\xFF".to_vec(); let err = String::from_utf8(xs).unwrap_err(); @@ -62,60 +64,87 @@ fn test_from_utf8_lossy() { assert_eq!(String::from_utf8_lossy(xs), ys); let xs = b"Hello\xC2 There\xFF Goodbye"; - assert_eq!(String::from_utf8_lossy(xs), - String::from("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow()); + assert_eq!( + String::from_utf8_lossy(xs), + String::from("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow() + ); let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye"; - assert_eq!(String::from_utf8_lossy(xs), - String::from("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow()); + assert_eq!( + String::from_utf8_lossy(xs), + String::from("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow() + ); let xs = b"\xF5foo\xF5\x80bar"; - assert_eq!(String::from_utf8_lossy(xs), - String::from("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow()); + assert_eq!( + String::from_utf8_lossy(xs), + String::from("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow() + ); let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz"; - assert_eq!(String::from_utf8_lossy(xs), - String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow()); + assert_eq!( + String::from_utf8_lossy(xs), + String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow() + ); let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz"; - assert_eq!(String::from_utf8_lossy(xs), - String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow()); + assert_eq!( + String::from_utf8_lossy(xs), + String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow() + ); let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar"; - assert_eq!(String::from_utf8_lossy(xs), - String::from("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}foo\u{10000}bar").into_cow()); + assert_eq!( + String::from_utf8_lossy(xs), + String::from("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}foo\u{10000}bar").into_cow() + ); // surrogates let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar"; - assert_eq!(String::from_utf8_lossy(xs), - String::from("\u{FFFD}\u{FFFD}\u{FFFD}foo\u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow()); + assert_eq!( + String::from_utf8_lossy(xs), + String::from("\u{FFFD}\u{FFFD}\u{FFFD}foo\u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow() + ); } #[test] fn test_from_utf16() { - let pairs = [(String::from("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"), - vec![0xd800, 0xdf45, 0xd800, 0xdf3f, 0xd800, 0xdf3b, 0xd800, 0xdf46, 0xd800, - 0xdf39, 0xd800, 0xdf3b, 0xd800, 0xdf30, 0x000a]), - - (String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"), - vec![0xd801, 0xdc12, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc40, 0xd801, - 0xdc32, 0xd801, 0xdc4b, 0x0020, 0xd801, 0xdc0f, 0xd801, 0xdc32, 0xd801, - 0xdc4d, 0x000a]), - - (String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"), - vec![0xd800, 0xdf00, 0xd800, 0xdf16, 0xd800, 0xdf0b, 0xd800, 0xdf04, 0xd800, - 0xdf11, 0xd800, 0xdf09, 0x00b7, 0xd800, 0xdf0c, 0xd800, 0xdf04, 0xd800, - 0xdf15, 0xd800, 0xdf04, 0xd800, 0xdf0b, 0xd800, 0xdf09, 0xd800, 0xdf11, - 0x000a]), - - (String::from("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"), - vec![0xd801, 0xdc8b, 0xd801, 0xdc98, 0xd801, 0xdc88, 0xd801, 0xdc91, 0xd801, - 0xdc9b, 0xd801, 0xdc92, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc93, 0x0020, - 0xd801, 0xdc88, 0xd801, 0xdc9a, 0xd801, 0xdc8d, 0x0020, 0xd801, 0xdc8f, - 0xd801, 0xdc9c, 0xd801, 0xdc92, 0xd801, 0xdc96, 0xd801, 0xdc86, 0x0020, - 0xd801, 0xdc95, 0xd801, 0xdc86, 0x000a]), - // Issue #12318, even-numbered non-BMP planes - (String::from("\u{20000}"), vec![0xD840, 0xDC00])]; + let pairs = [ + ( + String::from("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"), + vec![ + 0xd800, 0xdf45, 0xd800, 0xdf3f, 0xd800, 0xdf3b, 0xd800, 0xdf46, 0xd800, 0xdf39, + 0xd800, 0xdf3b, 0xd800, 0xdf30, 0x000a, + ], + ), + ( + String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"), + vec![ + 0xd801, 0xdc12, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc40, 0xd801, 0xdc32, + 0xd801, 0xdc4b, 0x0020, 0xd801, 0xdc0f, 0xd801, 0xdc32, 0xd801, 0xdc4d, 0x000a, + ], + ), + ( + String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"), + vec![ + 0xd800, 0xdf00, 0xd800, 0xdf16, 0xd800, 0xdf0b, 0xd800, 0xdf04, 0xd800, 0xdf11, + 0xd800, 0xdf09, 0x00b7, 0xd800, 0xdf0c, 0xd800, 0xdf04, 0xd800, 0xdf15, 0xd800, + 0xdf04, 0xd800, 0xdf0b, 0xd800, 0xdf09, 0xd800, 0xdf11, 0x000a, + ], + ), + ( + String::from("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"), + vec![ + 0xd801, 0xdc8b, 0xd801, 0xdc98, 0xd801, 0xdc88, 0xd801, 0xdc91, 0xd801, 0xdc9b, + 0xd801, 0xdc92, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc93, 0x0020, 0xd801, 0xdc88, + 0xd801, 0xdc9a, 0xd801, 0xdc8d, 0x0020, 0xd801, 0xdc8f, 0xd801, 0xdc9c, 0xd801, + 0xdc92, 0xd801, 0xdc96, 0xd801, 0xdc86, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc86, + 0x000a, + ], + ), + // Issue #12318, even-numbered non-BMP planes + (String::from("\u{20000}"), vec![0xD840, 0xDC00]), + ]; for p in &pairs { let (s, u) = (*p).clone(); @@ -152,19 +181,18 @@ fn test_utf16_invalid() { fn test_from_utf16_lossy() { // completely positive cases tested above. // lead + eof - assert_eq!(String::from_utf16_lossy(&[0xD800]), - String::from("\u{FFFD}")); + assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from("\u{FFFD}")); // lead + lead - assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]), - String::from("\u{FFFD}\u{FFFD}")); + assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]), String::from("\u{FFFD}\u{FFFD}")); // isolated trail - assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), - String::from("a\u{FFFD}")); + assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from("a\u{FFFD}")); // general - assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]), - String::from("\u{FFFD}𐒋\u{FFFD}")); + assert_eq!( + String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]), + String::from("\u{FFFD}𐒋\u{FFFD}") + ); } #[test] @@ -525,7 +553,6 @@ fn test_reserve_exact() { #[test] #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM fn test_try_reserve() { - // These are the interesting cases: // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM) // * > isize::MAX should always fail @@ -559,23 +586,30 @@ fn test_try_reserve() { if guards_against_isize { // Check isize::MAX + 1 does count as overflow if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP + 1) { - } else { panic!("isize::MAX + 1 should trigger an overflow!") } + } else { + panic!("isize::MAX + 1 should trigger an overflow!") + } // Check usize::MAX does count as overflow if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_USIZE) { - } else { panic!("usize::MAX should trigger an overflow!") } + } else { + panic!("usize::MAX should trigger an overflow!") + } } else { // Check isize::MAX + 1 is an OOM if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_CAP + 1) { - } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } else { + panic!("isize::MAX + 1 should trigger an OOM!") + } // Check usize::MAX is an OOM if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_USIZE) { - } else { panic!("usize::MAX should trigger an OOM!") } + } else { + panic!("usize::MAX should trigger an OOM!") + } } } - { // Same basic idea, but with non-zero len let mut ten_bytes: String = String::from("0123456789"); @@ -588,22 +622,26 @@ fn test_try_reserve() { } if guards_against_isize { if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) { - } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + panic!("isize::MAX + 1 should trigger an overflow!"); + } } else { if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) { - } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } else { + panic!("isize::MAX + 1 should trigger an OOM!") + } } // Should always overflow in the add-to-len if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) { - } else { panic!("usize::MAX should trigger an overflow!") } + } else { + panic!("usize::MAX should trigger an overflow!") + } } - } #[test] #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM fn test_try_reserve_exact() { - // This is exactly the same as test_try_reserve with the method changed. // See that test for comments. @@ -624,20 +662,27 @@ fn test_try_reserve_exact() { if guards_against_isize { if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP + 1) { - } else { panic!("isize::MAX + 1 should trigger an overflow!") } + } else { + panic!("isize::MAX + 1 should trigger an overflow!") + } if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_USIZE) { - } else { panic!("usize::MAX should trigger an overflow!") } + } else { + panic!("usize::MAX should trigger an overflow!") + } } else { if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_CAP + 1) { - } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } else { + panic!("isize::MAX + 1 should trigger an OOM!") + } if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_USIZE) { - } else { panic!("usize::MAX should trigger an OOM!") } + } else { + panic!("usize::MAX should trigger an OOM!") + } } } - { let mut ten_bytes: String = String::from("0123456789"); @@ -649,13 +694,18 @@ fn test_try_reserve_exact() { } if guards_against_isize { if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) { - } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + panic!("isize::MAX + 1 should trigger an overflow!"); + } } else { if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) { - } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } else { + panic!("isize::MAX + 1 should trigger an OOM!") + } } if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) { - } else { panic!("usize::MAX should trigger an overflow!") } + } else { + panic!("usize::MAX should trigger an overflow!") + } } - } diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 5e788d61f84fd..19acc70c73c8e 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; +use std::collections::TryReserveError::*; use std::mem::size_of; -use std::{usize, isize}; use std::vec::{Drain, IntoIter}; -use std::collections::TryReserveError::*; +use std::{isize, usize}; struct DropCounter<'a> { count: &'a mut u32, @@ -28,10 +28,7 @@ fn test_double_drop() { let (mut count_x, mut count_y) = (0, 0); { - let mut tv = TwoVec { - x: Vec::new(), - y: Vec::new(), - }; + let mut tv = TwoVec { x: Vec::new(), y: Vec::new() }; tv.x.push(DropCounter { count: &mut count_x }); tv.y.push(DropCounter { count: &mut count_y }); @@ -271,7 +268,12 @@ fn test_dedup_by() { assert_eq!(vec, ["foo", "bar", "baz", "bar"]); let mut vec = vec![("foo", 1), ("foo", 2), ("bar", 3), ("bar", 4), ("bar", 5)]; - vec.dedup_by(|a, b| a.0 == b.0 && { b.1 += a.1; true }); + vec.dedup_by(|a, b| { + a.0 == b.0 && { + b.1 += a.1; + true + } + }); assert_eq!(vec, [("foo", 3), ("bar", 12)]); } @@ -323,14 +325,10 @@ fn zero_sized_values() { #[test] fn test_partition() { - assert_eq!(vec![].into_iter().partition(|x: &i32| *x < 3), - (vec![], vec![])); - assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 4), - (vec![1, 2, 3], vec![])); - assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 2), - (vec![1], vec![2, 3])); - assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 0), - (vec![], vec![1, 2, 3])); + assert_eq!(vec![].into_iter().partition(|x: &i32| *x < 3), (vec![], vec![])); + assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 4), (vec![1, 2, 3], vec![])); + assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 2), (vec![1], vec![2, 3])); + assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 0), (vec![], vec![1, 2, 3])); } #[test] @@ -509,66 +507,59 @@ fn test_drain_out_of_bounds() { #[test] fn test_drain_range() { let mut v = vec![1, 2, 3, 4, 5]; - for _ in v.drain(4..) { - } + for _ in v.drain(4..) {} assert_eq!(v, &[1, 2, 3, 4]); let mut v: Vec<_> = (1..6).map(|x| x.to_string()).collect(); - for _ in v.drain(1..4) { - } + for _ in v.drain(1..4) {} assert_eq!(v, &[1.to_string(), 5.to_string()]); let mut v: Vec<_> = (1..6).map(|x| x.to_string()).collect(); - for _ in v.drain(1..4).rev() { - } + for _ in v.drain(1..4).rev() {} assert_eq!(v, &[1.to_string(), 5.to_string()]); let mut v: Vec<_> = vec![(); 5]; - for _ in v.drain(1..4).rev() { - } + for _ in v.drain(1..4).rev() {} assert_eq!(v, &[(), ()]); } #[test] fn test_drain_inclusive_range() { let mut v = vec!['a', 'b', 'c', 'd', 'e']; - for _ in v.drain(1..=3) { - } + for _ in v.drain(1..=3) {} assert_eq!(v, &['a', 'e']); let mut v: Vec<_> = (0..=5).map(|x| x.to_string()).collect(); - for _ in v.drain(1..=5) { - } + for _ in v.drain(1..=5) {} assert_eq!(v, &["0".to_string()]); let mut v: Vec = (0..=5).map(|x| x.to_string()).collect(); - for _ in v.drain(0..=5) { - } + for _ in v.drain(0..=5) {} assert_eq!(v, Vec::::new()); let mut v: Vec<_> = (0..=5).map(|x| x.to_string()).collect(); - for _ in v.drain(0..=3) { - } + for _ in v.drain(0..=3) {} assert_eq!(v, &["4".to_string(), "5".to_string()]); let mut v: Vec<_> = (0..=1).map(|x| x.to_string()).collect(); - for _ in v.drain(..=0) { - } + for _ in v.drain(..=0) {} assert_eq!(v, &["1".to_string()]); } #[test] fn test_drain_max_vec_size() { let mut v = Vec::<()>::with_capacity(usize::max_value()); - unsafe { v.set_len(usize::max_value()); } - for _ in v.drain(usize::max_value() - 1..) { + unsafe { + v.set_len(usize::max_value()); } + for _ in v.drain(usize::max_value() - 1..) {} assert_eq!(v.len(), usize::max_value() - 1); let mut v = Vec::<()>::with_capacity(usize::max_value()); - unsafe { v.set_len(usize::max_value()); } - for _ in v.drain(usize::max_value() - 1..=usize::max_value() - 1) { + unsafe { + v.set_len(usize::max_value()); } + for _ in v.drain(usize::max_value() - 1..=usize::max_value() - 1) {} assert_eq!(v.len(), usize::max_value() - 1); } @@ -864,17 +855,12 @@ fn drain_filter_true() { #[test] fn drain_filter_complex() { - - { // [+xxx++++++xxxxx++++x+x++] - let mut vec = vec![1, - 2, 4, 6, - 7, 9, 11, 13, 15, 17, - 18, 20, 22, 24, 26, - 27, 29, 31, 33, - 34, - 35, - 36, - 37, 39]; + { + // [+xxx++++++xxxxx++++x+x++] + let mut vec = vec![ + 1, 2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, + 39, + ]; let removed = vec.drain_filter(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); @@ -884,15 +870,11 @@ fn drain_filter_complex() { assert_eq!(vec, vec![1, 7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]); } - { // [xxx++++++xxxxx++++x+x++] - let mut vec = vec![2, 4, 6, - 7, 9, 11, 13, 15, 17, - 18, 20, 22, 24, 26, - 27, 29, 31, 33, - 34, - 35, - 36, - 37, 39]; + { + // [xxx++++++xxxxx++++x+x++] + let mut vec = vec![ + 2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, 39, + ]; let removed = vec.drain_filter(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); @@ -902,14 +884,10 @@ fn drain_filter_complex() { assert_eq!(vec, vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35, 37, 39]); } - { // [xxx++++++xxxxx++++x+x] - let mut vec = vec![2, 4, 6, - 7, 9, 11, 13, 15, 17, - 18, 20, 22, 24, 26, - 27, 29, 31, 33, - 34, - 35, - 36]; + { + // [xxx++++++xxxxx++++x+x] + let mut vec = + vec![2, 4, 6, 7, 9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 27, 29, 31, 33, 34, 35, 36]; let removed = vec.drain_filter(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); @@ -919,9 +897,9 @@ fn drain_filter_complex() { assert_eq!(vec, vec![7, 9, 11, 13, 15, 17, 27, 29, 31, 33, 35]); } - { // [xxxxxxxxxx+++++++++++] - let mut vec = vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20, - 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]; + { + // [xxxxxxxxxx+++++++++++] + let mut vec = vec![2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]; let removed = vec.drain_filter(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); @@ -931,9 +909,9 @@ fn drain_filter_complex() { assert_eq!(vec, vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]); } - { // [+++++++++++xxxxxxxxxx] - let mut vec = vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19, - 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]; + { + // [+++++++++++xxxxxxxxxx] + let mut vec = vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]; let removed = vec.drain_filter(|x| *x % 2 == 0).collect::>(); assert_eq!(removed.len(), 10); @@ -1082,7 +1060,6 @@ fn test_reserve_exact() { #[test] #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM fn test_try_reserve() { - // These are the interesting cases: // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM) // * > isize::MAX should always fail @@ -1116,23 +1093,30 @@ fn test_try_reserve() { if guards_against_isize { // Check isize::MAX + 1 does count as overflow if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP + 1) { - } else { panic!("isize::MAX + 1 should trigger an overflow!") } + } else { + panic!("isize::MAX + 1 should trigger an overflow!") + } // Check usize::MAX does count as overflow if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) { - } else { panic!("usize::MAX should trigger an overflow!") } + } else { + panic!("usize::MAX should trigger an overflow!") + } } else { // Check isize::MAX + 1 is an OOM if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_CAP + 1) { - } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } else { + panic!("isize::MAX + 1 should trigger an OOM!") + } // Check usize::MAX is an OOM if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE) { - } else { panic!("usize::MAX should trigger an OOM!") } + } else { + panic!("usize::MAX should trigger an OOM!") + } } } - { // Same basic idea, but with non-zero len let mut ten_bytes: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; @@ -1145,33 +1129,42 @@ fn test_try_reserve() { } if guards_against_isize { if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) { - } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + panic!("isize::MAX + 1 should trigger an overflow!"); + } } else { if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) { - } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } else { + panic!("isize::MAX + 1 should trigger an OOM!") + } } // Should always overflow in the add-to-len if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) { - } else { panic!("usize::MAX should trigger an overflow!") } + } else { + panic!("usize::MAX should trigger an overflow!") + } } - { // Same basic idea, but with interesting type size let mut ten_u32s: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) { + if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 10) { panic!("isize::MAX shouldn't trigger an overflow!"); } - if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) { + if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 10) { panic!("isize::MAX shouldn't trigger an overflow!"); } if guards_against_isize { - if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 9) { - } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP / 4 - 9) { + } else { + panic!("isize::MAX + 1 should trigger an overflow!"); + } } else { - if let Err(AllocError { .. }) = ten_u32s.try_reserve(MAX_CAP/4 - 9) { - } else { panic!("isize::MAX + 1 should trigger an OOM!") } + if let Err(AllocError { .. }) = ten_u32s.try_reserve(MAX_CAP / 4 - 9) { + } else { + panic!("isize::MAX + 1 should trigger an OOM!") + } } // Should fail in the mul-by-size if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_USIZE - 20) { @@ -1179,13 +1172,11 @@ fn test_try_reserve() { panic!("usize::MAX should trigger an overflow!"); } } - } #[test] #[cfg_attr(miri, ignore)] // Miri does not support signalling OOM fn test_try_reserve_exact() { - // This is exactly the same as test_try_reserve with the method changed. // See that test for comments. @@ -1206,20 +1197,27 @@ fn test_try_reserve_exact() { if guards_against_isize { if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP + 1) { - } else { panic!("isize::MAX + 1 should trigger an overflow!") } + } else { + panic!("isize::MAX + 1 should trigger an overflow!") + } if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_USIZE) { - } else { panic!("usize::MAX should trigger an overflow!") } + } else { + panic!("usize::MAX should trigger an overflow!") + } } else { if let Err(AllocError { .. }) = empty_bytes.try_reserve_exact(MAX_CAP + 1) { - } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } else { + panic!("isize::MAX + 1 should trigger an OOM!") + } if let Err(AllocError { .. }) = empty_bytes.try_reserve_exact(MAX_USIZE) { - } else { panic!("usize::MAX should trigger an OOM!") } + } else { + panic!("usize::MAX should trigger an OOM!") + } } } - { let mut ten_bytes: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; @@ -1231,36 +1229,46 @@ fn test_try_reserve_exact() { } if guards_against_isize { if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) { - } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + panic!("isize::MAX + 1 should trigger an overflow!"); + } } else { if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) { - } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } else { + panic!("isize::MAX + 1 should trigger an OOM!") + } } if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) { - } else { panic!("usize::MAX should trigger an overflow!") } + } else { + panic!("usize::MAX should trigger an overflow!") + } } - { let mut ten_u32s: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) { + if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 10) { panic!("isize::MAX shouldn't trigger an overflow!"); } - if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) { + if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 10) { panic!("isize::MAX shouldn't trigger an overflow!"); } if guards_against_isize { - if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) { - } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9) { + } else { + panic!("isize::MAX + 1 should trigger an overflow!"); + } } else { - if let Err(AllocError { .. }) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) { - } else { panic!("isize::MAX + 1 should trigger an OOM!") } + if let Err(AllocError { .. }) = ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9) { + } else { + panic!("isize::MAX + 1 should trigger an OOM!") + } } if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) { - } else { panic!("usize::MAX should trigger an overflow!") } + } else { + panic!("usize::MAX should trigger an overflow!") + } } - } #[test] @@ -1311,18 +1319,11 @@ fn vec_macro_repeating_null_raw_fat_pointer() { // Polyfill for https://github.com/rust-lang/rfcs/pull/2580 fn ptr_metadata(ptr: *mut dyn Fn()) -> *mut () { - unsafe { - std::mem::transmute::<*mut dyn Fn(), DynRepr>(ptr).vtable - } + unsafe { std::mem::transmute::<*mut dyn Fn(), DynRepr>(ptr).vtable } } - fn ptr_from_raw_parts(data: *mut (), vtable: *mut()) -> *mut dyn Fn() { - unsafe { - std::mem::transmute::(DynRepr { - data, - vtable - }) - } + fn ptr_from_raw_parts(data: *mut (), vtable: *mut ()) -> *mut dyn Fn() { + unsafe { std::mem::transmute::(DynRepr { data, vtable }) } } #[repr(C)] diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 19c95e2079313..dcd7dc49526b6 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -64,14 +64,14 @@ use core::intrinsics::{arith_offset, assume}; use core::iter::{FromIterator, FusedIterator, TrustedLen}; use core::marker::PhantomData; use core::mem; -use core::ops::{self, Index, IndexMut, RangeBounds}; use core::ops::Bound::{Excluded, Included, Unbounded}; +use core::ops::{self, Index, IndexMut, RangeBounds}; use core::ptr::{self, NonNull}; use core::slice::{self, SliceIndex}; -use crate::borrow::{ToOwned, Cow}; -use crate::collections::TryReserveError; +use crate::borrow::{Cow, ToOwned}; use crate::boxed::Box; +use crate::collections::TryReserveError; use crate::raw_vec::RawVec; /// A contiguous growable array type, written `Vec` but pronounced 'vector'. @@ -318,10 +318,7 @@ impl Vec { #[rustc_const_stable(feature = "const_vec_new", since = "1.32.0")] #[stable(feature = "rust1", since = "1.0.0")] pub const fn new() -> Vec { - Vec { - buf: RawVec::NEW, - len: 0, - } + Vec { buf: RawVec::NEW, len: 0 } } /// Constructs a new, empty `Vec` with the specified capacity. @@ -355,10 +352,7 @@ impl Vec { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn with_capacity(capacity: usize) -> Vec { - Vec { - buf: RawVec::with_capacity(capacity), - len: 0, - } + Vec { buf: RawVec::with_capacity(capacity), len: 0 } } /// Decomposes a `Vec` into its raw components. @@ -459,10 +453,7 @@ impl Vec { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Vec { - Vec { - buf: RawVec::from_raw_parts(ptr, capacity), - len: length, - } + Vec { buf: RawVec::from_raw_parts(ptr, capacity), len: length } } /// Returns the number of elements the vector can hold without @@ -559,7 +550,7 @@ impl Vec { /// } /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?"); /// ``` - #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] + #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")] pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> { self.buf.try_reserve(self.len, additional) } @@ -599,8 +590,8 @@ impl Vec { /// } /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?"); /// ``` - #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] - pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> { + #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")] + pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> { self.buf.try_reserve_exact(self.len, additional) } @@ -647,7 +638,7 @@ impl Vec { /// vec.shrink_to(0); /// assert!(vec.capacity() >= 3); /// ``` - #[unstable(feature = "shrink_to", reason = "new API", issue="56431")] + #[unstable(feature = "shrink_to", reason = "new API", issue = "56431")] pub fn shrink_to(&mut self, min_capacity: usize) { self.buf.shrink_to_fit(cmp::max(self.len, min_capacity)); } @@ -812,7 +803,9 @@ impl Vec { // We shadow the slice method of the same name to avoid going through // `deref`, which creates an intermediate reference. let ptr = self.buf.ptr(); - unsafe { assume(!ptr.is_null()); } + unsafe { + assume(!ptr.is_null()); + } ptr } @@ -846,7 +839,9 @@ impl Vec { // We shadow the slice method of the same name to avoid going through // `deref_mut`, which creates an intermediate reference. let ptr = self.buf.ptr(); - unsafe { assume(!ptr.is_null()); } + unsafe { + assume(!ptr.is_null()); + } ptr } @@ -1074,7 +1069,8 @@ impl Vec { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn retain(&mut self, mut f: F) - where F: FnMut(&T) -> bool + where + F: FnMut(&T) -> bool, { let len = self.len(); let mut del = 0; @@ -1110,7 +1106,11 @@ impl Vec { /// ``` #[stable(feature = "dedup_by", since = "1.16.0")] #[inline] - pub fn dedup_by_key(&mut self, mut key: F) where F: FnMut(&mut T) -> K, K: PartialEq { + pub fn dedup_by_key(&mut self, mut key: F) + where + F: FnMut(&mut T) -> K, + K: PartialEq, + { self.dedup_by(|a, b| key(a) == key(b)) } @@ -1133,7 +1133,10 @@ impl Vec { /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]); /// ``` #[stable(feature = "dedup_by", since = "1.16.0")] - pub fn dedup_by(&mut self, same_bucket: F) where F: FnMut(&mut T, &mut T) -> bool { + pub fn dedup_by(&mut self, same_bucket: F) + where + F: FnMut(&mut T, &mut T) -> bool, + { let len = { let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket); dedup.len() @@ -1256,7 +1259,8 @@ impl Vec { /// ``` #[stable(feature = "drain", since = "1.6.0")] pub fn drain(&mut self, range: R) -> Drain<'_, T> - where R: RangeBounds + where + R: RangeBounds, { // Memory safety // @@ -1272,12 +1276,12 @@ impl Vec { let start = match range.start_bound() { Included(&n) => n, Excluded(&n) => n + 1, - Unbounded => 0, + Unbounded => 0, }; let end = match range.end_bound() { Included(&n) => n + 1, Excluded(&n) => n, - Unbounded => len, + Unbounded => len, }; assert!(start <= end); assert!(end <= len); @@ -1287,8 +1291,7 @@ impl Vec { self.set_len(start); // Use the borrow in the IterMut to indicate borrowing behavior of the // whole Drain iterator (like &mut T). - let range_slice = slice::from_raw_parts_mut(self.as_mut_ptr().add(start), - end - start); + let range_slice = slice::from_raw_parts_mut(self.as_mut_ptr().add(start), end - start); Drain { tail_start: end, tail_len: len - end, @@ -1380,9 +1383,7 @@ impl Vec { self.set_len(at); other.set_len(other_len); - ptr::copy_nonoverlapping(self.as_ptr().add(at), - other.as_mut_ptr(), - other.len()); + ptr::copy_nonoverlapping(self.as_ptr().add(at), other.as_mut_ptr(), other.len()); } other } @@ -1418,7 +1419,8 @@ impl Vec { /// [`Clone`]: ../../std/clone/trait.Clone.html #[stable(feature = "vec_resize_with", since = "1.33.0")] pub fn resize_with(&mut self, new_len: usize, f: F) - where F: FnMut() -> T + where + F: FnMut() -> T, { let len = self.len(); if new_len > len { @@ -1455,7 +1457,7 @@ impl Vec { #[inline] pub fn leak<'a>(vec: Vec) -> &'a mut [T] where - T: 'a // Technically not needed, but kept to be explicit. + T: 'a, // Technically not needed, but kept to be explicit. { Box::leak(vec.into_boxed_slice()) } @@ -1553,9 +1555,12 @@ impl Vec { /// [`Default`]: ../../std/default/trait.Default.html /// [`Clone`]: ../../std/clone/trait.Clone.html #[unstable(feature = "vec_resize_default", issue = "41758")] - #[rustc_deprecated(reason = "This is moving towards being removed in favor \ + #[rustc_deprecated( + reason = "This is moving towards being removed in favor \ of `.resize_with(Default::default)`. If you disagree, please comment \ - in the tracking issue.", since = "1.33.0")] + in the tracking issue.", + since = "1.33.0" + )] pub fn resize_default(&mut self, new_len: usize) { let len = self.len(); @@ -1575,20 +1580,32 @@ trait ExtendWith { struct ExtendElement(T); impl ExtendWith for ExtendElement { - fn next(&mut self) -> T { self.0.clone() } - fn last(self) -> T { self.0 } + fn next(&mut self) -> T { + self.0.clone() + } + fn last(self) -> T { + self.0 + } } struct ExtendDefault; impl ExtendWith for ExtendDefault { - fn next(&mut self) -> T { Default::default() } - fn last(self) -> T { Default::default() } + fn next(&mut self) -> T { + Default::default() + } + fn last(self) -> T { + Default::default() + } } struct ExtendFunc(F); impl T> ExtendWith for ExtendFunc { - fn next(&mut self) -> T { (self.0)() } - fn last(mut self) -> T { (self.0)() } + fn next(&mut self) -> T { + (self.0)() + } + fn last(mut self) -> T { + (self.0)() + } } impl Vec { @@ -1718,10 +1735,7 @@ impl SpecFromElem for u8 { #[inline] fn from_elem(elem: u8, n: usize) -> Vec { if elem == 0 { - return Vec { - buf: RawVec::with_capacity_zeroed(n), - len: n, - } + return Vec { buf: RawVec::with_capacity_zeroed(n), len: n }; } unsafe { let mut v = Vec::with_capacity(n); @@ -1736,10 +1750,7 @@ impl SpecFromElem for T { #[inline] fn from_elem(elem: T, n: usize) -> Vec { if elem.is_zero() { - return Vec { - buf: RawVec::with_capacity_zeroed(n), - len: n, - } + return Vec { buf: RawVec::with_capacity_zeroed(n), len: n }; } let mut v = Vec::with_capacity(n); v.extend_with(n, ExtendElement(elem)); @@ -1760,7 +1771,7 @@ macro_rules! impl_is_zero { $is_zero(*self) } } - } + }; } impl_is_zero!(i8, |x| x == 0); @@ -1821,7 +1832,6 @@ unsafe impl IsZero for Option> { } } - //////////////////////////////////////////////////////////////////////////////// // Common trait implementations for Vec //////////////////////////////////////////////////////////////////////////////// @@ -1857,8 +1867,8 @@ impl Hash for Vec { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented( - message="vector indices are of type `usize` or ranges of `usize`", - label="vector indices are of type `usize` or ranges of `usize`", + message = "vector indices are of type `usize` or ranges of `usize`", + label = "vector indices are of type `usize` or ranges of `usize`" )] impl> Index for Vec { type Output = I::Output; @@ -1871,8 +1881,8 @@ impl> Index for Vec { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented( - message="vector indices are of type `usize` or ranges of `usize`", - label="vector indices are of type `usize` or ranges of `usize`", + message = "vector indices are of type `usize` or ranges of `usize`", + label = "vector indices are of type `usize` or ranges of `usize`" )] impl> IndexMut for Vec { #[inline] @@ -1886,18 +1896,14 @@ impl ops::Deref for Vec { type Target = [T]; fn deref(&self) -> &[T] { - unsafe { - slice::from_raw_parts(self.as_ptr(), self.len) - } + unsafe { slice::from_raw_parts(self.as_ptr(), self.len) } } } #[stable(feature = "rust1", since = "1.0.0")] impl ops::DerefMut for Vec { fn deref_mut(&mut self) -> &mut [T] { - unsafe { - slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) - } + unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) } } } @@ -1984,7 +1990,8 @@ trait SpecExtend { } impl SpecExtend for Vec - where I: Iterator, +where + I: Iterator, { default fn from_iter(mut iterator: I) -> Self { // Unroll the first iteration, as the vector is going to be @@ -2014,7 +2021,8 @@ impl SpecExtend for Vec } impl SpecExtend for Vec - where I: TrustedLen, +where + I: TrustedLen, { default fn from_iter(iterator: I) -> Self { let mut vector = Vec::new(); @@ -2026,9 +2034,12 @@ impl SpecExtend for Vec // This is the case for a TrustedLen iterator. let (low, high) = iterator.size_hint(); if let Some(high_value) = high { - debug_assert_eq!(low, high_value, - "TrustedLen iterator's size hint is not exact: {:?}", - (low, high)); + debug_assert_eq!( + low, + high_value, + "TrustedLen iterator's size hint is not exact: {:?}", + (low, high) + ); } if let Some(additional) = high { self.reserve(additional); @@ -2055,9 +2066,7 @@ impl SpecExtend> for Vec { // has not been advanced at all. if iterator.buf.as_ptr() as *const _ == iterator.ptr { unsafe { - let vec = Vec::from_raw_parts(iterator.buf.as_ptr(), - iterator.len(), - iterator.cap); + let vec = Vec::from_raw_parts(iterator.buf.as_ptr(), iterator.len(), iterator.cap); mem::forget(iterator); vec } @@ -2077,8 +2086,9 @@ impl SpecExtend> for Vec { } impl<'a, T: 'a, I> SpecExtend<&'a T, I> for Vec - where I: Iterator, - T: Clone, +where + I: Iterator, + T: Clone, { default fn from_iter(iterator: I) -> Self { SpecExtend::from_iter(iterator.cloned()) @@ -2090,7 +2100,8 @@ impl<'a, T: 'a, I> SpecExtend<&'a T, I> for Vec } impl<'a, T: 'a> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec - where T: Copy, +where + T: Copy, { fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) { let slice = iterator.as_slice(); @@ -2162,12 +2173,11 @@ impl Vec { #[inline] #[stable(feature = "vec_splice", since = "1.21.0")] pub fn splice(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter> - where R: RangeBounds, I: IntoIterator + where + R: RangeBounds, + I: IntoIterator, { - Splice { - drain: self.drain(range), - replace_with: replace_with.into_iter(), - } + Splice { drain: self.drain(range), replace_with: replace_with.into_iter() } } /// Creates an iterator which uses a closure to determine if an element should be removed. @@ -2217,21 +2227,17 @@ impl Vec { /// ``` #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F> - where F: FnMut(&mut T) -> bool, + where + F: FnMut(&mut T) -> bool, { let old_len = self.len(); // Guard against us getting leaked (leak amplification) - unsafe { self.set_len(0); } - - DrainFilter { - vec: self, - idx: 0, - del: 0, - old_len, - pred: filter, - panic_flag: false, + unsafe { + self.set_len(0); } + + DrainFilter { vec: self, idx: 0, del: 0, old_len, pred: filter, panic_flag: false } } } @@ -2380,7 +2386,10 @@ impl From<&mut [T]> for Vec { } #[stable(feature = "vec_from_cow_slice", since = "1.14.0")] -impl<'a, T> From> for Vec where [T]: ToOwned> { +impl<'a, T> From> for Vec +where + [T]: ToOwned>, +{ fn from(s: Cow<'a, [T]>) -> Vec { s.into_owned() } @@ -2437,7 +2446,10 @@ impl<'a, T: Clone> From<&'a Vec> for Cow<'a, [T]> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> FromIterator for Cow<'a, [T]> where T: Clone { +impl<'a, T> FromIterator for Cow<'a, [T]> +where + T: Clone, +{ fn from_iter>(it: I) -> Cow<'a, [T]> { Cow::Owned(FromIterator::from_iter(it)) } @@ -2466,9 +2478,7 @@ pub struct IntoIter { #[stable(feature = "vec_intoiter_debug", since = "1.13.0")] impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("IntoIter") - .field(&self.as_slice()) - .finish() + f.debug_tuple("IntoIter").field(&self.as_slice()).finish() } } @@ -2486,9 +2496,7 @@ impl IntoIter { /// ``` #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")] pub fn as_slice(&self) -> &[T] { - unsafe { - slice::from_raw_parts(self.ptr, self.len()) - } + unsafe { slice::from_raw_parts(self.ptr, self.len()) } } /// Returns the remaining items of this iterator as a mutable slice. @@ -2506,9 +2514,7 @@ impl IntoIter { /// ``` #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")] pub fn as_mut_slice(&mut self) -> &mut [T] { - unsafe { - slice::from_raw_parts_mut(self.ptr as *mut T, self.len()) - } + unsafe { slice::from_raw_parts_mut(self.ptr as *mut T, self.len()) } } } @@ -2636,9 +2642,7 @@ pub struct Drain<'a, T: 'a> { #[stable(feature = "collection_debug", since = "1.17.0")] impl fmt::Debug for Drain<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Drain") - .field(&self.iter.as_slice()) - .finish() + f.debug_tuple("Drain").field(&self.iter.as_slice()).finish() } } @@ -2711,7 +2715,6 @@ impl Drop for Drain<'_, T> { } } - #[stable(feature = "drain", since = "1.6.0")] impl ExactSizeIterator for Drain<'_, T> { fn is_empty(&self) -> bool { @@ -2762,7 +2765,6 @@ impl DoubleEndedIterator for Splice<'_, I> { #[stable(feature = "vec_splice", since = "1.21.0")] impl ExactSizeIterator for Splice<'_, I> {} - #[stable(feature = "vec_splice", since = "1.21.0")] impl Drop for Splice<'_, I> { fn drop(&mut self) { @@ -2771,21 +2773,21 @@ impl Drop for Splice<'_, I> { unsafe { if self.drain.tail_len == 0 { self.drain.vec.as_mut().extend(self.replace_with.by_ref()); - return + return; } // First fill the range left by drain(). if !self.drain.fill(&mut self.replace_with) { - return + return; } // There may be more elements. Use the lower bound as an estimate. // FIXME: Is the upper bound a better guess? Or something else? let (lower_bound, _upper_bound) = self.replace_with.size_hint(); - if lower_bound > 0 { + if lower_bound > 0 { self.drain.move_tail(lower_bound); if !self.drain.fill(&mut self.replace_with) { - return + return; } } @@ -2810,20 +2812,19 @@ impl Drain<'_, T> { /// that have been moved out. /// Fill that range as much as possible with new elements from the `replace_with` iterator. /// Returns `true` if we filled the entire range. (`replace_with.next()` didn’t return `None`.) - unsafe fn fill>(&mut self, replace_with: &mut I) -> bool { + unsafe fn fill>(&mut self, replace_with: &mut I) -> bool { let vec = self.vec.as_mut(); let range_start = vec.len; let range_end = self.tail_start; - let range_slice = slice::from_raw_parts_mut( - vec.as_mut_ptr().add(range_start), - range_end - range_start); + let range_slice = + slice::from_raw_parts_mut(vec.as_mut_ptr().add(range_start), range_end - range_start); for place in range_slice { if let Some(new_item) = replace_with.next() { ptr::write(place, new_item); vec.len += 1; } else { - return false + return false; } } true @@ -2847,7 +2848,8 @@ impl Drain<'_, T> { #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] #[derive(Debug)] pub struct DrainFilter<'a, T, F> - where F: FnMut(&mut T) -> bool, +where + F: FnMut(&mut T) -> bool, { vec: &'a mut Vec, /// The index of the item that will be inspected by the next call to `next`. @@ -2868,7 +2870,8 @@ pub struct DrainFilter<'a, T, F> #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] impl Iterator for DrainFilter<'_, T, F> - where F: FnMut(&mut T) -> bool, +where + F: FnMut(&mut T) -> bool, { type Item = T; @@ -2905,19 +2908,20 @@ impl Iterator for DrainFilter<'_, T, F> #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] impl Drop for DrainFilter<'_, T, F> - where F: FnMut(&mut T) -> bool, +where + F: FnMut(&mut T) -> bool, { fn drop(&mut self) { struct BackshiftOnDrop<'a, 'b, T, F> - where - F: FnMut(&mut T) -> bool, + where + F: FnMut(&mut T) -> bool, { drain: &'b mut DrainFilter<'a, T, F>, } impl<'a, 'b, T, F> Drop for BackshiftOnDrop<'a, 'b, T, F> - where - F: FnMut(&mut T) -> bool + where + F: FnMut(&mut T) -> bool, { fn drop(&mut self) { unsafe { @@ -2939,9 +2943,7 @@ impl Drop for DrainFilter<'_, T, F> } } - let backshift = BackshiftOnDrop { - drain: self - }; + let backshift = BackshiftOnDrop { drain: self }; // Attempt to consume any remaining elements if the filter predicate // has not yet panicked. We'll backshift any remaining elements diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 854942dad3ded..beb0bac17d2ea 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -8,14 +8,14 @@ //! This crate implements `TypedArena`, a simple arena that can only hold //! objects of a single type. -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", - test(no_crate_inject, attr(deny(warnings))))] - +#![doc( + html_root_url = "https://doc.rust-lang.org/nightly/", + test(no_crate_inject, attr(deny(warnings))) +)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] #![feature(raw_vec_internals)] #![cfg_attr(test, feature(test))] - #![allow(deprecated)] extern crate alloc; @@ -61,10 +61,7 @@ struct TypedArenaChunk { impl TypedArenaChunk { #[inline] unsafe fn new(capacity: usize) -> TypedArenaChunk { - TypedArenaChunk { - storage: RawVec::with_capacity(capacity), - entries: 0, - } + TypedArenaChunk { storage: RawVec::with_capacity(capacity), entries: 0 } } /// Destroys this arena chunk. @@ -133,9 +130,7 @@ impl TypedArena { unsafe { if mem::size_of::() == 0 { - self.ptr - .set(intrinsics::arith_offset(self.ptr.get() as *mut u8, 1) - as *mut T); + self.ptr.set(intrinsics::arith_offset(self.ptr.get() as *mut u8, 1) as *mut T); let ptr = mem::align_of::() as *mut T; // Don't drop the object. This `write` is equivalent to `forget`. ptr::write(ptr, object); @@ -260,7 +255,7 @@ impl TypedArena { self.clear_last_chunk(&mut last_chunk); let len = chunks_borrow.len(); // If `T` is ZST, code below has no effect. - for mut chunk in chunks_borrow.drain(..len-1) { + for mut chunk in chunks_borrow.drain(..len - 1) { chunk.destroy(chunk.entries); } } @@ -360,10 +355,7 @@ impl DroplessArena { let (chunk, mut new_capacity); if let Some(last_chunk) = chunks.last_mut() { let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize; - if last_chunk - .storage - .reserve_in_place(used_bytes, needed_bytes) - { + if last_chunk.storage.reserve_in_place(used_bytes, needed_bytes) { self.end.set(last_chunk.end()); return; } else { @@ -399,9 +391,7 @@ impl DroplessArena { let ptr = self.ptr.get(); // Set the pointer past ourselves - self.ptr.set( - intrinsics::arith_offset(self.ptr.get(), bytes as isize) as *mut u8, - ); + self.ptr.set(intrinsics::arith_offset(self.ptr.get(), bytes as isize) as *mut u8); slice::from_raw_parts_mut(ptr, bytes) } } @@ -410,9 +400,7 @@ impl DroplessArena { pub fn alloc(&self, object: T) -> &mut T { assert!(!mem::needs_drop::()); - let mem = self.alloc_raw( - mem::size_of::(), - mem::align_of::()) as *mut _ as *mut T; + let mem = self.alloc_raw(mem::size_of::(), mem::align_of::()) as *mut _ as *mut T; unsafe { // Write into uninitialized memory. @@ -437,9 +425,8 @@ impl DroplessArena { assert!(mem::size_of::() != 0); assert!(!slice.is_empty()); - let mem = self.alloc_raw( - slice.len() * mem::size_of::(), - mem::align_of::()) as *mut _ as *mut T; + let mem = self.alloc_raw(slice.len() * mem::size_of::(), mem::align_of::()) as *mut _ + as *mut T; unsafe { let arena_slice = slice::from_raw_parts_mut(mem, slice.len()); @@ -484,13 +471,11 @@ impl DroplessArena { let len = min; if len == 0 { - return &mut [] + return &mut []; } let size = len.checked_mul(mem::size_of::()).unwrap(); let mem = self.alloc_raw(size, mem::align_of::()) as *mut _ as *mut T; - unsafe { - self.write_from_iter(iter, len, mem) - } + unsafe { self.write_from_iter(iter, len, mem) } } (_, _) => { cold_path(move || -> &mut [T] { @@ -502,10 +487,9 @@ impl DroplessArena { // the content of the SmallVec unsafe { let len = vec.len(); - let start_ptr = self.alloc_raw( - len * mem::size_of::(), - mem::align_of::() - ) as *mut _ as *mut T; + let start_ptr = self + .alloc_raw(len * mem::size_of::(), mem::align_of::()) + as *mut _ as *mut T; vec.as_ptr().copy_to_nonoverlapping(start_ptr, len); vec.set_len(0); slice::from_raw_parts_mut(start_ptr, len) diff --git a/src/libarena/tests.rs b/src/libarena/tests.rs index fa4189409d0e8..8e63bdf545841 100644 --- a/src/libarena/tests.rs +++ b/src/libarena/tests.rs @@ -1,7 +1,7 @@ extern crate test; -use test::Bencher; use super::TypedArena; use std::cell::Cell; +use test::Bencher; #[allow(dead_code)] #[derive(Debug, Eq, PartialEq)] @@ -53,9 +53,7 @@ fn test_arena_alloc_nested() { let arena = Wrap(TypedArena::default()); - let result = arena.alloc_outer(|| Outer { - inner: arena.alloc_inner(|| Inner { value: 10 }), - }); + let result = arena.alloc_outer(|| Outer { inner: arena.alloc_inner(|| Inner { value: 10 }) }); assert_eq!(result.inner.value, 10); } @@ -91,10 +89,7 @@ struct Noncopy { pub fn test_noncopy() { let arena = TypedArena::default(); for _ in 0..100000 { - arena.alloc(Noncopy { - string: "hello world".to_string(), - array: vec![1, 2, 3, 4, 5], - }); + arena.alloc(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] }); } } @@ -195,19 +190,14 @@ fn test_typed_arena_drop_small_count() { pub fn bench_noncopy(b: &mut Bencher) { let arena = TypedArena::default(); b.iter(|| { - arena.alloc(Noncopy { - string: "hello world".to_string(), - array: vec![1, 2, 3, 4, 5], - }) + arena.alloc(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] }) }) } #[bench] pub fn bench_noncopy_nonarena(b: &mut Bencher) { b.iter(|| { - let _: Box<_> = Box::new(Noncopy { - string: "hello world".to_string(), - array: vec![1, 2, 3, 4, 5], - }); + let _: Box<_> = + Box::new(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] }); }) } diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs index cb476acfb3a9e..b2d4b1b5fb916 100644 --- a/src/libcore/alloc.rs +++ b/src/libcore/alloc.rs @@ -7,9 +7,9 @@ use crate::cmp; use crate::fmt; use crate::mem; -use crate::usize; -use crate::ptr::{self, NonNull}; use crate::num::NonZeroUsize; +use crate::ptr::{self, NonNull}; +use crate::usize; /// Represents the combination of a starting address and /// a total capacity of the returned block. @@ -88,9 +88,7 @@ impl Layout { return Err(LayoutErr { private: () }); } - unsafe { - Ok(Layout::from_size_align_unchecked(size, align)) - } + unsafe { Ok(Layout::from_size_align_unchecked(size, align)) } } /// Creates a layout, bypassing all checks. @@ -109,12 +107,16 @@ impl Layout { /// The minimum size in bytes for a memory block of this layout. #[stable(feature = "alloc_layout", since = "1.28.0")] #[inline] - pub fn size(&self) -> usize { self.size_ } + pub fn size(&self) -> usize { + self.size_ + } /// The minimum byte alignment for a memory block of this layout. #[stable(feature = "alloc_layout", since = "1.28.0")] #[inline] - pub fn align(&self) -> usize { self.align_.get() } + pub fn align(&self) -> usize { + self.align_.get() + } /// Constructs a `Layout` suitable for holding a value of type `T`. #[stable(feature = "alloc_layout", since = "1.28.0")] @@ -126,9 +128,7 @@ impl Layout { // result use the unchecked constructor here to avoid inserting code // that panics if it isn't optimized well enough. debug_assert!(Layout::from_size_align(size, align).is_ok()); - unsafe { - Layout::from_size_align_unchecked(size, align) - } + unsafe { Layout::from_size_align_unchecked(size, align) } } /// Produces layout describing a record that could be used to @@ -140,9 +140,7 @@ impl Layout { let (size, align) = (mem::size_of_val(t), mem::align_of_val(t)); // See rationale in `new` for why this is using an unsafe variant below debug_assert!(Layout::from_size_align(size, align).is_ok()); - unsafe { - Layout::from_size_align_unchecked(size, align) - } + unsafe { Layout::from_size_align_unchecked(size, align) } } /// Creates a layout describing the record that can hold a value @@ -206,8 +204,7 @@ impl Layout { // size and padding overflow in the above manner should cause // the allocator to yield an error anyway.) - let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) - & !align.wrapping_sub(1); + let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1); len_rounded_up.wrapping_sub(len) } @@ -245,8 +242,7 @@ impl Layout { // > must not overflow (i.e., the rounded value must be less than // > `usize::MAX`) let padded_size = self.size() + self.padding_needed_for(self.align()); - let alloc_size = padded_size.checked_mul(n) - .ok_or(LayoutErr { private: () })?; + let alloc_size = padded_size.checked_mul(n).ok_or(LayoutErr { private: () })?; unsafe { // self.align is already known to be valid and alloc_size has been @@ -275,10 +271,8 @@ impl Layout { let new_align = cmp::max(self.align(), next.align()); let pad = self.padding_needed_for(next.align()); - let offset = self.size().checked_add(pad) - .ok_or(LayoutErr { private: () })?; - let new_size = offset.checked_add(next.size()) - .ok_or(LayoutErr { private: () })?; + let offset = self.size().checked_add(pad).ok_or(LayoutErr { private: () })?; + let new_size = offset.checked_add(next.size()).ok_or(LayoutErr { private: () })?; let layout = Layout::from_size_align(new_size, new_align)?; Ok((layout, offset)) @@ -312,8 +306,7 @@ impl Layout { #[unstable(feature = "alloc_layout_extra", issue = "55724")] #[inline] pub fn extend_packed(&self, next: Self) -> Result { - let new_size = self.size().checked_add(next.size()) - .ok_or(LayoutErr { private: () })?; + let new_size = self.size().checked_add(next.size()).ok_or(LayoutErr { private: () })?; Layout::from_size_align(new_size, self.align()) } @@ -323,12 +316,10 @@ impl Layout { #[unstable(feature = "alloc_layout_extra", issue = "55724")] #[inline] pub fn array(n: usize) -> Result { - Layout::new::() - .repeat(n) - .map(|(k, offs)| { - debug_assert!(offs == mem::size_of::()); - k - }) + Layout::new::().repeat(n).map(|(k, offs)| { + debug_assert!(offs == mem::size_of::()); + k + }) } } @@ -338,7 +329,7 @@ impl Layout { #[stable(feature = "alloc_layout", since = "1.28.0")] #[derive(Clone, PartialEq, Eq, Debug)] pub struct LayoutErr { - private: () + private: (), } // (we need this for downstream impl of trait Error) @@ -577,11 +568,7 @@ pub unsafe trait GlobalAlloc { let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); let new_ptr = self.alloc(new_layout); if !new_ptr.is_null() { - ptr::copy_nonoverlapping( - ptr, - new_ptr, - cmp::min(layout.size(), new_size), - ); + ptr::copy_nonoverlapping(ptr, new_ptr, cmp::min(layout.size(), new_size)); self.dealloc(ptr, layout); } new_ptr @@ -669,7 +656,6 @@ pub unsafe trait GlobalAlloc { /// the future. #[unstable(feature = "allocator_api", issue = "32838")] pub unsafe trait Alloc { - // (Note: some existing allocators have unspecified but well-defined // behavior in response to a zero size allocation request ; // e.g., in C, `malloc` of 0 will either return a null pointer or a @@ -826,10 +812,12 @@ pub unsafe trait Alloc { /// rather than directly invoking `panic!` or similar. /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html - unsafe fn realloc(&mut self, - ptr: NonNull, - layout: Layout, - new_size: usize) -> Result, AllocErr> { + unsafe fn realloc( + &mut self, + ptr: NonNull, + layout: Layout, + new_size: usize, + ) -> Result, AllocErr> { let old_size = layout.size(); if new_size >= old_size { @@ -846,9 +834,7 @@ pub unsafe trait Alloc { let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); let result = self.alloc(new_layout); if let Ok(new_ptr) = result { - ptr::copy_nonoverlapping(ptr.as_ptr(), - new_ptr.as_ptr(), - cmp::min(old_size, new_size)); + ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_ptr(), cmp::min(old_size, new_size)); self.dealloc(ptr, layout); } result @@ -924,14 +910,15 @@ pub unsafe trait Alloc { /// rather than directly invoking `panic!` or similar. /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html - unsafe fn realloc_excess(&mut self, - ptr: NonNull, - layout: Layout, - new_size: usize) -> Result { + unsafe fn realloc_excess( + &mut self, + ptr: NonNull, + layout: Layout, + new_size: usize, + ) -> Result { let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); let usable_size = self.usable_size(&new_layout); - self.realloc(ptr, layout, new_size) - .map(|p| Excess(p, usable_size.1)) + self.realloc(ptr, layout, new_size).map(|p| Excess(p, usable_size.1)) } /// Attempts to extend the allocation referenced by `ptr` to fit `new_size`. @@ -969,20 +956,18 @@ pub unsafe trait Alloc { /// function; clients are expected either to be able to recover from /// `grow_in_place` failures without aborting, or to fall back on /// another reallocation method before resorting to an abort. - unsafe fn grow_in_place(&mut self, - ptr: NonNull, - layout: Layout, - new_size: usize) -> Result<(), CannotReallocInPlace> { + unsafe fn grow_in_place( + &mut self, + ptr: NonNull, + layout: Layout, + new_size: usize, + ) -> Result<(), CannotReallocInPlace> { let _ = ptr; // this default implementation doesn't care about the actual address. debug_assert!(new_size >= layout.size()); let (_l, u) = self.usable_size(&layout); // _l <= layout.size() [guaranteed by usable_size()] // layout.size() <= new_layout.size() [required by this method] - if new_size <= u { - Ok(()) - } else { - Err(CannotReallocInPlace) - } + if new_size <= u { Ok(()) } else { Err(CannotReallocInPlace) } } /// Attempts to shrink the allocation referenced by `ptr` to fit `new_size`. @@ -1024,23 +1009,20 @@ pub unsafe trait Alloc { /// function; clients are expected either to be able to recover from /// `shrink_in_place` failures without aborting, or to fall back /// on another reallocation method before resorting to an abort. - unsafe fn shrink_in_place(&mut self, - ptr: NonNull, - layout: Layout, - new_size: usize) -> Result<(), CannotReallocInPlace> { + unsafe fn shrink_in_place( + &mut self, + ptr: NonNull, + layout: Layout, + new_size: usize, + ) -> Result<(), CannotReallocInPlace> { let _ = ptr; // this default implementation doesn't care about the actual address. debug_assert!(new_size <= layout.size()); let (l, _u) = self.usable_size(&layout); // layout.size() <= _u [guaranteed by usable_size()] // new_layout.size() <= layout.size() [required by this method] - if l <= new_size { - Ok(()) - } else { - Err(CannotReallocInPlace) - } + if l <= new_size { Ok(()) } else { Err(CannotReallocInPlace) } } - // == COMMON USAGE PATTERNS == // alloc_one, dealloc_one, alloc_array, realloc_array. dealloc_array @@ -1074,14 +1056,11 @@ pub unsafe trait Alloc { /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html fn alloc_one(&mut self) -> Result, AllocErr> - where Self: Sized + where + Self: Sized, { let k = Layout::new::(); - if k.size() > 0 { - unsafe { self.alloc(k).map(|p| p.cast()) } - } else { - Err(AllocErr) - } + if k.size() > 0 { unsafe { self.alloc(k).map(|p| p.cast()) } } else { Err(AllocErr) } } /// Deallocates a block suitable for holding an instance of `T`. @@ -1102,7 +1081,8 @@ pub unsafe trait Alloc { /// /// * the layout of `T` must *fit* that block of memory. unsafe fn dealloc_one(&mut self, ptr: NonNull) - where Self: Sized + where + Self: Sized, { let k = Layout::new::(); if k.size() > 0 { @@ -1143,14 +1123,11 @@ pub unsafe trait Alloc { /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html fn alloc_array(&mut self, n: usize) -> Result, AllocErr> - where Self: Sized + where + Self: Sized, { match Layout::array::(n) { - Ok(layout) if layout.size() > 0 => { - unsafe { - self.alloc(layout).map(|p| p.cast()) - } - } + Ok(layout) if layout.size() > 0 => unsafe { self.alloc(layout).map(|p| p.cast()) }, _ => Err(AllocErr), } } @@ -1189,20 +1166,21 @@ pub unsafe trait Alloc { /// rather than directly invoking `panic!` or similar. /// /// [`handle_alloc_error`]: ../../alloc/alloc/fn.handle_alloc_error.html - unsafe fn realloc_array(&mut self, - ptr: NonNull, - n_old: usize, - n_new: usize) -> Result, AllocErr> - where Self: Sized + unsafe fn realloc_array( + &mut self, + ptr: NonNull, + n_old: usize, + n_new: usize, + ) -> Result, AllocErr> + where + Self: Sized, { match (Layout::array::(n_old), Layout::array::(n_new)) { (Ok(k_old), Ok(k_new)) if k_old.size() > 0 && k_new.size() > 0 => { debug_assert!(k_old.align() == k_new.align()); self.realloc(ptr.cast(), k_old, k_new.size()).map(NonNull::cast) } - _ => { - Err(AllocErr) - } + _ => Err(AllocErr), } } @@ -1227,15 +1205,12 @@ pub unsafe trait Alloc { /// /// Always returns `Err` on arithmetic overflow. unsafe fn dealloc_array(&mut self, ptr: NonNull, n: usize) -> Result<(), AllocErr> - where Self: Sized + where + Self: Sized, { match Layout::array::(n) { - Ok(k) if k.size() > 0 => { - Ok(self.dealloc(ptr.cast(), k)) - } - _ => { - Err(AllocErr) - } + Ok(k) if k.size() > 0 => Ok(self.dealloc(ptr.cast(), k)), + _ => Err(AllocErr), } } } diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 5126fe01a3f00..4afea12a362c8 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -105,8 +105,10 @@ pub trait Any: 'static { } #[stable(feature = "rust1", since = "1.0.0")] -impl Any for T { - fn type_id(&self) -> TypeId { TypeId::of::() } +impl Any for T { + fn type_id(&self) -> TypeId { + TypeId::of::() + } } /////////////////////////////////////////////////////////////////////////////// @@ -193,9 +195,7 @@ impl dyn Any { pub fn downcast_ref(&self) -> Option<&T> { if self.is::() { // SAFETY: just checked whether we are pointing to the correct type - unsafe { - Some(&*(self as *const dyn Any as *const T)) - } + unsafe { Some(&*(self as *const dyn Any as *const T)) } } else { None } @@ -229,16 +229,14 @@ impl dyn Any { pub fn downcast_mut(&mut self) -> Option<&mut T> { if self.is::() { // SAFETY: just checked whether we are pointing to the correct type - unsafe { - Some(&mut *(self as *mut dyn Any as *mut T)) - } + unsafe { Some(&mut *(self as *mut dyn Any as *mut T)) } } else { None } } } -impl dyn Any+Send { +impl dyn Any + Send { /// Forwards to the method defined on the type `Any`. /// /// # Examples @@ -316,7 +314,7 @@ impl dyn Any+Send { } } -impl dyn Any+Send+Sync { +impl dyn Any + Send + Sync { /// Forwards to the method defined on the type `Any`. /// /// # Examples @@ -433,11 +431,9 @@ impl TypeId { /// assert_eq!(is_string(&"cookie monster".to_string()), true); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature="const_type_id", issue = "41875")] + #[rustc_const_unstable(feature = "const_type_id", issue = "41875")] pub const fn of() -> TypeId { - TypeId { - t: intrinsics::type_id::(), - } + TypeId { t: intrinsics::type_id::() } } } diff --git a/src/libcore/array/iter.rs b/src/libcore/array/iter.rs index aab9463e3aade..80eaae0d4afb5 100644 --- a/src/libcore/array/iter.rs +++ b/src/libcore/array/iter.rs @@ -1,5 +1,6 @@ //! Defines the `IntoIter` owned iterator for arrays. +use super::LengthAtMost32; use crate::{ fmt, iter::{ExactSizeIterator, FusedIterator, TrustedLen}, @@ -7,8 +8,6 @@ use crate::{ ops::Range, ptr, }; -use super::LengthAtMost32; - /// A by-value [array] iterator. /// @@ -40,7 +39,7 @@ where alive: Range, } -impl IntoIter +impl IntoIter where [T; N]: LengthAtMost32, { @@ -75,10 +74,7 @@ where data }; - Self { - data, - alive: 0..N, - } + Self { data, alive: 0..N } } /// Returns an immutable slice of all elements that have not been yielded @@ -88,9 +84,7 @@ where // SAFETY: This transmute is safe. As mentioned in `new`, `MaybeUninit` retains // the size and alignment of `T`. Furthermore, we know that all // elements within `alive` are properly initialized. - unsafe { - mem::transmute::<&[MaybeUninit], &[T]>(slice) - } + unsafe { mem::transmute::<&[MaybeUninit], &[T]>(slice) } } /// Returns a mutable slice of all elements that have not been yielded yet. @@ -100,15 +94,12 @@ where // SAFETY: This transmute is safe. As mentioned in `new`, `MaybeUninit` retains // the size and alignment of `T`. Furthermore, we know that all // elements within `alive` are properly initialized. - unsafe { - mem::transmute::<&mut [MaybeUninit], &mut [T]>(slice) - } + unsafe { mem::transmute::<&mut [MaybeUninit], &mut [T]>(slice) } } } - #[stable(feature = "array_value_iter_impls", since = "1.40.0")] -impl Iterator for IntoIter +impl Iterator for IntoIter where [T; N]: LengthAtMost32, { @@ -155,7 +146,7 @@ where } #[stable(feature = "array_value_iter_impls", since = "1.40.0")] -impl DoubleEndedIterator for IntoIter +impl DoubleEndedIterator for IntoIter where [T; N]: LengthAtMost32, { @@ -191,7 +182,7 @@ where } #[stable(feature = "array_value_iter_impls", since = "1.40.0")] -impl Drop for IntoIter +impl Drop for IntoIter where [T; N]: LengthAtMost32, { @@ -199,14 +190,12 @@ where // SAFETY: This is safe: `as_mut_slice` returns exactly the sub-slice // of elements that have not been moved out yet and that remain // to be dropped. - unsafe { - ptr::drop_in_place(self.as_mut_slice()) - } + unsafe { ptr::drop_in_place(self.as_mut_slice()) } } } #[stable(feature = "array_value_iter_impls", since = "1.40.0")] -impl ExactSizeIterator for IntoIter +impl ExactSizeIterator for IntoIter where [T; N]: LengthAtMost32, { @@ -221,23 +210,17 @@ where } #[stable(feature = "array_value_iter_impls", since = "1.40.0")] -impl FusedIterator for IntoIter -where - [T; N]: LengthAtMost32, -{} +impl FusedIterator for IntoIter where [T; N]: LengthAtMost32 {} // The iterator indeed reports the correct length. The number of "alive" // elements (that will still be yielded) is the length of the range `alive`. // This range is decremented in length in either `next` or `next_back`. It is // always decremented by 1 in those methods, but only if `Some(_)` is returned. #[stable(feature = "array_value_iter_impls", since = "1.40.0")] -unsafe impl TrustedLen for IntoIter -where - [T; N]: LengthAtMost32, -{} +unsafe impl TrustedLen for IntoIter where [T; N]: LengthAtMost32 {} #[stable(feature = "array_value_iter_impls", since = "1.40.0")] -impl Clone for IntoIter +impl Clone for IntoIter where [T; N]: LengthAtMost32, { @@ -260,24 +243,19 @@ where new_data.get_unchecked_mut(idx).write(clone); } - Self { - data: new_data, - alive: self.alive.clone(), - } + Self { data: new_data, alive: self.alive.clone() } } } } #[stable(feature = "array_value_iter_impls", since = "1.40.0")] -impl fmt::Debug for IntoIter +impl fmt::Debug for IntoIter where [T; N]: LengthAtMost32, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Only print the elements that were not yielded yet: we cannot // access the yielded elements anymore. - f.debug_tuple("IntoIter") - .field(&self.as_slice()) - .finish() + f.debug_tuple("IntoIter").field(&self.as_slice()).finish() } } diff --git a/src/libcore/array/mod.rs b/src/libcore/array/mod.rs index fd80000b6fb8c..937451274cfc2 100644 --- a/src/libcore/array/mod.rs +++ b/src/libcore/array/mod.rs @@ -10,7 +10,7 @@ use crate::borrow::{Borrow, BorrowMut}; use crate::cmp::Ordering; use crate::convert::{Infallible, TryFrom}; use crate::fmt; -use crate::hash::{Hash, self}; +use crate::hash::{self, Hash}; use crate::marker::Unsize; use crate::slice::{Iter, IterMut}; @@ -71,10 +71,12 @@ impl fmt::Display for TryFromSliceError { } impl TryFromSliceError { - #[unstable(feature = "array_error_internals", - reason = "available through Error trait and this method should not \ + #[unstable( + feature = "array_error_internals", + reason = "available through Error trait and this method should not \ be exposed publicly", - issue = "none")] + issue = "none" + )] #[inline] #[doc(hidden)] pub fn __description(&self) -> &str { @@ -385,11 +387,12 @@ where } /// Implemented for lengths where trait impls are allowed on arrays in core/std -#[rustc_on_unimplemented( - message="arrays only have std trait implementations for lengths 0..=32", +#[rustc_on_unimplemented(message = "arrays only have std trait implementations for lengths 0..=32")] +#[unstable( + feature = "const_generic_impls_guard", + issue = "none", + reason = "will never be stable, just a temporary step until const generics are stable" )] -#[unstable(feature = "const_generic_impls_guard", issue = "none", - reason = "will never be stable, just a temporary step until const generics are stable")] pub trait LengthAtMost32 {} macro_rules! array_impls { @@ -429,4 +432,4 @@ macro_rules! array_impl_default { }; } -array_impl_default!{32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T} +array_impl_default! {32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T} diff --git a/src/libcore/benches/pattern.rs b/src/libcore/benches/pattern.rs index a49490cec1219..480ac6f36d202 100644 --- a/src/libcore/benches/pattern.rs +++ b/src/libcore/benches/pattern.rs @@ -21,7 +21,6 @@ fn starts_with_str(b: &mut Bencher) { }) } - #[bench] fn ends_with_char(b: &mut Bencher) { let text = black_box("kdjsfhlakfhlsghlkvcnljknfqiunvcijqenwodind"); diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 4d58aaca94183..3e533255becb5 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -189,7 +189,7 @@ pub trait Borrow { /// /// [`Borrow`]: trait.Borrow.html #[stable(feature = "rust1", since = "1.0.0")] -pub trait BorrowMut : Borrow { +pub trait BorrowMut: Borrow { /// Mutably borrows from an owned value. /// /// # Examples @@ -211,25 +211,35 @@ pub trait BorrowMut : Borrow { #[stable(feature = "rust1", since = "1.0.0")] impl Borrow for T { - fn borrow(&self) -> &T { self } + fn borrow(&self) -> &T { + self + } } #[stable(feature = "rust1", since = "1.0.0")] impl BorrowMut for T { - fn borrow_mut(&mut self) -> &mut T { self } + fn borrow_mut(&mut self) -> &mut T { + self + } } #[stable(feature = "rust1", since = "1.0.0")] impl Borrow for &T { - fn borrow(&self) -> &T { &**self } + fn borrow(&self) -> &T { + &**self + } } #[stable(feature = "rust1", since = "1.0.0")] impl Borrow for &mut T { - fn borrow(&self) -> &T { &**self } + fn borrow(&self) -> &T { + &**self + } } #[stable(feature = "rust1", since = "1.0.0")] impl BorrowMut for &mut T { - fn borrow_mut(&mut self) -> &mut T { &mut **self } + fn borrow_mut(&mut self) -> &mut T { + &mut **self + } } diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 099e5307f64c8..4fcd0d9737d56 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -195,7 +195,7 @@ use crate::cmp::Ordering; use crate::fmt::{self, Debug, Display}; use crate::marker::Unsize; use crate::mem; -use crate::ops::{Deref, DerefMut, CoerceUnsized}; +use crate::ops::{CoerceUnsized, Deref, DerefMut}; use crate::ptr; /// A mutable memory location. @@ -243,7 +243,7 @@ unsafe impl Send for Cell where T: Send {} impl !Sync for Cell {} #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Cell { +impl Clone for Cell { #[inline] fn clone(&self) -> Cell { Cell::new(self.get()) @@ -327,9 +327,7 @@ impl Cell { #[rustc_const_stable(feature = "const_cell_new", since = "1.32.0")] #[inline] pub const fn new(value: T) -> Cell { - Cell { - value: UnsafeCell::new(value), - } + Cell { value: UnsafeCell::new(value) } } /// Sets the contained value. @@ -410,7 +408,7 @@ impl Cell { } } -impl Cell { +impl Cell { /// Returns a copy of the contained value. /// /// # Examples @@ -425,7 +423,7 @@ impl Cell { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self) -> T { - unsafe{ *self.value.get() } + unsafe { *self.value.get() } } /// Updates the contained value using a function and returns the new value. @@ -493,9 +491,7 @@ impl Cell { #[inline] #[stable(feature = "cell_get_mut", since = "1.11.0")] pub fn get_mut(&mut self) -> &mut T { - unsafe { - &mut *self.value.get() - } + unsafe { &mut *self.value.get() } } /// Returns a `&Cell` from a `&mut T` @@ -514,9 +510,7 @@ impl Cell { #[inline] #[stable(feature = "as_cell", since = "1.37.0")] pub fn from_mut(t: &mut T) -> &Cell { - unsafe { - &*(t as *mut T as *const Cell) - } + unsafe { &*(t as *mut T as *const Cell) } } } @@ -559,9 +553,7 @@ impl Cell<[T]> { /// ``` #[stable(feature = "as_cell", since = "1.37.0")] pub fn as_slice_of_cells(&self) -> &[Cell] { - unsafe { - &*(self as *const Cell<[T]> as *const [Cell]) - } + unsafe { &*(self as *const Cell<[T]> as *const [Cell]) } } } @@ -654,10 +646,7 @@ impl RefCell { #[rustc_const_stable(feature = "const_refcell_new", since = "1.32.0")] #[inline] pub const fn new(value: T) -> RefCell { - RefCell { - value: UnsafeCell::new(value), - borrow: Cell::new(UNUSED), - } + RefCell { value: UnsafeCell::new(value), borrow: Cell::new(UNUSED) } } /// Consumes the `RefCell`, returning the wrapped value. @@ -700,7 +689,7 @@ impl RefCell { /// assert_eq!(cell, RefCell::new(6)); /// ``` #[inline] - #[stable(feature = "refcell_replace", since="1.24.0")] + #[stable(feature = "refcell_replace", since = "1.24.0")] pub fn replace(&self, t: T) -> T { mem::replace(&mut *self.borrow_mut(), t) } @@ -722,7 +711,7 @@ impl RefCell { /// assert_eq!(cell, RefCell::new(6)); /// ``` #[inline] - #[stable(feature = "refcell_replace_swap", since="1.35.0")] + #[stable(feature = "refcell_replace_swap", since = "1.35.0")] pub fn replace_with T>(&self, f: F) -> T { let mut_borrow = &mut *self.borrow_mut(); let replacement = f(mut_borrow); @@ -749,7 +738,7 @@ impl RefCell { /// assert_eq!(d, RefCell::new(5)); /// ``` #[inline] - #[stable(feature = "refcell_swap", since="1.24.0")] + #[stable(feature = "refcell_swap", since = "1.24.0")] pub fn swap(&self, other: &Self) { mem::swap(&mut *self.borrow_mut(), &mut *other.borrow_mut()) } @@ -827,10 +816,7 @@ impl RefCell { #[inline] pub fn try_borrow(&self) -> Result, BorrowError> { match BorrowRef::new(&self.borrow) { - Some(b) => Ok(Ref { - value: unsafe { &*self.value.get() }, - borrow: b, - }), + Some(b) => Ok(Ref { value: unsafe { &*self.value.get() }, borrow: b }), None => Err(BorrowError { _private: () }), } } @@ -905,10 +891,7 @@ impl RefCell { #[inline] pub fn try_borrow_mut(&self) -> Result, BorrowMutError> { match BorrowRefMut::new(&self.borrow) { - Some(b) => Ok(RefMut { - value: unsafe { &mut *self.value.get() }, - borrow: b, - }), + Some(b) => Ok(RefMut { value: unsafe { &mut *self.value.get() }, borrow: b }), None => Err(BorrowMutError { _private: () }), } } @@ -957,9 +940,7 @@ impl RefCell { #[inline] #[stable(feature = "cell_get_mut", since = "1.11.0")] pub fn get_mut(&mut self) -> &mut T { - unsafe { - &mut *self.value.get() - } + unsafe { &mut *self.value.get() } } /// Immutably borrows the wrapped value, returning an error if the value is @@ -1189,10 +1170,7 @@ impl<'b, T: ?Sized> Ref<'b, T> { #[stable(feature = "cell_extras", since = "1.15.0")] #[inline] pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> { - Ref { - value: orig.value, - borrow: orig.borrow.clone(), - } + Ref { value: orig.value, borrow: orig.borrow.clone() } } /// Makes a new `Ref` for a component of the borrowed data. @@ -1216,12 +1194,10 @@ impl<'b, T: ?Sized> Ref<'b, T> { #[stable(feature = "cell_map", since = "1.8.0")] #[inline] pub fn map(orig: Ref<'b, T>, f: F) -> Ref<'b, U> - where F: FnOnce(&T) -> &U + where + F: FnOnce(&T) -> &U, { - Ref { - value: f(orig.value), - borrow: orig.borrow, - } + Ref { value: f(orig.value), borrow: orig.borrow } } /// Splits a `Ref` into multiple `Ref`s for different components of the @@ -1247,7 +1223,8 @@ impl<'b, T: ?Sized> Ref<'b, T> { #[stable(feature = "refcell_map_split", since = "1.35.0")] #[inline] pub fn map_split(orig: Ref<'b, T>, f: F) -> (Ref<'b, U>, Ref<'b, V>) - where F: FnOnce(&T) -> (&U, &V) + where + F: FnOnce(&T) -> (&U, &V), { let (a, b) = f(orig.value); let borrow = orig.borrow.clone(); @@ -1292,14 +1269,12 @@ impl<'b, T: ?Sized> RefMut<'b, T> { #[stable(feature = "cell_map", since = "1.8.0")] #[inline] pub fn map(orig: RefMut<'b, T>, f: F) -> RefMut<'b, U> - where F: FnOnce(&mut T) -> &mut U + where + F: FnOnce(&mut T) -> &mut U, { // FIXME(nll-rfc#40): fix borrow-check let RefMut { value, borrow } = orig; - RefMut { - value: f(value), - borrow, - } + RefMut { value: f(value), borrow } } /// Splits a `RefMut` into multiple `RefMut`s for different components of the @@ -1330,9 +1305,11 @@ impl<'b, T: ?Sized> RefMut<'b, T> { #[stable(feature = "refcell_map_split", since = "1.35.0")] #[inline] pub fn map_split( - orig: RefMut<'b, T>, f: F + orig: RefMut<'b, T>, + f: F, ) -> (RefMut<'b, U>, RefMut<'b, V>) - where F: FnOnce(&mut T) -> (&mut U, &mut V) + where + F: FnOnce(&mut T) -> (&mut U, &mut V), { let (a, b) = f(orig.value); let borrow = orig.borrow.clone(); @@ -1364,7 +1341,7 @@ impl<'b> BorrowRefMut<'b> { UNUSED => { borrow.set(UNUSED - 1); Some(BorrowRefMut { borrow }) - }, + } _ => None, } } diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index a0e72fb66b0a1..0d4788dfc570b 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -195,8 +195,8 @@ use self::Ordering::*; #[doc(alias = "==")] #[doc(alias = "!=")] #[rustc_on_unimplemented( - message="can't compare `{Self}` with `{Rhs}`", - label="no implementation for `{Self} == {Rhs}`", + message = "can't compare `{Self}` with `{Rhs}`", + label = "no implementation for `{Self} == {Rhs}`" )] pub trait PartialEq { /// This method tests for `self` and `other` values to be equal, and is used @@ -209,14 +209,18 @@ pub trait PartialEq { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - fn ne(&self, other: &Rhs) -> bool { !self.eq(other) } + fn ne(&self, other: &Rhs) -> bool { + !self.eq(other) + } } /// Derive macro generating an impl of the trait `PartialEq`. #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics, structural_match)] -pub macro PartialEq($item:item) { /* compiler built-in */ } +pub macro PartialEq($item:item) { + /* compiler built-in */ +} /// Trait for equality comparisons which are [equivalence relations]( /// https://en.wikipedia.org/wiki/Equivalence_relation). @@ -278,7 +282,9 @@ pub trait Eq: PartialEq { #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics, derive_eq, structural_match)] -pub macro Eq($item:item) { /* compiler built-in */ } +pub macro Eq($item:item) { + /* compiler built-in */ +} // FIXME: this struct is used solely by #[derive] to // assert that every component of a type implements Eq. @@ -286,10 +292,10 @@ pub macro Eq($item:item) { /* compiler built-in */ } // This struct should never appear in user code. #[doc(hidden)] #[allow(missing_debug_implementations)] -#[unstable(feature = "derive_eq", - reason = "deriving hack, should not be public", - issue = "none")] -pub struct AssertParamIsEq { _field: crate::marker::PhantomData } +#[unstable(feature = "derive_eq", reason = "deriving hack, should not be public", issue = "none")] +pub struct AssertParamIsEq { + _field: crate::marker::PhantomData, +} /// An `Ordering` is the result of a comparison between two values. /// @@ -460,13 +466,21 @@ impl PartialOrd for Reverse { } #[inline] - fn lt(&self, other: &Self) -> bool { other.0 < self.0 } + fn lt(&self, other: &Self) -> bool { + other.0 < self.0 + } #[inline] - fn le(&self, other: &Self) -> bool { other.0 <= self.0 } + fn le(&self, other: &Self) -> bool { + other.0 <= self.0 + } #[inline] - fn gt(&self, other: &Self) -> bool { other.0 > self.0 } + fn gt(&self, other: &Self) -> bool { + other.0 > self.0 + } #[inline] - fn ge(&self, other: &Self) -> bool { other.0 >= self.0 } + fn ge(&self, other: &Self) -> bool { + other.0 >= self.0 + } } #[stable(feature = "reverse_cmp_key", since = "1.19.0")] @@ -570,7 +584,9 @@ pub trait Ord: Eq + PartialOrd { #[stable(feature = "ord_max_min", since = "1.21.0")] #[inline] fn max(self, other: Self) -> Self - where Self: Sized { + where + Self: Sized, + { max_by(self, other, Ord::cmp) } @@ -587,7 +603,9 @@ pub trait Ord: Eq + PartialOrd { #[stable(feature = "ord_max_min", since = "1.21.0")] #[inline] fn min(self, other: Self) -> Self - where Self: Sized { + where + Self: Sized, + { min_by(self, other, Ord::cmp) } @@ -611,7 +629,9 @@ pub trait Ord: Eq + PartialOrd { /// ``` #[unstable(feature = "clamp", issue = "44095")] fn clamp(self, min: Self, max: Self) -> Self - where Self: Sized { + where + Self: Sized, + { assert!(min <= max); if self < min { min @@ -627,7 +647,9 @@ pub trait Ord: Eq + PartialOrd { #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics)] -pub macro Ord($item:item) { /* compiler built-in */ } +pub macro Ord($item:item) { + /* compiler built-in */ +} #[stable(feature = "rust1", since = "1.0.0")] impl Eq for Ordering {} @@ -753,8 +775,8 @@ impl PartialOrd for Ordering { #[doc(alias = "<=")] #[doc(alias = ">=")] #[rustc_on_unimplemented( - message="can't compare `{Self}` with `{Rhs}`", - label="no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`", + message = "can't compare `{Self}` with `{Rhs}`", + label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`" )] pub trait PartialOrd: PartialEq { /// This method returns an ordering between `self` and `other` values if one exists. @@ -875,7 +897,9 @@ pub trait PartialOrd: PartialEq { #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics)] -pub macro PartialOrd($item:item) { /* compiler built-in */ } +pub macro PartialOrd($item:item) { + /* compiler built-in */ +} /// Compares and returns the minimum of two values. /// @@ -1005,8 +1029,8 @@ pub fn max_by_key K, K: Ord>(v1: T, v2: T, mut f: F) -> T { // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types mod impls { + use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::hint::unreachable_unchecked; - use crate::cmp::Ordering::{self, Less, Greater, Equal}; macro_rules! partial_eq_impl { ($($t:ty)*) => ($( @@ -1023,9 +1047,13 @@ mod impls { #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for () { #[inline] - fn eq(&self, _other: &()) -> bool { true } + fn eq(&self, _other: &()) -> bool { + true + } #[inline] - fn ne(&self, _other: &()) -> bool { false } + fn ne(&self, _other: &()) -> bool { + false + } } partial_eq_impl! { @@ -1119,7 +1147,9 @@ mod impls { #[stable(feature = "rust1", since = "1.0.0")] impl Ord for () { #[inline] - fn cmp(&self, _other: &()) -> Ordering { Equal } + fn cmp(&self, _other: &()) -> Ordering { + Equal + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1168,31 +1198,54 @@ mod impls { // & pointers #[stable(feature = "rust1", since = "1.0.0")] - impl PartialEq<&B> for &A where A: PartialEq { + impl PartialEq<&B> for &A + where + A: PartialEq, + { #[inline] - fn eq(&self, other: & &B) -> bool { PartialEq::eq(*self, *other) } + fn eq(&self, other: &&B) -> bool { + PartialEq::eq(*self, *other) + } #[inline] - fn ne(&self, other: & &B) -> bool { PartialEq::ne(*self, *other) } + fn ne(&self, other: &&B) -> bool { + PartialEq::ne(*self, *other) + } } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd<&B> for &A where A: PartialOrd { + impl PartialOrd<&B> for &A + where + A: PartialOrd, + { #[inline] fn partial_cmp(&self, other: &&B) -> Option { PartialOrd::partial_cmp(*self, *other) } #[inline] - fn lt(&self, other: & &B) -> bool { PartialOrd::lt(*self, *other) } + fn lt(&self, other: &&B) -> bool { + PartialOrd::lt(*self, *other) + } #[inline] - fn le(&self, other: & &B) -> bool { PartialOrd::le(*self, *other) } + fn le(&self, other: &&B) -> bool { + PartialOrd::le(*self, *other) + } #[inline] - fn gt(&self, other: & &B) -> bool { PartialOrd::gt(*self, *other) } + fn gt(&self, other: &&B) -> bool { + PartialOrd::gt(*self, *other) + } #[inline] - fn ge(&self, other: & &B) -> bool { PartialOrd::ge(*self, *other) } + fn ge(&self, other: &&B) -> bool { + PartialOrd::ge(*self, *other) + } } #[stable(feature = "rust1", since = "1.0.0")] - impl Ord for &A where A: Ord { + impl Ord for &A + where + A: Ord, + { #[inline] - fn cmp(&self, other: &Self) -> Ordering { Ord::cmp(*self, *other) } + fn cmp(&self, other: &Self) -> Ordering { + Ord::cmp(*self, *other) + } } #[stable(feature = "rust1", since = "1.0.0")] impl Eq for &A where A: Eq {} @@ -1200,48 +1253,85 @@ mod impls { // &mut pointers #[stable(feature = "rust1", since = "1.0.0")] - impl PartialEq<&mut B> for &mut A where A: PartialEq { + impl PartialEq<&mut B> for &mut A + where + A: PartialEq, + { #[inline] - fn eq(&self, other: &&mut B) -> bool { PartialEq::eq(*self, *other) } + fn eq(&self, other: &&mut B) -> bool { + PartialEq::eq(*self, *other) + } #[inline] - fn ne(&self, other: &&mut B) -> bool { PartialEq::ne(*self, *other) } + fn ne(&self, other: &&mut B) -> bool { + PartialEq::ne(*self, *other) + } } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialOrd<&mut B> for &mut A where A: PartialOrd { + impl PartialOrd<&mut B> for &mut A + where + A: PartialOrd, + { #[inline] fn partial_cmp(&self, other: &&mut B) -> Option { PartialOrd::partial_cmp(*self, *other) } #[inline] - fn lt(&self, other: &&mut B) -> bool { PartialOrd::lt(*self, *other) } + fn lt(&self, other: &&mut B) -> bool { + PartialOrd::lt(*self, *other) + } #[inline] - fn le(&self, other: &&mut B) -> bool { PartialOrd::le(*self, *other) } + fn le(&self, other: &&mut B) -> bool { + PartialOrd::le(*self, *other) + } #[inline] - fn gt(&self, other: &&mut B) -> bool { PartialOrd::gt(*self, *other) } + fn gt(&self, other: &&mut B) -> bool { + PartialOrd::gt(*self, *other) + } #[inline] - fn ge(&self, other: &&mut B) -> bool { PartialOrd::ge(*self, *other) } + fn ge(&self, other: &&mut B) -> bool { + PartialOrd::ge(*self, *other) + } } #[stable(feature = "rust1", since = "1.0.0")] - impl Ord for &mut A where A: Ord { + impl Ord for &mut A + where + A: Ord, + { #[inline] - fn cmp(&self, other: &Self) -> Ordering { Ord::cmp(*self, *other) } + fn cmp(&self, other: &Self) -> Ordering { + Ord::cmp(*self, *other) + } } #[stable(feature = "rust1", since = "1.0.0")] impl Eq for &mut A where A: Eq {} #[stable(feature = "rust1", since = "1.0.0")] - impl PartialEq<&mut B> for &A where A: PartialEq { + impl PartialEq<&mut B> for &A + where + A: PartialEq, + { #[inline] - fn eq(&self, other: &&mut B) -> bool { PartialEq::eq(*self, *other) } + fn eq(&self, other: &&mut B) -> bool { + PartialEq::eq(*self, *other) + } #[inline] - fn ne(&self, other: &&mut B) -> bool { PartialEq::ne(*self, *other) } + fn ne(&self, other: &&mut B) -> bool { + PartialEq::ne(*self, *other) + } } #[stable(feature = "rust1", since = "1.0.0")] - impl PartialEq<&B> for &mut A where A: PartialEq { + impl PartialEq<&B> for &mut A + where + A: PartialEq, + { #[inline] - fn eq(&self, other: &&B) -> bool { PartialEq::eq(*self, *other) } + fn eq(&self, other: &&B) -> bool { + PartialEq::eq(*self, *other) + } #[inline] - fn ne(&self, other: &&B) -> bool { PartialEq::ne(*self, *other) } + fn ne(&self, other: &&B) -> bool { + PartialEq::ne(*self, *other) + } } } diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs index e6e3454b36f81..626eb1e862d99 100644 --- a/src/libcore/fmt/builders.rs +++ b/src/libcore/fmt/builders.rs @@ -11,21 +11,18 @@ struct PadAdapterState { impl Default for PadAdapterState { fn default() -> Self { - PadAdapterState { - on_newline: true, - } + PadAdapterState { on_newline: true } } } impl<'buf, 'state> PadAdapter<'buf, 'state> { - fn wrap<'slot, 'fmt: 'buf+'slot>(fmt: &'fmt mut fmt::Formatter<'_>, - slot: &'slot mut Option, - state: &'state mut PadAdapterState) -> fmt::Formatter<'slot> { + fn wrap<'slot, 'fmt: 'buf + 'slot>( + fmt: &'fmt mut fmt::Formatter<'_>, + slot: &'slot mut Option, + state: &'state mut PadAdapterState, + ) -> fmt::Formatter<'slot> { fmt.wrap_buf(move |buf| { - *slot = Some(PadAdapter { - buf, - state, - }); + *slot = Some(PadAdapter { buf, state }); slot.as_mut().unwrap() }) } @@ -98,15 +95,12 @@ pub struct DebugStruct<'a, 'b: 'a> { has_fields: bool, } -pub(super) fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, - name: &str) - -> DebugStruct<'a, 'b> { +pub(super) fn debug_struct_new<'a, 'b>( + fmt: &'a mut fmt::Formatter<'b>, + name: &str, +) -> DebugStruct<'a, 'b> { let result = fmt.write_str(name); - DebugStruct { - fmt, - result, - has_fields: false, - } + DebugStruct { fmt, result, has_fields: false } } impl<'a, 'b: 'a> DebugStruct<'a, 'b> { @@ -196,11 +190,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> { pub fn finish(&mut self) -> fmt::Result { if self.has_fields { self.result = self.result.and_then(|_| { - if self.is_pretty() { - self.fmt.write_str("}") - } else { - self.fmt.write_str(" }") - } + if self.is_pretty() { self.fmt.write_str("}") } else { self.fmt.write_str(" }") } }); } self.result @@ -256,12 +246,7 @@ pub(super) fn debug_tuple_new<'a, 'b>( name: &str, ) -> DebugTuple<'a, 'b> { let result = fmt.write_str(name); - DebugTuple { - fmt, - result, - fields: 0, - empty_name: name.is_empty(), - } + DebugTuple { fmt, result, fields: 0, empty_name: name.is_empty() } } impl<'a, 'b: 'a> DebugTuple<'a, 'b> { @@ -423,13 +408,7 @@ pub struct DebugSet<'a, 'b: 'a> { pub(super) fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> { let result = fmt.write_str("{"); - DebugSet { - inner: DebugInner { - fmt, - result, - has_fields: false, - }, - } + DebugSet { inner: DebugInner { fmt, result, has_fields: false } } } impl<'a, 'b: 'a> DebugSet<'a, 'b> { @@ -487,8 +466,9 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> { /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn entries(&mut self, entries: I) -> &mut DebugSet<'a, 'b> - where D: fmt::Debug, - I: IntoIterator + where + D: fmt::Debug, + I: IntoIterator, { for entry in entries { self.entry(&entry); @@ -560,13 +540,7 @@ pub struct DebugList<'a, 'b: 'a> { pub(super) fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> { let result = fmt.write_str("["); - DebugList { - inner: DebugInner { - fmt, - result, - has_fields: false, - }, - } + DebugList { inner: DebugInner { fmt, result, has_fields: false } } } impl<'a, 'b: 'a> DebugList<'a, 'b> { @@ -624,8 +598,9 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> { /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn entries(&mut self, entries: I) -> &mut DebugList<'a, 'b> - where D: fmt::Debug, - I: IntoIterator + where + D: fmt::Debug, + I: IntoIterator, { for entry in entries { self.entry(&entry); @@ -702,13 +677,7 @@ pub struct DebugMap<'a, 'b: 'a> { pub(super) fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> { let result = fmt.write_str("{"); - DebugMap { - fmt, - result, - has_fields: false, - has_key: false, - state: Default::default(), - } + DebugMap { fmt, result, has_fields: false, has_key: false, state: Default::default() } } impl<'a, 'b: 'a> DebugMap<'a, 'b> { @@ -771,13 +740,14 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}", /// ); /// ``` - #[unstable(feature = "debug_map_key_value", - reason = "recently added", - issue = "62482")] + #[unstable(feature = "debug_map_key_value", reason = "recently added", issue = "62482")] pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> { self.result = self.result.and_then(|_| { - assert!(!self.has_key, "attempted to begin a new map entry \ - without completing the previous one"); + assert!( + !self.has_key, + "attempted to begin a new map entry \ + without completing the previous one" + ); if self.is_pretty() { if !self.has_fields { @@ -835,9 +805,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}", /// ); /// ``` - #[unstable(feature = "debug_map_key_value", - reason = "recently added", - issue = "62482")] + #[unstable(feature = "debug_map_key_value", reason = "recently added", issue = "62482")] pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> { self.result = self.result.and_then(|_| { assert!(self.has_key, "attempted to format a map value before its key"); @@ -885,9 +853,10 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn entries(&mut self, entries: I) -> &mut DebugMap<'a, 'b> - where K: fmt::Debug, - V: fmt::Debug, - I: IntoIterator + where + K: fmt::Debug, + V: fmt::Debug, + I: IntoIterator, { for (k, v) in entries { self.entry(&k, &v); diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 3c7aefc090f8e..7b20677ffb54c 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -2,17 +2,17 @@ // ignore-tidy-undocumented-unsafe - use crate::fmt; +use crate::mem::MaybeUninit; use crate::ops::{Div, Rem, Sub}; -use crate::str; -use crate::slice; use crate::ptr; -use crate::mem::MaybeUninit; +use crate::slice; +use crate::str; #[doc(hidden)] -trait Int: PartialEq + PartialOrd + Div + Rem + - Sub + Copy { +trait Int: + PartialEq + PartialOrd + Div + Rem + Sub + Copy +{ fn zero() -> Self; fn from_u8(u: u8) -> Self; fn to_u8(&self) -> u8; @@ -60,33 +60,32 @@ trait GenericRadix { // Accumulate each digit of the number from the least significant // to the most significant figure. for byte in buf.iter_mut().rev() { - let n = x % base; // Get the current place value. - x = x / base; // Deaccumulate the number. + let n = x % base; // Get the current place value. + x = x / base; // Deaccumulate the number. byte.write(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. - break + break; }; } } else { // Do the same as above, but accounting for two's complement. for byte in buf.iter_mut().rev() { - let n = zero - (x % base); // Get the current place value. - x = x / base; // Deaccumulate the number. + let n = zero - (x % base); // Get the current place value. + x = x / base; // Deaccumulate the number. byte.write(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. - break + break; }; } } let buf = &buf[curr..]; - let buf = unsafe { str::from_utf8_unchecked(slice::from_raw_parts( - MaybeUninit::first_ptr(buf), - buf.len() - )) }; + let buf = unsafe { + str::from_utf8_unchecked(slice::from_raw_parts(MaybeUninit::first_ptr(buf), buf.len())) + }; f.pad_integral(is_nonnegative, Self::PREFIX, buf) } } @@ -125,9 +124,9 @@ macro_rules! radix { radix! { Binary, 2, "0b", x @ 0 ..= 1 => b'0' + x } radix! { Octal, 8, "0o", x @ 0 ..= 7 => b'0' + x } radix! { LowerHex, 16, "0x", x @ 0 ..= 9 => b'0' + x, - x @ 10 ..= 15 => b'a' + (x - 10) } +x @ 10 ..= 15 => b'a' + (x - 10) } radix! { UpperHex, 16, "0x", x @ 0 ..= 9 => b'0' + x, - x @ 10 ..= 15 => b'A' + (x - 10) } +x @ 10 ..= 15 => b'A' + (x - 10) } macro_rules! int_base { ($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => { @@ -137,7 +136,7 @@ macro_rules! int_base { $Radix.fmt_int(*self as $U, f) } } - } + }; } macro_rules! debug { @@ -155,7 +154,7 @@ macro_rules! debug { } } } - } + }; } macro_rules! integer { @@ -171,7 +170,7 @@ macro_rules! integer { int_base! { LowerHex for $Uint as $Uint -> LowerHex } int_base! { UpperHex for $Uint as $Uint -> UpperHex } debug! { $Uint } - } + }; } integer! { isize, usize } integer! { i8, u8 } @@ -180,9 +179,7 @@ integer! { i32, u32 } integer! { i64, u64 } integer! { i128, u128 } - -static DEC_DIGITS_LUT: &[u8; 200] = - b"0001020304050607080910111213141516171819\ +static DEC_DIGITS_LUT: &[u8; 200] = b"0001020304050607080910111213141516171819\ 2021222324252627282930313233343536373839\ 4041424344454647484950515253545556575859\ 6061626364656667686970717273747576777879\ diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index e73d125c13f89..e6bae4864a4e1 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -29,18 +29,22 @@ //! guaranteed to happen in order. This is the standard mode for working //! with atomic types and is equivalent to Java's `volatile`. -#![unstable(feature = "core_intrinsics", - reason = "intrinsics are unlikely to ever be stabilized, instead \ +#![unstable( + feature = "core_intrinsics", + reason = "intrinsics are unlikely to ever be stabilized, instead \ they should be used through stabilized interfaces \ in the rest of the standard library", - issue = "none")] + issue = "none" +)] #![allow(missing_docs)] use crate::mem; #[stable(feature = "drop_in_place", since = "1.8.0")] -#[rustc_deprecated(reason = "no longer an intrinsic - use `ptr::drop_in_place` directly", - since = "1.18.0")] +#[rustc_deprecated( + reason = "no longer an intrinsic - use `ptr::drop_in_place` directly", + since = "1.18.0" +)] pub use crate::ptr::drop_in_place; extern "rust-intrinsic" { @@ -705,13 +709,14 @@ extern "rust-intrinsic" { /// which is unsafe unless `T` is `Copy`. Also, even if T is /// `Copy`, an all-zero value may not correspond to any legitimate /// state for the type in question. - #[unstable(feature = "core_intrinsics", - reason = "intrinsics are unlikely to ever be stabilized, instead \ + #[unstable( + feature = "core_intrinsics", + reason = "intrinsics are unlikely to ever be stabilized, instead \ they should be used through stabilized interfaces \ in the rest of the standard library", - issue = "none")] - #[rustc_deprecated(reason = "superseded by MaybeUninit, removal planned", - since = "1.38.0")] + issue = "none" + )] + #[rustc_deprecated(reason = "superseded by MaybeUninit, removal planned", since = "1.38.0")] pub fn init() -> T; /// Creates an uninitialized value. @@ -721,13 +726,14 @@ extern "rust-intrinsic" { /// state, which means it may claim either dropped or /// undropped. In the general case one must use `ptr::write` to /// initialize memory previous set to the result of `uninit`. - #[unstable(feature = "core_intrinsics", - reason = "intrinsics are unlikely to ever be stabilized, instead \ + #[unstable( + feature = "core_intrinsics", + reason = "intrinsics are unlikely to ever be stabilized, instead \ they should be used through stabilized interfaces \ in the rest of the standard library", - issue = "none")] - #[rustc_deprecated(reason = "superseded by MaybeUninit, removal planned", - since = "1.38.0")] + issue = "none" + )] + #[rustc_deprecated(reason = "superseded by MaybeUninit, removal planned", since = "1.38.0")] pub fn uninit() -> T; /// Moves a value out of scope without running drop glue. @@ -985,8 +991,7 @@ extern "rust-intrinsic" { /// /// The volatile parameter is set to `true`, so it will not be optimized out /// unless size is equal to zero. - pub fn volatile_copy_nonoverlapping_memory(dst: *mut T, src: *const T, - count: usize); + pub fn volatile_copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: usize); /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with /// a size of `count` * `size_of::()` and an alignment of /// `min_align_of::()` @@ -1148,7 +1153,6 @@ extern "rust-intrinsic" { /// https://github.com/rust-lang/rust/issues/10184 pub fn float_to_int_approx_unchecked(value: Float) -> Int; - /// Returns the number of bits set in an integer type `T` pub fn ctpop(x: T) -> T; @@ -1376,11 +1380,7 @@ fn overlaps(src: *const T, dst: *const T, count: usize) -> bool { let src_usize = src as usize; let dst_usize = dst as usize; let size = mem::size_of::().checked_mul(count).unwrap(); - let diff = if src_usize > dst_usize { - src_usize - dst_usize - } else { - dst_usize - src_usize - }; + let diff = if src_usize > dst_usize { src_usize - dst_usize } else { dst_usize - src_usize }; size > diff } diff --git a/src/libcore/iter/adapters/chain.rs b/src/libcore/iter/adapters/chain.rs index 3b669cad1c40f..3611a1aadaddb 100644 --- a/src/libcore/iter/adapters/chain.rs +++ b/src/libcore/iter/adapters/chain.rs @@ -1,7 +1,7 @@ use crate::ops::Try; use crate::usize; -use super::super::{Iterator, DoubleEndedIterator, FusedIterator, TrustedLen}; +use super::super::{DoubleEndedIterator, FusedIterator, Iterator, TrustedLen}; /// An iterator that links two iterators together, in a chain. /// @@ -48,9 +48,10 @@ enum ChainState { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Chain where +impl Iterator for Chain +where A: Iterator, - B: Iterator + B: Iterator, { type Item = A::Item; @@ -79,8 +80,11 @@ impl Iterator for Chain where } } - fn try_fold(&mut self, init: Acc, mut f: F) -> R where - Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try + fn try_fold(&mut self, init: Acc, mut f: F) -> R + where + Self: Sized, + F: FnMut(Acc, Self::Item) -> R, + R: Try, { let mut accum = init; match self.state { @@ -90,7 +94,7 @@ impl Iterator for Chain where self.state = ChainState::Back; } } - _ => { } + _ => {} } if let ChainState::Back = self.state { accum = self.b.try_fold(accum, &mut f)?; @@ -99,20 +103,21 @@ impl Iterator for Chain where } fn fold(self, init: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc, + where + F: FnMut(Acc, Self::Item) -> Acc, { let mut accum = init; match self.state { ChainState::Both | ChainState::Front => { accum = self.a.fold(accum, &mut f); } - _ => { } + _ => {} } match self.state { ChainState::Both | ChainState::Back => { accum = self.b.fold(accum, &mut f); } - _ => { } + _ => {} } accum } @@ -123,7 +128,7 @@ impl Iterator for Chain where ChainState::Both | ChainState::Front => { for x in self.a.by_ref() { if n == 0 { - return Some(x) + return Some(x); } n -= 1; } @@ -133,15 +138,12 @@ impl Iterator for Chain where } ChainState::Back => {} } - if let ChainState::Back = self.state { - self.b.nth(n) - } else { - None - } + if let ChainState::Back = self.state { self.b.nth(n) } else { None } } #[inline] - fn find

(&mut self, mut predicate: P) -> Option where + fn find

(&mut self, predicate: P) -> Option where - P: FnMut(&Self::Item) -> bool + fn find

(&mut self, predicate: P) -> Option + where + P: FnMut(&Self::Item) -> bool, { self.0.find(predicate) } #[inline] - fn position

(&mut self, predicate: P) -> Option where - P: FnMut(Self::Item) -> bool + fn position

(&mut self, predicate: P) -> Option + where + P: FnMut(Self::Item) -> bool, { self.0.position(predicate) } #[inline] - fn rposition

(&mut self, predicate: P) -> Option where - P: FnMut(Self::Item) -> bool + fn rposition

(&mut self, predicate: P) -> Option + where + P: FnMut(Self::Item) -> bool, { self.0.rposition(predicate) } @@ -814,8 +833,9 @@ impl DoubleEndedIterator for Bytes<'_> { } #[inline] - fn rfind

(&mut self, predicate: P) -> Option where - P: FnMut(&Self::Item) -> bool + fn rfind

(&mut self, predicate: P) -> Option + where + P: FnMut(&Self::Item) -> bool, { self.0.rfind(predicate) } @@ -845,7 +865,9 @@ unsafe impl TrustedRandomAccess for Bytes<'_> { unsafe fn get_unchecked(&mut self, i: usize) -> u8 { self.0.get_unchecked(i) } - fn may_have_side_effect() -> bool { false } + fn may_have_side_effect() -> bool { + false + } } /// This macro generates a Clone impl for string pattern API @@ -861,7 +883,7 @@ macro_rules! derive_pattern_clone { $e } } - } + }; } /// This macro generates two public iterator structs @@ -1047,7 +1069,7 @@ macro_rules! generate_pattern_iterators { } => {} } -derive_pattern_clone!{ +derive_pattern_clone! { clone SplitInternal with |s| SplitInternal { matcher: s.matcher.clone(), ..*s } } @@ -1091,7 +1113,9 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { #[inline] fn next(&mut self) -> Option<&'a str> { - if self.finished { return None } + if self.finished { + return None; + } let haystack = self.matcher.haystack(); match self.matcher.next_match() { @@ -1106,15 +1130,22 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { #[inline] fn next_back(&mut self) -> Option<&'a str> - where P::Searcher: ReverseSearcher<'a> + where + P::Searcher: ReverseSearcher<'a>, { - if self.finished { return None } + if self.finished { + return None; + } if !self.allow_trailing_empty { self.allow_trailing_empty = true; match self.next_back() { Some(elt) if !elt.is_empty() => return Some(elt), - _ => if self.finished { return None } + _ => { + if self.finished { + return None; + } + } } } @@ -1169,7 +1200,7 @@ generate_pattern_iterators! { delegate double ended; } -derive_pattern_clone!{ +derive_pattern_clone! { clone SplitNInternal with |s| SplitNInternal { iter: s.iter.clone(), ..*s } } @@ -1197,19 +1228,32 @@ impl<'a, P: Pattern<'a>> SplitNInternal<'a, P> { fn next(&mut self) -> Option<&'a str> { match self.count { 0 => None, - 1 => { self.count = 0; self.iter.get_end() } - _ => { self.count -= 1; self.iter.next() } + 1 => { + self.count = 0; + self.iter.get_end() + } + _ => { + self.count -= 1; + self.iter.next() + } } } #[inline] fn next_back(&mut self) -> Option<&'a str> - where P::Searcher: ReverseSearcher<'a> + where + P::Searcher: ReverseSearcher<'a>, { match self.count { 0 => None, - 1 => { self.count = 0; self.iter.get_end() } - _ => { self.count -= 1; self.iter.next_back() } + 1 => { + self.count = 0; + self.iter.get_end() + } + _ => { + self.count -= 1; + self.iter.next_back() + } } } } @@ -1232,7 +1276,7 @@ generate_pattern_iterators! { delegate single ended; } -derive_pattern_clone!{ +derive_pattern_clone! { clone MatchIndicesInternal with |s| MatchIndicesInternal(s.0.clone()) } @@ -1244,27 +1288,26 @@ where P: Pattern<'a, Searcher: fmt::Debug>, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("MatchIndicesInternal") - .field(&self.0) - .finish() + f.debug_tuple("MatchIndicesInternal").field(&self.0).finish() } } impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { #[inline] fn next(&mut self) -> Option<(usize, &'a str)> { - self.0.next_match().map(|(start, end)| unsafe { - (start, self.0.haystack().get_unchecked(start..end)) - }) + self.0 + .next_match() + .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) } #[inline] fn next_back(&mut self) -> Option<(usize, &'a str)> - where P::Searcher: ReverseSearcher<'a> + where + P::Searcher: ReverseSearcher<'a>, { - self.0.next_match_back().map(|(start, end)| unsafe { - (start, self.0.haystack().get_unchecked(start..end)) - }) + self.0 + .next_match_back() + .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) } } @@ -1286,7 +1329,7 @@ generate_pattern_iterators! { delegate double ended; } -derive_pattern_clone!{ +derive_pattern_clone! { clone MatchesInternal with |s| MatchesInternal(s.0.clone()) } @@ -1298,9 +1341,7 @@ where P: Pattern<'a, Searcher: fmt::Debug>, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("MatchesInternal") - .field(&self.0) - .finish() + f.debug_tuple("MatchesInternal").field(&self.0).finish() } } @@ -1315,7 +1356,8 @@ impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> { #[inline] fn next_back(&mut self) -> Option<&'a str> - where P::Searcher: ReverseSearcher<'a> + where + P::Searcher: ReverseSearcher<'a>, { self.0.next_match_back().map(|(a, b)| unsafe { // Indices are known to be on utf8 boundaries @@ -1461,21 +1503,20 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { let old_offset = index; macro_rules! err { ($error_len: expr) => { - return Err(Utf8Error { - valid_up_to: old_offset, - error_len: $error_len, - }) - } + return Err(Utf8Error { valid_up_to: old_offset, error_len: $error_len }); + }; } - macro_rules! next { () => {{ - index += 1; - // we needed data, but there was none: error! - if index >= len { - err!(None) - } - v[index] - }}} + macro_rules! next { + () => {{ + index += 1; + // we needed data, but there was none: error! + if index >= len { + err!(None) + } + v[index] + }}; + } let first = v[index]; if first >= 128 { @@ -1499,16 +1540,18 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { // UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / // %xF4 %x80-8F 2( UTF8-tail ) match w { - 2 => if next!() & !CONT_MASK != TAG_CONT_U8 { - err!(Some(1)) - }, + 2 => { + if next!() & !CONT_MASK != TAG_CONT_U8 { + err!(Some(1)) + } + } 3 => { match (first, next!()) { - (0xE0 , 0xA0 ..= 0xBF) | - (0xE1 ..= 0xEC, 0x80 ..= 0xBF) | - (0xED , 0x80 ..= 0x9F) | - (0xEE ..= 0xEF, 0x80 ..= 0xBF) => {} - _ => err!(Some(1)) + (0xE0, 0xA0..=0xBF) + | (0xE1..=0xEC, 0x80..=0xBF) + | (0xED, 0x80..=0x9F) + | (0xEE..=0xEF, 0x80..=0xBF) => {} + _ => err!(Some(1)), } if next!() & !CONT_MASK != TAG_CONT_U8 { err!(Some(2)) @@ -1516,10 +1559,8 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { } 4 => { match (first, next!()) { - (0xF0 , 0x90 ..= 0xBF) | - (0xF1 ..= 0xF3, 0x80 ..= 0xBF) | - (0xF4 , 0x80 ..= 0x8F) => {} - _ => err!(Some(1)) + (0xF0, 0x90..=0xBF) | (0xF1..=0xF3, 0x80..=0xBF) | (0xF4, 0x80..=0x8F) => {} + _ => err!(Some(1)), } if next!() & !CONT_MASK != TAG_CONT_U8 { err!(Some(2)) @@ -1528,7 +1569,7 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { err!(Some(3)) } } - _ => err!(Some(1)) + _ => err!(Some(1)), } index += 1; } else { @@ -1564,22 +1605,22 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { // https://tools.ietf.org/html/rfc3629 static UTF8_CHAR_WIDTH: [u8; 256] = [ -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF -0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2, -2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF -3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF -4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, // 0x1F + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, // 0x3F + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, // 0x5F + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, // 0x7F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // 0x9F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // 0xBF + 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, // 0xDF + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xEF + 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xFF ]; /// Given a first byte, determines how many bytes are in this UTF-8 character. @@ -1625,7 +1666,9 @@ mod traits { self.as_bytes() == other.as_bytes() } #[inline] - fn ne(&self, other: &str) -> bool { !(*self).eq(other) } + fn ne(&self, other: &str) -> bool { + !(*self).eq(other) + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1757,9 +1800,10 @@ mod traits { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { - if self.start <= self.end && - slice.is_char_boundary(self.start) && - slice.is_char_boundary(self.end) { + if self.start <= self.end + && slice.is_char_boundary(self.start) + && slice.is_char_boundary(self.end) + { Some(unsafe { self.get_unchecked(slice) }) } else { None @@ -1767,9 +1811,10 @@ mod traits { } #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { - if self.start <= self.end && - slice.is_char_boundary(self.start) && - slice.is_char_boundary(self.end) { + if self.start <= self.end + && slice.is_char_boundary(self.start) + && slice.is_char_boundary(self.end) + { Some(unsafe { self.get_unchecked_mut(slice) }) } else { None @@ -1796,9 +1841,10 @@ mod traits { fn index_mut(self, slice: &mut str) -> &mut Self::Output { // is_char_boundary checks that the index is in [0, .len()] // cannot reuse `get` as above, because of NLL trouble - if self.start <= self.end && - slice.is_char_boundary(self.start) && - slice.is_char_boundary(self.end) { + if self.start <= self.end + && slice.is_char_boundary(self.start) + && slice.is_char_boundary(self.end) + { unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, self.start, self.end) @@ -1950,31 +1996,41 @@ mod traits { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { - if *self.end() == usize::max_value() { None } - else { (*self.start()..self.end()+1).get(slice) } + if *self.end() == usize::max_value() { + None + } else { + (*self.start()..self.end() + 1).get(slice) + } } #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { - if *self.end() == usize::max_value() { None } - else { (*self.start()..self.end()+1).get_mut(slice) } + if *self.end() == usize::max_value() { + None + } else { + (*self.start()..self.end() + 1).get_mut(slice) + } } #[inline] unsafe fn get_unchecked(self, slice: &str) -> &Self::Output { - (*self.start()..self.end()+1).get_unchecked(slice) + (*self.start()..self.end() + 1).get_unchecked(slice) } #[inline] unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { - (*self.start()..self.end()+1).get_unchecked_mut(slice) + (*self.start()..self.end() + 1).get_unchecked_mut(slice) } #[inline] fn index(self, slice: &str) -> &Self::Output { - if *self.end() == usize::max_value() { str_index_overflow_fail(); } - (*self.start()..self.end()+1).index(slice) + if *self.end() == usize::max_value() { + str_index_overflow_fail(); + } + (*self.start()..self.end() + 1).index(slice) } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { - if *self.end() == usize::max_value() { str_index_overflow_fail(); } - (*self.start()..self.end()+1).index_mut(slice) + if *self.end() == usize::max_value() { + str_index_overflow_fail(); + } + (*self.start()..self.end() + 1).index_mut(slice) } } @@ -1997,31 +2053,33 @@ mod traits { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { - if self.end == usize::max_value() { None } - else { (..self.end+1).get(slice) } + if self.end == usize::max_value() { None } else { (..self.end + 1).get(slice) } } #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { - if self.end == usize::max_value() { None } - else { (..self.end+1).get_mut(slice) } + if self.end == usize::max_value() { None } else { (..self.end + 1).get_mut(slice) } } #[inline] unsafe fn get_unchecked(self, slice: &str) -> &Self::Output { - (..self.end+1).get_unchecked(slice) + (..self.end + 1).get_unchecked(slice) } #[inline] unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output { - (..self.end+1).get_unchecked_mut(slice) + (..self.end + 1).get_unchecked_mut(slice) } #[inline] fn index(self, slice: &str) -> &Self::Output { - if self.end == usize::max_value() { str_index_overflow_fail(); } - (..self.end+1).index(slice) + if self.end == usize::max_value() { + str_index_overflow_fail(); + } + (..self.end + 1).index(slice) } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { - if self.end == usize::max_value() { str_index_overflow_fail(); } - (..self.end+1).index_mut(slice) + if self.end == usize::max_value() { + str_index_overflow_fail(); + } + (..self.end + 1).index_mut(slice) } } } @@ -2053,8 +2111,14 @@ fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! { } // 2. begin <= end - assert!(begin <= end, "begin <= end ({} <= {}) when slicing `{}`{}", - begin, end, s_trunc, ellipsis); + assert!( + begin <= end, + "begin <= end ({} <= {}) when slicing `{}`{}", + begin, + end, + s_trunc, + ellipsis + ); // 3. character boundary let index = if !s.is_char_boundary(begin) { begin } else { end }; @@ -2065,9 +2129,11 @@ fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! { } // `char_start` must be less than len and a char boundary let ch = s[char_start..].chars().next().unwrap(); - let char_range = char_start .. char_start + ch.len_utf8(); - panic!("byte index {} is not a char boundary; it is inside {:?} (bytes {:?}) of `{}`{}", - index, ch, char_range, s_trunc, ellipsis); + let char_range = char_start..char_start + ch.len_utf8(); + panic!( + "byte index {} is not a char boundary; it is inside {:?} (bytes {:?}) of `{}`{}", + index, ch, char_range, s_trunc, ellipsis + ); } #[lang = "str"] @@ -2146,7 +2212,9 @@ impl str { // 0 and len are always ok. // Test for 0 explicitly so that it can optimize out the check // easily and skip reading string data for that case. - if index == 0 || index == self.len() { return true; } + if index == 0 || index == self.len() { + return true; + } match self.as_bytes().get(index) { None => false, // This is bit magic equivalent to: b < 128 || b >= 192 @@ -2505,10 +2573,7 @@ impl str { pub fn split_at(&self, mid: usize) -> (&str, &str) { // is_char_boundary checks that the index is in [0, .len()] if self.is_char_boundary(mid) { - unsafe { - (self.get_unchecked(0..mid), - self.get_unchecked(mid..self.len())) - } + unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) } } else { slice_error_fail(self, 0, mid) } @@ -2553,11 +2618,10 @@ impl str { let len = self.len(); let ptr = self.as_mut_ptr(); unsafe { - (from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, mid)), - from_utf8_unchecked_mut(slice::from_raw_parts_mut( - ptr.add(mid), - len - mid - ))) + ( + from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, mid)), + from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr.add(mid), len - mid)), + ) } } else { slice_error_fail(self, 0, mid) @@ -2611,7 +2675,7 @@ impl str { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn chars(&self) -> Chars<'_> { - Chars{iter: self.as_bytes().iter()} + Chars { iter: self.as_bytes().iter() } } /// Returns an iterator over the [`char`]s of a string slice, and their @@ -2775,11 +2839,8 @@ impl str { #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] #[inline] pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace<'_> { - let inner = self - .as_bytes() - .split(IsAsciiWhitespace) - .filter(BytesIsNotEmpty) - .map(UnsafeBytesToStr); + let inner = + self.as_bytes().split(IsAsciiWhitespace).filter(BytesIsNotEmpty).map(UnsafeBytesToStr); SplitAsciiWhitespace { inner } } @@ -3220,10 +3281,7 @@ impl str { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> { - SplitTerminator(SplitInternal { - allow_trailing_empty: false, - ..self.split(pat).0 - }) + SplitTerminator(SplitInternal { allow_trailing_empty: false, ..self.split(pat).0 }) } /// An iterator over substrings of `self`, separated by characters @@ -3317,10 +3375,7 @@ impl str { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> { - SplitN(SplitNInternal { - iter: self.split(pat).0, - count: n, - }) + SplitN(SplitNInternal { iter: self.split(pat).0, count: n }) } /// An iterator over substrings of this string slice, separated by a @@ -3662,7 +3717,7 @@ impl str { #[rustc_deprecated( since = "1.33.0", reason = "superseded by `trim_start`", - suggestion = "trim_start", + suggestion = "trim_start" )] pub fn trim_left(&self) -> &str { self.trim_start() @@ -3703,7 +3758,7 @@ impl str { #[rustc_deprecated( since = "1.33.0", reason = "superseded by `trim_end`", - suggestion = "trim_end", + suggestion = "trim_end" )] pub fn trim_right(&self) -> &str { self.trim_end() @@ -3745,7 +3800,7 @@ impl str { if let Some((a, b)) = matcher.next_reject() { i = a; j = b; // Remember earliest known match, correct it below if - // last match is different + // last match is different } if let Some((_, b)) = matcher.next_reject_back() { j = b; @@ -3818,8 +3873,11 @@ impl str { pub fn strip_prefix<'a, P: Pattern<'a>>(&'a self, prefix: P) -> Option<&'a str> { let mut matcher = prefix.into_searcher(self); if let SearchStep::Match(start, len) = matcher.next() { - debug_assert_eq!(start, 0, "The first search step from Searcher \ - must include the first character"); + debug_assert_eq!( + start, 0, + "The first search step from Searcher \ + must include the first character" + ); unsafe { // Searcher is known to return valid indices. Some(self.get_unchecked(len..)) @@ -3855,8 +3913,12 @@ impl str { { let mut matcher = suffix.into_searcher(self); if let SearchStep::Match(start, end) = matcher.next_back() { - debug_assert_eq!(end, self.len(), "The first search step from ReverseSearcher \ - must include the last character"); + debug_assert_eq!( + end, + self.len(), + "The first search step from ReverseSearcher \ + must include the last character" + ); unsafe { // Searcher is known to return valid indices. Some(self.get_unchecked(..start)) @@ -3944,7 +4006,7 @@ impl str { #[rustc_deprecated( since = "1.33.0", reason = "superseded by `trim_start_matches`", - suggestion = "trim_start_matches", + suggestion = "trim_start_matches" )] pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str { self.trim_start_matches(pat) @@ -3986,7 +4048,7 @@ impl str { #[rustc_deprecated( since = "1.33.0", reason = "superseded by `trim_end_matches`", - suggestion = "trim_end_matches", + suggestion = "trim_end_matches" )] pub fn trim_right_matches<'a, P>(&'a self, pat: P) -> &'a str where @@ -4173,11 +4235,12 @@ impl str { pub fn escape_debug(&self) -> EscapeDebug<'_> { let mut chars = self.chars(); EscapeDebug { - inner: chars.next() + inner: chars + .next() .map(|first| first.escape_debug_ext(true)) .into_iter() .flatten() - .chain(chars.flat_map(CharEscapeDebugContinue)) + .chain(chars.flat_map(CharEscapeDebugContinue)), } } @@ -4285,13 +4348,17 @@ impl AsRef<[u8]> for str { #[stable(feature = "rust1", since = "1.0.0")] impl Default for &str { /// Creates an empty str - fn default() -> Self { "" } + fn default() -> Self { + "" + } } #[stable(feature = "default_mut_str", since = "1.28.0")] impl Default for &mut str { /// Creates an empty mutable str - fn default() -> Self { unsafe { from_utf8_unchecked_mut(&mut []) } } + fn default() -> Self { + unsafe { from_utf8_unchecked_mut(&mut []) } + } } /// An iterator over the non-whitespace substrings of a string, @@ -4477,7 +4544,7 @@ impl FusedIterator for EncodeUtf16<'_> {} pub struct EscapeDebug<'a> { inner: Chain< Flatten>, - FlatMap, char::EscapeDebug, CharEscapeDebugContinue> + FlatMap, char::EscapeDebug, CharEscapeDebugContinue>, >, } diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index b7ebd5f88b589..2cbdeb2e4eed8 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -5,9 +5,11 @@ // ignore-tidy-undocumented-unsafe -#![unstable(feature = "pattern", - reason = "API not fully fleshed out and ready to be stabilized", - issue = "27721")] +#![unstable( + feature = "pattern", + reason = "API not fully fleshed out and ready to be stabilized", + issue = "27721" +)] use crate::cmp; use crate::fmt; @@ -53,7 +55,8 @@ pub trait Pattern<'a>: Sized { /// Checks whether the pattern matches at the back of the haystack #[inline] fn is_suffix_of(self, haystack: &'a str) -> bool - where Self::Searcher: ReverseSearcher<'a> + where + Self::Searcher: ReverseSearcher<'a>, { match self.into_searcher(haystack).next_back() { SearchStep::Match(_, j) if haystack.len() == j => true, @@ -78,7 +81,7 @@ pub enum SearchStep { Reject(usize, usize), /// Expresses that every byte of the haystack has been visited, ending /// the iteration. - Done + Done, } /// A searcher for a string pattern. @@ -189,7 +192,7 @@ pub unsafe trait ReverseSearcher<'a>: Searcher<'a> { /// Finds the next `Match` result. See `next_back()` #[inline] - fn next_match_back(&mut self) -> Option<(usize, usize)>{ + fn next_match_back(&mut self) -> Option<(usize, usize)> { loop { match self.next_back() { SearchStep::Match(a, b) => return Some((a, b)), @@ -201,7 +204,7 @@ pub unsafe trait ReverseSearcher<'a>: Searcher<'a> { /// Finds the next `Reject` result. See `next_back()` #[inline] - fn next_reject_back(&mut self) -> Option<(usize, usize)>{ + fn next_reject_back(&mut self) -> Option<(usize, usize)> { loop { match self.next_back() { SearchStep::Reject(a, b) => return Some((a, b)), @@ -235,7 +238,6 @@ pub unsafe trait ReverseSearcher<'a>: Searcher<'a> { /// `"[aa]a"` or `"a[aa]"`, depending from which side it is searched. pub trait DoubleEndedSearcher<'a>: ReverseSearcher<'a> {} - ///////////////////////////////////////////////////////////////////////////// // Impl for char ///////////////////////////////////////////////////////////////////////////// @@ -247,7 +249,6 @@ pub struct CharSearcher<'a> { // safety invariant: `finger`/`finger_back` must be a valid utf8 byte index of `haystack` // This invariant can be broken *within* next_match and next_match_back, however // they must exit with fingers on valid code point boundaries. - /// `finger` is the current byte index of the forward search. /// Imagine that it exists before the byte at its index, i.e. /// `haystack[finger]` is the first byte of the slice we must inspect during @@ -429,7 +430,7 @@ impl<'a> Pattern<'a> for char { finger_back: haystack.len(), needle: self, utf8_size, - utf8_encoded + utf8_encoded, } } @@ -449,7 +450,9 @@ impl<'a> Pattern<'a> for char { } #[inline] - fn is_suffix_of(self, haystack: &'a str) -> bool where Self::Searcher: ReverseSearcher<'a> + fn is_suffix_of(self, haystack: &'a str) -> bool + where + Self::Searcher: ReverseSearcher<'a>, { self.encode_utf8(&mut [0u8; 4]).is_suffix_of(haystack) } @@ -464,15 +467,20 @@ trait MultiCharEq { fn matches(&mut self, c: char) -> bool; } -impl MultiCharEq for F where F: FnMut(char) -> bool { +impl MultiCharEq for F +where + F: FnMut(char) -> bool, +{ #[inline] - fn matches(&mut self, c: char) -> bool { (*self)(c) } + fn matches(&mut self, c: char) -> bool { + (*self)(c) + } } impl MultiCharEq for &[char] { #[inline] fn matches(&mut self, c: char) -> bool { - self.iter().any(|&m| { m == c }) + self.iter().any(|&m| m == c) } } @@ -490,11 +498,7 @@ impl<'a, C: MultiCharEq> Pattern<'a> for MultiCharEqPattern { #[inline] fn into_searcher(self, haystack: &'a str) -> MultiCharEqSearcher<'a, C> { - MultiCharEqSearcher { - haystack, - char_eq: self.0, - char_indices: haystack.char_indices(), - } + MultiCharEqSearcher { haystack, char_eq: self.0, char_indices: haystack.char_indices() } } } @@ -642,10 +646,12 @@ impl<'a, 'b> Pattern<'a> for &'b [char] { /// Associated type for `>::Searcher`. #[derive(Clone)] pub struct CharPredicateSearcher<'a, F>( as Pattern<'a>>::Searcher) - where F: FnMut(char) -> bool; +where + F: FnMut(char) -> bool; impl fmt::Debug for CharPredicateSearcher<'_, F> - where F: FnMut(char) -> bool +where + F: FnMut(char) -> bool, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("CharPredicateSearcher") @@ -655,22 +661,26 @@ impl fmt::Debug for CharPredicateSearcher<'_, F> } } unsafe impl<'a, F> Searcher<'a> for CharPredicateSearcher<'a, F> - where F: FnMut(char) -> bool +where + F: FnMut(char) -> bool, { searcher_methods!(forward); } unsafe impl<'a, F> ReverseSearcher<'a> for CharPredicateSearcher<'a, F> - where F: FnMut(char) -> bool +where + F: FnMut(char) -> bool, { searcher_methods!(reverse); } -impl<'a, F> DoubleEndedSearcher<'a> for CharPredicateSearcher<'a, F> - where F: FnMut(char) -> bool {} +impl<'a, F> DoubleEndedSearcher<'a> for CharPredicateSearcher<'a, F> where F: FnMut(char) -> bool {} /// Searches for chars that match the given predicate -impl<'a, F> Pattern<'a> for F where F: FnMut(char) -> bool { +impl<'a, F> Pattern<'a> for F +where + F: FnMut(char) -> bool, +{ pattern_methods!(CharPredicateSearcher<'a, F>, MultiCharEqPattern, CharPredicateSearcher); } @@ -712,7 +722,6 @@ impl<'a, 'b> Pattern<'a> for &'b str { } } - ///////////////////////////////////////////////////////////////////////////// // Two Way substring searcher ///////////////////////////////////////////////////////////////////////////// @@ -757,9 +766,10 @@ impl<'a, 'b> StrSearcher<'a, 'b> { StrSearcher { haystack, needle, - searcher: StrSearcherImpl::TwoWay( - TwoWaySearcher::new(needle.as_bytes(), haystack.len()) - ), + searcher: StrSearcherImpl::TwoWay(TwoWaySearcher::new( + needle.as_bytes(), + haystack.len(), + )), } } } @@ -798,10 +808,11 @@ unsafe impl<'a, 'b> Searcher<'a> for StrSearcher<'a, 'b> { return SearchStep::Done; } let is_long = searcher.memory == usize::MAX; - match searcher.next::(self.haystack.as_bytes(), - self.needle.as_bytes(), - is_long) - { + match searcher.next::( + self.haystack.as_bytes(), + self.needle.as_bytes(), + is_long, + ) { SearchStep::Reject(a, mut b) => { // skip to next char boundary while !self.haystack.is_char_boundary(b) { @@ -819,27 +830,29 @@ unsafe impl<'a, 'b> Searcher<'a> for StrSearcher<'a, 'b> { #[inline] fn next_match(&mut self) -> Option<(usize, usize)> { match self.searcher { - StrSearcherImpl::Empty(..) => { - loop { - match self.next() { - SearchStep::Match(a, b) => return Some((a, b)), - SearchStep::Done => return None, - SearchStep::Reject(..) => { } - } + StrSearcherImpl::Empty(..) => loop { + match self.next() { + SearchStep::Match(a, b) => return Some((a, b)), + SearchStep::Done => return None, + SearchStep::Reject(..) => {} } - } + }, StrSearcherImpl::TwoWay(ref mut searcher) => { let is_long = searcher.memory == usize::MAX; // write out `true` and `false` cases to encourage the compiler // to specialize the two cases separately. if is_long { - searcher.next::(self.haystack.as_bytes(), - self.needle.as_bytes(), - true) + searcher.next::( + self.haystack.as_bytes(), + self.needle.as_bytes(), + true, + ) } else { - searcher.next::(self.haystack.as_bytes(), - self.needle.as_bytes(), - false) + searcher.next::( + self.haystack.as_bytes(), + self.needle.as_bytes(), + false, + ) } } } @@ -868,10 +881,11 @@ unsafe impl<'a, 'b> ReverseSearcher<'a> for StrSearcher<'a, 'b> { return SearchStep::Done; } let is_long = searcher.memory == usize::MAX; - match searcher.next_back::(self.haystack.as_bytes(), - self.needle.as_bytes(), - is_long) - { + match searcher.next_back::( + self.haystack.as_bytes(), + self.needle.as_bytes(), + is_long, + ) { SearchStep::Reject(mut a, b) => { // skip to next char boundary while !self.haystack.is_char_boundary(a) { @@ -889,26 +903,28 @@ unsafe impl<'a, 'b> ReverseSearcher<'a> for StrSearcher<'a, 'b> { #[inline] fn next_match_back(&mut self) -> Option<(usize, usize)> { match self.searcher { - StrSearcherImpl::Empty(..) => { - loop { - match self.next_back() { - SearchStep::Match(a, b) => return Some((a, b)), - SearchStep::Done => return None, - SearchStep::Reject(..) => { } - } + StrSearcherImpl::Empty(..) => loop { + match self.next_back() { + SearchStep::Match(a, b) => return Some((a, b)), + SearchStep::Done => return None, + SearchStep::Reject(..) => {} } - } + }, StrSearcherImpl::TwoWay(ref mut searcher) => { let is_long = searcher.memory == usize::MAX; // write out `true` and `false`, like `next_match` if is_long { - searcher.next_back::(self.haystack.as_bytes(), - self.needle.as_bytes(), - true) + searcher.next_back::( + self.haystack.as_bytes(), + self.needle.as_bytes(), + true, + ) } else { - searcher.next_back::(self.haystack.as_bytes(), - self.needle.as_bytes(), - false) + searcher.next_back::( + self.haystack.as_bytes(), + self.needle.as_bytes(), + false, + ) } } } @@ -1016,12 +1032,11 @@ impl TwoWaySearcher { let (crit_pos_false, period_false) = TwoWaySearcher::maximal_suffix(needle, false); let (crit_pos_true, period_true) = TwoWaySearcher::maximal_suffix(needle, true); - let (crit_pos, period) = - if crit_pos_false > crit_pos_true { - (crit_pos_false, period_false) - } else { - (crit_pos_true, period_true) - }; + let (crit_pos, period) = if crit_pos_false > crit_pos_true { + (crit_pos_false, period_false) + } else { + (crit_pos_true, period_true) + }; // A particularly readable explanation of what's going on here can be found // in Crochemore and Rytter's book "Text Algorithms", ch 13. Specifically @@ -1032,7 +1047,7 @@ impl TwoWaySearcher { // &v[..period]. If it is, we use "Algorithm CP1". Otherwise we use // "Algorithm CP2", which is optimized for when the period of the needle // is large. - if &needle[..crit_pos] == &needle[period.. period + crit_pos] { + if &needle[..crit_pos] == &needle[period..period + crit_pos] { // short period case -- the period is exact // compute a separate critical factorization for the reversed needle // x = u' v' where |v'| < period(x). @@ -1042,9 +1057,11 @@ impl TwoWaySearcher { // (crit_pos = 1, period = 3) while being factored with approximate // period in reverse (crit_pos = 2, period = 2). We use the given // reverse factorization but keep the exact period. - let crit_pos_back = needle.len() - cmp::max( - TwoWaySearcher::reverse_maximal_suffix(needle, period, false), - TwoWaySearcher::reverse_maximal_suffix(needle, period, true)); + let crit_pos_back = needle.len() + - cmp::max( + TwoWaySearcher::reverse_maximal_suffix(needle, period, false), + TwoWaySearcher::reverse_maximal_suffix(needle, period, true), + ); TwoWaySearcher { crit_pos, @@ -1095,9 +1112,9 @@ impl TwoWaySearcher { // How far we can jump when we encounter a mismatch is all based on the fact // that (u, v) is a critical factorization for the needle. #[inline] - fn next(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) - -> S::Output - where S: TwoWayStrategy + fn next(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) -> S::Output + where + S: TwoWayStrategy, { // `next()` uses `self.position` as its cursor let old_pos = self.position; @@ -1128,8 +1145,8 @@ impl TwoWaySearcher { } // See if the right part of the needle matches - let start = if long_period { self.crit_pos } - else { cmp::max(self.crit_pos, self.memory) }; + let start = + if long_period { self.crit_pos } else { cmp::max(self.crit_pos, self.memory) }; for i in start..needle.len() { if needle[i] != haystack[self.position + i] { self.position += i - self.crit_pos + 1; @@ -1178,9 +1195,9 @@ impl TwoWaySearcher { // To search in reverse through the haystack, we search forward through // a reversed haystack with a reversed needle, matching first u' and then v'. #[inline] - fn next_back(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) - -> S::Output - where S: TwoWayStrategy + fn next_back(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) -> S::Output + where + S: TwoWayStrategy, { // `next_back()` uses `self.end` as its cursor -- so that `next()` and `next_back()` // are independent. @@ -1212,8 +1229,11 @@ impl TwoWaySearcher { } // See if the left part of the needle matches - let crit = if long_period { self.crit_pos_back } - else { cmp::min(self.crit_pos_back, self.memory_back) }; + let crit = if long_period { + self.crit_pos_back + } else { + cmp::min(self.crit_pos_back, self.memory_back) + }; for i in (0..crit).rev() { if needle[i] != haystack[self.end - needle.len() + i] { self.end -= self.crit_pos_back - i; @@ -1225,8 +1245,7 @@ impl TwoWaySearcher { } // See if the right part of the needle matches - let needle_end = if long_period { needle.len() } - else { self.memory_back }; + let needle_end = if long_period { needle.len() } else { self.memory_back }; for i in self.crit_pos_back..needle_end { if needle[i] != haystack[self.end - needle.len() + i] { self.end -= self.period; @@ -1266,7 +1285,7 @@ impl TwoWaySearcher { let mut left = 0; // Corresponds to i in the paper let mut right = 1; // Corresponds to j in the paper let mut offset = 0; // Corresponds to k in the paper, but starting at 0 - // to match 0-based indexing. + // to match 0-based indexing. let mut period = 1; // Corresponds to p in the paper while let Some(&a) = arr.get(right + offset) { @@ -1308,13 +1327,11 @@ impl TwoWaySearcher { // a critical factorization. // // For long period cases, the resulting period is not exact (it is too short). - fn reverse_maximal_suffix(arr: &[u8], known_period: usize, - order_greater: bool) -> usize - { + fn reverse_maximal_suffix(arr: &[u8], known_period: usize, order_greater: bool) -> usize { let mut left = 0; // Corresponds to i in the paper let mut right = 1; // Corresponds to j in the paper let mut offset = 0; // Corresponds to k in the paper, but starting at 0 - // to match 0-based indexing. + // to match 0-based indexing. let mut period = 1; // Corresponds to p in the paper let n = arr.len(); @@ -1360,29 +1377,41 @@ trait TwoWayStrategy { } /// Skip to match intervals as quickly as possible -enum MatchOnly { } +enum MatchOnly {} impl TwoWayStrategy for MatchOnly { type Output = Option<(usize, usize)>; #[inline] - fn use_early_reject() -> bool { false } + fn use_early_reject() -> bool { + false + } #[inline] - fn rejecting(_a: usize, _b: usize) -> Self::Output { None } + fn rejecting(_a: usize, _b: usize) -> Self::Output { + None + } #[inline] - fn matching(a: usize, b: usize) -> Self::Output { Some((a, b)) } + fn matching(a: usize, b: usize) -> Self::Output { + Some((a, b)) + } } /// Emit Rejects regularly -enum RejectAndMatch { } +enum RejectAndMatch {} impl TwoWayStrategy for RejectAndMatch { type Output = SearchStep; #[inline] - fn use_early_reject() -> bool { true } + fn use_early_reject() -> bool { + true + } #[inline] - fn rejecting(a: usize, b: usize) -> Self::Output { SearchStep::Reject(a, b) } + fn rejecting(a: usize, b: usize) -> Self::Output { + SearchStep::Reject(a, b) + } #[inline] - fn matching(a: usize, b: usize) -> Self::Output { SearchStep::Match(a, b) } + fn matching(a: usize, b: usize) -> Self::Output { + SearchStep::Match(a, b) + } } diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 1f09895597a87..a2352c08e7316 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -120,9 +120,9 @@ use self::Ordering::*; -use crate::intrinsics; use crate::cell::UnsafeCell; use crate::fmt; +use crate::intrinsics; use crate::hint::spin_loop; @@ -313,7 +313,7 @@ pub enum Ordering { #[rustc_deprecated( since = "1.34.0", reason = "the `new` function is now preferred", - suggestion = "AtomicBool::new(false)", + suggestion = "AtomicBool::new(false)" )] pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false); @@ -557,12 +557,13 @@ impl AtomicBool { #[inline] #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] #[cfg(target_has_atomic = "8")] - pub fn compare_exchange(&self, - current: bool, - new: bool, - success: Ordering, - failure: Ordering) - -> Result { + pub fn compare_exchange( + &self, + current: bool, + new: bool, + success: Ordering, + failure: Ordering, + ) -> Result { match unsafe { atomic_compare_exchange(self.v.get(), current as u8, new as u8, success, failure) } { @@ -613,12 +614,13 @@ impl AtomicBool { #[inline] #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] #[cfg(target_has_atomic = "8")] - pub fn compare_exchange_weak(&self, - current: bool, - new: bool, - success: Ordering, - failure: Ordering) - -> Result { + pub fn compare_exchange_weak( + &self, + current: bool, + new: bool, + success: Ordering, + failure: Ordering, + ) -> Result { match unsafe { atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8, success, failure) } { @@ -834,9 +836,7 @@ impl AtomicBool { /// # } /// ``` #[inline] - #[unstable(feature = "atomic_mut_ptr", - reason = "recently added", - issue = "66893")] + #[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")] pub fn as_mut_ptr(&self) -> *mut bool { self.v.get() as *mut bool } @@ -1073,18 +1073,21 @@ impl AtomicPtr { #[inline] #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] #[cfg(target_has_atomic = "ptr")] - pub fn compare_exchange(&self, - current: *mut T, - new: *mut T, - success: Ordering, - failure: Ordering) - -> Result<*mut T, *mut T> { + pub fn compare_exchange( + &self, + current: *mut T, + new: *mut T, + success: Ordering, + failure: Ordering, + ) -> Result<*mut T, *mut T> { unsafe { - let res = atomic_compare_exchange(self.p.get() as *mut usize, - current as usize, - new as usize, - success, - failure); + let res = atomic_compare_exchange( + self.p.get() as *mut usize, + current as usize, + new as usize, + success, + failure, + ); match res { Ok(x) => Ok(x as *mut T), Err(x) => Err(x as *mut T), @@ -1133,18 +1136,21 @@ impl AtomicPtr { #[inline] #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] #[cfg(target_has_atomic = "ptr")] - pub fn compare_exchange_weak(&self, - current: *mut T, - new: *mut T, - success: Ordering, - failure: Ordering) - -> Result<*mut T, *mut T> { + pub fn compare_exchange_weak( + &self, + current: *mut T, + new: *mut T, + success: Ordering, + failure: Ordering, + ) -> Result<*mut T, *mut T> { unsafe { - let res = atomic_compare_exchange_weak(self.p.get() as *mut usize, - current as usize, - new as usize, - success, - failure); + let res = atomic_compare_exchange_weak( + self.p.get() as *mut usize, + current as usize, + new as usize, + success, + failure, + ); match res { Ok(x) => Ok(x as *mut T), Err(x) => Err(x as *mut T), @@ -1166,14 +1172,18 @@ impl From for AtomicBool { /// assert_eq!(format!("{:?}", atomic_bool), "true") /// ``` #[inline] - fn from(b: bool) -> Self { Self::new(b) } + fn from(b: bool) -> Self { + Self::new(b) + } } #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "atomic_from", since = "1.23.0")] impl From<*mut T> for AtomicPtr { #[inline] - fn from(p: *mut T) -> Self { Self::new(p) } + fn from(p: *mut T) -> Self { + Self::new(p) + } } #[cfg(target_has_atomic_load_store = "8")] @@ -2156,20 +2166,26 @@ atomic_int! { #[cfg(target_has_atomic_load_store = "ptr")] #[cfg(target_pointer_width = "16")] macro_rules! ptr_width { - () => { 2 } + () => { + 2 + }; } #[cfg(target_has_atomic_load_store = "ptr")] #[cfg(target_pointer_width = "32")] macro_rules! ptr_width { - () => { 4 } + () => { + 4 + }; } #[cfg(target_has_atomic_load_store = "ptr")] #[cfg(target_pointer_width = "64")] macro_rules! ptr_width { - () => { 8 } + () => { + 8 + }; } #[cfg(target_has_atomic_load_store = "ptr")] -atomic_int!{ +atomic_int! { cfg(target_has_atomic = "ptr"), stable(feature = "rust1", since = "1.0.0"), stable(feature = "extended_compare_and_swap", since = "1.10.0"), @@ -2187,7 +2203,7 @@ atomic_int!{ isize AtomicIsize ATOMIC_ISIZE_INIT } #[cfg(target_has_atomic_load_store = "ptr")] -atomic_int!{ +atomic_int! { cfg(target_has_atomic = "ptr"), stable(feature = "rust1", since = "1.0.0"), stable(feature = "extended_compare_and_swap", since = "1.10.0"), @@ -2279,12 +2295,13 @@ unsafe fn atomic_sub(dst: *mut T, val: T, order: Ordering) -> T { #[inline] #[cfg(target_has_atomic = "8")] -unsafe fn atomic_compare_exchange(dst: *mut T, - old: T, - new: T, - success: Ordering, - failure: Ordering) - -> Result { +unsafe fn atomic_compare_exchange( + dst: *mut T, + old: T, + new: T, + success: Ordering, + failure: Ordering, +) -> Result { let (val, ok) = match (success, failure) { (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new), (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new), @@ -2304,12 +2321,13 @@ unsafe fn atomic_compare_exchange(dst: *mut T, #[inline] #[cfg(target_has_atomic = "8")] -unsafe fn atomic_compare_exchange_weak(dst: *mut T, - old: T, - new: T, - success: Ordering, - failure: Ordering) - -> Result { +unsafe fn atomic_compare_exchange_weak( + dst: *mut T, + old: T, + new: T, + success: Ordering, + failure: Ordering, +) -> Result { let (val, ok) = match (success, failure) { (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acq(dst, old, new), (Release, Relaxed) => intrinsics::atomic_cxchgweak_rel(dst, old, new), @@ -2525,7 +2543,6 @@ pub fn fence(order: Ordering) { } } - /// A compiler memory fence. /// /// `compiler_fence` does not emit any machine code, but restricts the kinds @@ -2613,7 +2630,6 @@ pub fn compiler_fence(order: Ordering) { } } - #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "atomic_debug", since = "1.3.0")] impl fmt::Debug for AtomicBool { diff --git a/src/libcore/tests/cmp.rs b/src/libcore/tests/cmp.rs index 56a2f4acf6eaa..4086917780fa4 100644 --- a/src/libcore/tests/cmp.rs +++ b/src/libcore/tests/cmp.rs @@ -101,7 +101,7 @@ fn test_ordering_then_with() { fn test_user_defined_eq() { // Our type. struct SketchyNum { - num : isize + num: isize, } // Our implementation of `PartialEq` to support `==` and `!=`. @@ -113,6 +113,6 @@ fn test_user_defined_eq() { } // Now these binary operators will work when applied! - assert!(SketchyNum {num: 37} == SketchyNum {num: 34}); - assert!(SketchyNum {num: 25} != SketchyNum {num: 57}); + assert!(SketchyNum { num: 37 } == SketchyNum { num: 34 }); + assert!(SketchyNum { num: 25 } != SketchyNum { num: 57 }); } diff --git a/src/libcore/tests/fmt/builders.rs b/src/libcore/tests/fmt/builders.rs index 255724432816d..90a9bccda1580 100644 --- a/src/libcore/tests/fmt/builders.rs +++ b/src/libcore/tests/fmt/builders.rs @@ -21,18 +21,17 @@ mod debug_struct { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("Foo") - .field("bar", &true) - .finish() + fmt.debug_struct("Foo").field("bar", &true).finish() } } assert_eq!("Foo { bar: true }", format!("{:?}", Foo)); assert_eq!( -"Foo { + "Foo { bar: true, }", - format!("{:#?}", Foo)); + format!("{:#?}", Foo) + ); } #[test] @@ -50,11 +49,12 @@ mod debug_struct { assert_eq!("Foo { bar: true, baz: 10/20 }", format!("{:?}", Foo)); assert_eq!( -"Foo { + "Foo { bar: true, baz: 10/20, }", - format!("{:#?}", Foo)); + format!("{:#?}", Foo) + ); } #[test] @@ -74,24 +74,24 @@ mod debug_struct { impl fmt::Debug for Bar { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("Bar") - .field("foo", &Foo) - .field("hello", &"world") - .finish() + fmt.debug_struct("Bar").field("foo", &Foo).field("hello", &"world").finish() } } - assert_eq!("Bar { foo: Foo { bar: true, baz: 10/20 }, hello: \"world\" }", - format!("{:?}", Bar)); assert_eq!( -"Bar { + "Bar { foo: Foo { bar: true, baz: 10/20 }, hello: \"world\" }", + format!("{:?}", Bar) + ); + assert_eq!( + "Bar { foo: Foo { bar: true, baz: 10/20, }, hello: \"world\", }", - format!("{:#?}", Bar)); + format!("{:#?}", Bar) + ); } } @@ -118,18 +118,17 @@ mod debug_tuple { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_tuple("Foo") - .field(&true) - .finish() + fmt.debug_tuple("Foo").field(&true).finish() } } assert_eq!("Foo(true)", format!("{:?}", Foo)); assert_eq!( -"Foo( + "Foo( true, )", - format!("{:#?}", Foo)); + format!("{:#?}", Foo) + ); } #[test] @@ -138,20 +137,18 @@ mod debug_tuple { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_tuple("Foo") - .field(&true) - .field(&format_args!("{}/{}", 10, 20)) - .finish() + fmt.debug_tuple("Foo").field(&true).field(&format_args!("{}/{}", 10, 20)).finish() } } assert_eq!("Foo(true, 10/20)", format!("{:?}", Foo)); assert_eq!( -"Foo( + "Foo( true, 10/20, )", - format!("{:#?}", Foo)); + format!("{:#?}", Foo) + ); } #[test] @@ -160,10 +157,7 @@ mod debug_tuple { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_tuple("Foo") - .field(&true) - .field(&format_args!("{}/{}", 10, 20)) - .finish() + fmt.debug_tuple("Foo").field(&true).field(&format_args!("{}/{}", 10, 20)).finish() } } @@ -171,24 +165,21 @@ mod debug_tuple { impl fmt::Debug for Bar { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_tuple("Bar") - .field(&Foo) - .field(&"world") - .finish() + fmt.debug_tuple("Bar").field(&Foo).field(&"world").finish() } } - assert_eq!("Bar(Foo(true, 10/20), \"world\")", - format!("{:?}", Bar)); + assert_eq!("Bar(Foo(true, 10/20), \"world\")", format!("{:?}", Bar)); assert_eq!( -"Bar( + "Bar( Foo( true, 10/20, ), \"world\", )", - format!("{:#?}", Bar)); + format!("{:#?}", Bar) + ); } } @@ -215,9 +206,7 @@ mod debug_map { impl fmt::Debug for Entry { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_map() - .entry(&"bar", &true) - .finish() + fmt.debug_map().entry(&"bar", &true).finish() } } @@ -225,9 +214,7 @@ mod debug_map { impl fmt::Debug for KeyValue { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_map() - .key(&"bar").value(&true) - .finish() + fmt.debug_map().key(&"bar").value(&true).finish() } } @@ -236,10 +223,11 @@ mod debug_map { assert_eq!("{\"bar\": true}", format!("{:?}", Entry)); assert_eq!( -"{ + "{ \"bar\": true, }", - format!("{:#?}", Entry)); + format!("{:#?}", Entry) + ); } #[test] @@ -260,8 +248,10 @@ mod debug_map { impl fmt::Debug for KeyValue { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.debug_map() - .key(&"bar").value(&true) - .key(&10).value(&format_args!("{}/{}", 10, 20)) + .key(&"bar") + .value(&true) + .key(&10) + .value(&format_args!("{}/{}", 10, 20)) .finish() } } @@ -271,11 +261,12 @@ mod debug_map { assert_eq!("{\"bar\": true, 10: 10/20}", format!("{:?}", Entry)); assert_eq!( -"{ + "{ \"bar\": true, 10: 10/20, }", - format!("{:#?}", Entry)); + format!("{:#?}", Entry) + ); } #[test] @@ -295,18 +286,17 @@ mod debug_map { impl fmt::Debug for Bar { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_map() - .entry(&"foo", &Foo) - .entry(&Foo, &"world") - .finish() + fmt.debug_map().entry(&"foo", &Foo).entry(&Foo, &"world").finish() } } - assert_eq!("{\"foo\": {\"bar\": true, 10: 10/20}, \ + assert_eq!( + "{\"foo\": {\"bar\": true, 10: 10/20}, \ {\"bar\": true, 10: 10/20}: \"world\"}", - format!("{:?}", Bar)); + format!("{:?}", Bar) + ); assert_eq!( -"{ + "{ \"foo\": { \"bar\": true, 10: 10/20, @@ -316,7 +306,8 @@ mod debug_map { 10: 10/20, }: \"world\", }", - format!("{:#?}", Bar)); + format!("{:#?}", Bar) + ); } #[test] @@ -366,10 +357,7 @@ mod debug_map { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_map() - .key(&"bar") - .key(&"invalid") - .finish() + fmt.debug_map().key(&"bar").key(&"invalid").finish() } } @@ -383,9 +371,7 @@ mod debug_map { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_map() - .key(&"bar") - .finish() + fmt.debug_map().key(&"bar").finish() } } @@ -399,10 +385,7 @@ mod debug_map { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_map() - .value(&"invalid") - .key(&"bar") - .finish() + fmt.debug_map().value(&"invalid").key(&"bar").finish() } } @@ -433,18 +416,17 @@ mod debug_set { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_set() - .entry(&true) - .finish() + fmt.debug_set().entry(&true).finish() } } assert_eq!("{true}", format!("{:?}", Foo)); assert_eq!( -"{ + "{ true, }", - format!("{:#?}", Foo)); + format!("{:#?}", Foo) + ); } #[test] @@ -453,20 +435,18 @@ mod debug_set { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_set() - .entry(&true) - .entry(&format_args!("{}/{}", 10, 20)) - .finish() + fmt.debug_set().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish() } } assert_eq!("{true, 10/20}", format!("{:?}", Foo)); assert_eq!( -"{ + "{ true, 10/20, }", - format!("{:#?}", Foo)); + format!("{:#?}", Foo) + ); } #[test] @@ -475,10 +455,7 @@ mod debug_set { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_set() - .entry(&true) - .entry(&format_args!("{}/{}", 10, 20)) - .finish() + fmt.debug_set().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish() } } @@ -486,24 +463,21 @@ mod debug_set { impl fmt::Debug for Bar { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_set() - .entry(&Foo) - .entry(&"world") - .finish() + fmt.debug_set().entry(&Foo).entry(&"world").finish() } } - assert_eq!("{{true, 10/20}, \"world\"}", - format!("{:?}", Bar)); + assert_eq!("{{true, 10/20}, \"world\"}", format!("{:?}", Bar)); assert_eq!( -"{ + "{ { true, 10/20, }, \"world\", }", - format!("{:#?}", Bar)); + format!("{:#?}", Bar) + ); } } @@ -530,18 +504,17 @@ mod debug_list { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_list() - .entry(&true) - .finish() + fmt.debug_list().entry(&true).finish() } } assert_eq!("[true]", format!("{:?}", Foo)); assert_eq!( -"[ + "[ true, ]", - format!("{:#?}", Foo)); + format!("{:#?}", Foo) + ); } #[test] @@ -550,20 +523,18 @@ mod debug_list { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_list() - .entry(&true) - .entry(&format_args!("{}/{}", 10, 20)) - .finish() + fmt.debug_list().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish() } } assert_eq!("[true, 10/20]", format!("{:?}", Foo)); assert_eq!( -"[ + "[ true, 10/20, ]", - format!("{:#?}", Foo)); + format!("{:#?}", Foo) + ); } #[test] @@ -572,10 +543,7 @@ mod debug_list { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_list() - .entry(&true) - .entry(&format_args!("{}/{}", 10, 20)) - .finish() + fmt.debug_list().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish() } } @@ -583,24 +551,21 @@ mod debug_list { impl fmt::Debug for Bar { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_list() - .entry(&Foo) - .entry(&"world") - .finish() + fmt.debug_list().entry(&Foo).entry(&"world").finish() } } - assert_eq!("[[true, 10/20], \"world\"]", - format!("{:?}", Bar)); + assert_eq!("[[true, 10/20], \"world\"]", format!("{:?}", Bar)); assert_eq!( -"[ + "[ [ true, 10/20, ], \"world\", ]", - format!("{:#?}", Bar)); + format!("{:#?}", Bar) + ); } } @@ -627,34 +592,54 @@ fn test_formatting_parameters_are_forwarded() { assert_eq!(format!("{:03?}", list), "[1024, 007]"); assert_eq!(format!("{:03?}", map), r#"{"bar": 1024, "baz": 007}"#); assert_eq!(format!("{:03?}", set), "{007, 1024}"); - assert_eq!(format!("{:#03?}", struct_), " + assert_eq!( + format!("{:#03?}", struct_), + " Foo { bar: 1024, baz: 007, } - ".trim()); - assert_eq!(format!("{:#03?}", tuple), " + " + .trim() + ); + assert_eq!( + format!("{:#03?}", tuple), + " ( 1024, 007, ) - ".trim()); - assert_eq!(format!("{:#03?}", list), " + " + .trim() + ); + assert_eq!( + format!("{:#03?}", list), + " [ 1024, 007, ] - ".trim()); - assert_eq!(format!("{:#03?}", map), r#" + " + .trim() + ); + assert_eq!( + format!("{:#03?}", map), + r#" { "bar": 1024, "baz": 007, } - "#.trim()); - assert_eq!(format!("{:#03?}", set), " + "# + .trim() + ); + assert_eq!( + format!("{:#03?}", set), + " { 007, 1024, } - ".trim()); + " + .trim() + ); } diff --git a/src/libcore/tests/hash/mod.rs b/src/libcore/tests/hash/mod.rs index ba0220f0d92df..1566d35749017 100644 --- a/src/libcore/tests/hash/mod.rs +++ b/src/libcore/tests/hash/mod.rs @@ -71,7 +71,8 @@ fn test_writer_hasher() { let ptr = 5_usize as *mut i32; assert_eq!(hash(&ptr), 5); - if cfg!(miri) { // Miri cannot hash pointers + if cfg!(miri) { + // Miri cannot hash pointers return; } diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index c9096b713f20e..cf28ec8a636bc 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1,58 +1,58 @@ use core::cell::Cell; use core::convert::TryFrom; use core::iter::*; -use core::{i8, i16, isize}; use core::usize; +use core::{i16, i8, isize}; #[test] fn test_lt() { let empty: [isize; 0] = []; - let xs = [1,2,3]; - let ys = [1,2,0]; + let xs = [1, 2, 3]; + let ys = [1, 2, 0]; assert!(!xs.iter().lt(ys.iter())); assert!(!xs.iter().le(ys.iter())); - assert!( xs.iter().gt(ys.iter())); - assert!( xs.iter().ge(ys.iter())); + assert!(xs.iter().gt(ys.iter())); + assert!(xs.iter().ge(ys.iter())); - assert!( ys.iter().lt(xs.iter())); - assert!( ys.iter().le(xs.iter())); + assert!(ys.iter().lt(xs.iter())); + assert!(ys.iter().le(xs.iter())); assert!(!ys.iter().gt(xs.iter())); assert!(!ys.iter().ge(xs.iter())); - assert!( empty.iter().lt(xs.iter())); - assert!( empty.iter().le(xs.iter())); + assert!(empty.iter().lt(xs.iter())); + assert!(empty.iter().le(xs.iter())); assert!(!empty.iter().gt(xs.iter())); assert!(!empty.iter().ge(xs.iter())); // Sequence with NaN let u = [1.0f64, 2.0]; - let v = [0.0f64/0.0, 3.0]; + let v = [0.0f64 / 0.0, 3.0]; assert!(!u.iter().lt(v.iter())); assert!(!u.iter().le(v.iter())); assert!(!u.iter().gt(v.iter())); assert!(!u.iter().ge(v.iter())); - let a = [0.0f64/0.0]; + let a = [0.0f64 / 0.0]; let b = [1.0f64]; let c = [2.0f64]; - assert!(a.iter().lt(b.iter()) == (a[0] < b[0])); + assert!(a.iter().lt(b.iter()) == (a[0] < b[0])); assert!(a.iter().le(b.iter()) == (a[0] <= b[0])); - assert!(a.iter().gt(b.iter()) == (a[0] > b[0])); + assert!(a.iter().gt(b.iter()) == (a[0] > b[0])); assert!(a.iter().ge(b.iter()) == (a[0] >= b[0])); - assert!(c.iter().lt(b.iter()) == (c[0] < b[0])); + assert!(c.iter().lt(b.iter()) == (c[0] < b[0])); assert!(c.iter().le(b.iter()) == (c[0] <= b[0])); - assert!(c.iter().gt(b.iter()) == (c[0] > b[0])); + assert!(c.iter().gt(b.iter()) == (c[0] > b[0])); assert!(c.iter().ge(b.iter()) == (c[0] >= b[0])); } #[test] fn test_multi_iter() { - let xs = [1,2,3,4]; - let ys = [4,3,2,1]; + let xs = [1, 2, 3, 4]; + let ys = [4, 3, 2, 1]; assert!(xs.iter().eq(ys.iter().rev())); assert!(xs.iter().lt(xs.iter().skip(2))); } @@ -229,11 +229,7 @@ fn test_iterator_chain_size_hint() { } fn size_hint(&self) -> (usize, Option) { - if self.is_empty { - (0, Some(0)) - } else { - (1, Some(1)) - } + if self.is_empty { (0, Some(0)) } else { (1, Some(1)) } } } @@ -277,7 +273,9 @@ fn test_zip_nth() { fn test_zip_nth_side_effects() { let mut a = Vec::new(); let mut b = Vec::new(); - let value = [1, 2, 3, 4, 5, 6].iter().cloned() + let value = [1, 2, 3, 4, 5, 6] + .iter() + .cloned() .map(|n| { a.push(n); n * 10 @@ -356,7 +354,9 @@ fn test_iterator_step_by_nth_overflow() { struct Test(Bigger); impl Iterator for &mut Test { type Item = i32; - fn next(&mut self) -> Option { Some(21) } + fn next(&mut self) -> Option { + Some(21) + } fn nth(&mut self, n: usize) -> Option { self.0 += n as Bigger + 1; Some(42) @@ -499,7 +499,7 @@ fn test_iterator_step_by_size_hint() { let mut it = StubSizeHint(usize::MAX, None).step_by(1); assert_eq!(it.size_hint(), (usize::MAX, None)); it.next(); - assert_eq!(it.size_hint(), (usize::MAX-1, None)); + assert_eq!(it.size_hint(), (usize::MAX - 1, None)); // still infinite with larger step let mut it = StubSizeHint(7, None).step_by(3); @@ -508,18 +508,24 @@ fn test_iterator_step_by_size_hint() { assert_eq!(it.size_hint(), (2, None)); // propagates ExactSizeIterator - let a = [1,2,3,4,5]; + let a = [1, 2, 3, 4, 5]; let it = a.iter().step_by(2); assert_eq!(it.len(), 3); // Cannot be TrustedLen as a step greater than one makes an iterator // with (usize::MAX, None) no longer meet the safety requirements - trait TrustedLenCheck { fn test(self) -> bool; } - impl TrustedLenCheck for T { - default fn test(self) -> bool { false } + trait TrustedLenCheck { + fn test(self) -> bool; + } + impl TrustedLenCheck for T { + default fn test(self) -> bool { + false + } } - impl TrustedLenCheck for T { - fn test(self) -> bool { true } + impl TrustedLenCheck for T { + fn test(self) -> bool { + true + } } assert!(TrustedLenCheck::test(a.iter())); assert!(!TrustedLenCheck::test(a.iter().step_by(1))); @@ -527,23 +533,22 @@ fn test_iterator_step_by_size_hint() { #[test] fn test_filter_map() { - let it = (0..).step_by(1).take(10) - .filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None }); - assert_eq!(it.collect::>(), [0*0, 2*2, 4*4, 6*6, 8*8]); + let it = (0..).step_by(1).take(10).filter_map(|x| if x % 2 == 0 { Some(x * x) } else { None }); + assert_eq!(it.collect::>(), [0 * 0, 2 * 2, 4 * 4, 6 * 6, 8 * 8]); } #[test] fn test_filter_map_fold() { let xs = [0, 1, 2, 3, 4, 5, 6, 7, 8]; - let ys = [0*0, 2*2, 4*4, 6*6, 8*8]; - let it = xs.iter().filter_map(|&x| if x % 2 == 0 { Some(x*x) } else { None }); + let ys = [0 * 0, 2 * 2, 4 * 4, 6 * 6, 8 * 8]; + let it = xs.iter().filter_map(|&x| if x % 2 == 0 { Some(x * x) } else { None }); let i = it.fold(0, |i, x| { assert_eq!(x, ys[i]); i + 1 }); assert_eq!(i, ys.len()); - let it = xs.iter().filter_map(|&x| if x % 2 == 0 { Some(x*x) } else { None }); + let it = xs.iter().filter_map(|&x| if x % 2 == 0 { Some(x * x) } else { None }); let i = it.rfold(ys.len(), |i, x| { assert_eq!(x, ys[i - 1]); i - 1 @@ -736,7 +741,6 @@ fn test_iterator_peekable_count() { let mut it = zs.iter().peekable(); assert_eq!(it.peek(), None); - } #[test] @@ -805,10 +809,7 @@ pub struct CycleIter<'a, T> { } pub fn cycle(data: &[T]) -> CycleIter<'_, T> { - CycleIter { - index: 0, - data, - } + CycleIter { index: 0, data } } impl<'a, T> Iterator for CycleIter<'a, T> { @@ -832,7 +833,9 @@ fn test_iterator_peekable_remember_peek_none_1() { let is_the_last = iter.peek().is_none(); assert_eq!(is_the_last, n == data.len() - 1); n += 1; - if n > data.len() { break; } + if n > data.len() { + break; + } } assert_eq!(n, data.len()); } @@ -914,7 +917,7 @@ fn test_iterator_skip() { while let Some(&x) = it.next() { assert_eq!(x, ys[i]); i += 1; - assert_eq!(it.len(), xs.len()-5-i); + assert_eq!(it.len(), xs.len() - 5 - i); } assert_eq!(i, ys.len()); assert_eq!(it.len(), 0); @@ -972,7 +975,6 @@ fn test_iterator_skip_nth() { let mut it = xs.iter().skip(12); assert_eq!(it.nth(0), None); - } #[test] @@ -1037,7 +1039,6 @@ fn test_iterator_skip_fold() { i }); assert_eq!(i, 1); - } #[test] @@ -1178,7 +1179,7 @@ fn test_iterator_flat_map() { fn test_iterator_flat_map_fold() { let xs = [0, 3, 6]; let ys = [1, 2, 3, 4, 5, 6, 7]; - let mut it = xs.iter().flat_map(|&x| x..x+3); + let mut it = xs.iter().flat_map(|&x| x..x + 3); assert_eq!(it.next(), Some(0)); assert_eq!(it.next_back(), Some(8)); let i = it.fold(0, |i, x| { @@ -1187,7 +1188,7 @@ fn test_iterator_flat_map_fold() { }); assert_eq!(i, ys.len()); - let mut it = xs.iter().flat_map(|&x| x..x+3); + let mut it = xs.iter().flat_map(|&x| x..x + 3); assert_eq!(it.next(), Some(0)); assert_eq!(it.next_back(), Some(8)); let i = it.rfold(ys.len(), |i, x| { @@ -1216,7 +1217,7 @@ fn test_iterator_flatten() { fn test_iterator_flatten_fold() { let xs = [0, 3, 6]; let ys = [1, 2, 3, 4, 5, 6, 7]; - let mut it = xs.iter().map(|&x| x..x+3).flatten(); + let mut it = xs.iter().map(|&x| x..x + 3).flatten(); assert_eq!(it.next(), Some(0)); assert_eq!(it.next_back(), Some(8)); let i = it.fold(0, |i, x| { @@ -1225,7 +1226,7 @@ fn test_iterator_flatten_fold() { }); assert_eq!(i, ys.len()); - let mut it = xs.iter().map(|&x| x..x+3).flatten(); + let mut it = xs.iter().map(|&x| x..x + 3).flatten(); assert_eq!(it.next(), Some(0)); assert_eq!(it.next_back(), Some(8)); let i = it.rfold(ys.len(), |i, x| { @@ -1240,10 +1241,7 @@ fn test_inspect() { let xs = [1, 2, 3, 4]; let mut n = 0; - let ys = xs.iter() - .cloned() - .inspect(|_| n += 1) - .collect::>(); + let ys = xs.iter().cloned().inspect(|_| n += 1).collect::>(); assert_eq!(n, xs.len()); assert_eq!(&xs[..], &ys[..]); @@ -1483,7 +1481,7 @@ fn test_iterator_size_hint() { assert_eq!(c.clone().enumerate().size_hint(), (usize::MAX, None)); assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (usize::MAX, None)); assert_eq!(c.clone().zip(vi.clone()).size_hint(), (10, Some(10))); - assert_eq!(c.clone().scan(0, |_,_| Some(0)).size_hint(), (0, None)); + assert_eq!(c.clone().scan(0, |_, _| Some(0)).size_hint(), (0, None)); assert_eq!(c.clone().filter(|_| false).size_hint(), (0, None)); assert_eq!(c.clone().map(|_| 0).size_hint(), (usize::MAX, None)); assert_eq!(c.filter_map(|_| Some(0)).size_hint(), (0, None)); @@ -1497,9 +1495,9 @@ fn test_iterator_size_hint() { assert_eq!(vi.clone().enumerate().size_hint(), (10, Some(10))); assert_eq!(vi.clone().chain(v2).size_hint(), (13, Some(13))); assert_eq!(vi.clone().zip(v2).size_hint(), (3, Some(3))); - assert_eq!(vi.clone().scan(0, |_,_| Some(0)).size_hint(), (0, Some(10))); + assert_eq!(vi.clone().scan(0, |_, _| Some(0)).size_hint(), (0, Some(10))); assert_eq!(vi.clone().filter(|_| false).size_hint(), (0, Some(10))); - assert_eq!(vi.clone().map(|&i| i+1).size_hint(), (10, Some(10))); + assert_eq!(vi.clone().map(|&i| i + 1).size_hint(), (10, Some(10))); assert_eq!(vi.filter_map(|_| Some(0)).size_hint(), (0, Some(10))); } @@ -1555,11 +1553,7 @@ fn test_find_map() { assert_eq!(iter.next(), Some(&7)); fn half_if_even(x: &isize) -> Option { - if x % 2 == 0 { - Some(x / 2) - } else { - None - } + if x % 2 == 0 { Some(x / 2) } else { None } } } @@ -1618,8 +1612,7 @@ fn test_rev() { let mut it = xs.iter(); it.next(); it.next(); - assert!(it.rev().cloned().collect::>() == - vec![16, 14, 12, 10, 8, 6]); + assert!(it.rev().cloned().collect::>() == vec![16, 14, 12, 10, 8, 6]); } #[test] @@ -1748,14 +1741,22 @@ fn test_double_ended_chain() { assert_eq!(it.next_back().unwrap(), &7); assert_eq!(it.next_back(), None); - // test that .chain() is well behaved with an unfused iterator struct CrazyIterator(bool); - impl CrazyIterator { fn new() -> CrazyIterator { CrazyIterator(false) } } + impl CrazyIterator { + fn new() -> CrazyIterator { + CrazyIterator(false) + } + } impl Iterator for CrazyIterator { type Item = i32; fn next(&mut self) -> Option { - if self.0 { Some(99) } else { self.0 = true; None } + if self.0 { + Some(99) + } else { + self.0 = true; + None + } } } @@ -1771,8 +1772,14 @@ fn test_double_ended_chain() { #[test] fn test_rposition() { - fn f(xy: &(isize, char)) -> bool { let (_x, y) = *xy; y == 'b' } - fn g(xy: &(isize, char)) -> bool { let (_x, y) = *xy; y == 'd' } + fn f(xy: &(isize, char)) -> bool { + let (_x, y) = *xy; + y == 'b' + } + fn g(xy: &(isize, char)) -> bool { + let (_x, y) = *xy; + y == 'd' + } let v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; assert_eq!(v.iter().rposition(f), Some(3)); @@ -1788,9 +1795,7 @@ fn test_rev_rposition() { #[test] #[should_panic] fn test_rposition_panic() { - let v: [(Box<_>, Box<_>); 4] = - [(box 0, box 0), (box 0, box 0), - (box 0, box 0), (box 0, box 0)]; + let v: [(Box<_>, Box<_>); 4] = [(box 0, box 0), (box 0, box 0), (box 0, box 0), (box 0, box 0)]; let mut i = 0; v.iter().rposition(|_elt| { if i == 2 { @@ -1801,38 +1806,37 @@ fn test_rposition_panic() { }); } - #[test] fn test_double_ended_flat_map() { - let u = [0,1]; - let v = [5,6,7,8]; + let u = [0, 1]; + let v = [5, 6, 7, 8]; let mut it = u.iter().flat_map(|x| &v[*x..v.len()]); assert_eq!(it.next_back().unwrap(), &8); - assert_eq!(it.next().unwrap(), &5); + assert_eq!(it.next().unwrap(), &5); assert_eq!(it.next_back().unwrap(), &7); assert_eq!(it.next_back().unwrap(), &6); assert_eq!(it.next_back().unwrap(), &8); - assert_eq!(it.next().unwrap(), &6); + assert_eq!(it.next().unwrap(), &6); assert_eq!(it.next_back().unwrap(), &7); assert_eq!(it.next_back(), None); - assert_eq!(it.next(), None); + assert_eq!(it.next(), None); assert_eq!(it.next_back(), None); } #[test] fn test_double_ended_flatten() { - let u = [0,1]; - let v = [5,6,7,8]; + let u = [0, 1]; + let v = [5, 6, 7, 8]; let mut it = u.iter().map(|x| &v[*x..v.len()]).flatten(); assert_eq!(it.next_back().unwrap(), &8); - assert_eq!(it.next().unwrap(), &5); + assert_eq!(it.next().unwrap(), &5); assert_eq!(it.next_back().unwrap(), &7); assert_eq!(it.next_back().unwrap(), &6); assert_eq!(it.next_back().unwrap(), &8); - assert_eq!(it.next().unwrap(), &6); + assert_eq!(it.next().unwrap(), &6); assert_eq!(it.next_back().unwrap(), &7); assert_eq!(it.next_back(), None); - assert_eq!(it.next(), None); + assert_eq!(it.next(), None); assert_eq!(it.next_back(), None); } @@ -1867,8 +1871,10 @@ fn test_range() { assert_eq!((-70..58).size_hint(), (128, Some(128))); assert_eq!((-128..127).size_hint(), (255, Some(255))); - assert_eq!((-2..isize::MAX).size_hint(), - (isize::MAX as usize + 2, Some(isize::MAX as usize + 2))); + assert_eq!( + (-2..isize::MAX).size_hint(), + (isize::MAX as usize + 2, Some(isize::MAX as usize + 2)) + ); } #[test] @@ -2171,15 +2177,15 @@ fn test_range_inclusive_folds() { assert!(it.is_empty()); let mut it = 10..=20; - assert_eq!(it.try_fold(0, |a,b| Some(a+b)), Some(165)); + assert_eq!(it.try_fold(0, |a, b| Some(a + b)), Some(165)); assert!(it.is_empty()); - assert_eq!(it.try_fold(0, |a,b| Some(a+b)), Some(0)); + assert_eq!(it.try_fold(0, |a, b| Some(a + b)), Some(0)); assert!(it.is_empty()); let mut it = 10..=20; - assert_eq!(it.try_rfold(0, |a,b| Some(a+b)), Some(165)); + assert_eq!(it.try_rfold(0, |a, b| Some(a + b)), Some(165)); assert!(it.is_empty()); - assert_eq!(it.try_rfold(0, |a,b| Some(a+b)), Some(0)); + assert_eq!(it.try_rfold(0, |a, b| Some(a + b)), Some(0)); assert!(it.is_empty()); } @@ -2292,15 +2298,19 @@ fn test_repeat_with_take() { is_trusted_len(repeat_with(|| 42).take(3)); assert_eq!(repeat_with(|| 42).take(3).size_hint(), (3, Some(3))); assert_eq!(repeat_with(|| 42).take(0).size_hint(), (0, Some(0))); - assert_eq!(repeat_with(|| 42).take(usize::MAX).size_hint(), - (usize::MAX, Some(usize::MAX))); + assert_eq!(repeat_with(|| 42).take(usize::MAX).size_hint(), (usize::MAX, Some(usize::MAX))); } #[test] fn test_repeat_with_take_collect() { let mut curr = 1; - let v: Vec<_> = repeat_with(|| { let tmp = curr; curr *= 2; tmp }) - .take(5).collect(); + let v: Vec<_> = repeat_with(|| { + let tmp = curr; + curr *= 2; + tmp + }) + .take(5) + .collect(); assert_eq!(v, vec![1, 2, 4, 8, 16]); } @@ -2472,7 +2482,7 @@ fn test_step_replace_no_between() { #[test] fn test_rev_try_folds() { - let f = &|acc, x| i32::checked_add(2*acc, x); + let f = &|acc, x| i32::checked_add(2 * acc, x); assert_eq!((1..10).rev().try_fold(7, f), (1..10).try_rfold(7, f)); assert_eq!((1..10).rev().try_rfold(7, f), (1..10).try_fold(7, f)); @@ -2488,8 +2498,8 @@ fn test_rev_try_folds() { #[test] fn test_cloned_try_folds() { let a = [1, 2, 3, 4, 5, 6, 7, 8, 9]; - let f = &|acc, x| i32::checked_add(2*acc, x); - let f_ref = &|acc, &x| i32::checked_add(2*acc, x); + let f = &|acc, x| i32::checked_add(2 * acc, x); + let f_ref = &|acc, &x| i32::checked_add(2 * acc, x); assert_eq!(a.iter().cloned().try_fold(7, f), a.iter().try_fold(7, f_ref)); assert_eq!(a.iter().cloned().try_rfold(7, f), a.iter().try_rfold(7, f_ref)); @@ -2506,7 +2516,7 @@ fn test_cloned_try_folds() { fn test_chain_try_folds() { let c = || (0..10).chain(10..20); - let f = &|acc, x| i32::checked_add(2*acc, x); + let f = &|acc, x| i32::checked_add(2 * acc, x); assert_eq!(c().try_fold(7, f), (0..20).try_fold(7, f)); assert_eq!(c().try_rfold(7, f), (0..20).rev().try_fold(7, f)); @@ -2515,14 +2525,14 @@ fn test_chain_try_folds() { assert_eq!(iter.next(), Some(6), "stopped in front, state Both"); assert_eq!(iter.position(|x| x == 13), Some(6)); assert_eq!(iter.next(), Some(14), "stopped in back, state Back"); - assert_eq!(iter.try_fold(0, |acc, x| Some(acc+x)), Some((15..20).sum())); + assert_eq!(iter.try_fold(0, |acc, x| Some(acc + x)), Some((15..20).sum())); let mut iter = c().rev(); // use rev to access try_rfold assert_eq!(iter.position(|x| x == 15), Some(4)); assert_eq!(iter.next(), Some(14), "stopped in back, state Both"); assert_eq!(iter.position(|x| x == 5), Some(8)); assert_eq!(iter.next(), Some(4), "stopped in front, state Front"); - assert_eq!(iter.try_fold(0, |acc, x| Some(acc+x)), Some((0..4).sum())); + assert_eq!(iter.try_fold(0, |acc, x| Some(acc + x)), Some((0..4).sum())); let mut iter = c(); iter.by_ref().rev().nth(14); // skip the last 15, ending in state Front @@ -2535,11 +2545,11 @@ fn test_chain_try_folds() { #[test] fn test_map_try_folds() { - let f = &|acc, x| i32::checked_add(2*acc, x); - assert_eq!((0..10).map(|x| x+3).try_fold(7, f), (3..13).try_fold(7, f)); - assert_eq!((0..10).map(|x| x+3).try_rfold(7, f), (3..13).try_rfold(7, f)); + let f = &|acc, x| i32::checked_add(2 * acc, x); + assert_eq!((0..10).map(|x| x + 3).try_fold(7, f), (3..13).try_fold(7, f)); + assert_eq!((0..10).map(|x| x + 3).try_rfold(7, f), (3..13).try_rfold(7, f)); - let mut iter = (0..40).map(|x| x+10); + let mut iter = (0..40).map(|x| x + 10); assert_eq!(iter.try_fold(0, i8::checked_add), None); assert_eq!(iter.next(), Some(20)); assert_eq!(iter.try_rfold(0, i8::checked_add), None); @@ -2548,8 +2558,10 @@ fn test_map_try_folds() { #[test] fn test_filter_try_folds() { - fn p(&x: &i32) -> bool { 0 <= x && x < 10 } - let f = &|acc, x| i32::checked_add(2*acc, x); + fn p(&x: &i32) -> bool { + 0 <= x && x < 10 + } + let f = &|acc, x| i32::checked_add(2 * acc, x); assert_eq!((-10..20).filter(p).try_fold(7, f), (0..10).try_fold(7, f)); assert_eq!((-10..20).filter(p).try_rfold(7, f), (0..10).try_rfold(7, f)); @@ -2562,12 +2574,12 @@ fn test_filter_try_folds() { #[test] fn test_filter_map_try_folds() { - let mp = &|x| if 0 <= x && x < 10 { Some(x*2) } else { None }; - let f = &|acc, x| i32::checked_add(2*acc, x); - assert_eq!((-9..20).filter_map(mp).try_fold(7, f), (0..10).map(|x| 2*x).try_fold(7, f)); - assert_eq!((-9..20).filter_map(mp).try_rfold(7, f), (0..10).map(|x| 2*x).try_rfold(7, f)); + let mp = &|x| if 0 <= x && x < 10 { Some(x * 2) } else { None }; + let f = &|acc, x| i32::checked_add(2 * acc, x); + assert_eq!((-9..20).filter_map(mp).try_fold(7, f), (0..10).map(|x| 2 * x).try_fold(7, f)); + assert_eq!((-9..20).filter_map(mp).try_rfold(7, f), (0..10).map(|x| 2 * x).try_rfold(7, f)); - let mut iter = (0..40).filter_map(|x| if x%2 == 1 { None } else { Some(x*2 + 10) }); + let mut iter = (0..40).filter_map(|x| if x % 2 == 1 { None } else { Some(x * 2 + 10) }); assert_eq!(iter.try_fold(0, i8::checked_add), None); assert_eq!(iter.next(), Some(38)); assert_eq!(iter.try_rfold(0, i8::checked_add), None); @@ -2576,9 +2588,9 @@ fn test_filter_map_try_folds() { #[test] fn test_enumerate_try_folds() { - let f = &|acc, (i, x)| usize::checked_add(2*acc, x/(i+1) + i); - assert_eq!((9..18).enumerate().try_fold(7, f), (0..9).map(|i| (i, i+9)).try_fold(7, f)); - assert_eq!((9..18).enumerate().try_rfold(7, f), (0..9).map(|i| (i, i+9)).try_rfold(7, f)); + let f = &|acc, (i, x)| usize::checked_add(2 * acc, x / (i + 1) + i); + assert_eq!((9..18).enumerate().try_fold(7, f), (0..9).map(|i| (i, i + 9)).try_fold(7, f)); + assert_eq!((9..18).enumerate().try_rfold(7, f), (0..9).map(|i| (i, i + 9)).try_rfold(7, f)); let mut iter = (100..200).enumerate(); let f = &|acc, (i, x)| u8::checked_add(acc, u8::checked_div(x, i as u8 + 1)?); @@ -2590,7 +2602,7 @@ fn test_enumerate_try_folds() { #[test] fn test_peek_try_folds() { - let f = &|acc, x| i32::checked_add(2*acc, x); + let f = &|acc, x| i32::checked_add(2 * acc, x); assert_eq!((1..20).peekable().try_fold(7, f), (1..20).try_fold(7, f)); assert_eq!((1..20).peekable().try_rfold(7, f), (1..20).try_rfold(7, f)); @@ -2637,8 +2649,10 @@ fn test_peek_try_folds() { #[test] fn test_skip_while_try_fold() { - let f = &|acc, x| i32::checked_add(2*acc, x); - fn p(&x: &i32) -> bool { (x % 10) <= 5 } + let f = &|acc, x| i32::checked_add(2 * acc, x); + fn p(&x: &i32) -> bool { + (x % 10) <= 5 + } assert_eq!((1..20).skip_while(p).try_fold(7, f), (6..20).try_fold(7, f)); let mut iter = (1..20).skip_while(p); assert_eq!(iter.nth(5), Some(11)); @@ -2651,13 +2665,13 @@ fn test_skip_while_try_fold() { #[test] fn test_take_while_folds() { - let f = &|acc, x| i32::checked_add(2*acc, x); + let f = &|acc, x| i32::checked_add(2 * acc, x); assert_eq!((1..20).take_while(|&x| x != 10).try_fold(7, f), (1..10).try_fold(7, f)); let mut iter = (1..20).take_while(|&x| x != 10); - assert_eq!(iter.try_fold(0, |x, y| Some(x+y)), Some((1..10).sum())); + assert_eq!(iter.try_fold(0, |x, y| Some(x + y)), Some((1..10).sum())); assert_eq!(iter.next(), None, "flag should be set"); let iter = (1..20).take_while(|&x| x != 10); - assert_eq!(iter.fold(0, |x, y| x+y), (1..10).sum()); + assert_eq!(iter.fold(0, |x, y| x + y), (1..10).sum()); let mut iter = (10..50).take_while(|&x| x != 40); assert_eq!(iter.try_fold(0, i8::checked_add), None); @@ -2666,7 +2680,7 @@ fn test_take_while_folds() { #[test] fn test_skip_try_folds() { - let f = &|acc, x| i32::checked_add(2*acc, x); + let f = &|acc, x| i32::checked_add(2 * acc, x); assert_eq!((1..20).skip(9).try_fold(7, f), (10..20).try_fold(7, f)); assert_eq!((1..20).skip(9).try_rfold(7, f), (10..20).try_rfold(7, f)); @@ -2713,7 +2727,7 @@ fn test_skip_nth_back() { #[test] fn test_take_try_folds() { - let f = &|acc, x| i32::checked_add(2*acc, x); + let f = &|acc, x| i32::checked_add(2 * acc, x); assert_eq!((10..30).take(10).try_fold(7, f), (10..20).try_fold(7, f)); assert_eq!((10..30).take(10).try_rfold(7, f), (10..20).try_rfold(7, f)); @@ -2738,15 +2752,16 @@ fn test_take_try_folds() { #[test] fn test_flat_map_try_folds() { - let f = &|acc, x| i32::checked_add(acc*2/3, x); - let mr = &|x| (5*x)..(5*x + 5); + let f = &|acc, x| i32::checked_add(acc * 2 / 3, x); + let mr = &|x| (5 * x)..(5 * x + 5); assert_eq!((0..10).flat_map(mr).try_fold(7, f), (0..50).try_fold(7, f)); assert_eq!((0..10).flat_map(mr).try_rfold(7, f), (0..50).try_rfold(7, f)); let mut iter = (0..10).flat_map(mr); - iter.next(); iter.next_back(); // have front and back iters in progress + iter.next(); + iter.next_back(); // have front and back iters in progress assert_eq!(iter.try_rfold(7, f), (1..49).try_rfold(7, f)); - let mut iter = (0..10).flat_map(|x| (4*x)..(4*x + 4)); + let mut iter = (0..10).flat_map(|x| (4 * x)..(4 * x + 4)); assert_eq!(iter.try_fold(0, i8::checked_add), None); assert_eq!(iter.next(), Some(17)); assert_eq!(iter.try_rfold(0, i8::checked_add), None); @@ -2755,15 +2770,16 @@ fn test_flat_map_try_folds() { #[test] fn test_flatten_try_folds() { - let f = &|acc, x| i32::checked_add(acc*2/3, x); - let mr = &|x| (5*x)..(5*x + 5); + let f = &|acc, x| i32::checked_add(acc * 2 / 3, x); + let mr = &|x| (5 * x)..(5 * x + 5); assert_eq!((0..10).map(mr).flatten().try_fold(7, f), (0..50).try_fold(7, f)); assert_eq!((0..10).map(mr).flatten().try_rfold(7, f), (0..50).try_rfold(7, f)); let mut iter = (0..10).map(mr).flatten(); - iter.next(); iter.next_back(); // have front and back iters in progress + iter.next(); + iter.next_back(); // have front and back iters in progress assert_eq!(iter.try_rfold(7, f), (1..49).try_rfold(7, f)); - let mut iter = (0..10).map(|x| (4*x)..(4*x + 4)).flatten(); + let mut iter = (0..10).map(|x| (4 * x)..(4 * x + 4)).flatten(); assert_eq!(iter.try_fold(0, i8::checked_add), None); assert_eq!(iter.next(), Some(17)); assert_eq!(iter.try_rfold(0, i8::checked_add), None); @@ -2773,13 +2789,21 @@ fn test_flatten_try_folds() { #[test] fn test_functor_laws() { // identity: - fn identity(x: T) -> T { x } + fn identity(x: T) -> T { + x + } assert_eq!((0..10).map(identity).sum::(), (0..10).sum()); // composition: - fn f(x: usize) -> usize { x + 3 } - fn g(x: usize) -> usize { x * 2 } - fn h(x: usize) -> usize { g(f(x)) } + fn f(x: usize) -> usize { + x + 3 + } + fn g(x: usize) -> usize { + x * 2 + } + fn h(x: usize) -> usize { + g(f(x)) + } assert_eq!((0..10).map(f).map(g).sum::(), (0..10).map(h).sum()); } @@ -2798,10 +2822,16 @@ fn test_monad_laws_right_identity() { #[test] fn test_monad_laws_associativity() { - fn f(x: usize) -> impl Iterator { 0..x } - fn g(x: usize) -> impl Iterator { (0..x).rev() } - assert_eq!((0..10).flat_map(f).flat_map(g).sum::(), - (0..10).flat_map(|x| f(x).flat_map(g)).sum::()); + fn f(x: usize) -> impl Iterator { + 0..x + } + fn g(x: usize) -> impl Iterator { + (0..x).rev() + } + assert_eq!( + (0..10).flat_map(f).flat_map(g).sum::(), + (0..10).flat_map(|x| f(x).flat_map(g)).sum::() + ); } #[test] diff --git a/src/libcore/tests/num/dec2flt/mod.rs b/src/libcore/tests/num/dec2flt/mod.rs index 6bb348fd752e6..a1fa5556ae5db 100644 --- a/src/libcore/tests/num/dec2flt/mod.rs +++ b/src/libcore/tests/num/dec2flt/mod.rs @@ -32,7 +32,8 @@ fn ordinary() { test_literal!(12345.); test_literal!(0.9999999); - if cfg!(miri) { // Miri is too slow + if cfg!(miri) { + // Miri is too slow return; } @@ -82,7 +83,8 @@ fn zero() { test_literal!(0.0); test_literal!(1e-325); - if cfg!(miri) { // Miri is too slow + if cfg!(miri) { + // Miri is too slow return; } diff --git a/src/libcore/tests/num/flt2dec/mod.rs b/src/libcore/tests/num/flt2dec/mod.rs index 2f94ea2fc4b70..f693504824641 100644 --- a/src/libcore/tests/num/flt2dec/mod.rs +++ b/src/libcore/tests/num/flt2dec/mod.rs @@ -1,9 +1,10 @@ -use std::{str, i16, f32, f64, fmt}; +use std::{f32, f64, fmt, i16, str}; -use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded}; -use core::num::flt2dec::{MAX_SIG_DIGITS, round_up, Part, Formatted, Sign}; -use core::num::flt2dec::{to_shortest_str, to_shortest_exp_str, - to_exact_exp_str, to_exact_fixed_str}; +use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded}; +use core::num::flt2dec::{round_up, Formatted, Part, Sign, MAX_SIG_DIGITS}; +use core::num::flt2dec::{ + to_exact_exp_str, to_exact_fixed_str, to_shortest_exp_str, to_shortest_str, +}; pub use test::Bencher; @@ -17,7 +18,7 @@ mod random; pub fn decode_finite(v: T) -> Decoded { match decode(v).1 { FullDecoded::Finite(decoded) => decoded, - full_decoded => panic!("expected finite, got {:?} instead", full_decoded) + full_decoded => panic!("expected finite, got {:?} instead", full_decoded), } } @@ -81,7 +82,7 @@ fn ldexp_f32(a: f32, b: i32) -> f32 { } fn ldexp_f64(a: f64, b: i32) -> f64 { - extern { + extern "C" { fn ldexp(x: f64, n: i32) -> f64; } // SAFETY: assuming a correct `ldexp` has been supplied, the given arguments cannot possibly @@ -90,7 +91,10 @@ fn ldexp_f64(a: f64, b: i32) -> f64 { } fn check_exact(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16) - where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { +where + T: DecodableFloat, + F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), +{ // use a large enough buffer let mut buf = [b'_'; 1024]; let mut expected_ = [b'_'; 1024]; @@ -105,14 +109,18 @@ fn check_exact(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16 if expected[i] >= b'5' { // check if this is a rounding-to-even case. // we avoid rounding ...x5000... (with infinite zeroes) to ...(x+1) when x is even. - if !(i+1 < expected.len() && expected[i-1] & 1 == 0 && - expected[i] == b'5' && - expected[i+1] == b' ') { + if !(i + 1 < expected.len() + && expected[i - 1] & 1 == 0 + && expected[i] == b'5' + && expected[i + 1] == b' ') + { // if this returns true, expected_[..i] is all `9`s and being rounded up. // 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) { expectedk_ += 1; } + if let Some(_) = round_up(&mut expected_, i) { + expectedk_ += 1; + } } } @@ -146,9 +154,11 @@ fn check_exact(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16 // check infinite zero digits if let Some(cut) = cut { - for i in cut..expected.len()-1 { + for i in cut..expected.len() - 1 { expected_[..cut].copy_from_slice(&expected[..cut]); - for c in &mut expected_[cut..i] { *c = b'0'; } + for c in &mut expected_[cut..i] { + *c = b'0'; + } try_exact!(f(&decoded) => &mut buf, &expected_[..i], expectedk; "exact infzero mismatch for v={v}, i={i}: \ @@ -162,23 +172,29 @@ fn check_exact(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16 } } -trait TestableFloat : DecodableFloat + fmt::Display { +trait TestableFloat: DecodableFloat + fmt::Display { /// Returns `x * 2^exp`. Almost same to `std::{f32,f64}::ldexp`. /// This is used for testing. fn ldexpi(f: i64, exp: isize) -> Self; } impl TestableFloat for f32 { - fn ldexpi(f: i64, exp: isize) -> Self { f as Self * (exp as Self).exp2() } + fn ldexpi(f: i64, exp: isize) -> Self { + f as Self * (exp as Self).exp2() + } } impl TestableFloat for f64 { - fn ldexpi(f: i64, exp: isize) -> Self { f as Self * (exp as Self).exp2() } + fn ldexpi(f: i64, exp: isize) -> Self { + f as Self * (exp as Self).exp2() + } } fn check_exact_one(mut f: F, x: i64, e: isize, tstr: &str, expected: &[u8], expectedk: i16) - where T: TestableFloat, - F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { +where + T: TestableFloat, + F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), +{ // use a large enough buffer let mut buf = [b'_'; 1024]; let v: T = TestableFloat::ldexpi(x, e); @@ -193,15 +209,15 @@ fn check_exact_one(mut f: F, x: i64, e: isize, tstr: &str, expected: &[u8] } macro_rules! check_exact { - ($f:ident($v:expr) => $buf:expr, $exp:expr) => ( - check_exact(|d,b,k| $f(d,b,k), $v, stringify!($v), $buf, $exp) - ) + ($f:ident($v:expr) => $buf:expr, $exp:expr) => { + check_exact(|d, b, k| $f(d, b, k), $v, stringify!($v), $buf, $exp) + }; } macro_rules! check_exact_one { - ($f:ident($x:expr, $e:expr; $t:ty) => $buf:expr, $exp:expr) => ( - check_exact_one::<_, $t>(|d,b,k| $f(d,b,k), $x, $e, stringify!($t), $buf, $exp) - ) + ($f:ident($x:expr, $e:expr; $t:ty) => $buf:expr, $exp:expr) => { + check_exact_one::<_, $t>(|d, b, k| $f(d, b, k), $x, $e, stringify!($t), $buf, $exp) + }; } // in the following comments, three numbers are spaced by 1 ulp apart, @@ -212,7 +228,10 @@ macro_rules! check_exact_one { // [1] Vern Paxson, A Program for Testing IEEE Decimal-Binary Conversion // ftp://ftp.ee.lbl.gov/testbase-report.ps.Z -pub fn f32_shortest_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) { +pub fn f32_shortest_sanity_test(mut f: F) +where + F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), +{ // 0.0999999940395355224609375 // 0.100000001490116119384765625 // 0.10000000894069671630859375 @@ -257,7 +276,9 @@ pub fn f32_shortest_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8]) } pub fn f32_exact_sanity_test(mut f: F) - where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { +where + F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), +{ let minf32 = ldexp_f32(1.0, -149); check_exact!(f(0.1f32) => b"100000001490116119384765625 ", 0); @@ -298,7 +319,10 @@ pub fn f32_exact_sanity_test(mut f: F) check_exact_one!(f(13248074, 95; f32) => b"524810279937", 36); } -pub fn f64_shortest_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) { +pub fn f64_shortest_sanity_test(mut f: F) +where + F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), +{ // 0.0999999999999999777955395074968691915273... // 0.1000000000000000055511151231257827021181... // 0.1000000000000000333066907387546962127089... @@ -362,7 +386,9 @@ pub fn f64_shortest_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8]) } pub fn f64_exact_sanity_test(mut f: F) - where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { +where + F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), +{ let minf64 = ldexp_f64(1.0, -1074); check_exact!(f(0.1f64) => b"1000000000000000055511151231257827021181", 0); @@ -446,7 +472,10 @@ pub fn f64_exact_sanity_test(mut f: F) check_exact_one!(f(8549497411294502, -448; f64) => b"1176257830728540379990", -118); } -pub fn more_shortest_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) { +pub fn more_shortest_sanity_test(mut f: F) +where + F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), +{ check_shortest!(f{mant: 99_999_999_999_999_999, minus: 1, plus: 1, exp: 0, inclusive: true} => b"1", 18); check_shortest!(f{mant: 99_999_999_999_999_999, minus: 1, plus: 1, @@ -454,7 +483,9 @@ pub fn more_shortest_sanity_test(mut f: F) where F: FnMut(&Decoded, &mut [u8] } fn to_string_with_parts(mut f: F) -> String - where F: for<'a> FnMut(&'a mut [u8], &'a mut [Part<'a>]) -> Formatted<'a> { +where + F: for<'a> FnMut(&'a mut [u8], &'a mut [Part<'a>]) -> Formatted<'a>, +{ let mut buf = [0; 1024]; let mut parts = [Part::Zero(0); 16]; let formatted = f(&mut buf, &mut parts); @@ -464,66 +495,72 @@ fn to_string_with_parts(mut f: F) -> String } pub fn to_shortest_str_test(mut f_: F) - where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) { +where + F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), +{ use core::num::flt2dec::Sign::*; fn to_string(f: &mut F, v: T, sign: Sign, frac_digits: usize, upper: bool) -> String - where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) { - to_string_with_parts(|buf, parts| to_shortest_str(|d,b| f(d,b), v, sign, - frac_digits, upper, buf, parts)) + where + T: DecodableFloat, + F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + { + to_string_with_parts(|buf, parts| { + to_shortest_str(|d, b| f(d, b), v, sign, frac_digits, upper, buf, parts) + }) } let f = &mut f_; - assert_eq!(to_string(f, 0.0, Minus, 0, false), "0"); - assert_eq!(to_string(f, 0.0, MinusRaw, 0, false), "0"); - assert_eq!(to_string(f, 0.0, MinusPlus, 0, false), "+0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, 0, false), "+0"); - assert_eq!(to_string(f, -0.0, Minus, 0, false), "0"); - assert_eq!(to_string(f, -0.0, MinusRaw, 0, false), "-0"); - assert_eq!(to_string(f, -0.0, MinusPlus, 0, false), "+0"); + assert_eq!(to_string(f, 0.0, Minus, 0, false), "0"); + assert_eq!(to_string(f, 0.0, MinusRaw, 0, false), "0"); + assert_eq!(to_string(f, 0.0, MinusPlus, 0, false), "+0"); + assert_eq!(to_string(f, 0.0, MinusPlusRaw, 0, false), "+0"); + assert_eq!(to_string(f, -0.0, Minus, 0, false), "0"); + assert_eq!(to_string(f, -0.0, MinusRaw, 0, false), "-0"); + assert_eq!(to_string(f, -0.0, MinusPlus, 0, false), "+0"); assert_eq!(to_string(f, -0.0, MinusPlusRaw, 0, false), "-0"); - assert_eq!(to_string(f, 0.0, Minus, 1, true), "0.0"); - assert_eq!(to_string(f, 0.0, MinusRaw, 1, true), "0.0"); - assert_eq!(to_string(f, 0.0, MinusPlus, 1, true), "+0.0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, 1, true), "+0.0"); - assert_eq!(to_string(f, -0.0, Minus, 8, true), "0.00000000"); - assert_eq!(to_string(f, -0.0, MinusRaw, 8, true), "-0.00000000"); - assert_eq!(to_string(f, -0.0, MinusPlus, 8, true), "+0.00000000"); - assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8, true), "-0.00000000"); - - assert_eq!(to_string(f, 1.0/0.0, Minus, 0, false), "inf"); - assert_eq!(to_string(f, 1.0/0.0, MinusRaw, 0, true), "inf"); - assert_eq!(to_string(f, 1.0/0.0, MinusPlus, 0, false), "+inf"); - assert_eq!(to_string(f, 1.0/0.0, MinusPlusRaw, 0, true), "+inf"); - assert_eq!(to_string(f, 0.0/0.0, Minus, 0, false), "NaN"); - assert_eq!(to_string(f, 0.0/0.0, MinusRaw, 1, true), "NaN"); - assert_eq!(to_string(f, 0.0/0.0, MinusPlus, 8, false), "NaN"); - assert_eq!(to_string(f, 0.0/0.0, MinusPlusRaw, 64, true), "NaN"); - assert_eq!(to_string(f, -1.0/0.0, Minus, 0, false), "-inf"); - assert_eq!(to_string(f, -1.0/0.0, MinusRaw, 1, true), "-inf"); - assert_eq!(to_string(f, -1.0/0.0, MinusPlus, 8, false), "-inf"); - assert_eq!(to_string(f, -1.0/0.0, MinusPlusRaw, 64, true), "-inf"); - - assert_eq!(to_string(f, 3.14, Minus, 0, false), "3.14"); - assert_eq!(to_string(f, 3.14, MinusRaw, 0, false), "3.14"); - assert_eq!(to_string(f, 3.14, MinusPlus, 0, false), "+3.14"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, 0, false), "+3.14"); - assert_eq!(to_string(f, -3.14, Minus, 0, false), "-3.14"); - assert_eq!(to_string(f, -3.14, MinusRaw, 0, false), "-3.14"); - assert_eq!(to_string(f, -3.14, MinusPlus, 0, false), "-3.14"); + assert_eq!(to_string(f, 0.0, Minus, 1, true), "0.0"); + assert_eq!(to_string(f, 0.0, MinusRaw, 1, true), "0.0"); + assert_eq!(to_string(f, 0.0, MinusPlus, 1, true), "+0.0"); + assert_eq!(to_string(f, 0.0, MinusPlusRaw, 1, true), "+0.0"); + assert_eq!(to_string(f, -0.0, Minus, 8, true), "0.00000000"); + assert_eq!(to_string(f, -0.0, MinusRaw, 8, true), "-0.00000000"); + assert_eq!(to_string(f, -0.0, MinusPlus, 8, true), "+0.00000000"); + assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8, true), "-0.00000000"); + + assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0, false), "inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusRaw, 0, true), "inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 0, false), "+inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusPlusRaw, 0, true), "+inf"); + assert_eq!(to_string(f, 0.0 / 0.0, Minus, 0, false), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusRaw, 1, true), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 8, false), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusPlusRaw, 64, true), "NaN"); + assert_eq!(to_string(f, -1.0 / 0.0, Minus, 0, false), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusRaw, 1, true), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 8, false), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusPlusRaw, 64, true), "-inf"); + + assert_eq!(to_string(f, 3.14, Minus, 0, false), "3.14"); + assert_eq!(to_string(f, 3.14, MinusRaw, 0, false), "3.14"); + assert_eq!(to_string(f, 3.14, MinusPlus, 0, false), "+3.14"); + assert_eq!(to_string(f, 3.14, MinusPlusRaw, 0, false), "+3.14"); + assert_eq!(to_string(f, -3.14, Minus, 0, false), "-3.14"); + assert_eq!(to_string(f, -3.14, MinusRaw, 0, false), "-3.14"); + assert_eq!(to_string(f, -3.14, MinusPlus, 0, false), "-3.14"); assert_eq!(to_string(f, -3.14, MinusPlusRaw, 0, false), "-3.14"); - assert_eq!(to_string(f, 3.14, Minus, 1, true), "3.14"); - assert_eq!(to_string(f, 3.14, MinusRaw, 2, true), "3.14"); - assert_eq!(to_string(f, 3.14, MinusPlus, 3, true), "+3.140"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, 4, true), "+3.1400"); - assert_eq!(to_string(f, -3.14, Minus, 8, true), "-3.14000000"); - assert_eq!(to_string(f, -3.14, MinusRaw, 8, true), "-3.14000000"); - assert_eq!(to_string(f, -3.14, MinusPlus, 8, true), "-3.14000000"); - assert_eq!(to_string(f, -3.14, MinusPlusRaw, 8, true), "-3.14000000"); - - assert_eq!(to_string(f, 7.5e-11, Minus, 0, false), "0.000000000075"); - assert_eq!(to_string(f, 7.5e-11, Minus, 3, false), "0.000000000075"); + assert_eq!(to_string(f, 3.14, Minus, 1, true), "3.14"); + assert_eq!(to_string(f, 3.14, MinusRaw, 2, true), "3.14"); + assert_eq!(to_string(f, 3.14, MinusPlus, 3, true), "+3.140"); + assert_eq!(to_string(f, 3.14, MinusPlusRaw, 4, true), "+3.1400"); + assert_eq!(to_string(f, -3.14, Minus, 8, true), "-3.14000000"); + assert_eq!(to_string(f, -3.14, MinusRaw, 8, true), "-3.14000000"); + assert_eq!(to_string(f, -3.14, MinusPlus, 8, true), "-3.14000000"); + assert_eq!(to_string(f, -3.14, MinusPlusRaw, 8, true), "-3.14000000"); + + assert_eq!(to_string(f, 7.5e-11, Minus, 0, false), "0.000000000075"); + assert_eq!(to_string(f, 7.5e-11, Minus, 3, false), "0.000000000075"); assert_eq!(to_string(f, 7.5e-11, Minus, 12, false), "0.000000000075"); assert_eq!(to_string(f, 7.5e-11, Minus, 13, false), "0.0000000000750"); @@ -536,23 +573,24 @@ pub fn to_shortest_str_test(mut f_: F) assert_eq!(to_string(f, f32::MAX, Minus, 8, false), format!("34028235{:0>31}.00000000", "")); let minf32 = ldexp_f32(1.0, -149); - assert_eq!(to_string(f, minf32, Minus, 0, false), format!("0.{:0>44}1", "")); + assert_eq!(to_string(f, minf32, Minus, 0, false), format!("0.{:0>44}1", "")); assert_eq!(to_string(f, minf32, Minus, 45, false), format!("0.{:0>44}1", "")); assert_eq!(to_string(f, minf32, Minus, 46, false), format!("0.{:0>44}10", "")); - assert_eq!(to_string(f, f64::MAX, Minus, 0, false), - format!("17976931348623157{:0>292}", "")); - assert_eq!(to_string(f, f64::MAX, Minus, 1, false), - format!("17976931348623157{:0>292}.0", "")); - assert_eq!(to_string(f, f64::MAX, Minus, 8, false), - format!("17976931348623157{:0>292}.00000000", "")); + assert_eq!(to_string(f, f64::MAX, Minus, 0, false), format!("17976931348623157{:0>292}", "")); + assert_eq!(to_string(f, f64::MAX, Minus, 1, false), format!("17976931348623157{:0>292}.0", "")); + assert_eq!( + to_string(f, f64::MAX, Minus, 8, false), + format!("17976931348623157{:0>292}.00000000", "") + ); let minf64 = ldexp_f64(1.0, -1074); - assert_eq!(to_string(f, minf64, Minus, 0, false), format!("0.{:0>323}5", "")); + assert_eq!(to_string(f, minf64, Minus, 0, false), format!("0.{:0>323}5", "")); assert_eq!(to_string(f, minf64, Minus, 324, false), format!("0.{:0>323}5", "")); assert_eq!(to_string(f, minf64, Minus, 325, false), format!("0.{:0>323}50", "")); - if cfg!(miri) { // Miri is too slow + if cfg!(miri) { + // Miri is too slow return; } @@ -561,86 +599,92 @@ pub fn to_shortest_str_test(mut f_: F) } pub fn to_shortest_exp_str_test(mut f_: F) - where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) { +where + F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), +{ use core::num::flt2dec::Sign::*; fn to_string(f: &mut F, v: T, sign: Sign, exp_bounds: (i16, i16), upper: bool) -> String - where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) { - to_string_with_parts(|buf, parts| to_shortest_exp_str(|d,b| f(d,b), v, sign, - exp_bounds, upper, buf, parts)) + where + T: DecodableFloat, + F: FnMut(&Decoded, &mut [u8]) -> (usize, i16), + { + to_string_with_parts(|buf, parts| { + to_shortest_exp_str(|d, b| f(d, b), v, sign, exp_bounds, upper, buf, parts) + }) } let f = &mut f_; - assert_eq!(to_string(f, 0.0, Minus, (-4, 16), false), "0"); - assert_eq!(to_string(f, 0.0, MinusRaw, (-4, 16), false), "0"); - assert_eq!(to_string(f, 0.0, MinusPlus, (-4, 16), false), "+0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, (-4, 16), false), "+0"); - assert_eq!(to_string(f, -0.0, Minus, (-4, 16), false), "0"); - assert_eq!(to_string(f, -0.0, MinusRaw, (-4, 16), false), "-0"); - assert_eq!(to_string(f, -0.0, MinusPlus, (-4, 16), false), "+0"); + assert_eq!(to_string(f, 0.0, Minus, (-4, 16), false), "0"); + assert_eq!(to_string(f, 0.0, MinusRaw, (-4, 16), false), "0"); + assert_eq!(to_string(f, 0.0, MinusPlus, (-4, 16), false), "+0"); + assert_eq!(to_string(f, 0.0, MinusPlusRaw, (-4, 16), false), "+0"); + assert_eq!(to_string(f, -0.0, Minus, (-4, 16), false), "0"); + assert_eq!(to_string(f, -0.0, MinusRaw, (-4, 16), false), "-0"); + assert_eq!(to_string(f, -0.0, MinusPlus, (-4, 16), false), "+0"); assert_eq!(to_string(f, -0.0, MinusPlusRaw, (-4, 16), false), "-0"); - assert_eq!(to_string(f, 0.0, Minus, ( 0, 0), true), "0E0"); - assert_eq!(to_string(f, 0.0, MinusRaw, ( 0, 0), false), "0e0"); - assert_eq!(to_string(f, 0.0, MinusPlus, (-9, -5), true), "+0E0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, ( 5, 9), false), "+0e0"); - assert_eq!(to_string(f, -0.0, Minus, ( 0, 0), true), "0E0"); - assert_eq!(to_string(f, -0.0, MinusRaw, ( 0, 0), false), "-0e0"); - assert_eq!(to_string(f, -0.0, MinusPlus, (-9, -5), true), "+0E0"); - assert_eq!(to_string(f, -0.0, MinusPlusRaw, ( 5, 9), false), "-0e0"); - - assert_eq!(to_string(f, 1.0/0.0, Minus, (-4, 16), false), "inf"); - assert_eq!(to_string(f, 1.0/0.0, MinusRaw, (-4, 16), true), "inf"); - assert_eq!(to_string(f, 1.0/0.0, MinusPlus, (-4, 16), false), "+inf"); - assert_eq!(to_string(f, 1.0/0.0, MinusPlusRaw, (-4, 16), true), "+inf"); - assert_eq!(to_string(f, 0.0/0.0, Minus, ( 0, 0), false), "NaN"); - assert_eq!(to_string(f, 0.0/0.0, MinusRaw, ( 0, 0), true), "NaN"); - assert_eq!(to_string(f, 0.0/0.0, MinusPlus, (-9, -5), false), "NaN"); - assert_eq!(to_string(f, 0.0/0.0, MinusPlusRaw, ( 5, 9), true), "NaN"); - assert_eq!(to_string(f, -1.0/0.0, Minus, ( 0, 0), false), "-inf"); - assert_eq!(to_string(f, -1.0/0.0, MinusRaw, ( 0, 0), true), "-inf"); - assert_eq!(to_string(f, -1.0/0.0, MinusPlus, (-9, -5), false), "-inf"); - assert_eq!(to_string(f, -1.0/0.0, MinusPlusRaw, ( 5, 9), true), "-inf"); - - assert_eq!(to_string(f, 3.14, Minus, (-4, 16), false), "3.14"); - assert_eq!(to_string(f, 3.14, MinusRaw, (-4, 16), false), "3.14"); - assert_eq!(to_string(f, 3.14, MinusPlus, (-4, 16), false), "+3.14"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, (-4, 16), false), "+3.14"); - assert_eq!(to_string(f, -3.14, Minus, (-4, 16), false), "-3.14"); - assert_eq!(to_string(f, -3.14, MinusRaw, (-4, 16), false), "-3.14"); - assert_eq!(to_string(f, -3.14, MinusPlus, (-4, 16), false), "-3.14"); + assert_eq!(to_string(f, 0.0, Minus, (0, 0), true), "0E0"); + assert_eq!(to_string(f, 0.0, MinusRaw, (0, 0), false), "0e0"); + assert_eq!(to_string(f, 0.0, MinusPlus, (-9, -5), true), "+0E0"); + assert_eq!(to_string(f, 0.0, MinusPlusRaw, (5, 9), false), "+0e0"); + assert_eq!(to_string(f, -0.0, Minus, (0, 0), true), "0E0"); + assert_eq!(to_string(f, -0.0, MinusRaw, (0, 0), false), "-0e0"); + assert_eq!(to_string(f, -0.0, MinusPlus, (-9, -5), true), "+0E0"); + assert_eq!(to_string(f, -0.0, MinusPlusRaw, (5, 9), false), "-0e0"); + + assert_eq!(to_string(f, 1.0 / 0.0, Minus, (-4, 16), false), "inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusRaw, (-4, 16), true), "inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, (-4, 16), false), "+inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusPlusRaw, (-4, 16), true), "+inf"); + assert_eq!(to_string(f, 0.0 / 0.0, Minus, (0, 0), false), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusRaw, (0, 0), true), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, (-9, -5), false), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusPlusRaw, (5, 9), true), "NaN"); + assert_eq!(to_string(f, -1.0 / 0.0, Minus, (0, 0), false), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusRaw, (0, 0), true), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, (-9, -5), false), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusPlusRaw, (5, 9), true), "-inf"); + + assert_eq!(to_string(f, 3.14, Minus, (-4, 16), false), "3.14"); + assert_eq!(to_string(f, 3.14, MinusRaw, (-4, 16), false), "3.14"); + assert_eq!(to_string(f, 3.14, MinusPlus, (-4, 16), false), "+3.14"); + assert_eq!(to_string(f, 3.14, MinusPlusRaw, (-4, 16), false), "+3.14"); + assert_eq!(to_string(f, -3.14, Minus, (-4, 16), false), "-3.14"); + assert_eq!(to_string(f, -3.14, MinusRaw, (-4, 16), false), "-3.14"); + assert_eq!(to_string(f, -3.14, MinusPlus, (-4, 16), false), "-3.14"); assert_eq!(to_string(f, -3.14, MinusPlusRaw, (-4, 16), false), "-3.14"); - assert_eq!(to_string(f, 3.14, Minus, ( 0, 0), true), "3.14E0"); - assert_eq!(to_string(f, 3.14, MinusRaw, ( 0, 0), false), "3.14e0"); - assert_eq!(to_string(f, 3.14, MinusPlus, (-9, -5), true), "+3.14E0"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, ( 5, 9), false), "+3.14e0"); - assert_eq!(to_string(f, -3.14, Minus, ( 0, 0), true), "-3.14E0"); - assert_eq!(to_string(f, -3.14, MinusRaw, ( 0, 0), false), "-3.14e0"); - assert_eq!(to_string(f, -3.14, MinusPlus, (-9, -5), true), "-3.14E0"); - assert_eq!(to_string(f, -3.14, MinusPlusRaw, ( 5, 9), false), "-3.14e0"); - - assert_eq!(to_string(f, 0.1, Minus, (-4, 16), false), "0.1"); - assert_eq!(to_string(f, 0.1, MinusRaw, (-4, 16), false), "0.1"); - assert_eq!(to_string(f, 0.1, MinusPlus, (-4, 16), false), "+0.1"); - assert_eq!(to_string(f, 0.1, MinusPlusRaw, (-4, 16), false), "+0.1"); - assert_eq!(to_string(f, -0.1, Minus, (-4, 16), false), "-0.1"); - assert_eq!(to_string(f, -0.1, MinusRaw, (-4, 16), false), "-0.1"); - assert_eq!(to_string(f, -0.1, MinusPlus, (-4, 16), false), "-0.1"); + assert_eq!(to_string(f, 3.14, Minus, (0, 0), true), "3.14E0"); + assert_eq!(to_string(f, 3.14, MinusRaw, (0, 0), false), "3.14e0"); + assert_eq!(to_string(f, 3.14, MinusPlus, (-9, -5), true), "+3.14E0"); + assert_eq!(to_string(f, 3.14, MinusPlusRaw, (5, 9), false), "+3.14e0"); + assert_eq!(to_string(f, -3.14, Minus, (0, 0), true), "-3.14E0"); + assert_eq!(to_string(f, -3.14, MinusRaw, (0, 0), false), "-3.14e0"); + assert_eq!(to_string(f, -3.14, MinusPlus, (-9, -5), true), "-3.14E0"); + assert_eq!(to_string(f, -3.14, MinusPlusRaw, (5, 9), false), "-3.14e0"); + + assert_eq!(to_string(f, 0.1, Minus, (-4, 16), false), "0.1"); + assert_eq!(to_string(f, 0.1, MinusRaw, (-4, 16), false), "0.1"); + assert_eq!(to_string(f, 0.1, MinusPlus, (-4, 16), false), "+0.1"); + assert_eq!(to_string(f, 0.1, MinusPlusRaw, (-4, 16), false), "+0.1"); + assert_eq!(to_string(f, -0.1, Minus, (-4, 16), false), "-0.1"); + assert_eq!(to_string(f, -0.1, MinusRaw, (-4, 16), false), "-0.1"); + assert_eq!(to_string(f, -0.1, MinusPlus, (-4, 16), false), "-0.1"); assert_eq!(to_string(f, -0.1, MinusPlusRaw, (-4, 16), false), "-0.1"); - assert_eq!(to_string(f, 0.1, Minus, ( 0, 0), true), "1E-1"); - assert_eq!(to_string(f, 0.1, MinusRaw, ( 0, 0), false), "1e-1"); - assert_eq!(to_string(f, 0.1, MinusPlus, (-9, -5), true), "+1E-1"); - assert_eq!(to_string(f, 0.1, MinusPlusRaw, ( 5, 9), false), "+1e-1"); - assert_eq!(to_string(f, -0.1, Minus, ( 0, 0), true), "-1E-1"); - assert_eq!(to_string(f, -0.1, MinusRaw, ( 0, 0), false), "-1e-1"); - assert_eq!(to_string(f, -0.1, MinusPlus, (-9, -5), true), "-1E-1"); - assert_eq!(to_string(f, -0.1, MinusPlusRaw, ( 5, 9), false), "-1e-1"); - - assert_eq!(to_string(f, 7.5e-11, Minus, ( -4, 16), false), "7.5e-11"); + assert_eq!(to_string(f, 0.1, Minus, (0, 0), true), "1E-1"); + assert_eq!(to_string(f, 0.1, MinusRaw, (0, 0), false), "1e-1"); + assert_eq!(to_string(f, 0.1, MinusPlus, (-9, -5), true), "+1E-1"); + assert_eq!(to_string(f, 0.1, MinusPlusRaw, (5, 9), false), "+1e-1"); + assert_eq!(to_string(f, -0.1, Minus, (0, 0), true), "-1E-1"); + assert_eq!(to_string(f, -0.1, MinusRaw, (0, 0), false), "-1e-1"); + assert_eq!(to_string(f, -0.1, MinusPlus, (-9, -5), true), "-1E-1"); + assert_eq!(to_string(f, -0.1, MinusPlusRaw, (5, 9), false), "-1e-1"); + + assert_eq!(to_string(f, 7.5e-11, Minus, (-4, 16), false), "7.5e-11"); assert_eq!(to_string(f, 7.5e-11, Minus, (-11, 10), false), "0.000000000075"); assert_eq!(to_string(f, 7.5e-11, Minus, (-10, 11), false), "7.5e-11"); - assert_eq!(to_string(f, 1.9971e20, Minus, ( -4, 16), false), "1.9971e20"); + assert_eq!(to_string(f, 1.9971e20, Minus, (-4, 16), false), "1.9971e20"); assert_eq!(to_string(f, 1.9971e20, Minus, (-20, 21), false), "199710000000000000000"); assert_eq!(to_string(f, 1.9971e20, Minus, (-21, 20), false), "1.9971e20"); @@ -649,24 +693,24 @@ pub fn to_shortest_exp_str_test(mut f_: F) assert_eq!(to_string(f, 1.0e23, Minus, (23, 24), false), "100000000000000000000000"); assert_eq!(to_string(f, 1.0e23, Minus, (24, 25), false), "1e23"); - assert_eq!(to_string(f, f32::MAX, Minus, ( -4, 16), false), "3.4028235e38"); + assert_eq!(to_string(f, f32::MAX, Minus, (-4, 16), false), "3.4028235e38"); assert_eq!(to_string(f, f32::MAX, Minus, (-39, 38), false), "3.4028235e38"); assert_eq!(to_string(f, f32::MAX, Minus, (-38, 39), false), format!("34028235{:0>31}", "")); let minf32 = ldexp_f32(1.0, -149); - assert_eq!(to_string(f, minf32, Minus, ( -4, 16), false), "1e-45"); + assert_eq!(to_string(f, minf32, Minus, (-4, 16), false), "1e-45"); assert_eq!(to_string(f, minf32, Minus, (-44, 45), false), "1e-45"); assert_eq!(to_string(f, minf32, Minus, (-45, 44), false), format!("0.{:0>44}1", "")); - assert_eq!(to_string(f, f64::MAX, Minus, ( -4, 16), false), - "1.7976931348623157e308"); - assert_eq!(to_string(f, f64::MAX, Minus, (-308, 309), false), - format!("17976931348623157{:0>292}", "")); - assert_eq!(to_string(f, f64::MAX, Minus, (-309, 308), false), - "1.7976931348623157e308"); + assert_eq!(to_string(f, f64::MAX, Minus, (-4, 16), false), "1.7976931348623157e308"); + assert_eq!( + to_string(f, f64::MAX, Minus, (-308, 309), false), + format!("17976931348623157{:0>292}", "") + ); + assert_eq!(to_string(f, f64::MAX, Minus, (-309, 308), false), "1.7976931348623157e308"); let minf64 = ldexp_f64(1.0, -1074); - assert_eq!(to_string(f, minf64, Minus, ( -4, 16), false), "5e-324"); + assert_eq!(to_string(f, minf64, Minus, (-4, 16), false), "5e-324"); assert_eq!(to_string(f, minf64, Minus, (-324, 323), false), format!("0.{:0>323}5", "")); assert_eq!(to_string(f, minf64, Minus, (-323, 324), false), "5e-324"); @@ -674,88 +718,94 @@ pub fn to_shortest_exp_str_test(mut f_: F) } pub fn to_exact_exp_str_test(mut f_: F) - where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { +where + F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), +{ use core::num::flt2dec::Sign::*; fn to_string(f: &mut F, v: T, sign: Sign, ndigits: usize, upper: bool) -> String - where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { - to_string_with_parts(|buf, parts| to_exact_exp_str(|d,b,l| f(d,b,l), v, sign, - ndigits, upper, buf, parts)) + where + T: DecodableFloat, + F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), + { + to_string_with_parts(|buf, parts| { + to_exact_exp_str(|d, b, l| f(d, b, l), v, sign, ndigits, upper, buf, parts) + }) } let f = &mut f_; - assert_eq!(to_string(f, 0.0, Minus, 1, true), "0E0"); - assert_eq!(to_string(f, 0.0, MinusRaw, 1, false), "0e0"); - assert_eq!(to_string(f, 0.0, MinusPlus, 1, true), "+0E0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, 1, false), "+0e0"); - assert_eq!(to_string(f, -0.0, Minus, 1, true), "0E0"); - assert_eq!(to_string(f, -0.0, MinusRaw, 1, false), "-0e0"); - assert_eq!(to_string(f, -0.0, MinusPlus, 1, true), "+0E0"); + assert_eq!(to_string(f, 0.0, Minus, 1, true), "0E0"); + assert_eq!(to_string(f, 0.0, MinusRaw, 1, false), "0e0"); + assert_eq!(to_string(f, 0.0, MinusPlus, 1, true), "+0E0"); + assert_eq!(to_string(f, 0.0, MinusPlusRaw, 1, false), "+0e0"); + assert_eq!(to_string(f, -0.0, Minus, 1, true), "0E0"); + assert_eq!(to_string(f, -0.0, MinusRaw, 1, false), "-0e0"); + assert_eq!(to_string(f, -0.0, MinusPlus, 1, true), "+0E0"); assert_eq!(to_string(f, -0.0, MinusPlusRaw, 1, false), "-0e0"); - assert_eq!(to_string(f, 0.0, Minus, 2, true), "0.0E0"); - assert_eq!(to_string(f, 0.0, MinusRaw, 2, false), "0.0e0"); - assert_eq!(to_string(f, 0.0, MinusPlus, 2, true), "+0.0E0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, 2, false), "+0.0e0"); - assert_eq!(to_string(f, -0.0, Minus, 8, true), "0.0000000E0"); - assert_eq!(to_string(f, -0.0, MinusRaw, 8, false), "-0.0000000e0"); - assert_eq!(to_string(f, -0.0, MinusPlus, 8, true), "+0.0000000E0"); + assert_eq!(to_string(f, 0.0, Minus, 2, true), "0.0E0"); + assert_eq!(to_string(f, 0.0, MinusRaw, 2, false), "0.0e0"); + assert_eq!(to_string(f, 0.0, MinusPlus, 2, true), "+0.0E0"); + assert_eq!(to_string(f, 0.0, MinusPlusRaw, 2, false), "+0.0e0"); + assert_eq!(to_string(f, -0.0, Minus, 8, true), "0.0000000E0"); + assert_eq!(to_string(f, -0.0, MinusRaw, 8, false), "-0.0000000e0"); + assert_eq!(to_string(f, -0.0, MinusPlus, 8, true), "+0.0000000E0"); assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8, false), "-0.0000000e0"); - assert_eq!(to_string(f, 1.0/0.0, Minus, 1, false), "inf"); - assert_eq!(to_string(f, 1.0/0.0, MinusRaw, 1, true), "inf"); - assert_eq!(to_string(f, 1.0/0.0, MinusPlus, 1, false), "+inf"); - assert_eq!(to_string(f, 1.0/0.0, MinusPlusRaw, 1, true), "+inf"); - assert_eq!(to_string(f, 0.0/0.0, Minus, 8, false), "NaN"); - assert_eq!(to_string(f, 0.0/0.0, MinusRaw, 8, true), "NaN"); - assert_eq!(to_string(f, 0.0/0.0, MinusPlus, 8, false), "NaN"); - assert_eq!(to_string(f, 0.0/0.0, MinusPlusRaw, 8, true), "NaN"); - assert_eq!(to_string(f, -1.0/0.0, Minus, 64, false), "-inf"); - assert_eq!(to_string(f, -1.0/0.0, MinusRaw, 64, true), "-inf"); - assert_eq!(to_string(f, -1.0/0.0, MinusPlus, 64, false), "-inf"); - assert_eq!(to_string(f, -1.0/0.0, MinusPlusRaw, 64, true), "-inf"); - - assert_eq!(to_string(f, 3.14, Minus, 1, true), "3E0"); - assert_eq!(to_string(f, 3.14, MinusRaw, 1, false), "3e0"); - assert_eq!(to_string(f, 3.14, MinusPlus, 1, true), "+3E0"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, 1, false), "+3e0"); - assert_eq!(to_string(f, -3.14, Minus, 2, true), "-3.1E0"); - assert_eq!(to_string(f, -3.14, MinusRaw, 2, false), "-3.1e0"); - assert_eq!(to_string(f, -3.14, MinusPlus, 2, true), "-3.1E0"); + assert_eq!(to_string(f, 1.0 / 0.0, Minus, 1, false), "inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusRaw, 1, true), "inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 1, false), "+inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusPlusRaw, 1, true), "+inf"); + assert_eq!(to_string(f, 0.0 / 0.0, Minus, 8, false), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusRaw, 8, true), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 8, false), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusPlusRaw, 8, true), "NaN"); + assert_eq!(to_string(f, -1.0 / 0.0, Minus, 64, false), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusRaw, 64, true), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 64, false), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusPlusRaw, 64, true), "-inf"); + + assert_eq!(to_string(f, 3.14, Minus, 1, true), "3E0"); + assert_eq!(to_string(f, 3.14, MinusRaw, 1, false), "3e0"); + assert_eq!(to_string(f, 3.14, MinusPlus, 1, true), "+3E0"); + assert_eq!(to_string(f, 3.14, MinusPlusRaw, 1, false), "+3e0"); + assert_eq!(to_string(f, -3.14, Minus, 2, true), "-3.1E0"); + assert_eq!(to_string(f, -3.14, MinusRaw, 2, false), "-3.1e0"); + assert_eq!(to_string(f, -3.14, MinusPlus, 2, true), "-3.1E0"); assert_eq!(to_string(f, -3.14, MinusPlusRaw, 2, false), "-3.1e0"); - assert_eq!(to_string(f, 3.14, Minus, 3, true), "3.14E0"); - assert_eq!(to_string(f, 3.14, MinusRaw, 3, false), "3.14e0"); - assert_eq!(to_string(f, 3.14, MinusPlus, 3, true), "+3.14E0"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, 3, false), "+3.14e0"); - assert_eq!(to_string(f, -3.14, Minus, 4, true), "-3.140E0"); - assert_eq!(to_string(f, -3.14, MinusRaw, 4, false), "-3.140e0"); - assert_eq!(to_string(f, -3.14, MinusPlus, 4, true), "-3.140E0"); + assert_eq!(to_string(f, 3.14, Minus, 3, true), "3.14E0"); + assert_eq!(to_string(f, 3.14, MinusRaw, 3, false), "3.14e0"); + assert_eq!(to_string(f, 3.14, MinusPlus, 3, true), "+3.14E0"); + assert_eq!(to_string(f, 3.14, MinusPlusRaw, 3, false), "+3.14e0"); + assert_eq!(to_string(f, -3.14, Minus, 4, true), "-3.140E0"); + assert_eq!(to_string(f, -3.14, MinusRaw, 4, false), "-3.140e0"); + assert_eq!(to_string(f, -3.14, MinusPlus, 4, true), "-3.140E0"); assert_eq!(to_string(f, -3.14, MinusPlusRaw, 4, false), "-3.140e0"); - assert_eq!(to_string(f, 0.195, Minus, 1, false), "2e-1"); - assert_eq!(to_string(f, 0.195, MinusRaw, 1, true), "2E-1"); - assert_eq!(to_string(f, 0.195, MinusPlus, 1, false), "+2e-1"); - assert_eq!(to_string(f, 0.195, MinusPlusRaw, 1, true), "+2E-1"); - assert_eq!(to_string(f, -0.195, Minus, 2, false), "-2.0e-1"); - assert_eq!(to_string(f, -0.195, MinusRaw, 2, true), "-2.0E-1"); - assert_eq!(to_string(f, -0.195, MinusPlus, 2, false), "-2.0e-1"); - assert_eq!(to_string(f, -0.195, MinusPlusRaw, 2, true), "-2.0E-1"); - assert_eq!(to_string(f, 0.195, Minus, 3, false), "1.95e-1"); - assert_eq!(to_string(f, 0.195, MinusRaw, 3, true), "1.95E-1"); - assert_eq!(to_string(f, 0.195, MinusPlus, 3, false), "+1.95e-1"); - assert_eq!(to_string(f, 0.195, MinusPlusRaw, 3, true), "+1.95E-1"); - assert_eq!(to_string(f, -0.195, Minus, 4, false), "-1.950e-1"); - assert_eq!(to_string(f, -0.195, MinusRaw, 4, true), "-1.950E-1"); - assert_eq!(to_string(f, -0.195, MinusPlus, 4, false), "-1.950e-1"); - assert_eq!(to_string(f, -0.195, MinusPlusRaw, 4, true), "-1.950E-1"); - - assert_eq!(to_string(f, 9.5, Minus, 1, false), "1e1"); - assert_eq!(to_string(f, 9.5, Minus, 2, false), "9.5e0"); - assert_eq!(to_string(f, 9.5, Minus, 3, false), "9.50e0"); + assert_eq!(to_string(f, 0.195, Minus, 1, false), "2e-1"); + assert_eq!(to_string(f, 0.195, MinusRaw, 1, true), "2E-1"); + assert_eq!(to_string(f, 0.195, MinusPlus, 1, false), "+2e-1"); + assert_eq!(to_string(f, 0.195, MinusPlusRaw, 1, true), "+2E-1"); + assert_eq!(to_string(f, -0.195, Minus, 2, false), "-2.0e-1"); + assert_eq!(to_string(f, -0.195, MinusRaw, 2, true), "-2.0E-1"); + assert_eq!(to_string(f, -0.195, MinusPlus, 2, false), "-2.0e-1"); + assert_eq!(to_string(f, -0.195, MinusPlusRaw, 2, true), "-2.0E-1"); + assert_eq!(to_string(f, 0.195, Minus, 3, false), "1.95e-1"); + assert_eq!(to_string(f, 0.195, MinusRaw, 3, true), "1.95E-1"); + assert_eq!(to_string(f, 0.195, MinusPlus, 3, false), "+1.95e-1"); + assert_eq!(to_string(f, 0.195, MinusPlusRaw, 3, true), "+1.95E-1"); + assert_eq!(to_string(f, -0.195, Minus, 4, false), "-1.950e-1"); + assert_eq!(to_string(f, -0.195, MinusRaw, 4, true), "-1.950E-1"); + assert_eq!(to_string(f, -0.195, MinusPlus, 4, false), "-1.950e-1"); + assert_eq!(to_string(f, -0.195, MinusPlusRaw, 4, true), "-1.950E-1"); + + assert_eq!(to_string(f, 9.5, Minus, 1, false), "1e1"); + assert_eq!(to_string(f, 9.5, Minus, 2, false), "9.5e0"); + assert_eq!(to_string(f, 9.5, Minus, 3, false), "9.50e0"); assert_eq!(to_string(f, 9.5, Minus, 30, false), "9.50000000000000000000000000000e0"); - assert_eq!(to_string(f, 1.0e25, Minus, 1, false), "1e25"); - assert_eq!(to_string(f, 1.0e25, Minus, 2, false), "1.0e25"); + assert_eq!(to_string(f, 1.0e25, Minus, 1, false), "1e25"); + assert_eq!(to_string(f, 1.0e25, Minus, 2, false), "1.0e25"); assert_eq!(to_string(f, 1.0e25, Minus, 15, false), "1.00000000000000e25"); assert_eq!(to_string(f, 1.0e25, Minus, 16, false), "1.000000000000000e25"); assert_eq!(to_string(f, 1.0e25, Minus, 17, false), "1.0000000000000001e25"); @@ -771,104 +821,136 @@ pub fn to_exact_exp_str_test(mut f_: F) assert_eq!(to_string(f, 1.0e25, Minus, 27, false), "1.00000000000000009059696640e25"); assert_eq!(to_string(f, 1.0e25, Minus, 30, false), "1.00000000000000009059696640000e25"); - assert_eq!(to_string(f, 1.0e-6, Minus, 1, false), "1e-6"); - assert_eq!(to_string(f, 1.0e-6, Minus, 2, false), "1.0e-6"); + assert_eq!(to_string(f, 1.0e-6, Minus, 1, false), "1e-6"); + assert_eq!(to_string(f, 1.0e-6, Minus, 2, false), "1.0e-6"); assert_eq!(to_string(f, 1.0e-6, Minus, 16, false), "1.000000000000000e-6"); assert_eq!(to_string(f, 1.0e-6, Minus, 17, false), "9.9999999999999995e-7"); assert_eq!(to_string(f, 1.0e-6, Minus, 18, false), "9.99999999999999955e-7"); assert_eq!(to_string(f, 1.0e-6, Minus, 19, false), "9.999999999999999547e-7"); assert_eq!(to_string(f, 1.0e-6, Minus, 20, false), "9.9999999999999995475e-7"); assert_eq!(to_string(f, 1.0e-6, Minus, 30, false), "9.99999999999999954748111825886e-7"); - assert_eq!(to_string(f, 1.0e-6, Minus, 40, false), - "9.999999999999999547481118258862586856139e-7"); - assert_eq!(to_string(f, 1.0e-6, Minus, 50, false), - "9.9999999999999995474811182588625868561393872369081e-7"); - assert_eq!(to_string(f, 1.0e-6, Minus, 60, false), - "9.99999999999999954748111825886258685613938723690807819366455e-7"); - assert_eq!(to_string(f, 1.0e-6, Minus, 70, false), - "9.999999999999999547481118258862586856139387236908078193664550781250000e-7"); - - assert_eq!(to_string(f, f32::MAX, Minus, 1, false), "3e38"); - assert_eq!(to_string(f, f32::MAX, Minus, 2, false), "3.4e38"); - assert_eq!(to_string(f, f32::MAX, Minus, 4, false), "3.403e38"); - assert_eq!(to_string(f, f32::MAX, Minus, 8, false), "3.4028235e38"); + assert_eq!( + to_string(f, 1.0e-6, Minus, 40, false), + "9.999999999999999547481118258862586856139e-7" + ); + assert_eq!( + to_string(f, 1.0e-6, Minus, 50, false), + "9.9999999999999995474811182588625868561393872369081e-7" + ); + assert_eq!( + to_string(f, 1.0e-6, Minus, 60, false), + "9.99999999999999954748111825886258685613938723690807819366455e-7" + ); + assert_eq!( + to_string(f, 1.0e-6, Minus, 70, false), + "9.999999999999999547481118258862586856139387236908078193664550781250000e-7" + ); + + assert_eq!(to_string(f, f32::MAX, Minus, 1, false), "3e38"); + assert_eq!(to_string(f, f32::MAX, Minus, 2, false), "3.4e38"); + assert_eq!(to_string(f, f32::MAX, Minus, 4, false), "3.403e38"); + assert_eq!(to_string(f, f32::MAX, Minus, 8, false), "3.4028235e38"); assert_eq!(to_string(f, f32::MAX, Minus, 16, false), "3.402823466385289e38"); assert_eq!(to_string(f, f32::MAX, Minus, 32, false), "3.4028234663852885981170418348452e38"); - assert_eq!(to_string(f, f32::MAX, Minus, 64, false), - "3.402823466385288598117041834845169254400000000000000000000000000e38"); + assert_eq!( + to_string(f, f32::MAX, Minus, 64, false), + "3.402823466385288598117041834845169254400000000000000000000000000e38" + ); let minf32 = ldexp_f32(1.0, -149); - assert_eq!(to_string(f, minf32, Minus, 1, false), "1e-45"); - assert_eq!(to_string(f, minf32, Minus, 2, false), "1.4e-45"); - assert_eq!(to_string(f, minf32, Minus, 4, false), "1.401e-45"); - assert_eq!(to_string(f, minf32, Minus, 8, false), "1.4012985e-45"); - assert_eq!(to_string(f, minf32, Minus, 16, false), "1.401298464324817e-45"); - assert_eq!(to_string(f, minf32, Minus, 32, false), "1.4012984643248170709237295832899e-45"); - assert_eq!(to_string(f, minf32, Minus, 64, false), - "1.401298464324817070923729583289916131280261941876515771757068284e-45"); - assert_eq!(to_string(f, minf32, Minus, 128, false), - "1.401298464324817070923729583289916131280261941876515771757068283\ - 8897910826858606014866381883621215820312500000000000000000000000e-45"); - - if cfg!(miri) { // Miri is too slow + assert_eq!(to_string(f, minf32, Minus, 1, false), "1e-45"); + assert_eq!(to_string(f, minf32, Minus, 2, false), "1.4e-45"); + assert_eq!(to_string(f, minf32, Minus, 4, false), "1.401e-45"); + assert_eq!(to_string(f, minf32, Minus, 8, false), "1.4012985e-45"); + assert_eq!(to_string(f, minf32, Minus, 16, false), "1.401298464324817e-45"); + assert_eq!(to_string(f, minf32, Minus, 32, false), "1.4012984643248170709237295832899e-45"); + assert_eq!( + to_string(f, minf32, Minus, 64, false), + "1.401298464324817070923729583289916131280261941876515771757068284e-45" + ); + assert_eq!( + to_string(f, minf32, Minus, 128, false), + "1.401298464324817070923729583289916131280261941876515771757068283\ + 8897910826858606014866381883621215820312500000000000000000000000e-45" + ); + + if cfg!(miri) { + // Miri is too slow return; } - assert_eq!(to_string(f, f64::MAX, Minus, 1, false), "2e308"); - assert_eq!(to_string(f, f64::MAX, Minus, 2, false), "1.8e308"); - assert_eq!(to_string(f, f64::MAX, Minus, 4, false), "1.798e308"); - assert_eq!(to_string(f, f64::MAX, Minus, 8, false), "1.7976931e308"); - assert_eq!(to_string(f, f64::MAX, Minus, 16, false), "1.797693134862316e308"); - assert_eq!(to_string(f, f64::MAX, Minus, 32, false), "1.7976931348623157081452742373170e308"); - assert_eq!(to_string(f, f64::MAX, Minus, 64, false), - "1.797693134862315708145274237317043567980705675258449965989174768e308"); - assert_eq!(to_string(f, f64::MAX, Minus, 128, false), - "1.797693134862315708145274237317043567980705675258449965989174768\ - 0315726078002853876058955863276687817154045895351438246423432133e308"); - assert_eq!(to_string(f, f64::MAX, Minus, 256, false), - "1.797693134862315708145274237317043567980705675258449965989174768\ + assert_eq!(to_string(f, f64::MAX, Minus, 1, false), "2e308"); + assert_eq!(to_string(f, f64::MAX, Minus, 2, false), "1.8e308"); + assert_eq!(to_string(f, f64::MAX, Minus, 4, false), "1.798e308"); + assert_eq!(to_string(f, f64::MAX, Minus, 8, false), "1.7976931e308"); + assert_eq!(to_string(f, f64::MAX, Minus, 16, false), "1.797693134862316e308"); + assert_eq!(to_string(f, f64::MAX, Minus, 32, false), "1.7976931348623157081452742373170e308"); + assert_eq!( + to_string(f, f64::MAX, Minus, 64, false), + "1.797693134862315708145274237317043567980705675258449965989174768e308" + ); + assert_eq!( + to_string(f, f64::MAX, Minus, 128, false), + "1.797693134862315708145274237317043567980705675258449965989174768\ + 0315726078002853876058955863276687817154045895351438246423432133e308" + ); + assert_eq!( + to_string(f, f64::MAX, Minus, 256, false), + "1.797693134862315708145274237317043567980705675258449965989174768\ 0315726078002853876058955863276687817154045895351438246423432132\ 6889464182768467546703537516986049910576551282076245490090389328\ - 9440758685084551339423045832369032229481658085593321233482747978e308"); - assert_eq!(to_string(f, f64::MAX, Minus, 512, false), - "1.797693134862315708145274237317043567980705675258449965989174768\ + 9440758685084551339423045832369032229481658085593321233482747978e308" + ); + assert_eq!( + to_string(f, f64::MAX, Minus, 512, false), + "1.797693134862315708145274237317043567980705675258449965989174768\ 0315726078002853876058955863276687817154045895351438246423432132\ 6889464182768467546703537516986049910576551282076245490090389328\ 9440758685084551339423045832369032229481658085593321233482747978\ 2620414472316873817718091929988125040402618412485836800000000000\ 0000000000000000000000000000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000000000000000000000000000\ - 0000000000000000000000000000000000000000000000000000000000000000e308"); + 0000000000000000000000000000000000000000000000000000000000000000e308" + ); // okay, this is becoming tough. fortunately for us, this is almost the worst case. let minf64 = ldexp_f64(1.0, -1074); - assert_eq!(to_string(f, minf64, Minus, 1, false), "5e-324"); - assert_eq!(to_string(f, minf64, Minus, 2, false), "4.9e-324"); - assert_eq!(to_string(f, minf64, Minus, 4, false), "4.941e-324"); - assert_eq!(to_string(f, minf64, Minus, 8, false), "4.9406565e-324"); - assert_eq!(to_string(f, minf64, Minus, 16, false), "4.940656458412465e-324"); - assert_eq!(to_string(f, minf64, Minus, 32, false), "4.9406564584124654417656879286822e-324"); - assert_eq!(to_string(f, minf64, Minus, 64, false), - "4.940656458412465441765687928682213723650598026143247644255856825e-324"); - assert_eq!(to_string(f, minf64, Minus, 128, false), - "4.940656458412465441765687928682213723650598026143247644255856825\ - 0067550727020875186529983636163599237979656469544571773092665671e-324"); - assert_eq!(to_string(f, minf64, Minus, 256, false), - "4.940656458412465441765687928682213723650598026143247644255856825\ + assert_eq!(to_string(f, minf64, Minus, 1, false), "5e-324"); + assert_eq!(to_string(f, minf64, Minus, 2, false), "4.9e-324"); + assert_eq!(to_string(f, minf64, Minus, 4, false), "4.941e-324"); + assert_eq!(to_string(f, minf64, Minus, 8, false), "4.9406565e-324"); + assert_eq!(to_string(f, minf64, Minus, 16, false), "4.940656458412465e-324"); + assert_eq!(to_string(f, minf64, Minus, 32, false), "4.9406564584124654417656879286822e-324"); + assert_eq!( + to_string(f, minf64, Minus, 64, false), + "4.940656458412465441765687928682213723650598026143247644255856825e-324" + ); + assert_eq!( + to_string(f, minf64, Minus, 128, false), + "4.940656458412465441765687928682213723650598026143247644255856825\ + 0067550727020875186529983636163599237979656469544571773092665671e-324" + ); + assert_eq!( + to_string(f, minf64, Minus, 256, false), + "4.940656458412465441765687928682213723650598026143247644255856825\ 0067550727020875186529983636163599237979656469544571773092665671\ 0355939796398774796010781878126300713190311404527845817167848982\ - 1036887186360569987307230500063874091535649843873124733972731696e-324"); - assert_eq!(to_string(f, minf64, Minus, 512, false), - "4.940656458412465441765687928682213723650598026143247644255856825\ + 1036887186360569987307230500063874091535649843873124733972731696e-324" + ); + assert_eq!( + to_string(f, minf64, Minus, 512, false), + "4.940656458412465441765687928682213723650598026143247644255856825\ 0067550727020875186529983636163599237979656469544571773092665671\ 0355939796398774796010781878126300713190311404527845817167848982\ 1036887186360569987307230500063874091535649843873124733972731696\ 1514003171538539807412623856559117102665855668676818703956031062\ 4931945271591492455329305456544401127480129709999541931989409080\ 4165633245247571478690147267801593552386115501348035264934720193\ - 7902681071074917033322268447533357208324319360923828934583680601e-324"); - assert_eq!(to_string(f, minf64, Minus, 1024, false), - "4.940656458412465441765687928682213723650598026143247644255856825\ + 7902681071074917033322268447533357208324319360923828934583680601e-324" + ); + assert_eq!( + to_string(f, minf64, Minus, 1024, false), + "4.940656458412465441765687928682213723650598026143247644255856825\ 0067550727020875186529983636163599237979656469544571773092665671\ 0355939796398774796010781878126300713190311404527845817167848982\ 1036887186360569987307230500063874091535649843873124733972731696\ @@ -883,100 +965,117 @@ pub fn to_exact_exp_str_test(mut f_: F) 0000000000000000000000000000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000000000000000000000000000\ - 0000000000000000000000000000000000000000000000000000000000000000e-324"); + 0000000000000000000000000000000000000000000000000000000000000000e-324" + ); // very large output - assert_eq!(to_string(f, 0.0, Minus, 80000, false), format!("0.{:0>79999}e0", "")); - assert_eq!(to_string(f, 1.0e1, Minus, 80000, false), format!("1.{:0>79999}e1", "")); - assert_eq!(to_string(f, 1.0e0, Minus, 80000, false), format!("1.{:0>79999}e0", "")); - assert_eq!(to_string(f, 1.0e-1, Minus, 80000, false), - format!("1.000000000000000055511151231257827021181583404541015625{:0>79945}\ - e-1", "")); - assert_eq!(to_string(f, 1.0e-20, Minus, 80000, false), - format!("9.999999999999999451532714542095716517295037027873924471077157760\ - 66783064379706047475337982177734375{:0>79901}e-21", "")); + assert_eq!(to_string(f, 0.0, Minus, 80000, false), format!("0.{:0>79999}e0", "")); + assert_eq!(to_string(f, 1.0e1, Minus, 80000, false), format!("1.{:0>79999}e1", "")); + assert_eq!(to_string(f, 1.0e0, Minus, 80000, false), format!("1.{:0>79999}e0", "")); + assert_eq!( + to_string(f, 1.0e-1, Minus, 80000, false), + format!( + "1.000000000000000055511151231257827021181583404541015625{:0>79945}\ + e-1", + "" + ) + ); + assert_eq!( + to_string(f, 1.0e-20, Minus, 80000, false), + format!( + "9.999999999999999451532714542095716517295037027873924471077157760\ + 66783064379706047475337982177734375{:0>79901}e-21", + "" + ) + ); } pub fn to_exact_fixed_str_test(mut f_: F) - where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { +where + F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), +{ use core::num::flt2dec::Sign::*; fn to_string(f: &mut F, v: T, sign: Sign, frac_digits: usize, upper: bool) -> String - where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) { - to_string_with_parts(|buf, parts| to_exact_fixed_str(|d,b,l| f(d,b,l), v, sign, - frac_digits, upper, buf, parts)) + where + T: DecodableFloat, + F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16), + { + to_string_with_parts(|buf, parts| { + to_exact_fixed_str(|d, b, l| f(d, b, l), v, sign, frac_digits, upper, buf, parts) + }) } let f = &mut f_; - assert_eq!(to_string(f, 0.0, Minus, 0, false), "0"); - assert_eq!(to_string(f, 0.0, MinusRaw, 0, false), "0"); - assert_eq!(to_string(f, 0.0, MinusPlus, 0, false), "+0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, 0, false), "+0"); - assert_eq!(to_string(f, -0.0, Minus, 0, false), "0"); - assert_eq!(to_string(f, -0.0, MinusRaw, 0, false), "-0"); - assert_eq!(to_string(f, -0.0, MinusPlus, 0, false), "+0"); + assert_eq!(to_string(f, 0.0, Minus, 0, false), "0"); + assert_eq!(to_string(f, 0.0, MinusRaw, 0, false), "0"); + assert_eq!(to_string(f, 0.0, MinusPlus, 0, false), "+0"); + assert_eq!(to_string(f, 0.0, MinusPlusRaw, 0, false), "+0"); + assert_eq!(to_string(f, -0.0, Minus, 0, false), "0"); + assert_eq!(to_string(f, -0.0, MinusRaw, 0, false), "-0"); + assert_eq!(to_string(f, -0.0, MinusPlus, 0, false), "+0"); assert_eq!(to_string(f, -0.0, MinusPlusRaw, 0, false), "-0"); - assert_eq!(to_string(f, 0.0, Minus, 1, true), "0.0"); - assert_eq!(to_string(f, 0.0, MinusRaw, 1, true), "0.0"); - assert_eq!(to_string(f, 0.0, MinusPlus, 1, true), "+0.0"); - assert_eq!(to_string(f, 0.0, MinusPlusRaw, 1, true), "+0.0"); - assert_eq!(to_string(f, -0.0, Minus, 8, true), "0.00000000"); - assert_eq!(to_string(f, -0.0, MinusRaw, 8, true), "-0.00000000"); - assert_eq!(to_string(f, -0.0, MinusPlus, 8, true), "+0.00000000"); - assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8, true), "-0.00000000"); - - assert_eq!(to_string(f, 1.0/0.0, Minus, 0, false), "inf"); - assert_eq!(to_string(f, 1.0/0.0, MinusRaw, 1, true), "inf"); - assert_eq!(to_string(f, 1.0/0.0, MinusPlus, 8, false), "+inf"); - assert_eq!(to_string(f, 1.0/0.0, MinusPlusRaw, 64, true), "+inf"); - assert_eq!(to_string(f, 0.0/0.0, Minus, 0, false), "NaN"); - assert_eq!(to_string(f, 0.0/0.0, MinusRaw, 1, true), "NaN"); - assert_eq!(to_string(f, 0.0/0.0, MinusPlus, 8, false), "NaN"); - assert_eq!(to_string(f, 0.0/0.0, MinusPlusRaw, 64, true), "NaN"); - assert_eq!(to_string(f, -1.0/0.0, Minus, 0, false), "-inf"); - assert_eq!(to_string(f, -1.0/0.0, MinusRaw, 1, true), "-inf"); - assert_eq!(to_string(f, -1.0/0.0, MinusPlus, 8, false), "-inf"); - assert_eq!(to_string(f, -1.0/0.0, MinusPlusRaw, 64, true), "-inf"); - - assert_eq!(to_string(f, 3.14, Minus, 0, false), "3"); - assert_eq!(to_string(f, 3.14, MinusRaw, 0, false), "3"); - assert_eq!(to_string(f, 3.14, MinusPlus, 0, false), "+3"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, 0, false), "+3"); - assert_eq!(to_string(f, -3.14, Minus, 0, false), "-3"); - assert_eq!(to_string(f, -3.14, MinusRaw, 0, false), "-3"); - assert_eq!(to_string(f, -3.14, MinusPlus, 0, false), "-3"); + assert_eq!(to_string(f, 0.0, Minus, 1, true), "0.0"); + assert_eq!(to_string(f, 0.0, MinusRaw, 1, true), "0.0"); + assert_eq!(to_string(f, 0.0, MinusPlus, 1, true), "+0.0"); + assert_eq!(to_string(f, 0.0, MinusPlusRaw, 1, true), "+0.0"); + assert_eq!(to_string(f, -0.0, Minus, 8, true), "0.00000000"); + assert_eq!(to_string(f, -0.0, MinusRaw, 8, true), "-0.00000000"); + assert_eq!(to_string(f, -0.0, MinusPlus, 8, true), "+0.00000000"); + assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8, true), "-0.00000000"); + + assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0, false), "inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusRaw, 1, true), "inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 8, false), "+inf"); + assert_eq!(to_string(f, 1.0 / 0.0, MinusPlusRaw, 64, true), "+inf"); + assert_eq!(to_string(f, 0.0 / 0.0, Minus, 0, false), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusRaw, 1, true), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 8, false), "NaN"); + assert_eq!(to_string(f, 0.0 / 0.0, MinusPlusRaw, 64, true), "NaN"); + assert_eq!(to_string(f, -1.0 / 0.0, Minus, 0, false), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusRaw, 1, true), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 8, false), "-inf"); + assert_eq!(to_string(f, -1.0 / 0.0, MinusPlusRaw, 64, true), "-inf"); + + assert_eq!(to_string(f, 3.14, Minus, 0, false), "3"); + assert_eq!(to_string(f, 3.14, MinusRaw, 0, false), "3"); + assert_eq!(to_string(f, 3.14, MinusPlus, 0, false), "+3"); + assert_eq!(to_string(f, 3.14, MinusPlusRaw, 0, false), "+3"); + assert_eq!(to_string(f, -3.14, Minus, 0, false), "-3"); + assert_eq!(to_string(f, -3.14, MinusRaw, 0, false), "-3"); + assert_eq!(to_string(f, -3.14, MinusPlus, 0, false), "-3"); assert_eq!(to_string(f, -3.14, MinusPlusRaw, 0, false), "-3"); - assert_eq!(to_string(f, 3.14, Minus, 1, true), "3.1"); - assert_eq!(to_string(f, 3.14, MinusRaw, 2, true), "3.14"); - assert_eq!(to_string(f, 3.14, MinusPlus, 3, true), "+3.140"); - assert_eq!(to_string(f, 3.14, MinusPlusRaw, 4, true), "+3.1400"); - assert_eq!(to_string(f, -3.14, Minus, 8, true), "-3.14000000"); - assert_eq!(to_string(f, -3.14, MinusRaw, 8, true), "-3.14000000"); - assert_eq!(to_string(f, -3.14, MinusPlus, 8, true), "-3.14000000"); - assert_eq!(to_string(f, -3.14, MinusPlusRaw, 8, true), "-3.14000000"); - - assert_eq!(to_string(f, 0.195, Minus, 0, false), "0"); - assert_eq!(to_string(f, 0.195, MinusRaw, 0, false), "0"); - assert_eq!(to_string(f, 0.195, MinusPlus, 0, false), "+0"); - assert_eq!(to_string(f, 0.195, MinusPlusRaw, 0, false), "+0"); - assert_eq!(to_string(f, -0.195, Minus, 0, false), "-0"); - assert_eq!(to_string(f, -0.195, MinusRaw, 0, false), "-0"); - assert_eq!(to_string(f, -0.195, MinusPlus, 0, false), "-0"); + assert_eq!(to_string(f, 3.14, Minus, 1, true), "3.1"); + assert_eq!(to_string(f, 3.14, MinusRaw, 2, true), "3.14"); + assert_eq!(to_string(f, 3.14, MinusPlus, 3, true), "+3.140"); + assert_eq!(to_string(f, 3.14, MinusPlusRaw, 4, true), "+3.1400"); + assert_eq!(to_string(f, -3.14, Minus, 8, true), "-3.14000000"); + assert_eq!(to_string(f, -3.14, MinusRaw, 8, true), "-3.14000000"); + assert_eq!(to_string(f, -3.14, MinusPlus, 8, true), "-3.14000000"); + assert_eq!(to_string(f, -3.14, MinusPlusRaw, 8, true), "-3.14000000"); + + assert_eq!(to_string(f, 0.195, Minus, 0, false), "0"); + assert_eq!(to_string(f, 0.195, MinusRaw, 0, false), "0"); + assert_eq!(to_string(f, 0.195, MinusPlus, 0, false), "+0"); + assert_eq!(to_string(f, 0.195, MinusPlusRaw, 0, false), "+0"); + assert_eq!(to_string(f, -0.195, Minus, 0, false), "-0"); + assert_eq!(to_string(f, -0.195, MinusRaw, 0, false), "-0"); + assert_eq!(to_string(f, -0.195, MinusPlus, 0, false), "-0"); assert_eq!(to_string(f, -0.195, MinusPlusRaw, 0, false), "-0"); - assert_eq!(to_string(f, 0.195, Minus, 1, true), "0.2"); - assert_eq!(to_string(f, 0.195, MinusRaw, 2, true), "0.20"); - assert_eq!(to_string(f, 0.195, MinusPlus, 3, true), "+0.195"); - assert_eq!(to_string(f, 0.195, MinusPlusRaw, 4, true), "+0.1950"); - assert_eq!(to_string(f, -0.195, Minus, 5, true), "-0.19500"); - assert_eq!(to_string(f, -0.195, MinusRaw, 6, true), "-0.195000"); - assert_eq!(to_string(f, -0.195, MinusPlus, 7, true), "-0.1950000"); - assert_eq!(to_string(f, -0.195, MinusPlusRaw, 8, true), "-0.19500000"); - - assert_eq!(to_string(f, 999.5, Minus, 0, false), "1000"); - assert_eq!(to_string(f, 999.5, Minus, 1, false), "999.5"); - assert_eq!(to_string(f, 999.5, Minus, 2, false), "999.50"); - assert_eq!(to_string(f, 999.5, Minus, 3, false), "999.500"); + assert_eq!(to_string(f, 0.195, Minus, 1, true), "0.2"); + assert_eq!(to_string(f, 0.195, MinusRaw, 2, true), "0.20"); + assert_eq!(to_string(f, 0.195, MinusPlus, 3, true), "+0.195"); + assert_eq!(to_string(f, 0.195, MinusPlusRaw, 4, true), "+0.1950"); + assert_eq!(to_string(f, -0.195, Minus, 5, true), "-0.19500"); + assert_eq!(to_string(f, -0.195, MinusRaw, 6, true), "-0.195000"); + assert_eq!(to_string(f, -0.195, MinusPlus, 7, true), "-0.1950000"); + assert_eq!(to_string(f, -0.195, MinusPlusRaw, 8, true), "-0.19500000"); + + assert_eq!(to_string(f, 999.5, Minus, 0, false), "1000"); + assert_eq!(to_string(f, 999.5, Minus, 1, false), "999.5"); + assert_eq!(to_string(f, 999.5, Minus, 2, false), "999.50"); + assert_eq!(to_string(f, 999.5, Minus, 3, false), "999.500"); assert_eq!(to_string(f, 999.5, Minus, 30, false), "999.500000000000000000000000000000"); assert_eq!(to_string(f, 0.5, Minus, 0, false), "1"); @@ -984,32 +1083,32 @@ pub fn to_exact_fixed_str_test(mut f_: F) assert_eq!(to_string(f, 0.5, Minus, 2, false), "0.50"); assert_eq!(to_string(f, 0.5, Minus, 3, false), "0.500"); - assert_eq!(to_string(f, 0.95, Minus, 0, false), "1"); - assert_eq!(to_string(f, 0.95, Minus, 1, false), "0.9"); // because it really is less than 0.95 - assert_eq!(to_string(f, 0.95, Minus, 2, false), "0.95"); - assert_eq!(to_string(f, 0.95, Minus, 3, false), "0.950"); + assert_eq!(to_string(f, 0.95, Minus, 0, false), "1"); + assert_eq!(to_string(f, 0.95, Minus, 1, false), "0.9"); // because it really is less than 0.95 + assert_eq!(to_string(f, 0.95, Minus, 2, false), "0.95"); + assert_eq!(to_string(f, 0.95, Minus, 3, false), "0.950"); assert_eq!(to_string(f, 0.95, Minus, 10, false), "0.9500000000"); assert_eq!(to_string(f, 0.95, Minus, 30, false), "0.949999999999999955591079014994"); - assert_eq!(to_string(f, 0.095, Minus, 0, false), "0"); - assert_eq!(to_string(f, 0.095, Minus, 1, false), "0.1"); - assert_eq!(to_string(f, 0.095, Minus, 2, false), "0.10"); - assert_eq!(to_string(f, 0.095, Minus, 3, false), "0.095"); - assert_eq!(to_string(f, 0.095, Minus, 4, false), "0.0950"); + assert_eq!(to_string(f, 0.095, Minus, 0, false), "0"); + assert_eq!(to_string(f, 0.095, Minus, 1, false), "0.1"); + assert_eq!(to_string(f, 0.095, Minus, 2, false), "0.10"); + assert_eq!(to_string(f, 0.095, Minus, 3, false), "0.095"); + assert_eq!(to_string(f, 0.095, Minus, 4, false), "0.0950"); assert_eq!(to_string(f, 0.095, Minus, 10, false), "0.0950000000"); assert_eq!(to_string(f, 0.095, Minus, 30, false), "0.095000000000000001110223024625"); - assert_eq!(to_string(f, 0.0095, Minus, 0, false), "0"); - assert_eq!(to_string(f, 0.0095, Minus, 1, false), "0.0"); - assert_eq!(to_string(f, 0.0095, Minus, 2, false), "0.01"); - assert_eq!(to_string(f, 0.0095, Minus, 3, false), "0.009"); // really is less than 0.0095 - assert_eq!(to_string(f, 0.0095, Minus, 4, false), "0.0095"); - assert_eq!(to_string(f, 0.0095, Minus, 5, false), "0.00950"); + assert_eq!(to_string(f, 0.0095, Minus, 0, false), "0"); + assert_eq!(to_string(f, 0.0095, Minus, 1, false), "0.0"); + assert_eq!(to_string(f, 0.0095, Minus, 2, false), "0.01"); + assert_eq!(to_string(f, 0.0095, Minus, 3, false), "0.009"); // really is less than 0.0095 + assert_eq!(to_string(f, 0.0095, Minus, 4, false), "0.0095"); + assert_eq!(to_string(f, 0.0095, Minus, 5, false), "0.00950"); assert_eq!(to_string(f, 0.0095, Minus, 10, false), "0.0095000000"); assert_eq!(to_string(f, 0.0095, Minus, 30, false), "0.009499999999999999764077607267"); - assert_eq!(to_string(f, 7.5e-11, Minus, 0, false), "0"); - assert_eq!(to_string(f, 7.5e-11, Minus, 3, false), "0.000"); + assert_eq!(to_string(f, 7.5e-11, Minus, 0, false), "0"); + assert_eq!(to_string(f, 7.5e-11, Minus, 3, false), "0.000"); assert_eq!(to_string(f, 7.5e-11, Minus, 10, false), "0.0000000001"); assert_eq!(to_string(f, 7.5e-11, Minus, 11, false), "0.00000000007"); // ditto assert_eq!(to_string(f, 7.5e-11, Minus, 12, false), "0.000000000075"); @@ -1021,77 +1120,102 @@ pub fn to_exact_fixed_str_test(mut f_: F) assert_eq!(to_string(f, 1.0e25, Minus, 1, false), "10000000000000000905969664.0"); assert_eq!(to_string(f, 1.0e25, Minus, 3, false), "10000000000000000905969664.000"); - assert_eq!(to_string(f, 1.0e-6, Minus, 0, false), "0"); - assert_eq!(to_string(f, 1.0e-6, Minus, 3, false), "0.000"); - assert_eq!(to_string(f, 1.0e-6, Minus, 6, false), "0.000001"); - assert_eq!(to_string(f, 1.0e-6, Minus, 9, false), "0.000001000"); + assert_eq!(to_string(f, 1.0e-6, Minus, 0, false), "0"); + assert_eq!(to_string(f, 1.0e-6, Minus, 3, false), "0.000"); + assert_eq!(to_string(f, 1.0e-6, Minus, 6, false), "0.000001"); + assert_eq!(to_string(f, 1.0e-6, Minus, 9, false), "0.000001000"); assert_eq!(to_string(f, 1.0e-6, Minus, 12, false), "0.000001000000"); assert_eq!(to_string(f, 1.0e-6, Minus, 22, false), "0.0000010000000000000000"); assert_eq!(to_string(f, 1.0e-6, Minus, 23, false), "0.00000099999999999999995"); assert_eq!(to_string(f, 1.0e-6, Minus, 24, false), "0.000000999999999999999955"); assert_eq!(to_string(f, 1.0e-6, Minus, 25, false), "0.0000009999999999999999547"); assert_eq!(to_string(f, 1.0e-6, Minus, 35, false), "0.00000099999999999999995474811182589"); - assert_eq!(to_string(f, 1.0e-6, Minus, 45, false), - "0.000000999999999999999954748111825886258685614"); - assert_eq!(to_string(f, 1.0e-6, Minus, 55, false), - "0.0000009999999999999999547481118258862586856139387236908"); - assert_eq!(to_string(f, 1.0e-6, Minus, 65, false), - "0.00000099999999999999995474811182588625868561393872369080781936646"); - assert_eq!(to_string(f, 1.0e-6, Minus, 75, false), - "0.000000999999999999999954748111825886258685613938723690807819366455078125000"); - - assert_eq!(to_string(f, f32::MAX, Minus, 0, false), - "340282346638528859811704183484516925440"); - assert_eq!(to_string(f, f32::MAX, Minus, 1, false), - "340282346638528859811704183484516925440.0"); - assert_eq!(to_string(f, f32::MAX, Minus, 2, false), - "340282346638528859811704183484516925440.00"); - - if cfg!(miri) { // Miri is too slow + assert_eq!( + to_string(f, 1.0e-6, Minus, 45, false), + "0.000000999999999999999954748111825886258685614" + ); + assert_eq!( + to_string(f, 1.0e-6, Minus, 55, false), + "0.0000009999999999999999547481118258862586856139387236908" + ); + assert_eq!( + to_string(f, 1.0e-6, Minus, 65, false), + "0.00000099999999999999995474811182588625868561393872369080781936646" + ); + assert_eq!( + to_string(f, 1.0e-6, Minus, 75, false), + "0.000000999999999999999954748111825886258685613938723690807819366455078125000" + ); + + assert_eq!(to_string(f, f32::MAX, Minus, 0, false), "340282346638528859811704183484516925440"); + assert_eq!( + to_string(f, f32::MAX, Minus, 1, false), + "340282346638528859811704183484516925440.0" + ); + assert_eq!( + to_string(f, f32::MAX, Minus, 2, false), + "340282346638528859811704183484516925440.00" + ); + + if cfg!(miri) { + // Miri is too slow return; } let minf32 = ldexp_f32(1.0, -149); - assert_eq!(to_string(f, minf32, Minus, 0, false), "0"); - assert_eq!(to_string(f, minf32, Minus, 1, false), "0.0"); - assert_eq!(to_string(f, minf32, Minus, 2, false), "0.00"); - assert_eq!(to_string(f, minf32, Minus, 4, false), "0.0000"); - assert_eq!(to_string(f, minf32, Minus, 8, false), "0.00000000"); - assert_eq!(to_string(f, minf32, Minus, 16, false), "0.0000000000000000"); - assert_eq!(to_string(f, minf32, Minus, 32, false), "0.00000000000000000000000000000000"); - assert_eq!(to_string(f, minf32, Minus, 64, false), - "0.0000000000000000000000000000000000000000000014012984643248170709"); - assert_eq!(to_string(f, minf32, Minus, 128, false), - "0.0000000000000000000000000000000000000000000014012984643248170709\ - 2372958328991613128026194187651577175706828388979108268586060149"); - assert_eq!(to_string(f, minf32, Minus, 256, false), - "0.0000000000000000000000000000000000000000000014012984643248170709\ + assert_eq!(to_string(f, minf32, Minus, 0, false), "0"); + assert_eq!(to_string(f, minf32, Minus, 1, false), "0.0"); + assert_eq!(to_string(f, minf32, Minus, 2, false), "0.00"); + assert_eq!(to_string(f, minf32, Minus, 4, false), "0.0000"); + assert_eq!(to_string(f, minf32, Minus, 8, false), "0.00000000"); + assert_eq!(to_string(f, minf32, Minus, 16, false), "0.0000000000000000"); + assert_eq!(to_string(f, minf32, Minus, 32, false), "0.00000000000000000000000000000000"); + assert_eq!( + to_string(f, minf32, Minus, 64, false), + "0.0000000000000000000000000000000000000000000014012984643248170709" + ); + assert_eq!( + to_string(f, minf32, Minus, 128, false), + "0.0000000000000000000000000000000000000000000014012984643248170709\ + 2372958328991613128026194187651577175706828388979108268586060149" + ); + assert_eq!( + to_string(f, minf32, Minus, 256, false), + "0.0000000000000000000000000000000000000000000014012984643248170709\ 2372958328991613128026194187651577175706828388979108268586060148\ 6638188362121582031250000000000000000000000000000000000000000000\ - 0000000000000000000000000000000000000000000000000000000000000000"); + 0000000000000000000000000000000000000000000000000000000000000000" + ); - assert_eq!(to_string(f, f64::MAX, Minus, 0, false), - "1797693134862315708145274237317043567980705675258449965989174768\ + assert_eq!( + to_string(f, f64::MAX, Minus, 0, false), + "1797693134862315708145274237317043567980705675258449965989174768\ 0315726078002853876058955863276687817154045895351438246423432132\ 6889464182768467546703537516986049910576551282076245490090389328\ 9440758685084551339423045832369032229481658085593321233482747978\ - 26204144723168738177180919299881250404026184124858368"); - assert_eq!(to_string(f, f64::MAX, Minus, 10, false), - "1797693134862315708145274237317043567980705675258449965989174768\ + 26204144723168738177180919299881250404026184124858368" + ); + assert_eq!( + to_string(f, f64::MAX, Minus, 10, false), + "1797693134862315708145274237317043567980705675258449965989174768\ 0315726078002853876058955863276687817154045895351438246423432132\ 6889464182768467546703537516986049910576551282076245490090389328\ 9440758685084551339423045832369032229481658085593321233482747978\ - 26204144723168738177180919299881250404026184124858368.0000000000"); + 26204144723168738177180919299881250404026184124858368.0000000000" + ); let minf64 = ldexp_f64(1.0, -1074); assert_eq!(to_string(f, minf64, Minus, 0, false), "0"); assert_eq!(to_string(f, minf64, Minus, 1, false), "0.0"); assert_eq!(to_string(f, minf64, Minus, 10, false), "0.0000000000"); - assert_eq!(to_string(f, minf64, Minus, 100, false), - "0.0000000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000"); - assert_eq!(to_string(f, minf64, Minus, 1000, false), - "0.0000000000000000000000000000000000000000000000000000000000000000\ + assert_eq!( + to_string(f, minf64, Minus, 100, false), + "0.0000000000000000000000000000000000000000000000000000000000000000\ + 000000000000000000000000000000000000" + ); + assert_eq!( + to_string(f, minf64, Minus, 1000, false), + "0.0000000000000000000000000000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000000000000000000000000000\ 0000000000000000000000000000000000000000000000000000000000000000\ @@ -1106,15 +1230,23 @@ pub fn to_exact_fixed_str_test(mut f_: F) 1937902681071074917033322268447533357208324319360923828934583680\ 6010601150616980975307834227731832924790498252473077637592724787\ 4656084778203734469699533647017972677717585125660551199131504891\ - 1014510378627381672509558373897335989937"); + 1014510378627381672509558373897335989937" + ); // very large output - assert_eq!(to_string(f, 0.0, Minus, 80000, false), format!("0.{:0>80000}", "")); - assert_eq!(to_string(f, 1.0e1, Minus, 80000, false), format!("10.{:0>80000}", "")); - assert_eq!(to_string(f, 1.0e0, Minus, 80000, false), format!("1.{:0>80000}", "")); - assert_eq!(to_string(f, 1.0e-1, Minus, 80000, false), - format!("0.1000000000000000055511151231257827021181583404541015625{:0>79945}", "")); - assert_eq!(to_string(f, 1.0e-20, Minus, 80000, false), - format!("0.0000000000000000000099999999999999994515327145420957165172950370\ - 2787392447107715776066783064379706047475337982177734375{:0>79881}", "")); + assert_eq!(to_string(f, 0.0, Minus, 80000, false), format!("0.{:0>80000}", "")); + assert_eq!(to_string(f, 1.0e1, Minus, 80000, false), format!("10.{:0>80000}", "")); + assert_eq!(to_string(f, 1.0e0, Minus, 80000, false), format!("1.{:0>80000}", "")); + assert_eq!( + to_string(f, 1.0e-1, Minus, 80000, false), + format!("0.1000000000000000055511151231257827021181583404541015625{:0>79945}", "") + ); + assert_eq!( + to_string(f, 1.0e-20, Minus, 80000, false), + format!( + "0.0000000000000000000099999999999999994515327145420957165172950370\ + 2787392447107715776066783064379706047475337982177734375{:0>79881}", + "" + ) + ); } diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs index a17c094679ea8..f61793a3bca81 100644 --- a/src/libcore/tests/num/mod.rs +++ b/src/libcore/tests/num/mod.rs @@ -1,32 +1,31 @@ -use core::convert::{TryFrom, TryInto}; use core::cmp::PartialEq; +use core::convert::{TryFrom, TryInto}; use core::fmt::Debug; use core::marker::Copy; use core::num::TryFromIntError; -use core::ops::{Add, Sub, Mul, Div, Rem}; +use core::ops::{Add, Div, Mul, Rem, Sub}; use core::option::Option; -use core::option::Option::{Some, None}; +use core::option::Option::{None, Some}; #[macro_use] mod int_macros; -mod i8; mod i16; mod i32; mod i64; +mod i8; #[macro_use] mod uint_macros; -mod u8; mod u16; mod u32; mod u64; +mod u8; -mod flt2dec; -mod dec2flt; mod bignum; - +mod dec2flt; +mod flt2dec; /// Adds the attribute to all items in the block. macro_rules! cfg_block { @@ -48,25 +47,29 @@ macro_rules! assume_usize_width { } /// Helper function for testing numeric operations -pub fn test_num(ten: T, two: T) where +pub fn test_num(ten: T, two: T) +where T: PartialEq - + Add + Sub - + Mul + Div - + Rem + Debug - + Copy + + Add + + Sub + + Mul + + Div + + Rem + + Debug + + Copy, { - assert_eq!(ten.add(two), ten + two); - assert_eq!(ten.sub(two), ten - two); - assert_eq!(ten.mul(two), ten * two); - assert_eq!(ten.div(two), ten / two); - assert_eq!(ten.rem(two), ten % two); + assert_eq!(ten.add(two), ten + two); + assert_eq!(ten.sub(two), ten - two); + assert_eq!(ten.mul(two), ten * two); + assert_eq!(ten.div(two), ten / two); + assert_eq!(ten.rem(two), ten % two); } #[test] fn from_str_issue7588() { - let u : Option = u8::from_str_radix("1000", 10).ok(); + let u: Option = u8::from_str_radix("1000", 10).ok(); assert_eq!(u, None); - let s : Option = i16::from_str_radix("80000", 10).ok(); + let s: Option = i16::from_str_radix("80000", 10).ok(); assert_eq!(s, None); } @@ -144,7 +147,7 @@ macro_rules! test_impl_from { assert_eq!(large_max as $Small, small_max); assert_eq!(large_min as $Small, small_min); } - } + }; } // Unsigned -> Unsigned @@ -242,7 +245,6 @@ fn test_f32f64() { assert!(nan.is_nan()); } - /// Conversions where the full width of $source can be represented as $target macro_rules! test_impl_try_from_always_ok { ($fn_name:ident, $source:ty, $target: ty) => { @@ -251,14 +253,11 @@ macro_rules! test_impl_try_from_always_ok { let max = <$source>::max_value(); let min = <$source>::min_value(); let zero: $source = 0; - assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(), - max as $target); - assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(), - min as $target); - assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), - zero as $target); + assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(), max as $target); + assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(), min as $target); + assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), zero as $target); } - } + }; } test_impl_try_from_always_ok! { test_try_u8u8, u8, u8 } @@ -368,14 +367,12 @@ macro_rules! test_impl_try_from_signed_to_unsigned_upper_ok { let min = <$source>::min_value(); let zero: $source = 0; let neg_one: $source = -1; - assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(), - max as $target); + assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(), max as $target); assert!(<$target as TryFrom<$source>>::try_from(min).is_err()); - assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), - zero as $target); + assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), zero as $target); assert!(<$target as TryFrom<$source>>::try_from(neg_one).is_err()); } - } + }; } test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u8, i8, u8 } @@ -435,12 +432,10 @@ macro_rules! test_impl_try_from_unsigned_to_signed_upper_err { let min = <$source>::min_value(); let zero: $source = 0; assert!(<$target as TryFrom<$source>>::try_from(max).is_err()); - assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(), - min as $target); - assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), - zero as $target); + assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(), min as $target); + assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), zero as $target); } - } + }; } test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u8i8, u8, i8 } @@ -503,16 +498,17 @@ macro_rules! test_impl_try_from_same_sign_err { if min != 0 { assert!(<$target as TryFrom<$source>>::try_from(min).is_err()); } - assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), - zero as $target); - assert_eq!(<$target as TryFrom<$source>>::try_from(t_max as $source) - .unwrap(), - t_max as $target); - assert_eq!(<$target as TryFrom<$source>>::try_from(t_min as $source) - .unwrap(), - t_min as $target); + assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), zero as $target); + assert_eq!( + <$target as TryFrom<$source>>::try_from(t_max as $source).unwrap(), + t_max as $target + ); + assert_eq!( + <$target as TryFrom<$source>>::try_from(t_min as $source).unwrap(), + t_min as $target + ); } - } + }; } test_impl_try_from_same_sign_err! { test_try_u16u8, u16, u8 } @@ -589,16 +585,17 @@ macro_rules! test_impl_try_from_signed_to_unsigned_err { let t_min = <$target>::min_value(); assert!(<$target as TryFrom<$source>>::try_from(max).is_err()); assert!(<$target as TryFrom<$source>>::try_from(min).is_err()); - assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), - zero as $target); - assert_eq!(<$target as TryFrom<$source>>::try_from(t_max as $source) - .unwrap(), - t_max as $target); - assert_eq!(<$target as TryFrom<$source>>::try_from(t_min as $source) - .unwrap(), - t_min as $target); + assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), zero as $target); + assert_eq!( + <$target as TryFrom<$source>>::try_from(t_max as $source).unwrap(), + t_max as $target + ); + assert_eq!( + <$target as TryFrom<$source>>::try_from(t_min as $source).unwrap(), + t_min as $target + ); } - } + }; } test_impl_try_from_signed_to_unsigned_err! { test_try_i16u8, i16, u8 } @@ -637,72 +634,74 @@ assume_usize_width! { } macro_rules! test_float { - ($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr) => { mod $modname { - // FIXME(nagisa): these tests should test for sign of -0.0 - #[test] - fn min() { - assert_eq!((0.0 as $fty).min(0.0), 0.0); - assert_eq!((-0.0 as $fty).min(-0.0), -0.0); - assert_eq!((9.0 as $fty).min(9.0), 9.0); - assert_eq!((-9.0 as $fty).min(0.0), -9.0); - assert_eq!((0.0 as $fty).min(9.0), 0.0); - assert_eq!((-0.0 as $fty).min(-9.0), -9.0); - assert_eq!(($inf as $fty).min(9.0), 9.0); - assert_eq!((9.0 as $fty).min($inf), 9.0); - assert_eq!(($inf as $fty).min(-9.0), -9.0); - assert_eq!((-9.0 as $fty).min($inf), -9.0); - assert_eq!(($neginf as $fty).min(9.0), $neginf); - assert_eq!((9.0 as $fty).min($neginf), $neginf); - assert_eq!(($neginf as $fty).min(-9.0), $neginf); - assert_eq!((-9.0 as $fty).min($neginf), $neginf); - assert_eq!(($nan as $fty).min(9.0), 9.0); - assert_eq!(($nan as $fty).min(-9.0), -9.0); - assert_eq!((9.0 as $fty).min($nan), 9.0); - assert_eq!((-9.0 as $fty).min($nan), -9.0); - assert!(($nan as $fty).min($nan).is_nan()); - } - #[test] - fn max() { - assert_eq!((0.0 as $fty).max(0.0), 0.0); - assert_eq!((-0.0 as $fty).max(-0.0), -0.0); - assert_eq!((9.0 as $fty).max(9.0), 9.0); - assert_eq!((-9.0 as $fty).max(0.0), 0.0); - assert_eq!((0.0 as $fty).max(9.0), 9.0); - assert_eq!((-0.0 as $fty).max(-9.0), -0.0); - assert_eq!(($inf as $fty).max(9.0), $inf); - assert_eq!((9.0 as $fty).max($inf), $inf); - assert_eq!(($inf as $fty).max(-9.0), $inf); - assert_eq!((-9.0 as $fty).max($inf), $inf); - assert_eq!(($neginf as $fty).max(9.0), 9.0); - assert_eq!((9.0 as $fty).max($neginf), 9.0); - assert_eq!(($neginf as $fty).max(-9.0), -9.0); - assert_eq!((-9.0 as $fty).max($neginf), -9.0); - assert_eq!(($nan as $fty).max(9.0), 9.0); - assert_eq!(($nan as $fty).max(-9.0), -9.0); - assert_eq!((9.0 as $fty).max($nan), 9.0); - assert_eq!((-9.0 as $fty).max($nan), -9.0); - assert!(($nan as $fty).max($nan).is_nan()); - } - #[test] - fn rem_euclid() { - let a: $fty = 42.0; - assert!($inf.rem_euclid(a).is_nan()); - assert_eq!(a.rem_euclid($inf), a); - assert!(a.rem_euclid($nan).is_nan()); - assert!($inf.rem_euclid($inf).is_nan()); - assert!($inf.rem_euclid($nan).is_nan()); - assert!($nan.rem_euclid($inf).is_nan()); - } - #[test] - fn div_euclid() { - let a: $fty = 42.0; - assert_eq!(a.div_euclid($inf), 0.0); - assert!(a.div_euclid($nan).is_nan()); - assert!($inf.div_euclid($inf).is_nan()); - assert!($inf.div_euclid($nan).is_nan()); - assert!($nan.div_euclid($inf).is_nan()); + ($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr) => { + mod $modname { + // FIXME(nagisa): these tests should test for sign of -0.0 + #[test] + fn min() { + assert_eq!((0.0 as $fty).min(0.0), 0.0); + assert_eq!((-0.0 as $fty).min(-0.0), -0.0); + assert_eq!((9.0 as $fty).min(9.0), 9.0); + assert_eq!((-9.0 as $fty).min(0.0), -9.0); + assert_eq!((0.0 as $fty).min(9.0), 0.0); + assert_eq!((-0.0 as $fty).min(-9.0), -9.0); + assert_eq!(($inf as $fty).min(9.0), 9.0); + assert_eq!((9.0 as $fty).min($inf), 9.0); + assert_eq!(($inf as $fty).min(-9.0), -9.0); + assert_eq!((-9.0 as $fty).min($inf), -9.0); + assert_eq!(($neginf as $fty).min(9.0), $neginf); + assert_eq!((9.0 as $fty).min($neginf), $neginf); + assert_eq!(($neginf as $fty).min(-9.0), $neginf); + assert_eq!((-9.0 as $fty).min($neginf), $neginf); + assert_eq!(($nan as $fty).min(9.0), 9.0); + assert_eq!(($nan as $fty).min(-9.0), -9.0); + assert_eq!((9.0 as $fty).min($nan), 9.0); + assert_eq!((-9.0 as $fty).min($nan), -9.0); + assert!(($nan as $fty).min($nan).is_nan()); + } + #[test] + fn max() { + assert_eq!((0.0 as $fty).max(0.0), 0.0); + assert_eq!((-0.0 as $fty).max(-0.0), -0.0); + assert_eq!((9.0 as $fty).max(9.0), 9.0); + assert_eq!((-9.0 as $fty).max(0.0), 0.0); + assert_eq!((0.0 as $fty).max(9.0), 9.0); + assert_eq!((-0.0 as $fty).max(-9.0), -0.0); + assert_eq!(($inf as $fty).max(9.0), $inf); + assert_eq!((9.0 as $fty).max($inf), $inf); + assert_eq!(($inf as $fty).max(-9.0), $inf); + assert_eq!((-9.0 as $fty).max($inf), $inf); + assert_eq!(($neginf as $fty).max(9.0), 9.0); + assert_eq!((9.0 as $fty).max($neginf), 9.0); + assert_eq!(($neginf as $fty).max(-9.0), -9.0); + assert_eq!((-9.0 as $fty).max($neginf), -9.0); + assert_eq!(($nan as $fty).max(9.0), 9.0); + assert_eq!(($nan as $fty).max(-9.0), -9.0); + assert_eq!((9.0 as $fty).max($nan), 9.0); + assert_eq!((-9.0 as $fty).max($nan), -9.0); + assert!(($nan as $fty).max($nan).is_nan()); + } + #[test] + fn rem_euclid() { + let a: $fty = 42.0; + assert!($inf.rem_euclid(a).is_nan()); + assert_eq!(a.rem_euclid($inf), a); + assert!(a.rem_euclid($nan).is_nan()); + assert!($inf.rem_euclid($inf).is_nan()); + assert!($inf.rem_euclid($nan).is_nan()); + assert!($nan.rem_euclid($inf).is_nan()); + } + #[test] + fn div_euclid() { + let a: $fty = 42.0; + assert_eq!(a.div_euclid($inf), 0.0); + assert!(a.div_euclid($nan).is_nan()); + assert!($inf.div_euclid($inf).is_nan()); + assert!($inf.div_euclid($nan).is_nan()); + assert!($nan.div_euclid($inf).is_nan()); + } } - } } + }; } test_float!(f32, f32, ::core::f32::INFINITY, ::core::f32::NEG_INFINITY, ::core::f32::NAN); diff --git a/src/libcore/tests/pattern.rs b/src/libcore/tests/pattern.rs index 06c3a78c1698a..6ec61cc97c972 100644 --- a/src/libcore/tests/pattern.rs +++ b/src/libcore/tests/pattern.rs @@ -18,7 +18,7 @@ enum Step { Matches(usize, usize), Rejects(usize, usize), InRange(usize, usize), - Done + Done, } use self::Step::*; @@ -28,7 +28,7 @@ impl From for Step { match x { SearchStep::Match(a, b) => Matches(a, b), SearchStep::Reject(a, b) => Rejects(a, b), - SearchStep::Done => Done + SearchStep::Done => Done, } } } @@ -37,7 +37,7 @@ impl From> for Step { fn from(x: Option<(usize, usize)>) -> Self { match x { Some((a, b)) => InRange(a, b), - None => Done + None => Done, } } } @@ -52,57 +52,146 @@ impl From> for Step { #[test] fn test_simple_iteration() { - search_asserts! ("abcdeabcd", 'a', "forward iteration for ASCII string", + search_asserts!( + "abcdeabcd", + 'a', + "forward iteration for ASCII string", // a b c d e a b c d EOF - [next, next, next, next, next, next, next, next, next, next], - [Matches(0, 1), Rejects(1, 2), Rejects(2, 3), Rejects(3, 4), Rejects(4, 5), Matches(5, 6), Rejects(6, 7), Rejects(7, 8), Rejects(8, 9), Done] - ); - - search_asserts! ("abcdeabcd", 'a', "reverse iteration for ASCII string", + [next, next, next, next, next, next, next, next, next, next], + [ + Matches(0, 1), + Rejects(1, 2), + Rejects(2, 3), + Rejects(3, 4), + Rejects(4, 5), + Matches(5, 6), + Rejects(6, 7), + Rejects(7, 8), + Rejects(8, 9), + Done + ] + ); + + search_asserts!( + "abcdeabcd", + 'a', + "reverse iteration for ASCII string", // d c b a e d c b a EOF - [next_back, next_back, next_back, next_back, next_back, next_back, next_back, next_back, next_back, next_back], - [Rejects(8, 9), Rejects(7, 8), Rejects(6, 7), Matches(5, 6), Rejects(4, 5), Rejects(3, 4), Rejects(2, 3), Rejects(1, 2), Matches(0, 1), Done] - ); - - search_asserts! ("我爱我的猫", '我', "forward iteration for Chinese string", + [ + next_back, next_back, next_back, next_back, next_back, next_back, next_back, next_back, + next_back, next_back + ], + [ + Rejects(8, 9), + Rejects(7, 8), + Rejects(6, 7), + Matches(5, 6), + Rejects(4, 5), + Rejects(3, 4), + Rejects(2, 3), + Rejects(1, 2), + Matches(0, 1), + Done + ] + ); + + search_asserts!( + "我爱我的猫", + '我', + "forward iteration for Chinese string", // 我 愛 我 的 貓 EOF - [next, next, next, next, next, next], + [next, next, next, next, next, next], [Matches(0, 3), Rejects(3, 6), Matches(6, 9), Rejects(9, 12), Rejects(12, 15), Done] ); - search_asserts! ("我的猫说meow", 'm', "forward iteration for mixed string", + search_asserts!( + "我的猫说meow", + 'm', + "forward iteration for mixed string", // 我 的 猫 说 m e o w EOF - [next, next, next, next, next, next, next, next, next], - [Rejects(0, 3), Rejects(3, 6), Rejects(6, 9), Rejects(9, 12), Matches(12, 13), Rejects(13, 14), Rejects(14, 15), Rejects(15, 16), Done] - ); - - search_asserts! ("我的猫说meow", '猫', "reverse iteration for mixed string", + [next, next, next, next, next, next, next, next, next], + [ + Rejects(0, 3), + Rejects(3, 6), + Rejects(6, 9), + Rejects(9, 12), + Matches(12, 13), + Rejects(13, 14), + Rejects(14, 15), + Rejects(15, 16), + Done + ] + ); + + search_asserts!( + "我的猫说meow", + '猫', + "reverse iteration for mixed string", // w o e m 说 猫 的 我 EOF - [next_back, next_back, next_back, next_back, next_back, next_back, next_back, next_back, next_back], - [Rejects(15, 16), Rejects(14, 15), Rejects(13, 14), Rejects(12, 13), Rejects(9, 12), Matches(6, 9), Rejects(3, 6), Rejects(0, 3), Done] + [ + next_back, next_back, next_back, next_back, next_back, next_back, next_back, next_back, + next_back + ], + [ + Rejects(15, 16), + Rejects(14, 15), + Rejects(13, 14), + Rejects(12, 13), + Rejects(9, 12), + Matches(6, 9), + Rejects(3, 6), + Rejects(0, 3), + Done + ] ); } #[test] fn test_simple_search() { - search_asserts!("abcdeabcdeabcde", 'a', "next_match for ASCII string", - [next_match, next_match, next_match, next_match], + search_asserts!( + "abcdeabcdeabcde", + 'a', + "next_match for ASCII string", + [next_match, next_match, next_match, next_match], [InRange(0, 1), InRange(5, 6), InRange(10, 11), Done] ); - search_asserts!("abcdeabcdeabcde", 'a', "next_match_back for ASCII string", + search_asserts!( + "abcdeabcdeabcde", + 'a', + "next_match_back for ASCII string", [next_match_back, next_match_back, next_match_back, next_match_back], - [InRange(10, 11), InRange(5, 6), InRange(0, 1), Done] + [InRange(10, 11), InRange(5, 6), InRange(0, 1), Done] ); - search_asserts!("abcdeab", 'a', "next_reject for ASCII string", - [next_reject, next_reject, next_match, next_reject, next_reject], + search_asserts!( + "abcdeab", + 'a', + "next_reject for ASCII string", + [next_reject, next_reject, next_match, next_reject, next_reject], [InRange(1, 2), InRange(2, 3), InRange(5, 6), InRange(6, 7), Done] ); - search_asserts!("abcdeabcdeabcde", 'a', "next_reject_back for ASCII string", - [next_reject_back, next_reject_back, next_match_back, next_reject_back, next_reject_back, next_reject_back], - [InRange(14, 15), InRange(13, 14), InRange(10, 11), InRange(9, 10), InRange(8, 9), InRange(7, 8)] + search_asserts!( + "abcdeabcdeabcde", + 'a', + "next_reject_back for ASCII string", + [ + next_reject_back, + next_reject_back, + next_match_back, + next_reject_back, + next_reject_back, + next_reject_back + ], + [ + InRange(14, 15), + InRange(13, 14), + InRange(10, 11), + InRange(9, 10), + InRange(8, 9), + InRange(7, 8) + ] ); } @@ -121,134 +210,234 @@ const STRESS: &str = "Áa🁀bÁꁁfg😁각กᘀ각aÁ각ꁁก😁a"; fn test_stress_indices() { // this isn't really a test, more of documentation on the indices of each character in the stresstest string - search_asserts!(STRESS, 'x', "Indices of characters in stress test", - [next, next, next, next, next, next, next, next, next, next, next, next, next, next, next, next, next, next, next, next, next], - [Rejects(0, 2), // Á - Rejects(2, 3), // a - Rejects(3, 7), // 🁀 - Rejects(7, 8), // b - Rejects(8, 10), // Á - Rejects(10, 13), // ꁁ - Rejects(13, 14), // f - Rejects(14, 15), // g - Rejects(15, 19), // 😀 - Rejects(19, 22), // 각 - Rejects(22, 25), // ก - Rejects(25, 28), // ᘀ - Rejects(28, 31), // 각 - Rejects(31, 32), // a - Rejects(32, 34), // Á - Rejects(34, 37), // 각 - Rejects(37, 40), // ꁁ - Rejects(40, 43), // ก - Rejects(43, 47), // 😀 - Rejects(47, 48), // a - Done] + search_asserts!( + STRESS, + 'x', + "Indices of characters in stress test", + [ + next, next, next, next, next, next, next, next, next, next, next, next, next, next, + next, next, next, next, next, next, next + ], + [ + Rejects(0, 2), // Á + Rejects(2, 3), // a + Rejects(3, 7), // 🁀 + Rejects(7, 8), // b + Rejects(8, 10), // Á + Rejects(10, 13), // ꁁ + Rejects(13, 14), // f + Rejects(14, 15), // g + Rejects(15, 19), // 😀 + Rejects(19, 22), // 각 + Rejects(22, 25), // ก + Rejects(25, 28), // ᘀ + Rejects(28, 31), // 각 + Rejects(31, 32), // a + Rejects(32, 34), // Á + Rejects(34, 37), // 각 + Rejects(37, 40), // ꁁ + Rejects(40, 43), // ก + Rejects(43, 47), // 😀 + Rejects(47, 48), // a + Done + ] ); } #[test] fn test_forward_search_shared_bytes() { - search_asserts!(STRESS, 'Á', "Forward search for two-byte Latin character", - [next_match, next_match, next_match, next_match], + search_asserts!( + STRESS, + 'Á', + "Forward search for two-byte Latin character", + [next_match, next_match, next_match, next_match], [InRange(0, 2), InRange(8, 10), InRange(32, 34), Done] ); - search_asserts!(STRESS, 'Á', "Forward search for two-byte Latin character; check if next() still works", - [next_match, next, next_match, next, next_match, next, next_match], - [InRange(0, 2), Rejects(2, 3), InRange(8, 10), Rejects(10, 13), InRange(32, 34), Rejects(34, 37), Done] - ); - - search_asserts!(STRESS, '각', "Forward search for three-byte Hangul character", - [next_match, next, next_match, next_match, next_match], + search_asserts!( + STRESS, + 'Á', + "Forward search for two-byte Latin character; check if next() still works", + [next_match, next, next_match, next, next_match, next, next_match], + [ + InRange(0, 2), + Rejects(2, 3), + InRange(8, 10), + Rejects(10, 13), + InRange(32, 34), + Rejects(34, 37), + Done + ] + ); + + search_asserts!( + STRESS, + '각', + "Forward search for three-byte Hangul character", + [next_match, next, next_match, next_match, next_match], [InRange(19, 22), Rejects(22, 25), InRange(28, 31), InRange(34, 37), Done] ); - search_asserts!(STRESS, '각', "Forward search for three-byte Hangul character; check if next() still works", - [next_match, next, next_match, next, next_match, next, next_match], - [InRange(19, 22), Rejects(22, 25), InRange(28, 31), Rejects(31, 32), InRange(34, 37), Rejects(37, 40), Done] - ); - - search_asserts!(STRESS, 'ก', "Forward search for three-byte Thai character", - [next_match, next, next_match, next, next_match], + search_asserts!( + STRESS, + '각', + "Forward search for three-byte Hangul character; check if next() still works", + [next_match, next, next_match, next, next_match, next, next_match], + [ + InRange(19, 22), + Rejects(22, 25), + InRange(28, 31), + Rejects(31, 32), + InRange(34, 37), + Rejects(37, 40), + Done + ] + ); + + search_asserts!( + STRESS, + 'ก', + "Forward search for three-byte Thai character", + [next_match, next, next_match, next, next_match], [InRange(22, 25), Rejects(25, 28), InRange(40, 43), Rejects(43, 47), Done] ); - search_asserts!(STRESS, 'ก', "Forward search for three-byte Thai character; check if next() still works", - [next_match, next, next_match, next, next_match], + search_asserts!( + STRESS, + 'ก', + "Forward search for three-byte Thai character; check if next() still works", + [next_match, next, next_match, next, next_match], [InRange(22, 25), Rejects(25, 28), InRange(40, 43), Rejects(43, 47), Done] ); - search_asserts!(STRESS, '😁', "Forward search for four-byte emoji", - [next_match, next, next_match, next, next_match], + search_asserts!( + STRESS, + '😁', + "Forward search for four-byte emoji", + [next_match, next, next_match, next, next_match], [InRange(15, 19), Rejects(19, 22), InRange(43, 47), Rejects(47, 48), Done] ); - search_asserts!(STRESS, '😁', "Forward search for four-byte emoji; check if next() still works", - [next_match, next, next_match, next, next_match], + search_asserts!( + STRESS, + '😁', + "Forward search for four-byte emoji; check if next() still works", + [next_match, next, next_match, next, next_match], [InRange(15, 19), Rejects(19, 22), InRange(43, 47), Rejects(47, 48), Done] ); - search_asserts!(STRESS, 'ꁁ', "Forward search for three-byte Yi character with repeated bytes", - [next_match, next, next_match, next, next_match], + search_asserts!( + STRESS, + 'ꁁ', + "Forward search for three-byte Yi character with repeated bytes", + [next_match, next, next_match, next, next_match], [InRange(10, 13), Rejects(13, 14), InRange(37, 40), Rejects(40, 43), Done] ); - search_asserts!(STRESS, 'ꁁ', "Forward search for three-byte Yi character with repeated bytes; check if next() still works", - [next_match, next, next_match, next, next_match], + search_asserts!( + STRESS, + 'ꁁ', + "Forward search for three-byte Yi character with repeated bytes; check if next() still works", + [next_match, next, next_match, next, next_match], [InRange(10, 13), Rejects(13, 14), InRange(37, 40), Rejects(40, 43), Done] ); } #[test] fn test_reverse_search_shared_bytes() { - search_asserts!(STRESS, 'Á', "Reverse search for two-byte Latin character", + search_asserts!( + STRESS, + 'Á', + "Reverse search for two-byte Latin character", [next_match_back, next_match_back, next_match_back, next_match_back], - [InRange(32, 34), InRange(8, 10), InRange(0, 2), Done] - ); - - search_asserts!(STRESS, 'Á', "Reverse search for two-byte Latin character; check if next_back() still works", - [next_match_back, next_back, next_match_back, next_back, next_match_back, next_back], - [InRange(32, 34), Rejects(31, 32), InRange(8, 10), Rejects(7, 8), InRange(0, 2), Done] - ); - - search_asserts!(STRESS, '각', "Reverse search for three-byte Hangul character", - [next_match_back, next_back, next_match_back, next_match_back, next_match_back], - [InRange(34, 37), Rejects(32, 34), InRange(28, 31), InRange(19, 22), Done] - ); - - search_asserts!(STRESS, '각', "Reverse search for three-byte Hangul character; check if next_back() still works", - [next_match_back, next_back, next_match_back, next_back, next_match_back, next_back, next_match_back], - [InRange(34, 37), Rejects(32, 34), InRange(28, 31), Rejects(25, 28), InRange(19, 22), Rejects(15, 19), Done] - ); - - search_asserts!(STRESS, 'ก', "Reverse search for three-byte Thai character", - [next_match_back, next_back, next_match_back, next_back, next_match_back], + [InRange(32, 34), InRange(8, 10), InRange(0, 2), Done] + ); + + search_asserts!( + STRESS, + 'Á', + "Reverse search for two-byte Latin character; check if next_back() still works", + [next_match_back, next_back, next_match_back, next_back, next_match_back, next_back], + [InRange(32, 34), Rejects(31, 32), InRange(8, 10), Rejects(7, 8), InRange(0, 2), Done] + ); + + search_asserts!( + STRESS, + '각', + "Reverse search for three-byte Hangul character", + [next_match_back, next_back, next_match_back, next_match_back, next_match_back], + [InRange(34, 37), Rejects(32, 34), InRange(28, 31), InRange(19, 22), Done] + ); + + search_asserts!( + STRESS, + '각', + "Reverse search for three-byte Hangul character; check if next_back() still works", + [ + next_match_back, + next_back, + next_match_back, + next_back, + next_match_back, + next_back, + next_match_back + ], + [ + InRange(34, 37), + Rejects(32, 34), + InRange(28, 31), + Rejects(25, 28), + InRange(19, 22), + Rejects(15, 19), + Done + ] + ); + + search_asserts!( + STRESS, + 'ก', + "Reverse search for three-byte Thai character", + [next_match_back, next_back, next_match_back, next_back, next_match_back], [InRange(40, 43), Rejects(37, 40), InRange(22, 25), Rejects(19, 22), Done] ); - search_asserts!(STRESS, 'ก', "Reverse search for three-byte Thai character; check if next_back() still works", - [next_match_back, next_back, next_match_back, next_back, next_match_back], + search_asserts!( + STRESS, + 'ก', + "Reverse search for three-byte Thai character; check if next_back() still works", + [next_match_back, next_back, next_match_back, next_back, next_match_back], [InRange(40, 43), Rejects(37, 40), InRange(22, 25), Rejects(19, 22), Done] ); - search_asserts!(STRESS, '😁', "Reverse search for four-byte emoji", - [next_match_back, next_back, next_match_back, next_back, next_match_back], + search_asserts!( + STRESS, + '😁', + "Reverse search for four-byte emoji", + [next_match_back, next_back, next_match_back, next_back, next_match_back], [InRange(43, 47), Rejects(40, 43), InRange(15, 19), Rejects(14, 15), Done] ); - search_asserts!(STRESS, '😁', "Reverse search for four-byte emoji; check if next_back() still works", - [next_match_back, next_back, next_match_back, next_back, next_match_back], + search_asserts!( + STRESS, + '😁', + "Reverse search for four-byte emoji; check if next_back() still works", + [next_match_back, next_back, next_match_back, next_back, next_match_back], [InRange(43, 47), Rejects(40, 43), InRange(15, 19), Rejects(14, 15), Done] ); - search_asserts!(STRESS, 'ꁁ', "Reverse search for three-byte Yi character with repeated bytes", - [next_match_back, next_back, next_match_back, next_back, next_match_back], + search_asserts!( + STRESS, + 'ꁁ', + "Reverse search for three-byte Yi character with repeated bytes", + [next_match_back, next_back, next_match_back, next_back, next_match_back], [InRange(37, 40), Rejects(34, 37), InRange(10, 13), Rejects(8, 10), Done] ); - search_asserts!(STRESS, 'ꁁ', "Reverse search for three-byte Yi character with repeated bytes; check if next_back() still works", - [next_match_back, next_back, next_match_back, next_back, next_match_back], + search_asserts!( + STRESS, + 'ꁁ', + "Reverse search for three-byte Yi character with repeated bytes; check if next_back() still works", + [next_match_back, next_back, next_match_back, next_back, next_match_back], [InRange(37, 40), Rejects(34, 37), InRange(10, 13), Rejects(8, 10), Done] ); } @@ -257,36 +446,60 @@ fn test_reverse_search_shared_bytes() { fn double_ended_regression_test() { // https://github.com/rust-lang/rust/issues/47175 // Ensures that double ended searching comes to a convergence - search_asserts!("abcdeabcdeabcde", 'a', "alternating double ended search", - [next_match, next_match_back, next_match, next_match_back], + search_asserts!( + "abcdeabcdeabcde", + 'a', + "alternating double ended search", + [next_match, next_match_back, next_match, next_match_back], [InRange(0, 1), InRange(10, 11), InRange(5, 6), Done] ); - search_asserts!("abcdeabcdeabcde", 'a', "triple double ended search for a", - [next_match, next_match_back, next_match_back, next_match_back], + search_asserts!( + "abcdeabcdeabcde", + 'a', + "triple double ended search for a", + [next_match, next_match_back, next_match_back, next_match_back], [InRange(0, 1), InRange(10, 11), InRange(5, 6), Done] ); - search_asserts!("abcdeabcdeabcde", 'd', "triple double ended search for d", - [next_match, next_match_back, next_match_back, next_match_back], + search_asserts!( + "abcdeabcdeabcde", + 'd', + "triple double ended search for d", + [next_match, next_match_back, next_match_back, next_match_back], [InRange(3, 4), InRange(13, 14), InRange(8, 9), Done] ); - search_asserts!(STRESS, 'Á', "Double ended search for two-byte Latin character", - [next_match, next_match_back, next_match, next_match_back], + search_asserts!( + STRESS, + 'Á', + "Double ended search for two-byte Latin character", + [next_match, next_match_back, next_match, next_match_back], [InRange(0, 2), InRange(32, 34), InRange(8, 10), Done] ); - search_asserts!(STRESS, '각', "Reverse double ended search for three-byte Hangul character", - [next_match_back, next_back, next_match, next, next_match_back, next_match], + search_asserts!( + STRESS, + '각', + "Reverse double ended search for three-byte Hangul character", + [next_match_back, next_back, next_match, next, next_match_back, next_match], [InRange(34, 37), Rejects(32, 34), InRange(19, 22), Rejects(22, 25), InRange(28, 31), Done] ); - search_asserts!(STRESS, 'ก', "Double ended search for three-byte Thai character", - [next_match, next_back, next, next_match_back, next_match], + search_asserts!( + STRESS, + 'ก', + "Double ended search for three-byte Thai character", + [next_match, next_back, next, next_match_back, next_match], [InRange(22, 25), Rejects(47, 48), Rejects(25, 28), InRange(40, 43), Done] ); - search_asserts!(STRESS, '😁', "Double ended search for four-byte emoji", - [next_match_back, next, next_match, next_back, next_match], + search_asserts!( + STRESS, + '😁', + "Double ended search for four-byte emoji", + [next_match_back, next, next_match, next_back, next_match], [InRange(43, 47), Rejects(0, 2), InRange(15, 19), Rejects(40, 43), Done] ); - search_asserts!(STRESS, 'ꁁ', "Double ended search for three-byte Yi character with repeated bytes", - [next_match, next, next_match_back, next_back, next_match], + search_asserts!( + STRESS, + 'ꁁ', + "Double ended search for three-byte Yi character with repeated bytes", + [next_match, next, next_match_back, next_back, next_match], [InRange(10, 13), Rejects(13, 14), InRange(37, 40), Rejects(34, 37), Done] ); } diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs index 473bc881d2932..a008b3319f39a 100644 --- a/src/libcore/tests/ptr.rs +++ b/src/libcore/tests/ptr.rs @@ -8,7 +8,7 @@ fn test_const_from_raw_parts() { assert_eq!(SLICE, FROM_RAW); let slice = &[1, 2, 3, 4, 5]; - let from_raw = unsafe { &*slice_from_raw_parts(slice.as_ptr(), 2) } ; + let from_raw = unsafe { &*slice_from_raw_parts(slice.as_ptr(), 2) }; assert_eq!(&slice[..2], from_raw); } diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index 163f8d0ab3797..499a5613bd2fe 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -1,31 +1,30 @@ -use core::option::*; use core::array::FixedSizeArray; use core::ops::DerefMut; +use core::option::*; -fn op1() -> Result { Ok(666) } -fn op2() -> Result { Err("sadface") } +fn op1() -> Result { + Ok(666) +} +fn op2() -> Result { + Err("sadface") +} #[test] fn test_and() { assert_eq!(op1().and(Ok(667)).unwrap(), 667); - assert_eq!(op1().and(Err::("bad")).unwrap_err(), - "bad"); + assert_eq!(op1().and(Err::("bad")).unwrap_err(), "bad"); assert_eq!(op2().and(Ok(667)).unwrap_err(), "sadface"); - assert_eq!(op2().and(Err::("bad")).unwrap_err(), - "sadface"); + assert_eq!(op2().and(Err::("bad")).unwrap_err(), "sadface"); } #[test] fn test_and_then() { assert_eq!(op1().and_then(|i| Ok::(i + 1)).unwrap(), 667); - assert_eq!(op1().and_then(|_| Err::("bad")).unwrap_err(), - "bad"); + assert_eq!(op1().and_then(|_| Err::("bad")).unwrap_err(), "bad"); - assert_eq!(op2().and_then(|i| Ok::(i + 1)).unwrap_err(), - "sadface"); - assert_eq!(op2().and_then(|_| Err::("bad")).unwrap_err(), - "sadface"); + assert_eq!(op2().and_then(|i| Ok::(i + 1)).unwrap_err(), "sadface"); + assert_eq!(op2().and_then(|_| Err::("bad")).unwrap_err(), "sadface"); } #[test] @@ -43,8 +42,7 @@ fn test_or_else() { assert_eq!(op1().or_else(|e| Err::(e)).unwrap(), 666); assert_eq!(op2().or_else(|_| Ok::(667)).unwrap(), 667); - assert_eq!(op2().or_else(|e| Err::(e)).unwrap_err(), - "sadface"); + assert_eq!(op2().or_else(|e| Err::(e)).unwrap_err(), "sadface"); } #[test] @@ -67,9 +65,7 @@ fn test_collect() { let v: Result, ()> = (0..3).map(|x| Ok::(x)).collect(); assert!(v == Ok(vec![0, 1, 2])); - let v: Result, isize> = (0..3).map(|x| { - if x > 1 { Err(x) } else { Ok(x) } - }).collect(); + let v: Result, isize> = (0..3).map(|x| if x > 1 { Err(x) } else { Ok(x) }).collect(); assert!(v == Err(2)); // test that it does not take more elements than it needs @@ -103,11 +99,7 @@ fn test_unwrap_or() { #[test] fn test_unwrap_or_else() { fn handler(msg: &'static str) -> isize { - if msg == "I got this." { - 50 - } else { - panic!("BadBad") - } + if msg == "I got this." { 50 } else { panic!("BadBad") } } let ok: Result = Ok(100); @@ -121,38 +113,32 @@ fn test_unwrap_or_else() { #[should_panic] pub fn test_unwrap_or_else_panic() { fn handler(msg: &'static str) -> isize { - if msg == "I got this." { - 50 - } else { - panic!("BadBad") - } + if msg == "I got this." { 50 } else { panic!("BadBad") } } let bad_err: Result = Err("Unrecoverable mess."); - let _ : isize = bad_err.unwrap_or_else(handler); + let _: isize = bad_err.unwrap_or_else(handler); } - #[test] pub fn test_expect_ok() { let ok: Result = Ok(100); assert_eq!(ok.expect("Unexpected error"), 100); } #[test] -#[should_panic(expected="Got expected error: \"All good\"")] +#[should_panic(expected = "Got expected error: \"All good\"")] pub fn test_expect_err() { let err: Result = Err("All good"); err.expect("Got expected error"); } - #[test] pub fn test_expect_err_err() { let ok: Result<&'static str, isize> = Err(100); assert_eq!(ok.expect_err("Unexpected ok"), 100); } #[test] -#[should_panic(expected="Got expected ok: \"All good\"")] +#[should_panic(expected = "Got expected ok: \"All good\"")] pub fn test_expect_err_ok() { let err: Result<&'static str, isize> = Ok("All good"); err.expect_err("Got expected ok"); diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 2ecbe770729b5..fa0021a7c734f 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -4,24 +4,25 @@ //! Parsing does not happen at runtime: structures of `std::fmt::rt` are //! generated instead. -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", - html_playground_url = "https://play.rust-lang.org/", - test(attr(deny(warnings))))] - +#![doc( + html_root_url = "https://doc.rust-lang.org/nightly/", + html_playground_url = "https://play.rust-lang.org/", + test(attr(deny(warnings))) +)] #![feature(nll)] #![feature(rustc_private)] #![feature(unicode_internals)] #![feature(bool_to_option)] -pub use Piece::*; -pub use Position::*; pub use Alignment::*; -pub use Flag::*; pub use Count::*; +pub use Flag::*; +pub use Piece::*; +pub use Position::*; +use std::iter; use std::str; use std::string; -use std::iter; use syntax_pos::{InnerSpan, Symbol}; @@ -219,9 +220,7 @@ impl<'a> Iterator for Parser<'a> { None } } - '\n' => { - Some(String(self.string(pos))) - } + '\n' => Some(String(self.string(pos))), _ => Some(String(self.string(pos))), } } else { @@ -272,7 +271,11 @@ impl<'a> Parser<'a> { /// Notifies of an error. The message doesn't actually need to be of type /// String, but I think it does when this eventually uses conditions so it /// might as well start using it now. - fn err_with_note, S2: Into, S3: Into>( + fn err_with_note< + S1: Into, + S2: Into, + S3: Into, + >( &mut self, description: S1, label: S2, @@ -340,10 +343,13 @@ impl<'a> Parser<'a> { let description = format!("expected `'}}'`, found `{:?}`", maybe); let label = "expected `}`".to_owned(); let (note, secondary_label) = if c == '}' { - (Some("if you intended to print `{`, you can escape it using `{{`".to_owned()), - self.last_opening_brace.map(|sp| { - ("because of this opening brace".to_owned(), sp) - })) + ( + Some( + "if you intended to print `{`, you can escape it using `{{`".to_owned(), + ), + self.last_opening_brace + .map(|sp| ("because of this opening brace".to_owned(), sp)), + ) } else { (None, None) }; @@ -364,10 +370,13 @@ impl<'a> Parser<'a> { if c == '}' { let label = format!("expected `{:?}`", c); let (note, secondary_label) = if c == '}' { - (Some("if you intended to print `{`, you can escape it using `{{`".to_owned()), - self.last_opening_brace.map(|sp| { - ("because of this opening brace".to_owned(), sp) - })) + ( + Some( + "if you intended to print `{`, you can escape it using `{{`".to_owned(), + ), + self.last_opening_brace + .map(|sp| ("because of this opening brace".to_owned(), sp)), + ) } else { (None, None) }; @@ -428,10 +437,7 @@ impl<'a> Parser<'a> { } }; - Argument { - position: pos, - format, - } + Argument { position: pos, format } } /// Parses a positional argument for a format. This could either be an @@ -517,11 +523,7 @@ impl<'a> Parser<'a> { } } if !havewidth { - let width_span_start = if let Some((pos, _)) = self.cur.peek() { - *pos - } else { - 0 - }; + let width_span_start = if let Some((pos, _)) = self.cur.peek() { *pos } else { 0 }; let (w, sp) = self.count(width_span_start); spec.width = w; spec.width_span = sp; diff --git a/src/libfmt_macros/tests.rs b/src/libfmt_macros/tests.rs index 81359033eda29..71a6d51fc870c 100644 --- a/src/libfmt_macros/tests.rs +++ b/src/libfmt_macros/tests.rs @@ -58,27 +58,15 @@ fn invalid06() { #[test] fn format_nothing() { - same("{}", - &[NextArgument(Argument { - position: ArgumentImplicitlyIs(0), - format: fmtdflt(), - })]); + same("{}", &[NextArgument(Argument { position: ArgumentImplicitlyIs(0), format: fmtdflt() })]); } #[test] fn format_position() { - same("{3}", - &[NextArgument(Argument { - position: ArgumentIs(3), - format: fmtdflt(), - })]); + same("{3}", &[NextArgument(Argument { position: ArgumentIs(3), format: fmtdflt() })]); } #[test] fn format_position_nothing_else() { - same("{3:}", - &[NextArgument(Argument { - position: ArgumentIs(3), - format: fmtdflt(), - })]); + same("{3:}", &[NextArgument(Argument { position: ArgumentIs(3), format: fmtdflt() })]); } #[test] fn format_type() { @@ -97,7 +85,8 @@ fn format_type() { ty: "x", ty_span: None, }, - })]); + })], + ); } #[test] fn format_align_fill() { @@ -116,7 +105,8 @@ fn format_align_fill() { ty: "", ty_span: None, }, - })]); + })], + ); same( "{3:0<}", &[NextArgument(Argument { @@ -132,7 +122,8 @@ fn format_align_fill() { ty: "", ty_span: None, }, - })]); + })], + ); same( "{3:* { @@ -402,7 +403,7 @@ impl<'a> Id<'a> { Some(c) if c.is_ascii_alphabetic() || c == '_' => {} _ => return Err(()), } - if !name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' ) { + if !name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') { return Err(()); } @@ -475,10 +476,7 @@ pub trait Labeller<'a> { /// Escape tags in such a way that it is suitable for inclusion in a /// Graphviz HTML label. pub fn escape_html(s: &str) -> String { - s.replace("&", "&") - .replace("\"", """) - .replace("<", "<") - .replace(">", ">") + s.replace("&", "&").replace("\"", """).replace("<", "<").replace(">", ">") } impl<'a> LabelText<'a> { @@ -495,7 +493,8 @@ impl<'a> LabelText<'a> { } fn escape_char(c: char, mut f: F) - where F: FnMut(char) + where + F: FnMut(char), { match c { // not escaping \\, since Graphviz escString needs to @@ -559,8 +558,8 @@ impl<'a> LabelText<'a> { } } -pub type Nodes<'a,N> = Cow<'a,[N]>; -pub type Edges<'a,E> = Cow<'a,[E]>; +pub type Nodes<'a, N> = Cow<'a, [N]>; +pub type Edges<'a, E> = Cow<'a, [E]>; // (The type parameters in GraphWalk should be associated items, // when/if Rust supports such.) @@ -607,25 +606,24 @@ pub fn default_options() -> Vec { /// Renders directed graph `g` into the writer `w` in DOT syntax. /// (Simple wrapper around `render_opts` that passes a default set of options.) -pub fn render<'a,N,E,G,W>(g: &'a G, w: &mut W) -> io::Result<()> - where N: Clone + 'a, - E: Clone + 'a, - G: Labeller<'a, Node=N, Edge=E> + GraphWalk<'a, Node=N, Edge=E>, - W: Write +pub fn render<'a, N, E, G, W>(g: &'a G, w: &mut W) -> io::Result<()> +where + N: Clone + 'a, + E: Clone + 'a, + G: Labeller<'a, Node = N, Edge = E> + GraphWalk<'a, Node = N, Edge = E>, + W: Write, { render_opts(g, w, &[]) } /// Renders directed graph `g` into the writer `w` in DOT syntax. /// (Main entry point for the library.) -pub fn render_opts<'a, N, E, G, W>(g: &'a G, - w: &mut W, - options: &[RenderOption]) - -> io::Result<()> - where N: Clone + 'a, - E: Clone + 'a, - G: Labeller<'a, Node=N, Edge=E> + GraphWalk<'a, Node=N, Edge=E>, - W: Write +pub fn render_opts<'a, N, E, G, W>(g: &'a G, w: &mut W, options: &[RenderOption]) -> io::Result<()> +where + N: Clone + 'a, + E: Clone + 'a, + G: Labeller<'a, Node = N, Edge = E> + GraphWalk<'a, Node = N, Edge = E>, + W: Write, { writeln!(w, "digraph {} {{", g.graph_id().as_slice())?; for n in g.nodes().iter() { diff --git a/src/libgraphviz/tests.rs b/src/libgraphviz/tests.rs index 2f713579b17fa..055e13156ae84 100644 --- a/src/libgraphviz/tests.rs +++ b/src/libgraphviz/tests.rs @@ -1,8 +1,8 @@ -use NodeLabels::*; -use super::{Id, Labeller, Nodes, Edges, GraphWalk, render, Style}; -use super::LabelText::{self, LabelStr, EscStr, HtmlStr}; +use super::LabelText::{self, EscStr, HtmlStr, LabelStr}; +use super::{render, Edges, GraphWalk, Id, Labeller, Nodes, Style}; use std::io; use std::io::prelude::*; +use NodeLabels::*; /// each node is an index in a vector in the graph. type Node = usize; @@ -14,12 +14,7 @@ struct Edge { } fn edge(from: usize, to: usize, label: &'static str, style: Style) -> Edge { - Edge { - from, - to, - label, - style, - } + Edge { from, to, label, style } } struct LabelledGraph { @@ -75,11 +70,12 @@ impl NodeLabels<&'static str> { } impl LabelledGraph { - fn new(name: &'static str, - node_labels: Trivial, - edges: Vec, - node_styles: Option>) - -> LabelledGraph { + fn new( + name: &'static str, + node_labels: Trivial, + edges: Vec, + node_styles: Option>, + ) -> LabelledGraph { let count = node_labels.len(); LabelledGraph { name, @@ -94,10 +90,7 @@ impl LabelledGraph { } impl LabelledGraphWithEscStrs { - fn new(name: &'static str, - node_labels: Trivial, - edges: Vec) - -> LabelledGraphWithEscStrs { + fn new(name: &'static str, node_labels: Trivial, edges: Vec) -> LabelledGraphWithEscStrs { LabelledGraphWithEscStrs { graph: LabelledGraph::new(name, node_labels, edges, None) } } } @@ -203,21 +196,25 @@ fn test_input(g: LabelledGraph) -> io::Result { fn empty_graph() { let labels: Trivial = UnlabelledNodes(0); let r = test_input(LabelledGraph::new("empty_graph", labels, vec![], None)); - assert_eq!(r.unwrap(), -r#"digraph empty_graph { + assert_eq!( + r.unwrap(), + r#"digraph empty_graph { } -"#); +"# + ); } #[test] fn single_node() { let labels: Trivial = UnlabelledNodes(1); let r = test_input(LabelledGraph::new("single_node", labels, vec![], None)); - assert_eq!(r.unwrap(), -r#"digraph single_node { + assert_eq!( + r.unwrap(), + r#"digraph single_node { N0[label="N0"]; } -"#); +"# + ); } #[test] @@ -225,89 +222,112 @@ fn single_node_with_style() { let labels: Trivial = UnlabelledNodes(1); let styles = Some(vec![Style::Dashed]); let r = test_input(LabelledGraph::new("single_node", labels, vec![], styles)); - assert_eq!(r.unwrap(), -r#"digraph single_node { + assert_eq!( + r.unwrap(), + r#"digraph single_node { N0[label="N0"][style="dashed"]; } -"#); +"# + ); } #[test] fn single_edge() { let labels: Trivial = UnlabelledNodes(2); - let result = test_input(LabelledGraph::new("single_edge", - labels, - vec![edge(0, 1, "E", Style::None)], - None)); - assert_eq!(result.unwrap(), -r#"digraph single_edge { + let result = test_input(LabelledGraph::new( + "single_edge", + labels, + vec![edge(0, 1, "E", Style::None)], + None, + )); + assert_eq!( + result.unwrap(), + r#"digraph single_edge { N0[label="N0"]; N1[label="N1"]; N0 -> N1[label="E"]; } -"#); +"# + ); } #[test] fn single_edge_with_style() { let labels: Trivial = UnlabelledNodes(2); - let result = test_input(LabelledGraph::new("single_edge", - labels, - vec![edge(0, 1, "E", Style::Bold)], - None)); - assert_eq!(result.unwrap(), -r#"digraph single_edge { + let result = test_input(LabelledGraph::new( + "single_edge", + labels, + vec![edge(0, 1, "E", Style::Bold)], + None, + )); + assert_eq!( + result.unwrap(), + r#"digraph single_edge { N0[label="N0"]; N1[label="N1"]; N0 -> N1[label="E"][style="bold"]; } -"#); +"# + ); } #[test] fn test_some_labelled() { let labels: Trivial = SomeNodesLabelled(vec![Some("A"), None]); let styles = Some(vec![Style::None, Style::Dotted]); - let result = test_input(LabelledGraph::new("test_some_labelled", - labels, - vec![edge(0, 1, "A-1", Style::None)], - styles)); - assert_eq!(result.unwrap(), -r#"digraph test_some_labelled { + let result = test_input(LabelledGraph::new( + "test_some_labelled", + labels, + vec![edge(0, 1, "A-1", Style::None)], + styles, + )); + assert_eq!( + result.unwrap(), + r#"digraph test_some_labelled { N0[label="A"]; N1[label="N1"][style="dotted"]; N0 -> N1[label="A-1"]; } -"#); +"# + ); } #[test] fn single_cyclic_node() { let labels: Trivial = UnlabelledNodes(1); - let r = test_input(LabelledGraph::new("single_cyclic_node", - labels, - vec![edge(0, 0, "E", Style::None)], - None)); - assert_eq!(r.unwrap(), -r#"digraph single_cyclic_node { + let r = test_input(LabelledGraph::new( + "single_cyclic_node", + labels, + vec![edge(0, 0, "E", Style::None)], + None, + )); + assert_eq!( + r.unwrap(), + r#"digraph single_cyclic_node { N0[label="N0"]; N0 -> N0[label="E"]; } -"#); +"# + ); } #[test] fn hasse_diagram() { let labels = AllNodesLabelled(vec!["{x,y}", "{x}", "{y}", "{}"]); - let r = test_input(LabelledGraph::new("hasse_diagram", - labels, - vec![edge(0, 1, "", Style::None), - edge(0, 2, "", Style::None), - edge(1, 3, "", Style::None), - edge(2, 3, "", Style::None)], - None)); - assert_eq!(r.unwrap(), -r#"digraph hasse_diagram { + let r = test_input(LabelledGraph::new( + "hasse_diagram", + labels, + vec![ + edge(0, 1, "", Style::None), + edge(0, 2, "", Style::None), + edge(1, 3, "", Style::None), + edge(2, 3, "", Style::None), + ], + None, + )); + assert_eq!( + r.unwrap(), + r#"digraph hasse_diagram { N0[label="{x,y}"]; N1[label="{x}"]; N2[label="{y}"]; @@ -317,7 +337,8 @@ r#"digraph hasse_diagram { N1 -> N3[label=""]; N2 -> N3[label=""]; } -"#); +"# + ); } #[test] @@ -332,23 +353,29 @@ fn left_aligned_text() { \\l", "branch1", "branch2", - "afterward"]); + "afterward", + ]); let mut writer = Vec::new(); - let g = LabelledGraphWithEscStrs::new("syntax_tree", - labels, - vec![edge(0, 1, "then", Style::None), - edge(0, 2, "else", Style::None), - edge(1, 3, ";", Style::None), - edge(2, 3, ";", Style::None)]); + let g = LabelledGraphWithEscStrs::new( + "syntax_tree", + labels, + vec![ + edge(0, 1, "then", Style::None), + edge(0, 2, "else", Style::None), + edge(1, 3, ";", Style::None), + edge(2, 3, ";", Style::None), + ], + ); render(&g, &mut writer).unwrap(); let mut r = String::new(); Read::read_to_string(&mut &*writer, &mut r).unwrap(); - assert_eq!(r, -r#"digraph syntax_tree { + assert_eq!( + r, + r#"digraph syntax_tree { N0[label="if test {\l branch1\l} else {\l branch2\l}\lafterward\l"]; N1[label="branch1"]; N2[label="branch2"]; @@ -358,7 +385,8 @@ r#"digraph syntax_tree { N1 -> N3[label=";"]; N2 -> N3[label=";"]; } -"#); +"# + ); } #[test] diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index 5509f47bc8858..db7c250e21157 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -5,12 +5,12 @@ #![no_std] #![unstable(feature = "panic_abort", issue = "32837")] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", - issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")] +#![doc( + html_root_url = "https://doc.rust-lang.org/nightly/", + issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/" +)] #![panic_runtime] - #![allow(unused_features)] - #![feature(core_intrinsics)] #![feature(libc)] #![feature(nll)] @@ -21,10 +21,12 @@ // Rust's "try" function, but if we're aborting on panics we just call the // function as there's nothing else we need to do here. #[rustc_std_internal_symbol] -pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8), - data: *mut u8, - _data_ptr: *mut usize, - _vtable_ptr: *mut usize) -> u32 { +pub unsafe extern "C" fn __rust_maybe_catch_panic( + f: fn(*mut u8), + data: *mut u8, + _data_ptr: *mut usize, + _vtable_ptr: *mut usize, +) -> u32 { f(data); 0 } @@ -40,7 +42,7 @@ pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8), // will kill us with an illegal instruction, which will do a good enough job for // now hopefully. #[rustc_std_internal_symbol] -pub unsafe extern fn __rust_start_panic(_payload: usize) -> u32 { +pub unsafe extern "C" fn __rust_start_panic(_payload: usize) -> u32 { abort(); #[cfg(any(unix, target_os = "cloudabi"))] @@ -48,17 +50,17 @@ pub unsafe extern fn __rust_start_panic(_payload: usize) -> u32 { libc::abort(); } - #[cfg(any(windows, - all(target_arch = "wasm32", not(target_os = "emscripten"))))] + #[cfg(any(windows, all(target_arch = "wasm32", not(target_os = "emscripten"))))] unsafe fn abort() -> ! { core::intrinsics::abort(); } - #[cfg(any(target_os = "hermit", - all(target_vendor="fortanix", target_env="sgx")))] + #[cfg(any(target_os = "hermit", all(target_vendor = "fortanix", target_env = "sgx")))] unsafe fn abort() -> ! { // call std::sys::abort_internal - extern "C" { pub fn __rust_abort() -> !; } + extern "C" { + pub fn __rust_abort() -> !; + } __rust_abort(); } } @@ -92,28 +94,21 @@ pub unsafe extern fn __rust_start_panic(_payload: usize) -> u32 { pub mod personalities { #[no_mangle] #[cfg(not(any( - all( - target_arch = "wasm32", - not(target_os = "emscripten"), - ), - all( - target_os = "windows", - target_env = "gnu", - target_arch = "x86_64", - ), + all(target_arch = "wasm32", not(target_os = "emscripten"),), + all(target_os = "windows", target_env = "gnu", target_arch = "x86_64",), )))] - pub extern fn rust_eh_personality() {} + pub extern "C" fn rust_eh_personality() {} // On x86_64-pc-windows-gnu we use our own personality function that needs // to return `ExceptionContinueSearch` as we're passing on all our frames. #[no_mangle] - #[cfg(all(target_os = "windows", - target_env = "gnu", - target_arch = "x86_64"))] - pub extern fn rust_eh_personality(_record: usize, - _frame: usize, - _context: usize, - _dispatcher: usize) -> u32 { + #[cfg(all(target_os = "windows", target_env = "gnu", target_arch = "x86_64"))] + pub extern "C" fn rust_eh_personality( + _record: usize, + _frame: usize, + _context: usize, + _dispatcher: usize, + ) -> u32 { 1 // `ExceptionContinueSearch` } @@ -124,14 +119,14 @@ pub mod personalities { // body is empty. #[no_mangle] #[cfg(all(target_os = "windows", target_env = "gnu"))] - pub extern fn rust_eh_unwind_resume() {} + pub extern "C" fn rust_eh_unwind_resume() {} // These two are called by our startup objects on i686-pc-windows-gnu, but // they don't need to do anything so the bodies are nops. #[no_mangle] #[cfg(all(target_os = "windows", target_env = "gnu", target_arch = "x86"))] - pub extern fn rust_eh_register_frames() {} + pub extern "C" fn rust_eh_register_frames() {} #[no_mangle] #[cfg(all(target_os = "windows", target_env = "gnu", target_arch = "x86"))] - pub extern fn rust_eh_unregister_frames() {} + pub extern "C" fn rust_eh_unregister_frames() {} } diff --git a/src/libpanic_unwind/dwarf/eh.rs b/src/libpanic_unwind/dwarf/eh.rs index 242eb6750b3df..302478cfac8f5 100644 --- a/src/libpanic_unwind/dwarf/eh.rs +++ b/src/libpanic_unwind/dwarf/eh.rs @@ -36,8 +36,8 @@ pub const DW_EH_PE_indirect: u8 = 0x80; #[derive(Copy, Clone)] pub struct EHContext<'a> { - pub ip: usize, // Current instruction pointer - pub func_start: usize, // Address of the current function + pub ip: usize, // Current instruction pointer + pub func_start: usize, // Address of the current function pub get_text_start: &'a dyn Fn() -> usize, // Get address of the code section pub get_data_start: &'a dyn Fn() -> usize, // Get address of the data section } @@ -51,11 +51,13 @@ pub enum EHAction { pub const USING_SJLJ_EXCEPTIONS: bool = cfg!(all(target_os = "ios", target_arch = "arm")); -pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>, foreign_exception: bool) - -> Result -{ +pub unsafe fn find_eh_action( + lsda: *const u8, + context: &EHContext<'_>, + foreign_exception: bool, +) -> Result { if lsda.is_null() { - return Ok(EHAction::None) + return Ok(EHAction::None); } let func_start = context.func_start; @@ -93,10 +95,10 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>, foreign_e } if ip < func_start + cs_start + cs_len { if cs_lpad == 0 { - return Ok(EHAction::None) + return Ok(EHAction::None); } else { let lpad = lpad_base + cs_lpad; - return Ok(interpret_cs_action(cs_action, lpad, foreign_exception)) + return Ok(interpret_cs_action(cs_action, lpad, foreign_exception)); } } } @@ -121,7 +123,7 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>, foreign_e // Can never have null landing pad for sjlj -- that would have // been indicated by a -1 call site index. let lpad = (cs_lpad + 1) as usize; - return Ok(interpret_cs_action(cs_action, lpad, foreign_exception)) + return Ok(interpret_cs_action(cs_action, lpad, foreign_exception)); } } } @@ -144,25 +146,22 @@ fn interpret_cs_action(cs_action: u64, lpad: usize, foreign_exception: bool) -> #[inline] fn round_up(unrounded: usize, align: usize) -> Result { - if align.is_power_of_two() { - Ok((unrounded + align - 1) & !(align - 1)) - } else { - Err(()) - } + if align.is_power_of_two() { Ok((unrounded + align - 1) & !(align - 1)) } else { Err(()) } } -unsafe fn read_encoded_pointer(reader: &mut DwarfReader, - context: &EHContext<'_>, - encoding: u8) - -> Result { +unsafe fn read_encoded_pointer( + reader: &mut DwarfReader, + context: &EHContext<'_>, + encoding: u8, +) -> Result { if encoding == DW_EH_PE_omit { - return Err(()) + return Err(()); } // DW_EH_PE_aligned implies it's an absolute pointer value if encoding == DW_EH_PE_aligned { reader.ptr = round_up(reader.ptr as usize, mem::size_of::())? as *const u8; - return Ok(reader.read::()) + return Ok(reader.read::()); } let mut result = match encoding & 0x0F { @@ -184,7 +183,7 @@ unsafe fn read_encoded_pointer(reader: &mut DwarfReader, DW_EH_PE_pcrel => reader.ptr as usize, DW_EH_PE_funcrel => { if context.func_start == 0 { - return Err(()) + return Err(()); } context.func_start } diff --git a/src/libpanic_unwind/dwarf/mod.rs b/src/libpanic_unwind/dwarf/mod.rs index 34128e60d3638..649bbce52a364 100644 --- a/src/libpanic_unwind/dwarf/mod.rs +++ b/src/libpanic_unwind/dwarf/mod.rs @@ -17,7 +17,7 @@ pub struct DwarfReader { pub ptr: *const u8, } -#[repr(C,packed)] +#[repr(C, packed)] struct Unaligned(T); impl DwarfReader { diff --git a/src/libpanic_unwind/emcc.rs b/src/libpanic_unwind/emcc.rs index 3d0d5a4151eed..2098404ee1b9d 100644 --- a/src/libpanic_unwind/emcc.rs +++ b/src/libpanic_unwind/emcc.rs @@ -8,10 +8,10 @@ #![allow(private_no_mangle_fns)] +use alloc::boxed::Box; use core::any::Any; -use core::ptr; use core::mem; -use alloc::boxed::Box; +use core::ptr; use libc::{self, c_int}; use unwind as uw; @@ -72,12 +72,13 @@ pub unsafe fn panic(data: Box) -> u32 { #[lang = "eh_personality"] #[no_mangle] -unsafe extern "C" fn rust_eh_personality(version: c_int, - actions: uw::_Unwind_Action, - exception_class: uw::_Unwind_Exception_Class, - exception_object: *mut uw::_Unwind_Exception, - context: *mut uw::_Unwind_Context) - -> uw::_Unwind_Reason_Code { +unsafe extern "C" fn rust_eh_personality( + version: c_int, + actions: uw::_Unwind_Action, + exception_class: uw::_Unwind_Exception_Class, + exception_object: *mut uw::_Unwind_Exception, + context: *mut uw::_Unwind_Context, +) -> uw::_Unwind_Reason_Code { __gxx_personality_v0(version, actions, exception_class, exception_object, context) } @@ -85,13 +86,16 @@ extern "C" { fn __cxa_allocate_exception(thrown_size: libc::size_t) -> *mut libc::c_void; fn __cxa_begin_catch(thrown_exception: *mut libc::c_void) -> *mut libc::c_void; fn __cxa_end_catch(); - fn __cxa_throw(thrown_exception: *mut libc::c_void, - tinfo: *const TypeInfo, - dest: *mut libc::c_void) -> !; - fn __gxx_personality_v0(version: c_int, - actions: uw::_Unwind_Action, - exception_class: uw::_Unwind_Exception_Class, - exception_object: *mut uw::_Unwind_Exception, - context: *mut uw::_Unwind_Context) - -> uw::_Unwind_Reason_Code; + fn __cxa_throw( + thrown_exception: *mut libc::c_void, + tinfo: *const TypeInfo, + dest: *mut libc::c_void, + ) -> !; + fn __gxx_personality_v0( + version: c_int, + actions: uw::_Unwind_Action, + exception_class: uw::_Unwind_Exception_Class, + exception_object: *mut uw::_Unwind_Exception, + context: *mut uw::_Unwind_Context, + ) -> uw::_Unwind_Reason_Code; } diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index 4f572fe21b30b..e5e8e805b6e89 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -46,13 +46,13 @@ #![allow(private_no_mangle_fns)] +use alloc::boxed::Box; use core::any::Any; use core::ptr; -use alloc::boxed::Box; -use unwind as uw; +use crate::dwarf::eh::{self, EHAction, EHContext}; use libc::{c_int, uintptr_t}; -use crate::dwarf::eh::{self, EHContext, EHAction}; +use unwind as uw; #[repr(C)] struct Exception { @@ -72,8 +72,10 @@ pub unsafe fn panic(data: Box) -> u32 { let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception; return uw::_Unwind_RaiseException(exception_param) as u32; - extern "C" fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code, - exception: *mut uw::_Unwind_Exception) { + extern "C" fn exception_cleanup( + _unwind_code: uw::_Unwind_Reason_Code, + exception: *mut uw::_Unwind_Exception, + ) { unsafe { let _: Box = Box::from_raw(exception as *mut Exception); } @@ -98,7 +100,6 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class { 0x4d4f5a_00_52555354 } - // Register ids were lifted from LLVM's TargetLowering::getExceptionPointerRegister() // and TargetLowering::getExceptionSelectorRegister() for each architecture, // then mapped to DWARF register numbers via register definition tables @@ -302,9 +303,10 @@ cfg_if::cfg_if! { } } -unsafe fn find_eh_action(context: *mut uw::_Unwind_Context, foreign_exception: bool) - -> Result -{ +unsafe fn find_eh_action( + context: *mut uw::_Unwind_Context, + foreign_exception: bool, +) -> Result { let lsda = uw::_Unwind_GetLanguageSpecificData(context) as *const u8; let mut ip_before_instr: c_int = 0; let ip = uw::_Unwind_GetIPInfo(context, &mut ip_before_instr); @@ -320,7 +322,11 @@ unsafe fn find_eh_action(context: *mut uw::_Unwind_Context, foreign_exception: b } // See docs in the `unwind` module. -#[cfg(all(target_os="windows", any(target_arch = "x86", target_arch = "x86_64"), target_env="gnu"))] +#[cfg(all( + target_os = "windows", + any(target_arch = "x86", target_arch = "x86_64"), + target_env = "gnu" +))] #[lang = "eh_unwind_resume"] #[unwind(allowed)] unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! { @@ -343,7 +349,7 @@ unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! { // implementation of stack unwinding is (for now) deferred to libgcc_eh, however // Rust crates use these Rust-specific entry points to avoid potential clashes // with any GCC runtime. -#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))] +#[cfg(all(target_os = "windows", target_arch = "x86", target_env = "gnu"))] pub mod eh_frame_registry { extern "C" { fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8); @@ -356,8 +362,7 @@ pub mod eh_frame_registry { } #[no_mangle] - pub unsafe extern "C" fn rust_eh_unregister_frames(eh_frame_begin: *const u8, - object: *mut u8) { + pub unsafe extern "C" fn rust_eh_unregister_frames(eh_frame_begin: *const u8, object: *mut u8) { __deregister_frame_info(eh_frame_begin, object); } } diff --git a/src/libpanic_unwind/hermit.rs b/src/libpanic_unwind/hermit.rs index 8bee6ff09e551..2f53df2861d44 100644 --- a/src/libpanic_unwind/hermit.rs +++ b/src/libpanic_unwind/hermit.rs @@ -3,19 +3,23 @@ //! Right now we don't support this, so this is just stubs. use alloc::boxed::Box; -use core::ptr; use core::any::Any; +use core::ptr; pub fn payload() -> *mut u8 { ptr::null_mut() } pub unsafe fn cleanup(_ptr: *mut u8) -> Box { - extern "C" { pub fn __rust_abort() -> !; } + extern "C" { + pub fn __rust_abort() -> !; + } __rust_abort(); } pub unsafe fn panic(_data: Box) -> u32 { - extern "C" { pub fn __rust_abort() -> !; } + extern "C" { + pub fn __rust_abort() -> !; + } __rust_abort(); } diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 3a14197c77bec..e721162edc067 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -13,9 +13,10 @@ #![no_std] #![unstable(feature = "panic_unwind", issue = "32837")] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", - issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")] - +#![doc( + html_root_url = "https://doc.rust-lang.org/nightly/", + issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/" +)] #![feature(core_intrinsics)] #![feature(lang_items)] #![feature(libc)] @@ -25,15 +26,14 @@ #![feature(staged_api)] #![feature(std_internals)] #![feature(unwind_attributes)] - #![panic_runtime] #![feature(panic_runtime)] use alloc::boxed::Box; use core::intrinsics; use core::mem; -use core::raw; use core::panic::BoxMeUp; +use core::raw; cfg_if::cfg_if! { if #[cfg(target_os = "emscripten")] { @@ -69,11 +69,12 @@ mod dwarf; // hairy and tightly coupled, for more information see the compiler's // implementation of this. #[no_mangle] -pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8), - data: *mut u8, - data_ptr: *mut usize, - vtable_ptr: *mut usize) - -> u32 { +pub unsafe extern "C" fn __rust_maybe_catch_panic( + f: fn(*mut u8), + data: *mut u8, + data_ptr: *mut usize, + vtable_ptr: *mut usize, +) -> u32 { let mut payload = imp::payload(); if intrinsics::r#try(f, data, &mut payload as *mut _ as *mut _) == 0 { 0 diff --git a/src/libpanic_unwind/seh.rs b/src/libpanic_unwind/seh.rs index ff9a215d339e3..9a28c47ba9458 100644 --- a/src/libpanic_unwind/seh.rs +++ b/src/libpanic_unwind/seh.rs @@ -99,8 +99,12 @@ mod imp { pub type ptr_t = *mut u8; macro_rules! ptr { - (0) => (core::ptr::null_mut()); - ($e:expr) => ($e as *mut u8); + (0) => { + core::ptr::null_mut() + }; + ($e:expr) => { + $e as *mut u8 + }; } } @@ -169,19 +173,13 @@ static mut THROW_INFO: _ThrowInfo = _ThrowInfo { pCatchableTypeArray: ptr!(0), }; -static mut CATCHABLE_TYPE_ARRAY: _CatchableTypeArray = _CatchableTypeArray { - nCatchableTypes: 1, - arrayOfCatchableTypes: [ptr!(0)], -}; +static mut CATCHABLE_TYPE_ARRAY: _CatchableTypeArray = + _CatchableTypeArray { nCatchableTypes: 1, arrayOfCatchableTypes: [ptr!(0)] }; static mut CATCHABLE_TYPE: _CatchableType = _CatchableType { properties: 0, pType: ptr!(0), - thisDisplacement: _PMD { - mdisp: 0, - pdisp: -1, - vdisp: 0, - }, + thisDisplacement: _PMD { mdisp: 0, pdisp: -1, vdisp: 0 }, sizeOrOffset: mem::size_of::<[u64; 2]>() as c_int, copy_function: ptr!(0), }; @@ -245,20 +243,25 @@ pub unsafe fn panic(data: Box) -> u32 { // // In any case, we basically need to do something like this until we can // express more operations in statics (and we may never be able to). - atomic_store(&mut THROW_INFO.pCatchableTypeArray as *mut _ as *mut u32, - ptr!(&CATCHABLE_TYPE_ARRAY as *const _) as u32); - atomic_store(&mut CATCHABLE_TYPE_ARRAY.arrayOfCatchableTypes[0] as *mut _ as *mut u32, - ptr!(&CATCHABLE_TYPE as *const _) as u32); - atomic_store(&mut CATCHABLE_TYPE.pType as *mut _ as *mut u32, - ptr!(&TYPE_DESCRIPTOR as *const _) as u32); + atomic_store( + &mut THROW_INFO.pCatchableTypeArray as *mut _ as *mut u32, + ptr!(&CATCHABLE_TYPE_ARRAY as *const _) as u32, + ); + atomic_store( + &mut CATCHABLE_TYPE_ARRAY.arrayOfCatchableTypes[0] as *mut _ as *mut u32, + ptr!(&CATCHABLE_TYPE as *const _) as u32, + ); + atomic_store( + &mut CATCHABLE_TYPE.pType as *mut _ as *mut u32, + ptr!(&TYPE_DESCRIPTOR as *const _) as u32, + ); extern "system" { #[unwind(allowed)] pub fn _CxxThrowException(pExceptionObject: *mut c_void, pThrowInfo: *mut u8) -> !; } - _CxxThrowException(throw_ptr, - &mut THROW_INFO as *mut _ as *mut _); + _CxxThrowException(throw_ptr, &mut THROW_INFO as *mut _ as *mut _); } pub fn payload() -> [u64; 2] { @@ -266,10 +269,7 @@ pub fn payload() -> [u64; 2] { } pub unsafe fn cleanup(payload: [u64; 2]) -> Box { - mem::transmute(raw::TraitObject { - data: payload[0] as *mut _, - vtable: payload[1] as *mut _, - }) + mem::transmute(raw::TraitObject { data: payload[0] as *mut _, vtable: payload[1] as *mut _ }) } // This is required by the compiler to exist (e.g., it's a lang item), but diff --git a/src/libproc_macro/bridge/buffer.rs b/src/libproc_macro/bridge/buffer.rs index a51e3a9a33d7b..aeecbd496621b 100644 --- a/src/libproc_macro/bridge/buffer.rs +++ b/src/libproc_macro/bridge/buffer.rs @@ -23,10 +23,7 @@ impl Clone for Slice<'a, T> { impl From<&'a [T]> for Slice<'a, T> { fn from(xs: &'a [T]) -> Self { - Slice { - data: unsafe { &*(xs.as_ptr() as *const [T; 0]) }, - len: xs.len(), - } + Slice { data: unsafe { &*(xs.as_ptr() as *const [T; 0]) }, len: xs.len() } } } @@ -128,12 +125,7 @@ impl From> for Buffer { // be safely called on `Buffer`s created by *this* `proc_macro`. fn to_vec(b: Buffer) -> Vec { unsafe { - let Buffer { - data, - len, - capacity, - .. - } = b; + let Buffer { data, len, capacity, .. } = b; mem::forget(b); Vec::from_raw_parts(data, len, capacity) } @@ -149,12 +141,6 @@ impl From> for Buffer { mem::drop(to_vec(b)); } - Buffer { - data, - len, - capacity, - extend_from_slice, - drop, - } + Buffer { data, len, capacity, extend_from_slice, drop } } } diff --git a/src/libproc_macro/bridge/client.rs b/src/libproc_macro/bridge/client.rs index 9643dba997aa4..dd948025c91ca 100644 --- a/src/libproc_macro/bridge/client.rs +++ b/src/libproc_macro/bridge/client.rs @@ -393,17 +393,13 @@ impl Client crate::TokenStream> { ) -> Buffer { run_client(bridge, |input| f(crate::TokenStream(input)).0) } - Client { - get_handle_counters: HandleCounters::get, - run, - f, - } + Client { get_handle_counters: HandleCounters::get, run, f } } } impl Client crate::TokenStream> { pub const fn expand2( - f: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream + f: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream, ) -> Self { extern "C" fn run( bridge: Bridge<'_>, @@ -413,11 +409,7 @@ impl Client crate::TokenStream> { f(crate::TokenStream(input), crate::TokenStream(input2)).0 }) } - Client { - get_handle_counters: HandleCounters::get, - run, - f, - } + Client { get_handle_counters: HandleCounters::get, run, f } } } @@ -446,7 +438,7 @@ impl ProcMacro { match self { ProcMacro::CustomDerive { trait_name, .. } => trait_name, ProcMacro::Attr { name, .. } => name, - ProcMacro::Bang { name, ..} => name + ProcMacro::Bang { name, .. } => name, } } @@ -455,30 +447,20 @@ impl ProcMacro { attributes: &'static [&'static str], expand: fn(crate::TokenStream) -> crate::TokenStream, ) -> Self { - ProcMacro::CustomDerive { - trait_name, - attributes, - client: Client::expand1(expand), - } + ProcMacro::CustomDerive { trait_name, attributes, client: Client::expand1(expand) } } pub const fn attr( name: &'static str, expand: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream, ) -> Self { - ProcMacro::Attr { - name, - client: Client::expand2(expand), - } + ProcMacro::Attr { name, client: Client::expand2(expand) } } pub const fn bang( name: &'static str, - expand: fn(crate::TokenStream) -> crate::TokenStream + expand: fn(crate::TokenStream) -> crate::TokenStream, ) -> Self { - ProcMacro::Bang { - name, - client: Client::expand1(expand), - } + ProcMacro::Bang { name, client: Client::expand1(expand) } } } diff --git a/src/libproc_macro/bridge/closure.rs b/src/libproc_macro/bridge/closure.rs index 8d8adfa1caada..5bfe287d33ab7 100644 --- a/src/libproc_macro/bridge/closure.rs +++ b/src/libproc_macro/bridge/closure.rs @@ -18,10 +18,7 @@ impl<'a, A, R, F: FnMut(A) -> R> From<&'a mut F> for Closure<'a, A, R> { unsafe extern "C" fn call R>(env: &mut Env, arg: A) -> R { (*(env as *mut _ as *mut F))(arg) } - Closure { - call: call::, - env: unsafe { &mut *(f as *mut _ as *mut Env) }, - } + Closure { call: call::, env: unsafe { &mut *(f as *mut _ as *mut Env) } } } } diff --git a/src/libproc_macro/bridge/handle.rs b/src/libproc_macro/bridge/handle.rs index 66496ff3f1ad8..bcbb86812470a 100644 --- a/src/libproc_macro/bridge/handle.rs +++ b/src/libproc_macro/bridge/handle.rs @@ -19,10 +19,7 @@ impl OwnedStore { // when `NonZeroU32::new` (aka `Handle::new`) is called in `alloc`. assert_ne!(counter.load(Ordering::SeqCst), 0); - OwnedStore { - counter, - data: BTreeMap::new(), - } + OwnedStore { counter, data: BTreeMap::new() } } } @@ -35,26 +32,20 @@ impl OwnedStore { } pub(super) fn take(&mut self, h: Handle) -> T { - self.data - .remove(&h) - .expect("use-after-free in `proc_macro` handle") + self.data.remove(&h).expect("use-after-free in `proc_macro` handle") } } impl Index for OwnedStore { type Output = T; fn index(&self, h: Handle) -> &T { - self.data - .get(&h) - .expect("use-after-free in `proc_macro` handle") + self.data.get(&h).expect("use-after-free in `proc_macro` handle") } } impl IndexMut for OwnedStore { fn index_mut(&mut self, h: Handle) -> &mut T { - self.data - .get_mut(&h) - .expect("use-after-free in `proc_macro` handle") + self.data.get_mut(&h).expect("use-after-free in `proc_macro` handle") } } @@ -65,10 +56,7 @@ pub(super) struct InternedStore { impl InternedStore { pub(super) fn new(counter: &'static AtomicUsize) -> Self { - InternedStore { - owned: OwnedStore::new(counter), - interner: HashMap::new(), - } + InternedStore { owned: OwnedStore::new(counter), interner: HashMap::new() } } pub(super) fn alloc(&mut self, x: T) -> Handle { diff --git a/src/libproc_macro/bridge/mod.rs b/src/libproc_macro/bridge/mod.rs index c26b59f473c36..a0e7d90f4974e 100644 --- a/src/libproc_macro/bridge/mod.rs +++ b/src/libproc_macro/bridge/mod.rs @@ -8,6 +8,7 @@ #![deny(unsafe_code)] +use crate::{Delimiter, Level, LineColumn, Spacing}; use std::fmt; use std::hash::Hash; use std::marker; @@ -17,7 +18,6 @@ use std::panic; use std::sync::atomic::AtomicUsize; use std::sync::Once; use std::thread; -use crate::{Delimiter, Level, LineColumn, Spacing}; /// Higher-order macro describing the server RPC API, allowing automatic /// generation of type-safe Rust APIs, both client-side and server-side. @@ -270,10 +270,7 @@ struct Marked { impl Mark for Marked { type Unmarked = T; fn mark(unmarked: Self::Unmarked) -> Self { - Marked { - value: unmarked, - _marker: marker::PhantomData, - } + Marked { value: unmarked, _marker: marker::PhantomData } } } impl Unmark for Marked { diff --git a/src/libproc_macro/bridge/server.rs b/src/libproc_macro/bridge/server.rs index f303e3e828834..ca18d4459aa89 100644 --- a/src/libproc_macro/bridge/server.rs +++ b/src/libproc_macro/bridge/server.rs @@ -148,13 +148,7 @@ impl ExecutionStrategy for SameThread { ) -> Buffer { 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() }, client_data) } } @@ -183,10 +177,7 @@ impl ExecutionStrategy for CrossThread1 { }; run_client( - Bridge { - cached_buffer: input, - dispatch: (&mut dispatch).into(), - }, + Bridge { cached_buffer: input, dispatch: (&mut dispatch).into() }, client_data, ) }); @@ -233,10 +224,7 @@ impl ExecutionStrategy for CrossThread2 { }; let r = run_client( - Bridge { - cached_buffer: input, - dispatch: (&mut dispatch).into(), - }, + Bridge { cached_buffer: input, dispatch: (&mut dispatch).into() }, client_data, ); @@ -276,10 +264,8 @@ fn run_server< run_client: extern "C" fn(Bridge<'_>, D) -> Buffer, client_data: D, ) -> Result { - let mut dispatcher = Dispatcher { - handle_store: HandleStore::new(handle_counters), - server: MarkedTypes(server), - }; + let mut dispatcher = + Dispatcher { handle_store: HandleStore::new(handle_counters), server: MarkedTypes(server) }; let mut b = Buffer::new(); input.encode(&mut b, &mut dispatcher.handle_store); @@ -296,11 +282,7 @@ impl client::Client crate::TokenStream> { server: S, input: S::TokenStream, ) -> Result { - let client::Client { - get_handle_counters, - run, - f, - } = *self; + let client::Client { get_handle_counters, run, f } = *self; run_server( strategy, get_handle_counters(), @@ -321,11 +303,7 @@ impl client::Client crate::TokenSt input: S::TokenStream, input2: S::TokenStream, ) -> Result { - let client::Client { - get_handle_counters, - run, - f, - } = *self; + let client::Client { get_handle_counters, run, f } = *self; run_server( strategy, get_handle_counters(), diff --git a/src/libproc_macro/diagnostic.rs b/src/libproc_macro/diagnostic.rs index 65eebb5ec3737..fdf252e53387e 100644 --- a/src/libproc_macro/diagnostic.rs +++ b/src/libproc_macro/diagnostic.rs @@ -51,7 +51,7 @@ pub struct Diagnostic { level: Level, message: String, spans: Vec, - children: Vec + children: Vec, } macro_rules! diagnostic_child_methods { @@ -96,25 +96,22 @@ impl Diagnostic { /// Creates a new diagnostic with the given `level` and `message`. #[unstable(feature = "proc_macro_diagnostic", issue = "54140")] pub fn new>(level: Level, message: T) -> Diagnostic { - Diagnostic { - level: level, - message: message.into(), - spans: vec![], - children: vec![] - } + Diagnostic { level: level, message: message.into(), spans: vec![], children: vec![] } } /// Creates a new diagnostic with the given `level` and `message` pointing to /// the given set of `spans`. #[unstable(feature = "proc_macro_diagnostic", issue = "54140")] pub fn spanned(spans: S, level: Level, message: T) -> Diagnostic - where S: MultiSpan, T: Into + where + S: MultiSpan, + T: Into, { Diagnostic { level: level, message: message.into(), spans: spans.into_spans(), - children: vec![] + children: vec![], } } diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 87cd8fcb14385..0b74a104da44b 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -11,12 +11,13 @@ #![stable(feature = "proc_macro_lib", since = "1.15.0")] #![deny(missing_docs)] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", - html_playground_url = "https://play.rust-lang.org/", - issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", - test(no_crate_inject, attr(deny(warnings))), - test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] - +#![doc( + html_root_url = "https://doc.rust-lang.org/nightly/", + html_playground_url = "https://play.rust-lang.org/", + issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", + test(no_crate_inject, attr(deny(warnings))), + test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))) +)] #![feature(nll)] #![feature(staged_api)] #![feature(allow_internal_unstable)] @@ -27,8 +28,7 @@ #![feature(optin_builtin_traits)] #![feature(rustc_attrs)] #![feature(specialization)] - -#![recursion_limit="256"] +#![recursion_limit = "256"] #[unstable(feature = "proc_macro_internals", issue = "27812")] #[doc(hidden)] @@ -39,10 +39,10 @@ mod diagnostic; #[unstable(feature = "proc_macro_diagnostic", issue = "54140")] pub use diagnostic::{Diagnostic, Level, MultiSpan}; -use std::{fmt, iter, mem}; use std::ops::{Bound, RangeBounds}; use std::path::PathBuf; use std::str::FromStr; +use std::{fmt, iter, mem}; /// The main type provided by this crate, representing an abstract stream of /// tokens, or, more specifically, a sequence of token trees. @@ -134,20 +134,20 @@ impl fmt::Debug for TokenStream { pub use quote::{quote, quote_span}; /// Creates a token stream containing a single token tree. - #[stable(feature = "proc_macro_lib2", since = "1.29.0")] +#[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl From for TokenStream { fn from(tree: TokenTree) -> TokenStream { TokenStream(bridge::client::TokenStream::from_token_tree(match tree { TokenTree::Group(tt) => bridge::TokenTree::Group(tt.0), TokenTree::Punct(tt) => bridge::TokenTree::Punct(tt.0), TokenTree::Ident(tt) => bridge::TokenTree::Ident(tt.0), - TokenTree::Literal(tt) => bridge::TokenTree::Literal(tt.0) + TokenTree::Literal(tt) => bridge::TokenTree::Literal(tt.0), })) } } /// Collects a number of token trees into a single stream. - #[stable(feature = "proc_macro_lib2", since = "1.29.0")] +#[stable(feature = "proc_macro_lib2", since = "1.29.0")] impl iter::FromIterator for TokenStream { fn from_iter>(trees: I) -> Self { trees.into_iter().map(TokenStream::from).collect() @@ -183,7 +183,7 @@ impl Extend for TokenStream { /// Public implementation details for the `TokenStream` type, such as iterators. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub mod token_stream { - use crate::{bridge, Group, Ident, Literal, Punct, TokenTree, TokenStream}; + use crate::{bridge, Group, Ident, Literal, Punct, TokenStream, TokenTree}; /// An iterator over `TokenStream`'s `TokenTree`s. /// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups, @@ -226,7 +226,9 @@ pub mod token_stream { #[unstable(feature = "proc_macro_quote", issue = "54722")] #[allow_internal_unstable(proc_macro_def_site)] #[rustc_builtin_macro] -pub macro quote ($($t:tt)*) { /* compiler built-in */ } +pub macro quote($($t:tt)*) { + /* compiler built-in */ +} #[unstable(feature = "proc_macro_internals", issue = "27812")] #[doc(hidden)] @@ -375,7 +377,7 @@ pub struct LineColumn { /// The 0-indexed column (in UTF-8 characters) in the source file on which /// the span starts or ends (inclusive). #[unstable(feature = "proc_macro_span", issue = "54725")] - pub column: usize + pub column: usize, } #[unstable(feature = "proc_macro_span", issue = "54725")] @@ -415,7 +417,6 @@ impl SourceFile { } } - #[unstable(feature = "proc_macro_span", issue = "54725")] impl fmt::Debug for SourceFile { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -442,28 +443,16 @@ impl Eq for SourceFile {} pub enum TokenTree { /// A token stream surrounded by bracket delimiters. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] - Group( - #[stable(feature = "proc_macro_lib2", since = "1.29.0")] - Group - ), + Group(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Group), /// An identifier. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] - Ident( - #[stable(feature = "proc_macro_lib2", since = "1.29.0")] - Ident - ), + Ident(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Ident), /// A single punctuation character (`+`, `,`, `$`, etc.). #[stable(feature = "proc_macro_lib2", since = "1.29.0")] - Punct( - #[stable(feature = "proc_macro_lib2", since = "1.29.0")] - Punct - ), + Punct(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Punct), /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] - Literal( - #[stable(feature = "proc_macro_lib2", since = "1.29.0")] - Literal - ), + Literal(#[stable(feature = "proc_macro_lib2", since = "1.29.0")] Literal), } #[stable(feature = "proc_macro_lib2", since = "1.29.0")] @@ -1092,10 +1081,7 @@ impl Literal { } } - self.0.subspan( - cloned_bound(range.start_bound()), - cloned_bound(range.end_bound()), - ).map(Span) + self.0.subspan(cloned_bound(range.start_bound()), cloned_bound(range.end_bound())).map(Span) } } diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs index 775f84535fbf2..04cd2efe00093 100644 --- a/src/libprofiler_builtins/build.rs +++ b/src/libprofiler_builtins/build.rs @@ -9,21 +9,23 @@ fn main() { let target = env::var("TARGET").expect("TARGET was not set"); let cfg = &mut cc::Build::new(); - let mut profile_sources = vec!["GCDAProfiling.c", - "InstrProfiling.c", - "InstrProfilingBuffer.c", - "InstrProfilingFile.c", - "InstrProfilingMerge.c", - "InstrProfilingMergeFile.c", - "InstrProfilingNameVar.c", - "InstrProfilingPlatformDarwin.c", - "InstrProfilingPlatformLinux.c", - "InstrProfilingPlatformOther.c", - "InstrProfilingPlatformWindows.c", - "InstrProfilingRuntime.cc", - "InstrProfilingUtil.c", - "InstrProfilingValue.c", - "InstrProfilingWriter.c"]; + let mut profile_sources = vec![ + "GCDAProfiling.c", + "InstrProfiling.c", + "InstrProfilingBuffer.c", + "InstrProfilingFile.c", + "InstrProfilingMerge.c", + "InstrProfilingMergeFile.c", + "InstrProfilingNameVar.c", + "InstrProfilingPlatformDarwin.c", + "InstrProfilingPlatformLinux.c", + "InstrProfilingPlatformOther.c", + "InstrProfilingPlatformWindows.c", + "InstrProfilingRuntime.cc", + "InstrProfilingUtil.c", + "InstrProfilingValue.c", + "InstrProfilingWriter.c", + ]; if target.contains("msvc") { // Don't pull in extra libraries on MSVC @@ -56,9 +58,10 @@ fn main() { // This should be a pretty good heuristic for when to set // COMPILER_RT_HAS_ATOMICS - if env::var_os("CARGO_CFG_TARGET_HAS_ATOMIC").map(|features| { - features.to_string_lossy().to_lowercase().contains("cas") - }).unwrap_or(false) { + if env::var_os("CARGO_CFG_TARGET_HAS_ATOMIC") + .map(|features| features.to_string_lossy().to_lowercase().contains("cas")) + .unwrap_or(false) + { cfg.define("COMPILER_RT_HAS_ATOMICS", Some("1")); } diff --git a/src/libprofiler_builtins/lib.rs b/src/libprofiler_builtins/lib.rs index e503795c519d4..bb1f2785deb1b 100644 --- a/src/libprofiler_builtins/lib.rs +++ b/src/libprofiler_builtins/lib.rs @@ -1,9 +1,11 @@ #![no_std] #![feature(profiler_runtime)] #![profiler_runtime] -#![unstable(feature = "profiler_runtime_lib", - reason = "internal implementation detail of rustc right now", - issue = "none")] +#![unstable( + feature = "profiler_runtime_lib", + reason = "internal implementation detail of rustc right now", + issue = "none" +)] #![allow(unused_features)] #![feature(nll)] #![feature(staged_api)] diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index 3695607ff3c60..3d5bd313f8838 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -1,10 +1,10 @@ -use arena::{TypedArena, DroplessArena}; +use arena::{DroplessArena, TypedArena}; +use smallvec::SmallVec; +use std::cell::RefCell; +use std::marker::PhantomData; use std::mem; use std::ptr; use std::slice; -use std::cell::RefCell; -use std::marker::PhantomData; -use smallvec::SmallVec; /// This declares a list of types which can be allocated by `Arena`. /// @@ -226,17 +226,14 @@ impl<'tcx> Arena<'tcx> { #[inline] pub fn alloc_slice(&self, value: &[T]) -> &mut [T] { if value.len() == 0 { - return &mut [] + return &mut []; } self.dropless.alloc_slice(value) } - pub fn alloc_from_iter< - T: ArenaAllocatable, - I: IntoIterator - >( + pub fn alloc_from_iter>( &'a self, - iter: I + iter: I, ) -> &'a mut [T] { if !mem::needs_drop::() { return self.dropless.alloc_from_iter(iter); @@ -260,9 +257,7 @@ unsafe fn drop_for_type(to_drop: *mut u8) { impl Drop for DropType { fn drop(&mut self) { - unsafe { - (self.drop_fn)(self.obj) - } + unsafe { (self.drop_fn)(self.obj) } } } @@ -283,19 +278,16 @@ struct DropArena { impl DropArena { #[inline] unsafe fn alloc(&self, object: T) -> &mut T { - let mem = self.arena.alloc_raw( - mem::size_of::(), - mem::align_of::() - ) as *mut _ as *mut T; + let mem = + self.arena.alloc_raw(mem::size_of::(), mem::align_of::()) as *mut _ as *mut T; // Write into uninitialized memory. ptr::write(mem, object); let result = &mut *mem; // Record the destructor after doing the allocation as that may panic // and would cause `object`'s destuctor to run twice if it was recorded before - self.destructors.borrow_mut().push(DropType { - drop_fn: drop_for_type::, - obj: result as *mut T as *mut u8, - }); + self.destructors + .borrow_mut() + .push(DropType { drop_fn: drop_for_type::, obj: result as *mut T as *mut u8 }); result } @@ -307,10 +299,10 @@ impl DropArena { } let len = vec.len(); - let start_ptr = self.arena.alloc_raw( - len.checked_mul(mem::size_of::()).unwrap(), - mem::align_of::() - ) as *mut _ as *mut T; + let start_ptr = self + .arena + .alloc_raw(len.checked_mul(mem::size_of::()).unwrap(), mem::align_of::()) + as *mut _ as *mut T; let mut destructors = self.destructors.borrow_mut(); // Reserve space for the destructors so we can't panic while adding them diff --git a/src/librustc/benches/lib.rs b/src/librustc/benches/lib.rs index 6b624028896ac..ffb12f11c5136 100644 --- a/src/librustc/benches/lib.rs +++ b/src/librustc/benches/lib.rs @@ -8,7 +8,7 @@ use test::Bencher; // Static/dynamic method dispatch struct Struct { - field: isize + field: isize, } trait Trait { @@ -25,17 +25,13 @@ impl Trait for Struct { fn trait_vtable_method_call(b: &mut Bencher) { let s = Struct { field: 10 }; let t = &s as &dyn Trait; - b.iter(|| { - t.method() - }); + b.iter(|| t.method()); } #[bench] fn trait_static_method_call(b: &mut Bencher) { let s = Struct { field: 10 }; - b.iter(|| { - s.method() - }); + b.iter(|| s.method()); } // Overhead of various match forms @@ -43,21 +39,17 @@ fn trait_static_method_call(b: &mut Bencher) { #[bench] fn option_some(b: &mut Bencher) { let x = Some(10); - b.iter(|| { - match x { - Some(y) => y, - None => 11 - } + b.iter(|| match x { + Some(y) => y, + None => 11, }); } #[bench] fn vec_pattern(b: &mut Bencher) { - let x = [1,2,3,4,5,6]; - b.iter(|| { - match x { - [1,2,3,..] => 10, - _ => 11, - } + let x = [1, 2, 3, 4, 5, 6]; + b.iter(|| match x { + [1, 2, 3, ..] => 10, + _ => 11, }); } diff --git a/src/librustc/dep_graph/debug.rs b/src/librustc/dep_graph/debug.rs index f18ee3dced72d..d44c54593a627 100644 --- a/src/librustc/dep_graph/debug.rs +++ b/src/librustc/dep_graph/debug.rs @@ -12,14 +12,12 @@ use std::error::Error; /// `z`. #[derive(Debug)] pub struct DepNodeFilter { - text: String + text: String, } impl DepNodeFilter { pub fn new(text: &str) -> Self { - DepNodeFilter { - text: text.trim().to_string() - } + DepNodeFilter { text: text.trim().to_string() } } /// Returns `true` if all nodes always pass the filter. @@ -30,9 +28,7 @@ impl DepNodeFilter { /// Tests whether `node` meets the filter, returning true if so. pub fn test(&self, node: &DepNode) -> bool { let debug_str = format!("{:?}", node); - self.text.split('&') - .map(|s| s.trim()) - .all(|f| debug_str.contains(f)) + self.text.split('&').map(|s| s.trim()).all(|f| debug_str.contains(f)) } } @@ -56,10 +52,7 @@ impl EdgeFilter { } } - pub fn test(&self, - source: &DepNode, - target: &DepNode) - -> bool { + pub fn test(&self, source: &DepNode, target: &DepNode) -> bool { self.source.test(source) && self.target.test(target) } } diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 17ab0c187a2fc..57f72ba050789 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -49,31 +49,31 @@ //! user of the `DepNode` API of having to know how to compute the expected //! fingerprint for a given set of node parameters. -use crate::mir; -use crate::mir::interpret::GlobalId; use crate::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; use crate::hir::map::DefPathHash; use crate::hir::HirId; +use crate::mir; +use crate::mir::interpret::GlobalId; use crate::ich::{Fingerprint, StableHashingContext}; -use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; -use std::fmt; -use std::hash::Hash; -use syntax_pos::symbol::Symbol; use crate::traits; use crate::traits::query::{ - CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, - CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal, CanonicalPredicateGoal, - CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal, + CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, + CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal, + CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, }; -use crate::ty::{self, TyCtxt, ParamEnvAnd, Ty}; use crate::ty::subst::SubstsRef; +use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use std::fmt; +use std::hash::Hash; +use syntax_pos::symbol::Symbol; // erase!() just makes tokens go away. It's used to specify which macro argument // is repeated (i.e., which sub-expression of the macro we are in) but don't need // to actually use any of the arguments. macro_rules! erase { - ($x:tt) => ({}) + ($x:tt) => {{}}; } macro_rules! replace { @@ -81,13 +81,21 @@ macro_rules! replace { } macro_rules! is_anon_attr { - (anon) => (true); - ($attr:ident) => (false); + (anon) => { + true + }; + ($attr:ident) => { + false + }; } macro_rules! is_eval_always_attr { - (eval_always) => (true); - ($attr:ident) => (false); + (eval_always) => { + true + }; + ($attr:ident) => { + false + }; } macro_rules! contains_anon_attr { @@ -382,7 +390,6 @@ impl fmt::Debug for DepNode { } } - impl DefPathHash { pub fn to_dep_node(self, kind: DepKind) -> DepNode { DepNode::from_def_path_hash(kind, self) @@ -517,10 +524,7 @@ impl<'tcx> DepNodeParams<'tcx> for CrateNum { const CAN_RECONSTRUCT_QUERY_KEY: bool = true; fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint { - let def_id = DefId { - krate: *self, - index: CRATE_DEF_INDEX, - }; + let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX }; tcx.def_path_hash(def_id).0 } @@ -547,9 +551,7 @@ impl<'tcx> DepNodeParams<'tcx> for (DefId, DefId) { fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { let (def_id_0, def_id_1) = *self; - format!("({}, {})", - tcx.def_path_debug_str(def_id_0), - tcx.def_path_debug_str(def_id_1)) + format!("({}, {})", tcx.def_path_debug_str(def_id_0), tcx.def_path_debug_str(def_id_1)) } } @@ -560,10 +562,7 @@ impl<'tcx> DepNodeParams<'tcx> for HirId { // method but it's faster to combine the hashes than to instantiate a full // hashing context and stable-hashing state. fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint { - let HirId { - owner, - local_id, - } = *self; + let HirId { owner, local_id } = *self; let def_path_hash = tcx.def_path_hash(DefId::local(owner)); let local_id = Fingerprint::from_smaller_hash(local_id.as_u32().into()); @@ -577,10 +576,21 @@ impl<'tcx> DepNodeParams<'tcx> for HirId { /// some independent path or string that persists between runs without /// the need to be mapped or unmapped. (This ensures we can serialize /// them even in the absence of a tcx.) -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, - RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + RustcEncodable, + RustcDecodable, + HashStable +)] pub struct WorkProductId { - hash: Fingerprint + hash: Fingerprint, } impl WorkProductId { @@ -588,14 +598,10 @@ impl WorkProductId { let mut hasher = StableHasher::new(); cgu_name.len().hash(&mut hasher); cgu_name.hash(&mut hasher); - WorkProductId { - hash: hasher.finish() - } + WorkProductId { hash: hasher.finish() } } pub fn from_fingerprint(fingerprint: Fingerprint) -> WorkProductId { - WorkProductId { - hash: fingerprint - } + WorkProductId { hash: fingerprint } } } diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index d952bf7ab9e25..0d03c834e0f7b 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -1,26 +1,26 @@ +use crate::ty::{self, TyCtxt}; use errors::Diagnostic; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use parking_lot::{Condvar, Mutex}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::sharded::{self, Sharded}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering}; use rustc_index::vec::{Idx, IndexVec}; use smallvec::SmallVec; -use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, AtomicU64, Ordering}; -use rustc_data_structures::sharded::{self, Sharded}; -use std::sync::atomic::Ordering::SeqCst; +use std::collections::hash_map::Entry; use std::env; use std::hash::Hash; -use std::collections::hash_map::Entry; use std::mem; -use crate::ty::{self, TyCtxt}; -use parking_lot::{Mutex, Condvar}; +use std::sync::atomic::Ordering::SeqCst; -use crate::ich::{StableHashingContext, StableHashingContextProvider, Fingerprint}; +use crate::ich::{Fingerprint, StableHashingContext, StableHashingContextProvider}; use super::debug::EdgeFilter; -use super::dep_node::{DepNode, DepKind, WorkProductId}; +use super::dep_node::{DepKind, DepNode, WorkProductId}; +use super::prev::PreviousDepGraph; use super::query::DepGraphQuery; use super::safe::DepGraphSafe; use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex}; -use super::prev::PreviousDepGraph; #[derive(Clone)] pub struct DepGraph { @@ -38,7 +38,7 @@ impl DepNodeIndex { #[derive(PartialEq)] pub enum DepNodeColor { Red, - Green(DepNodeIndex) + Green(DepNodeIndex), } impl DepNodeColor { @@ -89,8 +89,10 @@ where } impl DepGraph { - pub fn new(prev_graph: PreviousDepGraph, - prev_work_products: FxHashMap) -> DepGraph { + pub fn new( + prev_graph: PreviousDepGraph, + prev_work_products: FxHashMap, + ) -> DepGraph { let prev_graph_node_count = prev_graph.node_count(); DepGraph { @@ -107,9 +109,7 @@ impl DepGraph { } pub fn new_disabled() -> DepGraph { - DepGraph { - data: None, - } + DepGraph { data: None } } /// Returns `true` if we are actually building the full dep-graph, and `false` otherwise. @@ -132,8 +132,7 @@ impl DepGraph { DepGraphQuery::new(&nodes[..], &edges[..]) } - pub fn assert_ignored(&self) - { + pub fn assert_ignored(&self) { if let Some(..) = self.data { ty::tls::with_context_opt(|icx| { let icx = if let Some(icx) = icx { icx } else { return }; @@ -142,18 +141,14 @@ impl DepGraph { } } - pub fn with_ignore(&self, op: OP) -> R - where OP: FnOnce() -> R + pub fn with_ignore(&self, op: OP) -> R + where + OP: FnOnce() -> R, { ty::tls::with_context(|icx| { - let icx = ty::tls::ImplicitCtxt { - task_deps: None, - ..icx.clone() - }; + let icx = ty::tls::ImplicitCtxt { task_deps: None, ..icx.clone() }; - ty::tls::enter_context(&icx, |_| { - op() - }) + ty::tls::enter_context(&icx, |_| op()) }) } @@ -195,38 +190,45 @@ impl DepGraph { where C: DepGraphSafe + StableHashingContextProvider<'a>, { - self.with_task_impl(key, cx, arg, false, task, - |_key| Some(TaskDeps { - #[cfg(debug_assertions)] - node: Some(_key), - reads: SmallVec::new(), - read_set: Default::default(), - }), - |data, key, fingerprint, task| { - data.complete_task(key, task.unwrap(), fingerprint) + self.with_task_impl( + key, + cx, + arg, + false, + task, + |_key| { + Some(TaskDeps { + #[cfg(debug_assertions)] + node: Some(_key), + reads: SmallVec::new(), + read_set: Default::default(), + }) }, - hash_result) + |data, key, fingerprint, task| data.complete_task(key, task.unwrap(), fingerprint), + hash_result, + ) } /// Creates a new dep-graph input with value `input` - pub fn input_task<'a, C, R>(&self, - key: DepNode, - cx: C, - input: R) - -> (R, DepNodeIndex) - where C: DepGraphSafe + StableHashingContextProvider<'a>, - R: for<'b> HashStable>, + pub fn input_task<'a, C, R>(&self, key: DepNode, cx: C, input: R) -> (R, DepNodeIndex) + where + C: DepGraphSafe + StableHashingContextProvider<'a>, + R: for<'b> HashStable>, { fn identity_fn(_: C, arg: A) -> A { arg } - self.with_task_impl(key, cx, input, true, identity_fn, + self.with_task_impl( + key, + cx, + input, + true, + identity_fn, |_| None, - |data, key, fingerprint, _| { - data.alloc_node(key, SmallVec::new(), fingerprint) - }, - hash_result::) + |data, key, fingerprint, _| data.alloc_node(key, SmallVec::new(), fingerprint), + hash_result::, + ) } fn with_task_impl<'a, C, A, R>( @@ -237,10 +239,12 @@ impl DepGraph { no_tcx: bool, task: fn(C, A) -> R, create_task: fn(DepNode) -> Option, - finish_task_and_alloc_depnode: fn(&CurrentDepGraph, - DepNode, - Fingerprint, - Option) -> DepNodeIndex, + finish_task_and_alloc_depnode: fn( + &CurrentDepGraph, + DepNode, + Fingerprint, + Option, + ) -> DepNodeIndex, hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option, ) -> (R, DepNodeIndex) where @@ -260,14 +264,10 @@ impl DepGraph { task(cx, arg) } else { ty::tls::with_context(|icx| { - let icx = ty::tls::ImplicitCtxt { - task_deps: task_deps.as_ref(), - ..icx.clone() - }; - - ty::tls::enter_context(&icx, |_| { - task(cx, arg) - }) + let icx = + ty::tls::ImplicitCtxt { task_deps: task_deps.as_ref(), ..icx.clone() }; + + ty::tls::enter_context(&icx, |_| task(cx, arg)) }) }; @@ -306,9 +306,12 @@ impl DepGraph { DepNodeColor::Red }; - debug_assert!(data.colors.get(prev_index).is_none(), - "DepGraph::with_task() - Duplicate DepNodeColor \ - insertion for {:?}", key); + debug_assert!( + data.colors.get(prev_index).is_none(), + "DepGraph::with_task() - Duplicate DepNodeColor \ + insertion for {:?}", + key + ); data.colors.insert(prev_index, color); } else { @@ -325,8 +328,9 @@ impl DepGraph { /// Executes something within an "anonymous" task, that is, a task the /// `DepNode` of which is determined by the list of inputs it read from. - pub fn with_anon_task(&self, dep_kind: DepKind, op: OP) -> (R, DepNodeIndex) - where OP: FnOnce() -> R + pub fn with_anon_task(&self, dep_kind: DepKind, op: OP) -> (R, DepNodeIndex) + where + OP: FnOnce() -> R, { if let Some(ref data) = self.data { let (result, task_deps) = ty::tls::with_context(|icx| { @@ -338,20 +342,14 @@ impl DepGraph { }); let r = { - let icx = ty::tls::ImplicitCtxt { - task_deps: Some(&task_deps), - ..icx.clone() - }; - - ty::tls::enter_context(&icx, |_| { - op() - }) + let icx = ty::tls::ImplicitCtxt { task_deps: Some(&task_deps), ..icx.clone() }; + + ty::tls::enter_context(&icx, |_| op()) }; (r, task_deps.into_inner()) }); - let dep_node_index = data.current - .complete_anon_task(dep_kind, task_deps); + let dep_node_index = data.current.complete_anon_task(dep_kind, task_deps); (result, dep_node_index) } else { (op(), DepNodeIndex::INVALID) @@ -371,12 +369,16 @@ impl DepGraph { where C: DepGraphSafe + StableHashingContextProvider<'a>, { - self.with_task_impl(key, cx, arg, false, task, + self.with_task_impl( + key, + cx, + arg, + false, + task, |_| None, - |data, key, fingerprint, _| { - data.alloc_node(key, smallvec![], fingerprint) - }, - hash_result) + |data, key, fingerprint, _| data.alloc_node(key, smallvec![], fingerprint), + hash_result, + ) } #[inline] @@ -444,11 +446,7 @@ impl DepGraph { /// Checks whether a previous work product exists for `v` and, if /// so, return the path that leads to it. Used to skip doing work. pub fn previous_work_product(&self, v: &WorkProductId) -> Option { - self.data - .as_ref() - .and_then(|data| { - data.previous_work_products.get(v).cloned() - }) + self.data.as_ref().and_then(|data| data.previous_work_products.get(v).cloned()) } /// Access the map of work-products created during the cached run. Only @@ -458,35 +456,31 @@ impl DepGraph { } #[inline(always)] - pub fn register_dep_node_debug_str(&self, - dep_node: DepNode, - debug_str_gen: F) - where F: FnOnce() -> String + pub fn register_dep_node_debug_str(&self, dep_node: DepNode, debug_str_gen: F) + where + F: FnOnce() -> String, { let dep_node_debug = &self.data.as_ref().unwrap().dep_node_debug; if dep_node_debug.borrow().contains_key(&dep_node) { - return + return; } let debug_str = debug_str_gen(); dep_node_debug.borrow_mut().insert(dep_node, debug_str); } pub(super) fn dep_node_debug_str(&self, dep_node: DepNode) -> Option { - self.data - .as_ref()? - .dep_node_debug - .borrow() - .get(&dep_node) - .cloned() + self.data.as_ref()?.dep_node_debug.borrow().get(&dep_node).cloned() } pub fn edge_deduplication_data(&self) -> Option<(u64, u64)> { if cfg!(debug_assertions) { let current_dep_graph = &self.data.as_ref().unwrap().current; - Some((current_dep_graph.total_read_count.load(SeqCst), - current_dep_graph.total_duplicate_read_count.load(SeqCst))) + Some(( + current_dep_graph.total_read_count.load(SeqCst), + current_dep_graph.total_duplicate_read_count.load(SeqCst), + )) } else { None } @@ -497,8 +491,7 @@ impl DepGraph { let fingerprints: IndexVec = data.iter().map(|d| d.fingerprint).collect(); - let nodes: IndexVec = - data.iter().map(|d| d.node).collect(); + let nodes: IndexVec = data.iter().map(|d| d.node).collect(); let total_edge_count: usize = data.iter().map(|d| d.edges.len()).sum(); @@ -518,22 +511,17 @@ impl DepGraph { debug_assert!(edge_list_data.len() <= ::std::u32::MAX as usize); debug_assert_eq!(edge_list_data.len(), total_edge_count); - SerializedDepGraph { - nodes, - fingerprints, - edge_list_indices, - edge_list_data, - } + SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data } } pub fn node_color(&self, dep_node: &DepNode) -> Option { if let Some(ref data) = self.data { if let Some(prev_index) = data.previous.node_to_index_opt(dep_node) { - return data.colors.get(prev_index) + return data.colors.get(prev_index); } else { // This is a node that did not exist in the previous compilation // session, so we consider it to be red. - return Some(DepNodeColor::Red) + return Some(DepNodeColor::Red); } } @@ -577,14 +565,8 @@ impl DepGraph { // in the previous compilation session too, so we can try to // mark it as green by recursively marking all of its // dependencies green. - self.try_mark_previous_green( - tcx, - data, - prev_index, - &dep_node - ).map(|dep_node_index| { - (prev_index, dep_node_index) - }) + self.try_mark_previous_green(tcx, data, prev_index, &dep_node) + .map(|dep_node_index| (prev_index, dep_node_index)) } } } @@ -601,11 +583,14 @@ impl DepGraph { #[cfg(not(parallel_compiler))] { - debug_assert!(!data.current - .node_to_node_index - .get_shard_by_value(dep_node) - .lock() - .contains_key(dep_node)); + debug_assert!( + !data + .current + .node_to_node_index + .get_shard_by_value(dep_node) + .lock() + .contains_key(dep_node) + ); debug_assert!(data.colors.get(prev_dep_node_index).is_none()); } @@ -626,10 +611,12 @@ impl DepGraph { // This dependency has been marked as green before, we are // still fine and can continue with checking the other // dependencies. - debug!("try_mark_previous_green({:?}) --- found dependency {:?} to \ + debug!( + "try_mark_previous_green({:?}) --- found dependency {:?} to \ be immediately green", - dep_node, - data.previous.index_to_node(dep_dep_node_index)); + dep_node, + data.previous.index_to_node(dep_dep_node_index) + ); current_deps.push(node_index); } Some(DepNodeColor::Red) => { @@ -637,11 +624,13 @@ impl DepGraph { // compared to the previous compilation session. We cannot // mark the DepNode as green and also don't need to bother // with checking any of the other dependencies. - debug!("try_mark_previous_green({:?}) - END - dependency {:?} was \ + debug!( + "try_mark_previous_green({:?}) - END - dependency {:?} was \ immediately red", - dep_node, - data.previous.index_to_node(dep_dep_node_index)); - return None + dep_node, + data.previous.index_to_node(dep_dep_node_index) + ); + return None; } None => { let dep_dep_node = &data.previous.index_to_node(dep_dep_node_index); @@ -649,37 +638,42 @@ impl DepGraph { // We don't know the state of this dependency. If it isn't // an eval_always node, let's try to mark it green recursively. if !dep_dep_node.kind.is_eval_always() { - debug!("try_mark_previous_green({:?}) --- state of dependency {:?} \ - is unknown, trying to mark it green", dep_node, - dep_dep_node); + debug!( + "try_mark_previous_green({:?}) --- state of dependency {:?} \ + is unknown, trying to mark it green", + dep_node, dep_dep_node + ); let node_index = self.try_mark_previous_green( tcx, data, dep_dep_node_index, - dep_dep_node + dep_dep_node, ); if let Some(node_index) = node_index { - debug!("try_mark_previous_green({:?}) --- managed to MARK \ - dependency {:?} as green", dep_node, dep_dep_node); + debug!( + "try_mark_previous_green({:?}) --- managed to MARK \ + dependency {:?} as green", + dep_node, dep_dep_node + ); current_deps.push(node_index); continue; } } else { match dep_dep_node.kind { - DepKind::Hir | - DepKind::HirBody | - DepKind::CrateMetadata => { + DepKind::Hir | DepKind::HirBody | DepKind::CrateMetadata => { if dep_dep_node.extract_def_id(tcx).is_none() { // If the node does not exist anymore, we // just fail to mark green. - return None + return None; } else { // If the node does exist, it should have // been pre-allocated. - bug!("DepNode {:?} should have been \ + bug!( + "DepNode {:?} should have been \ pre-allocated but wasn't.", - dep_dep_node) + dep_dep_node + ) } } _ => { @@ -690,29 +684,37 @@ impl DepGraph { } // We failed to mark it green, so we try to force the query. - debug!("try_mark_previous_green({:?}) --- trying to force \ - dependency {:?}", dep_node, dep_dep_node); + debug!( + "try_mark_previous_green({:?}) --- trying to force \ + dependency {:?}", + dep_node, dep_dep_node + ); if crate::ty::query::force_from_dep_node(tcx, dep_dep_node) { let dep_dep_node_color = data.colors.get(dep_dep_node_index); match dep_dep_node_color { Some(DepNodeColor::Green(node_index)) => { - debug!("try_mark_previous_green({:?}) --- managed to \ + debug!( + "try_mark_previous_green({:?}) --- managed to \ FORCE dependency {:?} to green", - dep_node, dep_dep_node); + dep_node, dep_dep_node + ); current_deps.push(node_index); } Some(DepNodeColor::Red) => { - debug!("try_mark_previous_green({:?}) - END - \ + debug!( + "try_mark_previous_green({:?}) - END - \ dependency {:?} was red after forcing", - dep_node, - dep_dep_node); - return None + dep_node, dep_dep_node + ); + return None; } None => { if !tcx.sess.has_errors_or_delayed_span_bugs() { - bug!("try_mark_previous_green() - Forcing the DepNode \ - should have set its color") + bug!( + "try_mark_previous_green() - Forcing the DepNode \ + should have set its color" + ) } else { // If the query we just forced has resulted in // some kind of compilation error, we cannot rely on @@ -724,19 +726,23 @@ impl DepGraph { // invalid state will not be persisted to the // incremental compilation cache because of // compilation errors being present. - debug!("try_mark_previous_green({:?}) - END - \ + debug!( + "try_mark_previous_green({:?}) - END - \ dependency {:?} resulted in compilation error", - dep_node, - dep_dep_node); - return None + dep_node, dep_dep_node + ); + return None; } } } } else { // The DepNode could not be forced. - debug!("try_mark_previous_green({:?}) - END - dependency {:?} \ - could not be forced", dep_node, dep_dep_node); - return None + debug!( + "try_mark_previous_green({:?}) - END - dependency {:?} \ + could not be forced", + dep_node, dep_dep_node + ); + return None; } } } @@ -762,22 +768,18 @@ impl DepGraph { // FIXME: Store the fact that a node has diagnostics in a bit in the dep graph somewhere // Maybe store a list on disk and encode this fact in the DepNodeState - let diagnostics = tcx.queries.on_disk_cache - .load_diagnostics(tcx, prev_dep_node_index); + let diagnostics = tcx.queries.on_disk_cache.load_diagnostics(tcx, prev_dep_node_index); #[cfg(not(parallel_compiler))] - debug_assert!(data.colors.get(prev_dep_node_index).is_none(), - "DepGraph::try_mark_previous_green() - Duplicate DepNodeColor \ - insertion for {:?}", dep_node); + debug_assert!( + data.colors.get(prev_dep_node_index).is_none(), + "DepGraph::try_mark_previous_green() - Duplicate DepNodeColor \ + insertion for {:?}", + dep_node + ); if unlikely!(diagnostics.len() > 0) { - self.emit_diagnostics( - tcx, - data, - dep_node_index, - prev_dep_node_index, - diagnostics - ); + self.emit_diagnostics(tcx, data, dep_node_index, prev_dep_node_index, diagnostics); } // ... and finally storing a "Green" entry in the color map. @@ -814,8 +816,7 @@ impl DepGraph { mem::drop(emitting); // Promote the previous diagnostics to the current session. - tcx.queries.on_disk_cache - .store_diagnostics(dep_node_index, diagnostics.clone().into()); + tcx.queries.on_disk_cache.store_diagnostics(dep_node_index, diagnostics.clone().into()); let handle = tcx.sess.diagnostic(); @@ -836,8 +837,8 @@ impl DepGraph { loop { data.emitting_diagnostics_cond_var.wait(&mut emitting); - if data.colors - .get(prev_dep_node_index) == Some(DepNodeColor::Green(dep_node_index)) { + if data.colors.get(prev_dep_node_index) == Some(DepNodeColor::Green(dep_node_index)) + { break; } } @@ -868,8 +869,7 @@ impl DepGraph { let dep_node = data.previous.index_to_node(prev_index); dep_node.try_load_from_on_disk_cache(tcx); } - None | - Some(DepNodeColor::Red) => { + None | Some(DepNodeColor::Red) => { // We can skip red nodes because a node can only be marked // as red if the query result was recomputed and thus is // already in memory. @@ -979,19 +979,16 @@ impl CurrentDepGraph { use std::time::{SystemTime, UNIX_EPOCH}; let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); - let nanos = duration.as_secs() * 1_000_000_000 + - duration.subsec_nanos() as u64; + let nanos = duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64; let mut stable_hasher = StableHasher::new(); nanos.hash(&mut stable_hasher); let forbidden_edge = if cfg!(debug_assertions) { match env::var("RUST_FORBID_DEP_GRAPH_EDGE") { - Ok(s) => { - match EdgeFilter::new(&s) { - Ok(f) => Some(f), - Err(err) => bug!("RUST_FORBID_DEP_GRAPH_EDGE invalid: {}", err), - } - } + Ok(s) => match EdgeFilter::new(&s) { + Ok(f) => Some(f), + Err(err) => bug!("RUST_FORBID_DEP_GRAPH_EDGE invalid: {}", err), + }, Err(_) => None, } } else { @@ -1006,10 +1003,12 @@ impl CurrentDepGraph { CurrentDepGraph { data: Lock::new(IndexVec::with_capacity(new_node_count_estimate)), - node_to_node_index: Sharded::new(|| FxHashMap::with_capacity_and_hasher( - new_node_count_estimate / sharded::SHARDS, - Default::default(), - )), + node_to_node_index: Sharded::new(|| { + FxHashMap::with_capacity_and_hasher( + new_node_count_estimate / sharded::SHARDS, + Default::default(), + ) + }), anon_id_seed: stable_hasher.finish(), forbidden_edge, total_read_count: AtomicU64::new(0), @@ -1021,7 +1020,7 @@ impl CurrentDepGraph { &self, node: DepNode, task_deps: TaskDeps, - fingerprint: Fingerprint + fingerprint: Fingerprint, ) -> DepNodeIndex { self.alloc_node(node, task_deps.reads, fingerprint) } @@ -1054,12 +1053,11 @@ impl CurrentDepGraph { &self, dep_node: DepNode, edges: SmallVec<[DepNodeIndex; 8]>, - fingerprint: Fingerprint + fingerprint: Fingerprint, ) -> DepNodeIndex { - debug_assert!(!self.node_to_node_index - .get_shard_by_value(&dep_node) - .lock() - .contains_key(&dep_node)); + debug_assert!( + !self.node_to_node_index.get_shard_by_value(&dep_node).lock().contains_key(&dep_node) + ); self.intern_node(dep_node, edges, fingerprint) } @@ -1067,18 +1065,14 @@ impl CurrentDepGraph { &self, dep_node: DepNode, edges: SmallVec<[DepNodeIndex; 8]>, - fingerprint: Fingerprint + fingerprint: Fingerprint, ) -> DepNodeIndex { match self.node_to_node_index.get_shard_by_value(&dep_node).lock().entry(dep_node) { Entry::Occupied(entry) => *entry.get(), Entry::Vacant(entry) => { let mut data = self.data.lock(); let dep_node_index = DepNodeIndex::new(data.len()); - data.push(DepNodeData { - node: dep_node, - edges, - fingerprint - }); + data.push(DepNodeData { node: dep_node, edges, fingerprint }); entry.insert(dep_node_index); dep_node_index } @@ -1089,7 +1083,7 @@ impl CurrentDepGraph { impl DepGraphData { fn read_index(&self, source: DepNodeIndex) { ty::tls::with_context_opt(|icx| { - let icx = if let Some(icx) = icx { icx } else { return }; + let icx = if let Some(icx) = icx { icx } else { return }; if let Some(task_deps) = icx.task_deps { let mut task_deps = task_deps.lock(); if cfg!(debug_assertions) { @@ -1105,9 +1099,7 @@ impl DepGraphData { if let Some(ref forbidden_edge) = self.current.forbidden_edge { let source = data[source].node; if forbidden_edge.test(&source, &target) { - bug!("forbidden edge {:?} -> {:?} created", - source, - target) + bug!("forbidden edge {:?} -> {:?} created", source, target) } } } @@ -1139,25 +1131,26 @@ const COMPRESSED_FIRST_GREEN: u32 = 2; impl DepNodeColorMap { fn new(size: usize) -> DepNodeColorMap { - DepNodeColorMap { - values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect(), - } + DepNodeColorMap { values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect() } } fn get(&self, index: SerializedDepNodeIndex) -> Option { match self.values[index].load(Ordering::Acquire) { COMPRESSED_NONE => None, COMPRESSED_RED => Some(DepNodeColor::Red), - value => Some(DepNodeColor::Green(DepNodeIndex::from_u32( - value - COMPRESSED_FIRST_GREEN - ))) + value => { + Some(DepNodeColor::Green(DepNodeIndex::from_u32(value - COMPRESSED_FIRST_GREEN))) + } } } fn insert(&self, index: SerializedDepNodeIndex, color: DepNodeColor) { - self.values[index].store(match color { - DepNodeColor::Red => COMPRESSED_RED, - DepNodeColor::Green(index) => index.as_u32() + COMPRESSED_FIRST_GREEN, - }, Ordering::Release) + self.values[index].store( + match color { + DepNodeColor::Red => COMPRESSED_RED, + DepNodeColor::Green(index) => index.as_u32() + COMPRESSED_FIRST_GREEN, + }, + Ordering::Release, + ) } } diff --git a/src/librustc/dep_graph/mod.rs b/src/librustc/dep_graph/mod.rs index a1321d50f28bb..eb377d20f5963 100644 --- a/src/librustc/dep_graph/mod.rs +++ b/src/librustc/dep_graph/mod.rs @@ -6,9 +6,9 @@ mod query; mod safe; mod serialized; -pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, RecoverKey, label_strs}; -pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps, hash_result}; +pub use self::dep_node::{label_strs, DepConstructor, DepKind, DepNode, RecoverKey, WorkProductId}; pub use self::graph::WorkProductFileKind; +pub use self::graph::{hash_result, DepGraph, DepNodeColor, DepNodeIndex, TaskDeps, WorkProduct}; pub use self::prev::PreviousDepGraph; pub use self::query::DepGraphQuery; pub use self::safe::AssertDepGraphSafe; diff --git a/src/librustc/dep_graph/prev.rs b/src/librustc/dep_graph/prev.rs index d971690bbe317..fbc8f7bc997e0 100644 --- a/src/librustc/dep_graph/prev.rs +++ b/src/librustc/dep_graph/prev.rs @@ -1,7 +1,7 @@ -use crate::ich::Fingerprint; -use rustc_data_structures::fx::FxHashMap; use super::dep_node::DepNode; use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex}; +use crate::ich::Fingerprint; +use rustc_data_structures::fx::FxHashMap; #[derive(Debug, RustcEncodable, RustcDecodable, Default)] pub struct PreviousDepGraph { @@ -11,17 +11,15 @@ pub struct PreviousDepGraph { impl PreviousDepGraph { pub fn new(data: SerializedDepGraph) -> PreviousDepGraph { - let index: FxHashMap<_, _> = data.nodes - .iter_enumerated() - .map(|(idx, &dep_node)| (dep_node, idx)) - .collect(); + let index: FxHashMap<_, _> = + data.nodes.iter_enumerated().map(|(idx, &dep_node)| (dep_node, idx)).collect(); PreviousDepGraph { data, index } } #[inline] pub fn edge_targets_from( &self, - dep_node_index: SerializedDepNodeIndex + dep_node_index: SerializedDepNodeIndex, ) -> &[SerializedDepNodeIndex] { self.data.edge_targets_from(dep_node_index) } @@ -43,15 +41,11 @@ impl PreviousDepGraph { #[inline] pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option { - self.index - .get(dep_node) - .map(|&node_index| self.data.fingerprints[node_index]) + self.index.get(dep_node).map(|&node_index| self.data.fingerprints[node_index]) } #[inline] - pub fn fingerprint_by_index(&self, - dep_node_index: SerializedDepNodeIndex) - -> Fingerprint { + pub fn fingerprint_by_index(&self, dep_node_index: SerializedDepNodeIndex) -> Fingerprint { self.data.fingerprints[dep_node_index] } diff --git a/src/librustc/dep_graph/query.rs b/src/librustc/dep_graph/query.rs index cd4ced238d360..c71c11ed0ebdf 100644 --- a/src/librustc/dep_graph/query.rs +++ b/src/librustc/dep_graph/query.rs @@ -1,6 +1,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::implementation::{ - Direction, INCOMING, Graph, NodeIndex, OUTGOING + Direction, Graph, NodeIndex, INCOMING, OUTGOING, }; use super::DepNode; @@ -11,9 +11,7 @@ pub struct DepGraphQuery { } impl DepGraphQuery { - pub fn new(nodes: &[DepNode], - edges: &[(DepNode, DepNode)]) - -> DepGraphQuery { + pub fn new(nodes: &[DepNode], edges: &[(DepNode, DepNode)]) -> DepGraphQuery { let mut graph = Graph::with_capacity(nodes.len(), edges.len()); let mut indices = FxHashMap::default(); for node in nodes { @@ -26,10 +24,7 @@ impl DepGraphQuery { graph.add_edge(source, target, ()); } - DepGraphQuery { - graph, - indices, - } + DepGraphQuery { graph, indices } } pub fn contains_node(&self, node: &DepNode) -> bool { @@ -37,26 +32,21 @@ impl DepGraphQuery { } pub fn nodes(&self) -> Vec<&DepNode> { - self.graph.all_nodes() - .iter() - .map(|n| &n.data) - .collect() + self.graph.all_nodes().iter().map(|n| &n.data).collect() } - pub fn edges(&self) -> Vec<(&DepNode,&DepNode)> { - self.graph.all_edges() - .iter() - .map(|edge| (edge.source(), edge.target())) - .map(|(s, t)| (self.graph.node_data(s), - self.graph.node_data(t))) - .collect() + pub fn edges(&self) -> Vec<(&DepNode, &DepNode)> { + self.graph + .all_edges() + .iter() + .map(|edge| (edge.source(), edge.target())) + .map(|(s, t)| (self.graph.node_data(s), self.graph.node_data(t))) + .collect() } fn reachable_nodes(&self, node: &DepNode, direction: Direction) -> Vec<&DepNode> { if let Some(&index) = self.indices.get(node) { - self.graph.depth_traverse(index, direction) - .map(|s| self.graph.node_data(s)) - .collect() + self.graph.depth_traverse(index, direction).map(|s| self.graph.node_data(s)).collect() } else { vec![] } @@ -76,9 +66,7 @@ impl DepGraphQuery { /// Just the outgoing edges from `node`. pub fn immediate_successors(&self, node: &DepNode) -> Vec<&DepNode> { if let Some(&index) = self.indices.get(&node) { - self.graph.successor_nodes(index) - .map(|s| self.graph.node_data(s)) - .collect() + self.graph.successor_nodes(index).map(|s| self.graph.node_data(s)).collect() } else { vec![] } diff --git a/src/librustc/dep_graph/safe.rs b/src/librustc/dep_graph/safe.rs index e5eda14cdbe61..5395117ff24fc 100644 --- a/src/librustc/dep_graph/safe.rs +++ b/src/librustc/dep_graph/safe.rs @@ -1,35 +1,31 @@ //! The `DepGraphSafe` trait -use crate::hir::BodyId; use crate::hir::def_id::DefId; -use syntax::ast::NodeId; +use crate::hir::BodyId; use crate::ty::TyCtxt; +use syntax::ast::NodeId; /// The `DepGraphSafe` trait is used to specify what kinds of values /// are safe to "leak" into a task. The idea is that this should be /// only be implemented for things like the tcx as well as various id /// types, which will create reads in the dep-graph whenever the trait /// loads anything that might depend on the input program. -pub trait DepGraphSafe { -} +pub trait DepGraphSafe {} /// A `BodyId` on its own doesn't give access to any particular state. /// You must fetch the state from the various maps or generate /// on-demand queries, all of which create reads. -impl DepGraphSafe for BodyId { -} +impl DepGraphSafe for BodyId {} /// A `NodeId` on its own doesn't give access to any particular state. /// You must fetch the state from the various maps or generate /// on-demand queries, all of which create reads. -impl DepGraphSafe for NodeId { -} +impl DepGraphSafe for NodeId {} /// A `DefId` on its own doesn't give access to any particular state. /// You must fetch the state from the various maps or generate /// on-demand queries, all of which create reads. -impl DepGraphSafe for DefId { -} +impl DepGraphSafe for DefId {} /// The type context itself can be used to access all kinds of tracked /// state, but those accesses should always generate read events. @@ -37,31 +33,24 @@ impl<'tcx> DepGraphSafe for TyCtxt<'tcx> {} /// Tuples make it easy to build up state. impl DepGraphSafe for (A, B) - where A: DepGraphSafe, B: DepGraphSafe +where + A: DepGraphSafe, + B: DepGraphSafe, { } /// Shared ref to dep-graph-safe stuff should still be dep-graph-safe. -impl<'a, A> DepGraphSafe for &'a A - where A: DepGraphSafe, -{ -} +impl<'a, A> DepGraphSafe for &'a A where A: DepGraphSafe {} /// Mut ref to dep-graph-safe stuff should still be dep-graph-safe. -impl<'a, A> DepGraphSafe for &'a mut A - where A: DepGraphSafe, -{ -} - +impl<'a, A> DepGraphSafe for &'a mut A where A: DepGraphSafe {} /// No data here! :) -impl DepGraphSafe for () { -} +impl DepGraphSafe for () {} /// A convenient override that lets you pass arbitrary state into a /// task. Every use should be accompanied by a comment explaining why /// it makes sense (or how it could be refactored away in the future). pub struct AssertDepGraphSafe(pub T); -impl DepGraphSafe for AssertDepGraphSafe { -} +impl DepGraphSafe for AssertDepGraphSafe {} diff --git a/src/librustc/dep_graph/serialized.rs b/src/librustc/dep_graph/serialized.rs index 4302195755ea5..640877d3d55c3 100644 --- a/src/librustc/dep_graph/serialized.rs +++ b/src/librustc/dep_graph/serialized.rs @@ -2,7 +2,7 @@ use crate::dep_graph::DepNode; use crate::ich::Fingerprint; -use rustc_index::vec::{IndexVec, Idx}; +use rustc_index::vec::{Idx, IndexVec}; rustc_index::newtype_index! { pub struct SerializedDepNodeIndex { .. } @@ -27,9 +27,7 @@ pub struct SerializedDepGraph { impl SerializedDepGraph { #[inline] - pub fn edge_targets_from(&self, - source: SerializedDepNodeIndex) - -> &[SerializedDepNodeIndex] { + pub fn edge_targets_from(&self, source: SerializedDepNodeIndex) -> &[SerializedDepNodeIndex] { let targets = self.edge_list_indices[source]; &self.edge_list_data[targets.0 as usize..targets.1 as usize] } diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 9e95cba7fcbfc..5918ff03d585d 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -4,13 +4,13 @@ //! conflicts between multiple such attributes attached to the same //! item. -use crate::hir::{self, HirId, Attribute, Item, ItemKind, TraitItem, TraitItemKind}; -use crate::hir::DUMMY_HIR_ID; use crate::hir::def_id::DefId; -use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; +use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; +use crate::hir::DUMMY_HIR_ID; +use crate::hir::{self, Attribute, HirId, Item, ItemKind, TraitItem, TraitItemKind}; use crate::lint::builtin::UNUSED_ATTRIBUTES; -use crate::ty::TyCtxt; use crate::ty::query::Providers; +use crate::ty::TyCtxt; use std::fmt::{self, Display}; use syntax::{attr, symbol::sym}; @@ -55,33 +55,37 @@ pub(crate) enum Target { impl Display for Target { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", match *self { - Target::ExternCrate => "extern crate", - Target::Use => "use", - Target::Static => "static item", - Target::Const => "constant item", - Target::Fn => "function", - Target::Closure => "closure", - Target::Mod => "module", - Target::ForeignMod => "foreign module", - Target::GlobalAsm => "global asm", - Target::TyAlias => "type alias", - Target::OpaqueTy => "opaque type", - Target::Enum => "enum", - Target::Struct => "struct", - Target::Union => "union", - Target::Trait => "trait", - Target::TraitAlias => "trait alias", - Target::Impl => "item", - Target::Expression => "expression", - Target::Statement => "statement", - Target::AssocConst => "associated const", - Target::Method(_) => "method", - Target::AssocTy => "associated type", - Target::ForeignFn => "foreign function", - Target::ForeignStatic => "foreign static item", - Target::ForeignTy => "foreign type", - }) + write!( + f, + "{}", + match *self { + Target::ExternCrate => "extern crate", + Target::Use => "use", + Target::Static => "static item", + Target::Const => "constant item", + Target::Fn => "function", + Target::Closure => "closure", + Target::Mod => "module", + Target::ForeignMod => "foreign module", + Target::GlobalAsm => "global asm", + Target::TyAlias => "type alias", + Target::OpaqueTy => "opaque type", + Target::Enum => "enum", + Target::Struct => "struct", + Target::Union => "union", + Target::Trait => "trait", + Target::TraitAlias => "trait alias", + Target::Impl => "item", + Target::Expression => "expression", + Target::Statement => "statement", + Target::AssocConst => "associated const", + Target::Method(_) => "method", + Target::AssocTy => "associated type", + Target::ForeignFn => "foreign function", + Target::ForeignStatic => "foreign static item", + Target::ForeignTy => "foreign type", + } + ) } } @@ -195,15 +199,19 @@ impl CheckAttrVisitor<'tcx> { /// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid. fn check_inline(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) -> bool { match target { - Target::Fn | Target::Closure | Target::Method(MethodKind::Trait { body: true }) + Target::Fn + | Target::Closure + | Target::Method(MethodKind::Trait { body: true }) | Target::Method(MethodKind::Inherent) => true, Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { - self.tcx.struct_span_lint_hir( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - "`#[inline]` is ignored on function prototypes", - ).emit(); + self.tcx + .struct_span_lint_hir( + UNUSED_ATTRIBUTES, + hir_id, + attr.span, + "`#[inline]` is ignored on function prototypes", + ) + .emit(); true } // FIXME(#65833): We permit associated consts to have an `#[inline]` attribute with @@ -211,17 +219,23 @@ impl CheckAttrVisitor<'tcx> { // accidentally, to to be compatible with crates depending on them, we can't throw an // error here. Target::AssocConst => { - self.tcx.struct_span_lint_hir( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - "`#[inline]` is ignored on constants", - ).warn("this was previously accepted by the compiler but is \ + self.tcx + .struct_span_lint_hir( + UNUSED_ATTRIBUTES, + hir_id, + attr.span, + "`#[inline]` is ignored on constants", + ) + .warn( + "this was previously accepted by the compiler but is \ being phased out; it will become a hard error in \ - a future release!") - .note("for more information, see issue #65833 \ - ") - .emit(); + a future release!", + ) + .note( + "for more information, see issue #65833 \ + ", + ) + .emit(); true } _ => { @@ -230,8 +244,9 @@ impl CheckAttrVisitor<'tcx> { attr.span, E0518, "attribute should be applied to function or closure", - ).span_label(*span, "not a function or closure") - .emit(); + ) + .span_label(*span, "not a function or closure") + .emit(); false } } @@ -252,7 +267,8 @@ impl CheckAttrVisitor<'tcx> { *attr_span, E0736, "cannot use `#[track_caller]` with `#[naked]`", - ).emit(); + ) + .emit(); false } Target::Fn | Target::Method(MethodKind::Inherent) => true, @@ -262,7 +278,8 @@ impl CheckAttrVisitor<'tcx> { *attr_span, E0738, "`#[track_caller]` may not be used on trait methods", - ).emit(); + ) + .emit(); false } _ => { @@ -280,21 +297,18 @@ impl CheckAttrVisitor<'tcx> { } /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid. - fn check_non_exhaustive( - &self, - attr: &Attribute, - span: &Span, - target: Target, - ) -> bool { + fn check_non_exhaustive(&self, attr: &Attribute, span: &Span, target: Target) -> bool { match target { Target::Struct | Target::Enum => true, _ => { - struct_span_err!(self.tcx.sess, - attr.span, - E0701, - "attribute can only be applied to a struct or enum") - .span_label(*span, "not a struct or enum") - .emit(); + struct_span_err!( + self.tcx.sess, + attr.span, + E0701, + "attribute can only be applied to a struct or enum" + ) + .span_label(*span, "not a struct or enum") + .emit(); false } } @@ -305,7 +319,8 @@ impl CheckAttrVisitor<'tcx> { match target { Target::Trait => true, _ => { - self.tcx.sess + self.tcx + .sess .struct_span_err(attr.span, "attribute can only be applied to a trait") .span_label(*span, "not a trait") .emit(); @@ -317,15 +332,17 @@ impl CheckAttrVisitor<'tcx> { /// Checks if the `#[target_feature]` attribute on `item` is valid. Returns `true` if valid. fn check_target_feature(&self, attr: &Attribute, span: &Span, target: Target) -> bool { match target { - Target::Fn | Target::Method(MethodKind::Trait { body: true }) + Target::Fn + | Target::Method(MethodKind::Trait { body: true }) | Target::Method(MethodKind::Inherent) => true, _ => { - self.tcx.sess + self.tcx + .sess .struct_span_err(attr.span, "attribute should be applied to a function") .span_label(*span, "not a function") .emit(); false - }, + } } } @@ -364,20 +381,15 @@ impl CheckAttrVisitor<'tcx> { } } sym::packed => { - if target != Target::Struct && - target != Target::Union { - ("a", "struct or union") + if target != Target::Struct && target != Target::Union { + ("a", "struct or union") } else { - continue + continue; } } sym::simd => { is_simd = true; - if target != Target::Struct { - ("a", "struct") - } else { - continue - } + if target != Target::Struct { ("a", "struct") } else { continue } } sym::transparent => { is_transparent = true; @@ -386,15 +398,18 @@ impl CheckAttrVisitor<'tcx> { _ => ("a", "struct, enum, or union"), } } - sym::i8 | sym::u8 | sym::i16 | sym::u16 | - sym::i32 | sym::u32 | sym::i64 | sym::u64 | - sym::isize | sym::usize => { + sym::i8 + | sym::u8 + | sym::i16 + | sym::u16 + | sym::i32 + | sym::u32 + | sym::i64 + | sym::u64 + | sym::isize + | sym::usize => { int_reprs += 1; - if target != Target::Enum { - ("an", "enum") - } else { - continue - } + if target != Target::Enum { ("an", "enum") } else { continue } } _ => continue, }; @@ -413,16 +428,21 @@ impl CheckAttrVisitor<'tcx> { // Error on repr(transparent, ). if is_transparent && hints.len() > 1 { let hint_spans: Vec<_> = hint_spans.clone().collect(); - span_err!(self.tcx.sess, hint_spans, E0692, - "transparent {} cannot have other repr hints", target); + span_err!( + self.tcx.sess, + hint_spans, + E0692, + "transparent {} cannot have other repr hints", + target + ); } // Warn on repr(u8, u16), repr(C, simd), and c-like-enum-repr(C, u8) if (int_reprs > 1) - || (is_simd && is_c) - || (int_reprs == 1 && is_c && item.map_or(false, |item| is_c_like_enum(item))) { + || (is_simd && is_c) + || (int_reprs == 1 && is_c && item.map_or(false, |item| is_c_like_enum(item))) + { let hint_spans: Vec<_> = hint_spans.collect(); - span_warn!(self.tcx.sess, hint_spans, E0566, - "conflicting representation hints"); + span_warn!(self.tcx.sess, hint_spans, E0566, "conflicting representation hints"); } } @@ -480,7 +500,8 @@ impl CheckAttrVisitor<'tcx> { fn check_used(&self, attrs: &'hir [Attribute], target: Target) { for attr in attrs { if attr.check_name(sym::used) && target != Target::Static { - self.tcx.sess + self.tcx + .sess .span_err(attr.span, "attribute must be applied to a `static` variable"); } } @@ -542,15 +563,10 @@ fn is_c_like_enum(item: &Item<'_>) -> bool { } fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: DefId) { - tcx.hir().visit_item_likes_in_module( - module_def_id, - &mut CheckAttrVisitor { tcx }.as_deep_visitor() - ); + tcx.hir() + .visit_item_likes_in_module(module_def_id, &mut CheckAttrVisitor { tcx }.as_deep_visitor()); } pub(crate) fn provide(providers: &mut Providers<'_>) { - *providers = Providers { - check_mod_attrs, - ..*providers - }; + *providers = Providers { check_mod_attrs, ..*providers }; } diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index d4e89c5f047d2..38223843e2756 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -1,15 +1,15 @@ use self::Namespace::*; -use crate::hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::hir; +use crate::hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::ty; use crate::util::nodemap::DefIdMap; +use rustc_macros::HashStable; use syntax::ast; use syntax::ast::NodeId; use syntax_pos::hygiene::MacroKind; use syntax_pos::Span; -use rustc_macros::HashStable; use std::fmt::Debug; @@ -84,8 +84,9 @@ impl DefKind { pub fn descr(self, def_id: DefId) -> &'static str { match self { DefKind::Fn => "function", - DefKind::Mod if def_id.index == CRATE_DEF_INDEX && def_id.krate != LOCAL_CRATE => - "crate", + DefKind::Mod if def_id.index == CRATE_DEF_INDEX && def_id.krate != LOCAL_CRATE => { + "crate" + } DefKind::Mod => "module", DefKind::Static => "static", DefKind::Enum => "enum", @@ -96,8 +97,9 @@ impl DefKind { DefKind::Struct => "struct", DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct", DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct", - DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) => - bug!("impossible struct constructor"), + DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) => { + bug!("impossible struct constructor") + } DefKind::OpaqueTy => "opaque type", DefKind::TyAlias => "type alias", DefKind::TraitAlias => "trait alias", @@ -162,22 +164,18 @@ pub enum Res { Def(DefKind, DefId), // Type namespace - PrimTy(hir::PrimTy), SelfTy(Option /* trait */, Option /* impl */), ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]` // Value namespace - - SelfCtor(DefId /* impl */), // `DefId` refers to the impl + SelfCtor(DefId /* impl */), // `DefId` refers to the impl Local(Id), // Macro namespace - NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]` // All namespaces - Err, } @@ -211,7 +209,9 @@ impl PartialRes { #[inline] pub fn with_unresolved_segments(base_res: Res, mut unresolved_segments: usize) -> Self { - if base_res == Res::Err { unresolved_segments = 0 } + if base_res == Res::Err { + unresolved_segments = 0 + } PartialRes { base_res, unresolved_segments } } @@ -256,11 +256,7 @@ pub struct PerNS { impl PerNS { pub fn map U>(self, mut f: F) -> PerNS { - PerNS { - value_ns: f(self.value_ns), - type_ns: f(self.type_ns), - macro_ns: f(self.macro_ns), - } + PerNS { value_ns: f(self.value_ns), type_ns: f(self.type_ns), macro_ns: f(self.macro_ns) } } } @@ -293,13 +289,10 @@ impl PerNS> { } /// Returns an iterator over the items which are `Some`. - pub fn present_items(self) -> impl Iterator { + pub fn present_items(self) -> impl Iterator { use std::iter::once; - once(self.type_ns) - .chain(once(self.value_ns)) - .chain(once(self.macro_ns)) - .filter_map(|it| it) + once(self.type_ns).chain(once(self.value_ns)).chain(once(self.macro_ns)).filter_map(|it| it) } } @@ -322,12 +315,7 @@ pub struct Export { impl Export { pub fn map_id(self, map: impl FnMut(Id) -> R) -> Export { - Export { - ident: self.ident, - res: self.res.map_id(map), - span: self.span, - vis: self.vis, - } + Export { ident: self.ident, res: self.res.map_id(map), span: self.span, vis: self.vis } } } @@ -370,7 +358,7 @@ impl NonMacroAttrKind { pub fn is_used(self) -> bool { match self { NonMacroAttrKind::Tool | NonMacroAttrKind::DeriveHelper => true, - NonMacroAttrKind::Builtin | NonMacroAttrKind::Registered => false, + NonMacroAttrKind::Builtin | NonMacroAttrKind::Registered => false, } } } @@ -381,9 +369,7 @@ impl Res { where Id: Debug, { - self.opt_def_id().unwrap_or_else(|| { - bug!("attempted .def_id() on invalid res: {:?}", self) - }) + self.opt_def_id().unwrap_or_else(|| bug!("attempted .def_id() on invalid res: {:?}", self)) } /// Return `Some(..)` with the `DefId` of this `Res` if it has a ID, else `None`. @@ -391,15 +377,13 @@ impl Res { match *self { Res::Def(_, id) => Some(id), - Res::Local(..) | - Res::PrimTy(..) | - Res::SelfTy(..) | - Res::SelfCtor(..) | - Res::ToolMod | - Res::NonMacroAttr(..) | - Res::Err => { - None - } + Res::Local(..) + | Res::PrimTy(..) + | Res::SelfTy(..) + | Res::SelfCtor(..) + | Res::ToolMod + | Res::NonMacroAttr(..) + | Res::Err => None, } } diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index 13200b38f2cda..b26617a57f475 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -72,7 +72,9 @@ impl CrateNum { } } - pub fn as_def_id(&self) -> DefId { DefId { krate: *self, index: CRATE_DEF_INDEX } } + pub fn as_def_id(&self) -> DefId { + DefId { krate: *self, index: CRATE_DEF_INDEX } + } } impl fmt::Display for CrateNum { @@ -173,10 +175,7 @@ impl LocalDefId { #[inline] pub fn to_def_id(self) -> DefId { - DefId { - krate: LOCAL_CRATE, - index: self.0 - } + DefId { krate: LOCAL_CRATE, index: self.0 } } } diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 26e287037f72c..dc2008fdd9743 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -33,10 +33,10 @@ use super::itemlikevisit::DeepVisitor; -use crate::hir::*; use crate::hir::map::Map; +use crate::hir::*; -use syntax::ast::{Ident, Name, Attribute}; +use syntax::ast::{Attribute, Ident, Name}; use syntax_pos::Span; #[derive(Copy, Clone)] @@ -316,22 +316,26 @@ pub trait Visitor<'v>: Sized { fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: TraitBoundModifier) { walk_poly_trait_ref(self, t, m) } - fn visit_variant_data(&mut self, - s: &'v VariantData<'v>, - _: Name, - _: &'v Generics, - _parent_id: HirId, - _: Span) { + fn visit_variant_data( + &mut self, + s: &'v VariantData<'v>, + _: Name, + _: &'v Generics, + _parent_id: HirId, + _: Span, + ) { walk_struct_def(self, s) } fn visit_struct_field(&mut self, s: &'v StructField<'v>) { walk_struct_field(self, s) } - fn visit_enum_def(&mut self, - enum_definition: &'v EnumDef<'v>, - generics: &'v Generics, - item_id: HirId, - _: Span) { + fn visit_enum_def( + &mut self, + enum_definition: &'v EnumDef<'v>, + generics: &'v Generics, + item_id: HirId, + _: Span, + ) { walk_enum_def(self, enum_definition, generics, item_id) } fn visit_variant(&mut self, v: &'v Variant<'v>, g: &'v Generics, item_id: HirId) { @@ -365,8 +369,7 @@ pub trait Visitor<'v>: Sized { fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding) { walk_assoc_type_binding(self, type_binding) } - fn visit_attribute(&mut self, _attr: &'v Attribute) { - } + fn visit_attribute(&mut self, _attr: &'v Attribute) {} fn visit_macro_def(&mut self, macro_def: &'v MacroDef<'v>) { walk_macro_def(self, macro_def) } @@ -430,27 +433,30 @@ pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime LifetimeName::Param(ParamName::Plain(ident)) => { visitor.visit_ident(ident); } - LifetimeName::Param(ParamName::Fresh(_)) | - LifetimeName::Param(ParamName::Error) | - LifetimeName::Static | - LifetimeName::Error | - LifetimeName::Implicit | - LifetimeName::ImplicitObjectLifetimeDefault | - LifetimeName::Underscore => {} + LifetimeName::Param(ParamName::Fresh(_)) + | LifetimeName::Param(ParamName::Error) + | LifetimeName::Static + | LifetimeName::Error + | LifetimeName::Implicit + | LifetimeName::ImplicitObjectLifetimeDefault + | LifetimeName::Underscore => {} } } -pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V, - trait_ref: &'v PolyTraitRef, - _modifier: TraitBoundModifier) - where V: Visitor<'v> +pub fn walk_poly_trait_ref<'v, V>( + visitor: &mut V, + trait_ref: &'v PolyTraitRef, + _modifier: TraitBoundModifier, +) where + V: Visitor<'v>, { walk_list!(visitor, visit_generic_param, &trait_ref.bound_generic_params); visitor.visit_trait_ref(&trait_ref.trait_ref); } pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef) - where V: Visitor<'v> +where + V: Visitor<'v>, { visitor.visit_id(trait_ref.hir_ref_id); visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id) @@ -475,23 +481,18 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { ItemKind::Use(ref path, _) => { visitor.visit_use(path, item.hir_id); } - ItemKind::Static(ref typ, _, body) | - ItemKind::Const(ref typ, body) => { + ItemKind::Static(ref typ, _, body) | ItemKind::Const(ref typ, body) => { visitor.visit_id(item.hir_id); visitor.visit_ty(typ); visitor.visit_nested_body(body); } - ItemKind::Fn(ref sig, ref generics, body_id) => { - visitor.visit_fn(FnKind::ItemFn(item.ident, - generics, - sig.header, - &item.vis, - &item.attrs), - &sig.decl, - body_id, - item.span, - item.hir_id) - } + ItemKind::Fn(ref sig, ref generics, body_id) => visitor.visit_fn( + FnKind::ItemFn(item.ident, generics, sig.header, &item.vis, &item.attrs), + &sig.decl, + body_id, + item.span, + item.hir_id, + ), ItemKind::Mod(ref module) => { // `visit_mod()` takes care of visiting the `Item`'s `HirId`. visitor.visit_mod(module, item.span, item.hir_id) @@ -508,11 +509,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { visitor.visit_ty(ty); visitor.visit_generics(generics) } - ItemKind::OpaqueTy(OpaqueTy { - ref generics, - ref bounds, - .. - }) => { + ItemKind::OpaqueTy(OpaqueTy { ref generics, ref bounds, .. }) => { visitor.visit_id(item.hir_id); walk_generics(visitor, generics); walk_list!(visitor, visit_param_bound, bounds); @@ -522,25 +519,24 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { // `visit_enum_def()` takes care of visiting the `Item`'s `HirId`. visitor.visit_enum_def(enum_definition, generics, item.hir_id, item.span) } - ItemKind::Impl( - .., - ref generics, - ref opt_trait_reference, - ref typ, - impl_item_refs - ) => { + ItemKind::Impl(.., ref generics, ref opt_trait_reference, ref typ, impl_item_refs) => { visitor.visit_id(item.hir_id); visitor.visit_generics(generics); walk_list!(visitor, visit_trait_ref, opt_trait_reference); visitor.visit_ty(typ); walk_list!(visitor, visit_impl_item_ref, impl_item_refs); } - ItemKind::Struct(ref struct_definition, ref generics) | - ItemKind::Union(ref struct_definition, ref generics) => { + ItemKind::Struct(ref struct_definition, ref generics) + | ItemKind::Union(ref struct_definition, ref generics) => { visitor.visit_generics(generics); visitor.visit_id(item.hir_id); - visitor.visit_variant_data(struct_definition, item.ident.name, generics, item.hir_id, - item.span); + visitor.visit_variant_data( + struct_definition, + item.ident.name, + generics, + item.hir_id, + item.span, + ); } ItemKind::Trait(.., ref generics, ref bounds, trait_item_refs) => { visitor.visit_id(item.hir_id); @@ -557,36 +553,36 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { walk_list!(visitor, visit_attribute, item.attrs); } -pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V, - path: &'v Path, - hir_id: HirId) { +pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path, hir_id: HirId) { visitor.visit_id(hir_id); visitor.visit_path(path, hir_id); } -pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V, - enum_definition: &'v EnumDef<'v>, - generics: &'v Generics, - item_id: HirId) { +pub fn walk_enum_def<'v, V: Visitor<'v>>( + visitor: &mut V, + enum_definition: &'v EnumDef<'v>, + generics: &'v Generics, + item_id: HirId, +) { visitor.visit_id(item_id); - walk_list!(visitor, - visit_variant, - enum_definition.variants, - generics, - item_id); + walk_list!(visitor, visit_variant, enum_definition.variants, generics, item_id); } -pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, - variant: &'v Variant<'v>, - generics: &'v Generics, - parent_item_id: HirId) { +pub fn walk_variant<'v, V: Visitor<'v>>( + visitor: &mut V, + variant: &'v Variant<'v>, + generics: &'v Generics, + parent_item_id: HirId, +) { visitor.visit_ident(variant.ident); visitor.visit_id(variant.id); - visitor.visit_variant_data(&variant.data, - variant.ident.name, - generics, - parent_item_id, - variant.span); + visitor.visit_variant_data( + &variant.data, + variant.ident.name, + generics, + parent_item_id, + variant.span, + ); walk_list!(visitor, visit_anon_const, &variant.disr_expr); walk_list!(visitor, visit_attribute, variant.attrs); } @@ -595,12 +591,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { visitor.visit_id(typ.hir_id); match typ.kind { - TyKind::Slice(ref ty) => { - visitor.visit_ty(ty) - } - TyKind::Ptr(ref mutable_type) => { - visitor.visit_ty(&mutable_type.ty) - } + TyKind::Slice(ref ty) => visitor.visit_ty(ty), + TyKind::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty), TyKind::Rptr(ref lifetime, ref mutable_type) => { visitor.visit_lifetime(lifetime); visitor.visit_ty(&mutable_type.ty) @@ -630,9 +622,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { } visitor.visit_lifetime(lifetime); } - TyKind::Typeof(ref expression) => { - visitor.visit_anon_const(expression) - } + TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression), TyKind::Infer | TyKind::Err => {} } } @@ -658,9 +648,11 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) { } } -pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, - path_span: Span, - segment: &'v PathSegment) { +pub fn walk_path_segment<'v, V: Visitor<'v>>( + visitor: &mut V, + path_span: Span, + segment: &'v PathSegment, +) { visitor.visit_ident(segment.ident); if let Some(id) = segment.hir_id { visitor.visit_id(id); @@ -670,15 +662,16 @@ pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, } } -pub fn walk_generic_args<'v, V: Visitor<'v>>(visitor: &mut V, - _path_span: Span, - generic_args: &'v GenericArgs) { +pub fn walk_generic_args<'v, V: Visitor<'v>>( + visitor: &mut V, + _path_span: Span, + generic_args: &'v GenericArgs, +) { walk_list!(visitor, visit_generic_arg, &generic_args.args); walk_list!(visitor, visit_assoc_type_binding, &generic_args.bindings); } -pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V, - type_binding: &'v TypeBinding) { +pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V, type_binding: &'v TypeBinding) { visitor.visit_id(type_binding.hir_id); visitor.visit_ident(type_binding.ident); match type_binding.kind { @@ -713,8 +706,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { PatKind::Tuple(ref tuple_elements, _) => { walk_list!(visitor, visit_pat, tuple_elements); } - PatKind::Box(ref subpattern) | - PatKind::Ref(ref subpattern, _) => { + PatKind::Box(ref subpattern) | PatKind::Ref(ref subpattern, _) => { visitor.visit_pat(subpattern) } PatKind::Binding(_, _hir_id, ident, ref optional_subpattern) => { @@ -784,29 +776,27 @@ pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates); } -pub fn walk_where_predicate<'v, V: Visitor<'v>>( - visitor: &mut V, - predicate: &'v WherePredicate) -{ +pub fn walk_where_predicate<'v, V: Visitor<'v>>(visitor: &mut V, predicate: &'v WherePredicate) { match predicate { - &WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty, - ref bounds, - ref bound_generic_params, - ..}) => { + &WherePredicate::BoundPredicate(WhereBoundPredicate { + ref bounded_ty, + ref bounds, + ref bound_generic_params, + .. + }) => { visitor.visit_ty(bounded_ty); walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_generic_param, bound_generic_params); } - &WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime, - ref bounds, - ..}) => { + &WherePredicate::RegionPredicate(WhereRegionPredicate { + ref lifetime, ref bounds, .. + }) => { visitor.visit_lifetime(lifetime); walk_list!(visitor, visit_param_bound, bounds); } - &WherePredicate::EqPredicate(WhereEqPredicate{hir_id, - ref lhs_ty, - ref rhs_ty, - ..}) => { + &WherePredicate::EqPredicate(WhereEqPredicate { + hir_id, ref lhs_ty, ref rhs_ty, .. + }) => { visitor.visit_id(hir_id); visitor.visit_ty(lhs_ty); visitor.visit_ty(rhs_ty); @@ -832,17 +822,18 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<' FnKind::ItemFn(_, generics, ..) => { visitor.visit_generics(generics); } - FnKind::Method(..) | - FnKind::Closure(_) => {} + FnKind::Method(..) | FnKind::Closure(_) => {} } } -pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, - function_kind: FnKind<'v>, - function_declaration: &'v FnDecl, - body_id: BodyId, - _span: Span, - id: HirId) { +pub fn walk_fn<'v, V: Visitor<'v>>( + visitor: &mut V, + function_kind: FnKind<'v>, + function_declaration: &'v FnDecl, + body_id: BodyId, + _span: Span, + id: HirId, +) { visitor.visit_id(id); visitor.visit_fn_decl(function_declaration); walk_fn_kind(visitor, function_kind); @@ -867,14 +858,13 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai } } TraitItemKind::Method(ref sig, TraitMethod::Provided(body_id)) => { - visitor.visit_fn(FnKind::Method(trait_item.ident, - sig, - None, - &trait_item.attrs), - &sig.decl, - body_id, - trait_item.span, - trait_item.hir_id); + visitor.visit_fn( + FnKind::Method(trait_item.ident, sig, None, &trait_item.attrs), + &sig.decl, + body_id, + trait_item.span, + trait_item.hir_id, + ); } TraitItemKind::Type(ref bounds, ref default) => { visitor.visit_id(trait_item.hir_id); @@ -918,14 +908,13 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt visitor.visit_nested_body(body); } ImplItemKind::Method(ref sig, body_id) => { - visitor.visit_fn(FnKind::Method(impl_item.ident, - sig, - Some(&impl_item.vis), - &impl_item.attrs), - &sig.decl, - body_id, - impl_item.span, - impl_item.hir_id); + visitor.visit_fn( + FnKind::Method(impl_item.ident, sig, Some(&impl_item.vis), &impl_item.attrs), + &sig.decl, + body_id, + impl_item.span, + impl_item.hir_id, + ); } ImplItemKind::TyAlias(ref ty) => { visitor.visit_id(impl_item.hir_id); @@ -977,8 +966,7 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { match statement.kind { StmtKind::Local(ref local) => visitor.visit_local(local), StmtKind::Item(item) => visitor.visit_nested_item(item), - StmtKind::Expr(ref expression) | - StmtKind::Semi(ref expression) => { + StmtKind::Expr(ref expression) | StmtKind::Semi(ref expression) => { visitor.visit_expr(expression) } } @@ -993,9 +981,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_id(expression.hir_id); walk_list!(visitor, visit_attribute, expression.attrs.iter()); match expression.kind { - ExprKind::Box(ref subexpression) => { - visitor.visit_expr(subexpression) - } + ExprKind::Box(ref subexpression) => visitor.visit_expr(subexpression), ExprKind::Array(ref subexpressions) => { walk_list!(visitor, visit_expr, subexpressions); } @@ -1045,13 +1031,14 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_expr(subexpression); walk_list!(visitor, visit_arm, arms); } - ExprKind::Closure(_, ref function_declaration, body, _fn_decl_span, _gen) => { - visitor.visit_fn(FnKind::Closure(&expression.attrs), - function_declaration, - body, - expression.span, - expression.hir_id) - } + ExprKind::Closure(_, ref function_declaration, body, _fn_decl_span, _gen) => visitor + .visit_fn( + FnKind::Closure(&expression.attrs), + function_declaration, + body, + expression.span, + expression.hir_id, + ), ExprKind::Block(ref block, ref opt_label) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_block(block); diff --git a/src/librustc/hir/itemlikevisit.rs b/src/librustc/hir/itemlikevisit.rs index 30b41ea4acb3b..56dcf91a134ce 100644 --- a/src/librustc/hir/itemlikevisit.rs +++ b/src/librustc/hir/itemlikevisit.rs @@ -1,5 +1,5 @@ -use super::{Item, ImplItem, TraitItem}; use super::intravisit::Visitor; +use super::{ImplItem, Item, TraitItem}; /// The "item-like visitor" defines only the top-level methods /// that can be invoked by `Crate::visit_all_item_likes()`. Whether @@ -55,7 +55,8 @@ pub struct DeepVisitor<'v, V> { } impl<'v, 'hir, V> DeepVisitor<'v, V> - where V: Visitor<'hir> + 'v +where + V: Visitor<'hir> + 'v, { pub fn new(base: &'v mut V) -> Self { DeepVisitor { visitor: base } @@ -63,7 +64,8 @@ impl<'v, 'hir, V> DeepVisitor<'v, V> } impl<'v, 'hir, V> ItemLikeVisitor<'hir> for DeepVisitor<'v, V> - where V: Visitor<'hir> +where + V: Visitor<'hir>, { fn visit_item(&mut self, item: &'hir Item<'hir>) { self.visitor.visit_item(item); @@ -93,7 +95,8 @@ pub trait IntoVisitor<'hir> { pub struct ParDeepVisitor(pub V); impl<'hir, V> ParItemLikeVisitor<'hir> for ParDeepVisitor - where V: IntoVisitor<'hir> +where + V: IntoVisitor<'hir>, { fn visit_item(&self, item: &'hir Item<'hir>) { self.0.into_visitor().visit_item(item); diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs index 08b00ce69addb..8939b5eef2660 100644 --- a/src/librustc/hir/lowering/expr.rs +++ b/src/librustc/hir/lowering/expr.rs @@ -1,13 +1,13 @@ -use super::{LoweringContext, ParamMode, ParenthesizedGenericArgs, ImplTraitContext}; -use crate::hir::{self, HirVec}; +use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs}; use crate::hir::def::Res; use crate::hir::ptr::P; +use crate::hir::{self, HirVec}; use rustc_data_structures::thin_vec::ThinVec; +use syntax::ast::*; use syntax::attr; use syntax::ptr::P as AstP; -use syntax::ast::*; use syntax::source_map::{respan, DesugaringKind, Span, Spanned}; use syntax::symbol::{sym, Symbol}; @@ -89,29 +89,39 @@ impl LoweringContext<'_, '_> { arms.iter().map(|x| self.lower_arm(x)).collect(), hir::MatchSource::Normal, ), - ExprKind::Async(capture_clause, closure_node_id, ref block) => { - self.make_async_expr( - capture_clause, - closure_node_id, - None, - block.span, - hir::AsyncGeneratorKind::Block, - |this| this.with_new_scopes(|this| this.lower_block_expr(block)), - ) - } + ExprKind::Async(capture_clause, closure_node_id, ref block) => self.make_async_expr( + capture_clause, + closure_node_id, + None, + block.span, + hir::AsyncGeneratorKind::Block, + |this| this.with_new_scopes(|this| this.lower_block_expr(block)), + ), ExprKind::Await(ref expr) => self.lower_expr_await(e.span, expr), ExprKind::Closure( - capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span - ) => if let IsAsync::Async { closure_id, .. } = asyncness { - self.lower_expr_async_closure(capture_clause, closure_id, decl, body, fn_decl_span) - } else { - self.lower_expr_closure(capture_clause, movability, decl, body, fn_decl_span) - } - ExprKind::Block(ref blk, opt_label) => { - hir::ExprKind::Block(self.lower_block(blk, - opt_label.is_some()), - self.lower_label(opt_label)) + capture_clause, + asyncness, + movability, + ref decl, + ref body, + fn_decl_span, + ) => { + if let IsAsync::Async { closure_id, .. } = asyncness { + self.lower_expr_async_closure( + capture_clause, + closure_id, + decl, + body, + fn_decl_span, + ) + } else { + self.lower_expr_closure(capture_clause, movability, decl, body, fn_decl_span) + } } + ExprKind::Block(ref blk, opt_label) => hir::ExprKind::Block( + self.lower_block(blk, opt_label.is_some()), + self.lower_label(opt_label), + ), ExprKind::Assign(ref el, ref er) => { hir::ExprKind::Assign(P(self.lower_expr(el)), P(self.lower_expr(er))) } @@ -140,12 +150,10 @@ impl LoweringContext<'_, '_> { ); hir::ExprKind::Path(qpath) } - ExprKind::Break(opt_label, ref opt_expr) => { - hir::ExprKind::Break( - self.lower_jump_destination(e.id, opt_label), - opt_expr.as_ref().map(|x| P(self.lower_expr(x))), - ) - } + ExprKind::Break(opt_label, ref opt_expr) => hir::ExprKind::Break( + self.lower_jump_destination(e.id, opt_label), + opt_expr.as_ref().map(|x| P(self.lower_expr(x))), + ), ExprKind::Continue(opt_label) => { hir::ExprKind::Continue(self.lower_jump_destination(e.id, opt_label)) } @@ -188,12 +196,7 @@ impl LoweringContext<'_, '_> { ExprKind::Mac(_) => panic!("Shouldn't exist here"), }; - hir::Expr { - hir_id: self.lower_node_id(e.id), - kind, - span: e.span, - attrs: e.attrs.clone(), - } + hir::Expr { hir_id: self.lower_node_id(e.id), kind, span: e.span, attrs: e.attrs.clone() } } fn lower_unop(&mut self, u: UnOp) -> hir::UnOp { @@ -243,8 +246,7 @@ impl LoweringContext<'_, '_> { .note("only supported directly in conditions of `if`- and `while`-expressions") .note("as well as when nested within `&&` and parenthesis in those conditions") .emit(); - } - else { + } else { self.sess .struct_span_err(span, "expected expression, found statement (`let`)") .note("variable declaration using `let` is a statement") @@ -308,11 +310,8 @@ impl LoweringContext<'_, '_> { _ => { // Lower condition: let cond = self.lower_expr(cond); - let span_block = self.mark_span_with_reason( - DesugaringKind::CondTemporary, - cond.span, - None - ); + let span_block = + self.mark_span_with_reason(DesugaringKind::CondTemporary, cond.span, None); // Wrap in a construct equivalent to `{ let _t = $cond; _t }` // to preserve drop semantics since `if cond { ... }` does not // let temporaries live outside of `cond`. @@ -331,7 +330,7 @@ impl LoweringContext<'_, '_> { span: Span, cond: &Expr, body: &Block, - opt_label: Option Trait for Foo { .. }`. - Impl(Unsafety, - ImplPolarity, - Defaultness, - Generics, - Option, // (optional) trait this impl implements - &'hir Ty, // self - &'hir [ImplItemRef]), + Impl( + Unsafety, + ImplPolarity, + Defaultness, + Generics, + Option, // (optional) trait this impl implements + &'hir Ty, // self + &'hir [ImplItemRef], + ), } impl ItemKind<'_> { @@ -2552,15 +2523,15 @@ impl ItemKind<'_> { pub fn generics(&self) -> Option<&Generics> { Some(match *self { - ItemKind::Fn(_, ref generics, _) | - ItemKind::TyAlias(_, ref generics) | - ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. }) | - ItemKind::Enum(_, ref generics) | - ItemKind::Struct(_, ref generics) | - ItemKind::Union(_, ref generics) | - ItemKind::Trait(_, _, ref generics, _, _) | - ItemKind::Impl(_, _, _, ref generics, _, _, _)=> generics, - _ => return None + ItemKind::Fn(_, ref generics, _) + | ItemKind::TyAlias(_, ref generics) + | ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. }) + | ItemKind::Enum(_, ref generics) + | ItemKind::Struct(_, ref generics) + | ItemKind::Union(_, ref generics) + | ItemKind::Trait(_, _, ref generics, _, _) + | ItemKind::Impl(_, _, _, ref generics, _, _, _) => generics, + _ => return None, }) } } @@ -2642,14 +2613,14 @@ impl ForeignItemKind<'hir> { #[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)] pub struct Upvar { // First span where it is accessed (there can be multiple). - pub span: Span + pub span: Span, } pub type CaptureModeMap = NodeMap; - // The TraitCandidate's import_ids is empty if the trait is defined in the same module, and - // has length > 0 if the trait is found through an chain of imports, starting with the - // import/use statement in the scope where the trait is used. +// The TraitCandidate's import_ids is empty if the trait is defined in the same module, and +// has length > 0 if the trait is found through an chain of imports, starting with the +// import/use statement in the scope where the trait is used. #[derive(Clone, Debug)] pub struct TraitCandidate { pub def_id: DefId, @@ -2771,14 +2742,12 @@ impl CodegenFnAttrs { /// * `#[export_name(...)]` is present /// * `#[linkage]` is present pub fn contains_extern_indicator(&self) -> bool { - self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) || - self.export_name.is_some() || - match self.linkage { + self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) + || self.export_name.is_some() + || match self.linkage { // These are private, so make sure we don't try to consider // them external. - None | - Some(Linkage::Internal) | - Some(Linkage::Private) => false, + None | Some(Linkage::Internal) | Some(Linkage::Private) => false, Some(_) => true, } } @@ -2820,10 +2789,10 @@ pub enum Node<'hir> { impl Node<'_> { pub fn ident(&self) -> Option { match self { - Node::TraitItem(TraitItem { ident, .. }) | - Node::ImplItem(ImplItem { ident, .. }) | - Node::ForeignItem(ForeignItem { ident, .. }) | - Node::Item(Item { ident, .. }) => Some(*ident), + Node::TraitItem(TraitItem { ident, .. }) + | Node::ImplItem(ImplItem { ident, .. }) + | Node::ForeignItem(ForeignItem { ident, .. }) + | Node::Item(Item { ident, .. }) => Some(*ident), _ => None, } } diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index b59c7438005b2..c0aa54beac275 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -1,4 +1,4 @@ -use crate::hir::def::{CtorOf, Res, DefKind}; +use crate::hir::def::{CtorOf, DefKind, Res}; use crate::hir::def_id::DefId; use crate::hir::{self, HirId, PatKind}; use syntax::ast; @@ -12,13 +12,16 @@ pub struct EnumerateAndAdjust { gap_len: usize, } -impl Iterator for EnumerateAndAdjust where I: Iterator { +impl Iterator for EnumerateAndAdjust +where + I: Iterator, +{ type Item = (usize, ::Item); fn next(&mut self) -> Option<(usize, ::Item)> { - self.enumerate.next().map(|(i, elem)| { - (if i < self.gap_pos { i } else { i + self.gap_len }, elem) - }) + self.enumerate + .next() + .map(|(i, elem)| (if i < self.gap_pos { i } else { i + self.gap_len }, elem)) } fn size_hint(&self) -> (usize, Option) { @@ -27,13 +30,24 @@ impl Iterator for EnumerateAndAdjust where I: Iterator { } pub trait EnumerateAndAdjustIterator { - fn enumerate_and_adjust(self, expected_len: usize, gap_pos: Option) - -> EnumerateAndAdjust where Self: Sized; + fn enumerate_and_adjust( + self, + expected_len: usize, + gap_pos: Option, + ) -> EnumerateAndAdjust + where + Self: Sized; } impl EnumerateAndAdjustIterator for T { - fn enumerate_and_adjust(self, expected_len: usize, gap_pos: Option) - -> EnumerateAndAdjust where Self: Sized { + fn enumerate_and_adjust( + self, + expected_len: usize, + gap_pos: Option, + ) -> EnumerateAndAdjust + where + Self: Sized, + { let actual_len = self.len(); EnumerateAndAdjust { enumerate: self.enumerate(), @@ -46,21 +60,19 @@ impl EnumerateAndAdjustIterator for T { impl hir::Pat { pub fn is_refutable(&self) -> bool { match self.kind { - PatKind::Lit(_) | - PatKind::Range(..) | - PatKind::Path(hir::QPath::Resolved(Some(..), _)) | - PatKind::Path(hir::QPath::TypeRelative(..)) => true, - - PatKind::Path(hir::QPath::Resolved(_, ref path)) | - PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..) | - PatKind::Struct(hir::QPath::Resolved(_, ref path), ..) => { - match path.res { - Res::Def(DefKind::Variant, _) => true, - _ => false - } - } + PatKind::Lit(_) + | PatKind::Range(..) + | PatKind::Path(hir::QPath::Resolved(Some(..), _)) + | PatKind::Path(hir::QPath::TypeRelative(..)) => true, + + PatKind::Path(hir::QPath::Resolved(_, ref path)) + | PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..) + | PatKind::Struct(hir::QPath::Resolved(_, ref path), ..) => match path.res { + Res::Def(DefKind::Variant, _) => true, + _ => false, + }, PatKind::Slice(..) => true, - _ => false + _ => false, } } @@ -87,8 +99,8 @@ impl hir::Pat { PatKind::Or(ps) => { ps[0].each_binding_or_first(f); false - }, - PatKind::Binding(bm, _, ident, _) => { + } + PatKind::Binding(bm, _, ident, _) => { f(*bm, p.hir_id, p.span, *ident); true } @@ -130,8 +142,8 @@ impl hir::Pat { pub fn simple_ident(&self) -> Option { match self.kind { - PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, None) | - PatKind::Binding(hir::BindingAnnotation::Mutable, _, ident, None) => Some(ident), + PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, None) + | PatKind::Binding(hir::BindingAnnotation::Mutable, _, ident, None) => Some(ident), _ => None, } } @@ -141,12 +153,11 @@ impl hir::Pat { let mut variants = vec![]; self.walk(|p| match &p.kind { PatKind::Or(_) => false, - PatKind::Path(hir::QPath::Resolved(_, path)) | - PatKind::TupleStruct(hir::QPath::Resolved(_, path), ..) | - PatKind::Struct(hir::QPath::Resolved(_, path), ..) => { + PatKind::Path(hir::QPath::Resolved(_, path)) + | PatKind::TupleStruct(hir::QPath::Resolved(_, path), ..) + | PatKind::Struct(hir::QPath::Resolved(_, path), ..) => { if let Res::Def(DefKind::Variant, id) - | Res::Def(DefKind::Ctor(CtorOf::Variant, ..), id) - = path.res + | Res::Def(DefKind::Ctor(CtorOf::Variant, ..), id) = path.res { variants.push(id); } @@ -166,15 +177,13 @@ impl hir::Pat { // ref bindings are be implicit after #42640 (default match binding modes). See issue #44848. pub fn contains_explicit_ref_binding(&self) -> Option { let mut result = None; - self.each_binding(|annotation, _, _, _| { - match annotation { - hir::BindingAnnotation::Ref => match result { - None | Some(hir::Mutability::Not) => result = Some(hir::Mutability::Not), - _ => {} - } - hir::BindingAnnotation::RefMut => result = Some(hir::Mutability::Mut), + self.each_binding(|annotation, _, _, _| match annotation { + hir::BindingAnnotation::Ref => match result { + None | Some(hir::Mutability::Not) => result = Some(hir::Mutability::Not), _ => {} - } + }, + hir::BindingAnnotation::RefMut => result = Some(hir::Mutability::Mut), + _ => {} }); result } diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 85747cadbd717..767e53f951901 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1,18 +1,18 @@ use rustc_target::spec::abi::Abi; use syntax::ast; -use syntax::source_map::{SourceMap, Spanned}; -use syntax::print::pp::{self, Breaks}; use syntax::print::pp::Breaks::{Consistent, Inconsistent}; +use syntax::print::pp::{self, Breaks}; use syntax::print::pprust::{self, Comments, PrintState}; use syntax::sess::ParseSess; +use syntax::source_map::{SourceMap, Spanned}; use syntax::symbol::kw; use syntax::util::parser::{self, AssocOp, Fixity}; use syntax_pos::{self, BytePos, FileName}; use crate::hir; -use crate::hir::{PatKind, GenericBound, TraitBoundModifier, RangeEnd}; -use crate::hir::{GenericParam, GenericParamKind, GenericArg}; use crate::hir::ptr::P; +use crate::hir::{GenericArg, GenericParam, GenericParamKind}; +use crate::hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier}; use std::borrow::Cow; use std::cell::Cell; @@ -33,16 +33,13 @@ pub enum Nested { TraitItem(hir::TraitItemId), ImplItem(hir::ImplItemId), Body(hir::BodyId), - BodyParamPat(hir::BodyId, usize) + BodyParamPat(hir::BodyId, usize), } pub trait PpAnn { - fn nested(&self, _state: &mut State<'_>, _nested: Nested) { - } - fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) { - } - fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) { - } + fn nested(&self, _state: &mut State<'_>, _nested: Nested) {} + fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {} + fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {} fn try_fetch_item(&self, _: hir::HirId) -> Option<&hir::Item<'_>> { None } @@ -62,7 +59,7 @@ impl PpAnn for hir::Crate<'a> { Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)), Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)), Nested::Body(id) => state.print_expr(&self.body(id).value), - Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat) + Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat), } } } @@ -105,12 +102,14 @@ pub const INDENT_UNIT: usize = 4; /// Requires you to pass an input filename and reader so that /// it can scan the input text for comments to copy forward. -pub fn print_crate<'a>(cm: &'a SourceMap, - sess: &ParseSess, - krate: &hir::Crate<'_>, - filename: FileName, - input: String, - ann: &'a dyn PpAnn) -> String { +pub fn print_crate<'a>( + cm: &'a SourceMap, + sess: &ParseSess, + krate: &hir::Crate<'_>, + filename: FileName, + input: String, + ann: &'a dyn PpAnn, +) -> String { let mut s = State::new_from_input(cm, sess, filename, input, ann); // When printing the AST, we sometimes need to inject `#[no_std]` here. @@ -122,28 +121,22 @@ pub fn print_crate<'a>(cm: &'a SourceMap, } impl<'a> State<'a> { - pub fn new_from_input(cm: &'a SourceMap, - sess: &ParseSess, - filename: FileName, - input: String, - ann: &'a dyn PpAnn) - -> State<'a> { - State { - s: pp::mk_printer(), - comments: Some(Comments::new(cm, sess, filename, input)), - ann, - } + pub fn new_from_input( + cm: &'a SourceMap, + sess: &ParseSess, + filename: FileName, + input: String, + ann: &'a dyn PpAnn, + ) -> State<'a> { + State { s: pp::mk_printer(), comments: Some(Comments::new(cm, sess, filename, input)), ann } } } pub fn to_string(ann: &dyn PpAnn, f: F) -> String - where F: FnOnce(&mut State<'_>) +where + F: FnOnce(&mut State<'_>), { - let mut printer = State { - s: pp::mk_printer(), - comments: None, - ann, - }; + let mut printer = State { s: pp::mk_printer(), comments: None, ann }; f(&mut printer); printer.s.eof() } @@ -186,10 +179,7 @@ impl<'a> State<'a> { self.end(); // close the head-box } - pub fn bclose_maybe_open(&mut self, - span: syntax_pos::Span, - close_box: bool) - { + pub fn bclose_maybe_open(&mut self, span: syntax_pos::Span, close_box: bool) { self.maybe_print_comment(span.hi()); self.break_offset_if_not_bol(1, -(INDENT_UNIT as isize)); self.s.word("}"); @@ -231,13 +221,10 @@ impl<'a> State<'a> { self.s.word("*/") } - pub fn commasep_cmnt(&mut self, - b: Breaks, - elts: &[T], - mut op: F, - mut get_span: G) - where F: FnMut(&mut State<'_>, &T), - G: FnMut(&T) -> syntax_pos::Span + pub fn commasep_cmnt(&mut self, b: Breaks, elts: &[T], mut op: F, mut get_span: G) + where + F: FnMut(&mut State<'_>, &T), + G: FnMut(&T) -> syntax_pos::Span, { self.rbox(0, b); let len = elts.len(); @@ -266,10 +253,7 @@ impl<'a> State<'a> { } } - pub fn print_foreign_mod(&mut self, - nmod: &hir::ForeignMod<'_>, - attrs: &[ast::Attribute]) - { + pub fn print_foreign_mod(&mut self, nmod: &hir::ForeignMod<'_>, attrs: &[ast::Attribute]) { self.print_inner_attributes(attrs); for item in nmod.items { self.print_foreign_item(item); @@ -303,7 +287,7 @@ impl<'a> State<'a> { } hir::TyKind::Never => { self.s.word("!"); - }, + } hir::TyKind::Tup(ref elts) => { self.popen(); self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&ty)); @@ -313,13 +297,17 @@ impl<'a> State<'a> { self.pclose(); } hir::TyKind::BareFn(ref f) => { - self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &f.generic_params, - &f.param_names[..]); - } - hir::TyKind::Def(..) => {}, - hir::TyKind::Path(ref qpath) => { - self.print_qpath(qpath, false) - } + self.print_ty_fn( + f.abi, + f.unsafety, + &f.decl, + None, + &f.generic_params, + &f.param_names[..], + ); + } + hir::TyKind::Def(..) => {} + hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false), hir::TyKind::TraitObject(ref bounds, ref lifetime) => { let mut first = true; for bound in bounds { @@ -368,18 +356,20 @@ impl<'a> State<'a> { match item.kind { hir::ForeignItemKind::Fn(ref decl, ref arg_names, ref generics) => { self.head(""); - self.print_fn(decl, - hir::FnHeader { - unsafety: hir::Unsafety::Normal, - constness: hir::Constness::NotConst, - abi: Abi::Rust, - asyncness: hir::IsAsync::NotAsync, - }, - Some(item.ident.name), - generics, - &item.vis, - arg_names, - None); + self.print_fn( + decl, + hir::FnHeader { + unsafety: hir::Unsafety::Normal, + constness: hir::Constness::NotConst, + abi: Abi::Rust, + asyncness: hir::IsAsync::NotAsync, + }, + Some(item.ident.name), + generics, + &item.vis, + arg_names, + None, + ); self.end(); // end head-ibox self.s.word(";"); self.end() // end the outer fn box @@ -406,12 +396,13 @@ impl<'a> State<'a> { } } - fn print_associated_const(&mut self, - ident: ast::Ident, - ty: &hir::Ty, - default: Option, - vis: &hir::Visibility) - { + fn print_associated_const( + &mut self, + ident: ast::Ident, + ty: &hir::Ty, + default: Option, + vis: &hir::Visibility, + ) { self.s.word(visibility_qualified(vis, "")); self.word_space("const"); self.print_ident(ident); @@ -425,11 +416,12 @@ impl<'a> State<'a> { self.s.word(";") } - fn print_associated_type(&mut self, - ident: ast::Ident, - bounds: Option<&hir::GenericBounds>, - ty: Option<&hir::Ty>) - { + fn print_associated_type( + &mut self, + ident: ast::Ident, + bounds: Option<&hir::GenericBounds>, + ty: Option<&hir::Ty>, + ) { self.word_space("type"); self.print_ident(ident); if let Some(bounds) = bounds { @@ -495,7 +487,7 @@ impl<'a> State<'a> { self.s.word(";"); } hir::UseKind::Glob => self.s.word("::*;"), - hir::UseKind::ListStem => self.s.word("::{};") + hir::UseKind::ListStem => self.s.word("::{};"), } self.end(); // end inner head-block self.end(); // end outer head-block @@ -531,13 +523,15 @@ impl<'a> State<'a> { } hir::ItemKind::Fn(ref sig, ref param_names, body) => { self.head(""); - self.print_fn(&sig.decl, - sig.header, - Some(item.ident.name), - param_names, - &item.vis, - &[], - Some(body)); + self.print_fn( + &sig.decl, + sig.header, + Some(item.ident.name), + param_names, + &item.vis, + &[], + Some(body), + ); self.s.word(" "); self.end(); // need to close a box self.end(); // need to close a box @@ -595,13 +589,15 @@ impl<'a> State<'a> { self.head(visibility_qualified(&item.vis, "union")); self.print_struct(struct_def, generics, item.ident.name, item.span, true); } - hir::ItemKind::Impl(unsafety, - polarity, - defaultness, - ref generics, - ref opt_trait, - ref ty, - impl_items) => { + hir::ItemKind::Impl( + unsafety, + polarity, + defaultness, + ref generics, + ref opt_trait, + ref ty, + impl_items, + ) => { self.head(""); self.print_visibility(&item.vis); self.print_defaultness(defaultness); @@ -691,10 +687,7 @@ impl<'a> State<'a> { self.print_path(&t.path, false) } - fn print_formal_generic_params( - &mut self, - generic_params: &[hir::GenericParam] - ) { + fn print_formal_generic_params(&mut self, generic_params: &[hir::GenericParam]) { if !generic_params.is_empty() { self.s.word("for"); self.print_generic_params(generic_params); @@ -707,13 +700,14 @@ impl<'a> State<'a> { self.print_trait_ref(&t.trait_ref) } - pub fn print_enum_def(&mut self, - enum_definition: &hir::EnumDef<'_>, - generics: &hir::Generics, - name: ast::Name, - span: syntax_pos::Span, - visibility: &hir::Visibility) - { + pub fn print_enum_def( + &mut self, + enum_definition: &hir::EnumDef<'_>, + generics: &hir::Generics, + name: ast::Name, + span: syntax_pos::Span, + visibility: &hir::Visibility, + ) { self.head(visibility_qualified(visibility, "enum")); self.print_name(name); self.print_generic_params(&generics.params); @@ -722,10 +716,7 @@ impl<'a> State<'a> { self.print_variants(&enum_definition.variants, span) } - pub fn print_variants(&mut self, - variants: &[hir::Variant<'_>], - span: syntax_pos::Span) - { + pub fn print_variants(&mut self, variants: &[hir::Variant<'_>], span: syntax_pos::Span) { self.bopen(); for v in variants { self.space_if_not_bol(); @@ -747,8 +738,7 @@ impl<'a> State<'a> { hir::VisibilityKind::Crate(ast::CrateSugar::PubCrate) => self.word_nbsp("pub(crate)"), hir::VisibilityKind::Restricted { ref path, .. } => { self.s.word("pub("); - if path.segments.len() == 1 && - path.segments[0].ident.name == kw::Super { + if path.segments.len() == 1 && path.segments[0].ident.name == kw::Super { // Special case: `super` can print like `pub(super)`. self.s.word("super"); } else { @@ -758,7 +748,7 @@ impl<'a> State<'a> { } self.word_nbsp(")"); } - hir::VisibilityKind::Inherited => () + hir::VisibilityKind::Inherited => (), } } @@ -769,13 +759,14 @@ impl<'a> State<'a> { } } - pub fn print_struct(&mut self, - struct_def: &hir::VariantData<'_>, - generics: &hir::Generics, - name: ast::Name, - span: syntax_pos::Span, - print_finalizer: bool) - { + pub fn print_struct( + &mut self, + struct_def: &hir::VariantData<'_>, + generics: &hir::Generics, + name: ast::Name, + span: syntax_pos::Span, + print_finalizer: bool, + ) { self.print_name(name); self.print_generic_params(&generics.params); match struct_def { @@ -829,21 +820,16 @@ impl<'a> State<'a> { self.print_anon_const(d); } } - pub fn print_method_sig(&mut self, - ident: ast::Ident, - m: &hir::FnSig, - generics: &hir::Generics, - vis: &hir::Visibility, - arg_names: &[ast::Ident], - body_id: Option) - { - self.print_fn(&m.decl, - m.header, - Some(ident.name), - generics, - vis, - arg_names, - body_id) + pub fn print_method_sig( + &mut self, + ident: ast::Ident, + m: &hir::FnSig, + generics: &hir::Generics, + vis: &hir::Visibility, + arg_names: &[ast::Ident], + body_id: Option, + ) { + self.print_fn(&m.decl, m.header, Some(ident.name), generics, vis, arg_names, body_id) } pub fn print_trait_item(&mut self, ti: &hir::TraitItem<'_>) { @@ -853,19 +839,19 @@ impl<'a> State<'a> { self.print_outer_attributes(&ti.attrs); match ti.kind { hir::TraitItemKind::Const(ref ty, default) => { - let vis = Spanned { span: syntax_pos::DUMMY_SP, - node: hir::VisibilityKind::Inherited }; + let vis = + Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Inherited }; self.print_associated_const(ti.ident, &ty, default, &vis); } hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref arg_names)) => { - let vis = Spanned { span: syntax_pos::DUMMY_SP, - node: hir::VisibilityKind::Inherited }; + let vis = + Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Inherited }; self.print_method_sig(ti.ident, sig, &ti.generics, &vis, arg_names, None); self.s.word(";"); } hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => { - let vis = Spanned { span: syntax_pos::DUMMY_SP, - node: hir::VisibilityKind::Inherited }; + let vis = + Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Inherited }; self.head(""); self.print_method_sig(ti.ident, sig, &ti.generics, &vis, &[], Some(body)); self.nbsp(); @@ -874,9 +860,11 @@ impl<'a> State<'a> { self.ann.nested(self, Nested::Body(body)); } hir::TraitItemKind::Type(ref bounds, ref default) => { - self.print_associated_type(ti.ident, - Some(bounds), - default.as_ref().map(|ty| &**ty)); + self.print_associated_type( + ti.ident, + Some(bounds), + default.as_ref().map(|ty| &**ty), + ); } } self.ann.post(self, AnnNode::SubItem(ti.hir_id)) @@ -914,11 +902,7 @@ impl<'a> State<'a> { self.ann.post(self, AnnNode::SubItem(ii.hir_id)) } - pub fn print_local( - &mut self, - init: Option<&hir::Expr>, - decl: impl Fn(&mut Self) - ) { + pub fn print_local(&mut self, init: Option<&hir::Expr>, decl: impl Fn(&mut Self)) { self.space_if_not_bol(); self.ibox(INDENT_UNIT); self.word_nbsp("let"); @@ -941,9 +925,7 @@ impl<'a> State<'a> { hir::StmtKind::Local(ref loc) => { self.print_local(loc.init.as_deref(), |this| this.print_local_decl(&loc)); } - hir::StmtKind::Item(item) => { - self.ann.nested(self, Nested::Item(item)) - } + hir::StmtKind::Item(item) => self.ann.nested(self, Nested::Item(item)), hir::StmtKind::Expr(ref expr) => { self.space_if_not_bol(); self.print_expr(&expr); @@ -968,18 +950,16 @@ impl<'a> State<'a> { self.print_block_maybe_unclosed(blk, &[], false) } - pub fn print_block_with_attrs(&mut self, - blk: &hir::Block, - attrs: &[ast::Attribute]) - { + pub fn print_block_with_attrs(&mut self, blk: &hir::Block, attrs: &[ast::Attribute]) { self.print_block_maybe_unclosed(blk, attrs, true) } - pub fn print_block_maybe_unclosed(&mut self, - blk: &hir::Block, - attrs: &[ast::Attribute], - close_box: bool) - { + pub fn print_block_maybe_unclosed( + &mut self, + blk: &hir::Block, + attrs: &[ast::Attribute], + close_box: bool, + ) { match blk.rules { hir::UnsafeBlock(..) => self.word_space("unsafe"), hir::PushUnsafeBlock(..) => self.word_space("push_unsafe"), @@ -1031,9 +1011,7 @@ impl<'a> State<'a> { let needs_par = match expr.kind { // These cases need parens due to the parse error observed in #26461: `if return {}` // parses as the erroneous construct `if (return {})`, not `if (return) {}`. - hir::ExprKind::Closure(..) | - hir::ExprKind::Ret(..) | - hir::ExprKind::Break(..) => true, + hir::ExprKind::Closure(..) | hir::ExprKind::Ret(..) | hir::ExprKind::Break(..) => true, _ => contains_exterior_struct_lit(expr), }; @@ -1065,25 +1043,28 @@ impl<'a> State<'a> { self.end() } - fn print_expr_struct(&mut self, - qpath: &hir::QPath, - fields: &[hir::Field], - wth: &Option>) - { + fn print_expr_struct( + &mut self, + qpath: &hir::QPath, + fields: &[hir::Field], + wth: &Option>, + ) { self.print_qpath(qpath, true); self.s.word("{"); - self.commasep_cmnt(Consistent, - &fields[..], - |s, field| { - s.ibox(INDENT_UNIT); - if !field.is_shorthand { - s.print_ident(field.ident); - s.word_space(":"); - } - s.print_expr(&field.expr); - s.end() - }, - |f| f.span); + self.commasep_cmnt( + Consistent, + &fields[..], + |s, field| { + s.ibox(INDENT_UNIT); + if !field.is_shorthand { + s.print_ident(field.ident); + s.word_space(":"); + } + s.print_expr(&field.expr); + s.end() + }, + |f| f.span, + ); match *wth { Some(ref expr) => { self.ibox(INDENT_UNIT); @@ -1095,9 +1076,11 @@ impl<'a> State<'a> { self.print_expr(&expr); self.end(); } - _ => if !fields.is_empty() { - self.s.word(",") - }, + _ => { + if !fields.is_empty() { + self.s.word(",") + } + } } self.s.word("}"); } @@ -1121,10 +1104,7 @@ impl<'a> State<'a> { self.print_call_post(args) } - fn print_expr_method_call(&mut self, - segment: &hir::PathSegment, - args: &[hir::Expr]) - { + fn print_expr_method_call(&mut self, segment: &hir::PathSegment, args: &[hir::Expr]) { let base_args = &args[1..]; self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX); self.s.word("."); @@ -1138,11 +1118,7 @@ impl<'a> State<'a> { self.print_call_post(base_args) } - fn print_expr_binary(&mut self, - op: hir::BinOp, - lhs: &hir::Expr, - rhs: &hir::Expr) - { + fn print_expr_binary(&mut self, op: hir::BinOp, lhs: &hir::Expr, rhs: &hir::Expr) { let assoc_op = bin_op_to_assoc_op(op.node); let prec = assoc_op.precedence() as i8; let fixity = assoc_op.fixity(); @@ -1157,8 +1133,8 @@ impl<'a> State<'a> { // These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is // the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead // of `(x as i32) < ...`. We need to convince it _not_ to do that. - (&hir::ExprKind::Cast { .. }, hir::BinOpKind::Lt) | - (&hir::ExprKind::Cast { .. }, hir::BinOpKind::Shl) => parser::PREC_FORCE_PAREN, + (&hir::ExprKind::Cast { .. }, hir::BinOpKind::Lt) + | (&hir::ExprKind::Cast { .. }, hir::BinOpKind::Shl) => parser::PREC_FORCE_PAREN, _ => left_prec, }; @@ -1173,11 +1149,12 @@ impl<'a> State<'a> { self.print_expr_maybe_paren(expr, parser::PREC_PREFIX) } - fn print_expr_addr_of(&mut self, - kind: hir::BorrowKind, - mutability: hir::Mutability, - expr: &hir::Expr) - { + fn print_expr_addr_of( + &mut self, + kind: hir::BorrowKind, + mutability: hir::Mutability, + expr: &hir::Expr, + ) { self.s.word("&"); match kind { hir::BorrowKind::Ref => self.print_mutability(mutability, false), @@ -1338,9 +1315,7 @@ impl<'a> State<'a> { self.print_expr(&index); self.s.word("]"); } - hir::ExprKind::Path(ref qpath) => { - self.print_qpath(qpath, true) - } + hir::ExprKind::Path(ref qpath) => self.print_qpath(qpath, true), hir::ExprKind::Break(destination, ref opt_expr) => { self.s.word("break"); self.s.space(); @@ -1381,8 +1356,7 @@ impl<'a> State<'a> { let mut ch = constraint.chars(); match ch.next() { Some('=') if out.is_rw => { - s.print_string(&format!("+{}", ch.as_str()), - ast::StrStyle::Cooked) + s.print_string(&format!("+{}", ch.as_str()), ast::StrStyle::Cooked) } _ => s.print_string(&constraint, ast::StrStyle::Cooked), } @@ -1467,10 +1441,7 @@ impl<'a> State<'a> { self.print_expr(coll) } - pub fn print_path(&mut self, - path: &hir::Path, - colons_before_params: bool) - { + pub fn print_path(&mut self, path: &hir::Path, colons_before_params: bool) { self.maybe_print_comment(path.span.lo()); for (i, segment) in path.segments.iter().enumerate() { @@ -1479,8 +1450,11 @@ impl<'a> State<'a> { } if segment.ident.name != kw::PathRoot { self.print_ident(segment.ident); - self.print_generic_args(segment.generic_args(), segment.infer_args, - colons_before_params); + self.print_generic_args( + segment.generic_args(), + segment.infer_args, + colons_before_params, + ); } } } @@ -1492,14 +1466,9 @@ impl<'a> State<'a> { } } - pub fn print_qpath(&mut self, - qpath: &hir::QPath, - colons_before_params: bool) - { + pub fn print_qpath(&mut self, qpath: &hir::QPath, colons_before_params: bool) { match *qpath { - hir::QPath::Resolved(None, ref path) => { - self.print_path(path, colons_before_params) - } + hir::QPath::Resolved(None, ref path) => self.print_path(path, colons_before_params), hir::QPath::Resolved(Some(ref qself), ref path) => { self.s.word("<"); self.print_type(qself); @@ -1512,9 +1481,11 @@ impl<'a> State<'a> { } if segment.ident.name != kw::PathRoot { self.print_ident(segment.ident); - self.print_generic_args(segment.generic_args(), - segment.infer_args, - colons_before_params); + self.print_generic_args( + segment.generic_args(), + segment.infer_args, + colons_before_params, + ); } } @@ -1522,9 +1493,11 @@ impl<'a> State<'a> { self.s.word("::"); let item_segment = path.segments.last().unwrap(); self.print_ident(item_segment.ident); - self.print_generic_args(item_segment.generic_args(), - item_segment.infer_args, - colons_before_params) + self.print_generic_args( + item_segment.generic_args(), + item_segment.infer_args, + colons_before_params, + ) } hir::QPath::TypeRelative(ref qself, ref item_segment) => { // If we've got a compound-qualified-path, let's push an additional pair of angle @@ -1540,18 +1513,21 @@ impl<'a> State<'a> { self.s.word("::"); self.print_ident(item_segment.ident); - self.print_generic_args(item_segment.generic_args(), - item_segment.infer_args, - colons_before_params) + self.print_generic_args( + item_segment.generic_args(), + item_segment.infer_args, + colons_before_params, + ) } } } - fn print_generic_args(&mut self, - generic_args: &hir::GenericArgs, - infer_args: bool, - colons_before_params: bool) - { + fn print_generic_args( + &mut self, + generic_args: &hir::GenericArgs, + infer_args: bool, + colons_before_params: bool, + ) { if generic_args.parenthesized { self.s.word("("); self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(&ty)); @@ -1583,14 +1559,16 @@ impl<'a> State<'a> { if nonelided_generic_args { start_or_comma(self); - self.commasep(Inconsistent, &generic_args.args, |s, generic_arg| { - match generic_arg { + self.commasep( + Inconsistent, + &generic_args.args, + |s, generic_arg| match generic_arg { GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt), - GenericArg::Lifetime(_) => {}, + GenericArg::Lifetime(_) => {} GenericArg::Type(ty) => s.print_type(ty), GenericArg::Const(ct) => s.print_anon_const(&ct.value), - } - }); + }, + ); } // FIXME(eddyb): this would leak into error messages (e.g., @@ -1674,18 +1652,20 @@ impl<'a> State<'a> { self.print_qpath(qpath, true); self.nbsp(); self.word_space("{"); - self.commasep_cmnt(Consistent, - &fields[..], - |s, f| { - s.cbox(INDENT_UNIT); - if !f.is_shorthand { - s.print_ident(f.ident); - s.word_nbsp(":"); - } - s.print_pat(&f.pat); - s.end() - }, - |f| f.pat.span); + self.commasep_cmnt( + Consistent, + &fields[..], + |s, f| { + s.cbox(INDENT_UNIT); + if !f.is_shorthand { + s.print_ident(f.ident); + s.word_nbsp(":"); + } + s.print_pat(&f.pat); + s.end() + }, + |f| f.pat.span, + ); if etc { if !fields.is_empty() { self.word_space(","); @@ -1833,15 +1813,16 @@ impl<'a> State<'a> { self.end() // close enclosing cbox } - pub fn print_fn(&mut self, - decl: &hir::FnDecl, - header: hir::FnHeader, - name: Option, - generics: &hir::Generics, - vis: &hir::Visibility, - arg_names: &[ast::Ident], - body_id: Option) - { + pub fn print_fn( + &mut self, + decl: &hir::FnDecl, + header: hir::FnHeader, + name: Option, + generics: &hir::Generics, + vis: &hir::Visibility, + arg_names: &[ast::Ident], + body_id: Option, + ) { self.print_fn_header_info(header, vis); if let Some(name) = name { @@ -1916,7 +1897,7 @@ impl<'a> State<'a> { pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureBy) { match capture_clause { hir::CaptureBy::Value => self.word_space("move"), - hir::CaptureBy::Ref => {}, + hir::CaptureBy::Ref => {} } } @@ -1957,9 +1938,7 @@ impl<'a> State<'a> { if !generic_params.is_empty() { self.s.word("<"); - self.commasep(Inconsistent, generic_params, |s, param| { - s.print_generic_param(param) - }); + self.commasep(Inconsistent, generic_params, |s, param| s.print_generic_param(param)); self.s.word(">"); } @@ -2032,9 +2011,11 @@ impl<'a> State<'a> { self.print_type(&bounded_ty); self.print_bounds(":", bounds); } - &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime, - ref bounds, - ..}) => { + &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { + ref lifetime, + ref bounds, + .. + }) => { self.print_lifetime(lifetime); self.s.word(":"); @@ -2051,9 +2032,11 @@ impl<'a> State<'a> { } } } - &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ref lhs_ty, - ref rhs_ty, - ..}) => { + &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { + ref lhs_ty, + ref rhs_ty, + .. + }) => { self.print_type(lhs_ty); self.s.space(); self.word_space("="); @@ -2066,7 +2049,11 @@ impl<'a> State<'a> { pub fn print_mutability(&mut self, mutbl: hir::Mutability, print_const: bool) { match mutbl { hir::Mutability::Mut => self.word_nbsp("mut"), - hir::Mutability::Not => if print_const { self.word_nbsp("const") }, + hir::Mutability::Not => { + if print_const { + self.word_nbsp("const") + } + } } } @@ -2091,18 +2078,19 @@ impl<'a> State<'a> { match decl.output { hir::Return(ref output) => self.maybe_print_comment(output.span.lo()), - _ => {}, + _ => {} } } - pub fn print_ty_fn(&mut self, - abi: Abi, - unsafety: hir::Unsafety, - decl: &hir::FnDecl, - name: Option, - generic_params: &[hir::GenericParam], - arg_names: &[ast::Ident]) - { + pub fn print_ty_fn( + &mut self, + abi: Abi, + unsafety: hir::Unsafety, + decl: &hir::FnDecl, + name: Option, + generic_params: &[hir::GenericParam], + arg_names: &[ast::Ident], + ) { self.ibox(INDENT_UNIT); if !generic_params.is_empty() { self.s.word("for"); @@ -2116,26 +2104,28 @@ impl<'a> State<'a> { }, span: syntax_pos::DUMMY_SP, }; - self.print_fn(decl, - hir::FnHeader { - unsafety, - abi, - constness: hir::Constness::NotConst, - asyncness: hir::IsAsync::NotAsync, - }, - name, - &generics, - &Spanned { span: syntax_pos::DUMMY_SP, - node: hir::VisibilityKind::Inherited }, - arg_names, - None); + self.print_fn( + decl, + hir::FnHeader { + unsafety, + abi, + constness: hir::Constness::NotConst, + asyncness: hir::IsAsync::NotAsync, + }, + name, + &generics, + &Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Inherited }, + arg_names, + None, + ); self.end(); } - pub fn maybe_print_trailing_comment(&mut self, - span: syntax_pos::Span, - next_pos: Option) - { + pub fn maybe_print_trailing_comment( + &mut self, + span: syntax_pos::Span, + next_pos: Option, + ) { if let Some(cmnts) = self.comments() { if let Some(cmnt) = cmnts.trailing_comment(span, next_pos) { self.print_comment(&cmnt); @@ -2154,16 +2144,14 @@ impl<'a> State<'a> { } } - pub fn print_opt_abi_and_extern_if_nondefault(&mut self, - opt_abi: Option) - { + pub fn print_opt_abi_and_extern_if_nondefault(&mut self, opt_abi: Option) { match opt_abi { - Some(Abi::Rust) => {}, + Some(Abi::Rust) => {} Some(abi) => { self.word_nbsp("extern"); self.word_nbsp(abi.to_string()) } - None => {}, + None => {} } } @@ -2173,14 +2161,11 @@ impl<'a> State<'a> { self.word_nbsp("extern"); self.word_nbsp(abi.to_string()) } - None => {}, + None => {} } } - pub fn print_fn_header_info(&mut self, - header: hir::FnHeader, - vis: &hir::Visibility) - { + pub fn print_fn_header_info(&mut self, header: hir::FnHeader, vis: &hir::Visibility) { self.s.word(visibility_qualified(vis, "")); match header.constness { @@ -2213,7 +2198,7 @@ impl<'a> State<'a> { pub fn print_is_auto(&mut self, s: hir::IsAuto) { match s { hir::IsAuto::Yes => self.word_nbsp("auto"), - hir::IsAuto::No => {}, + hir::IsAuto::No => {} } } } @@ -2229,9 +2214,7 @@ impl<'a> State<'a> { // Duplicated from `parse::classify`, but adapted for the HIR. fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool { match e.kind { - hir::ExprKind::Match(..) | - hir::ExprKind::Block(..) | - hir::ExprKind::Loop(..) => false, + hir::ExprKind::Match(..) | hir::ExprKind::Block(..) | hir::ExprKind::Loop(..) => false, _ => true, } } @@ -2282,17 +2265,17 @@ fn contains_exterior_struct_lit(value: &hir::Expr) -> bool { match value.kind { hir::ExprKind::Struct(..) => true, - hir::ExprKind::Assign(ref lhs, ref rhs) | - hir::ExprKind::AssignOp(_, ref lhs, ref rhs) | - hir::ExprKind::Binary(_, ref lhs, ref rhs) => { + hir::ExprKind::Assign(ref lhs, ref rhs) + | hir::ExprKind::AssignOp(_, ref lhs, ref rhs) + | hir::ExprKind::Binary(_, ref lhs, ref rhs) => { // `X { y: 1 } + X { y: 2 }` contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs) } - hir::ExprKind::Unary(_, ref x) | - hir::ExprKind::Cast(ref x, _) | - hir::ExprKind::Type(ref x, _) | - hir::ExprKind::Field(ref x, _) | - hir::ExprKind::Index(ref x, _) => { + hir::ExprKind::Unary(_, ref x) + | hir::ExprKind::Cast(ref x, _) + | hir::ExprKind::Type(ref x, _) + | hir::ExprKind::Field(ref x, _) + | hir::ExprKind::Index(ref x, _) => { // `&X { y: 1 }, X { y: 1 }.y` contains_exterior_struct_lit(&x) } diff --git a/src/librustc/hir/ptr.rs b/src/librustc/hir/ptr.rs index 7ee461a859bd6..b5d0c6b051f8d 100644 --- a/src/librustc/hir/ptr.rs +++ b/src/librustc/hir/ptr.rs @@ -2,26 +2,24 @@ // frozen anyway). The only reason for doing this instead of replacing `P` // with `Box` in HIR, is that `&Box<[T]>` doesn't implement `IntoIterator`. -use std::fmt::{self, Display, Debug}; +use std::fmt::{self, Debug, Display}; use std::iter::FromIterator; use std::ops::Deref; use std::{slice, vec}; -use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; +use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; -use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; /// An owned smart pointer. #[derive(PartialEq, Eq)] pub struct P { - ptr: Box + ptr: Box, } /// Construct a `P` from a `T` value. #[allow(non_snake_case)] pub fn P(value: T) -> P { - P { - ptr: box value - } + P { ptr: box value } } impl P { @@ -89,7 +87,6 @@ impl P<[T]> { } } - impl Default for P<[T]> { /// Creates an empty `P<[T]>`. fn default() -> P<[T]> { @@ -104,7 +101,7 @@ impl From> for P<[T]> { } impl FromIterator for P<[T]> { - fn from_iter>(iter: I) -> P<[T]> { + fn from_iter>(iter: I) -> P<[T]> { P::from_vec(iter.into_iter().collect()) } } @@ -130,7 +127,8 @@ impl Decodable for P<[T]> { } impl HashStable for P - where T: ?Sized + HashStable +where + T: ?Sized + HashStable, { fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { (**self).hash_stable(hcx, hasher); diff --git a/src/librustc/hir/upvars.rs b/src/librustc/hir/upvars.rs index 5c5f7f6120082..2df7a38693af6 100644 --- a/src/librustc/hir/upvars.rs +++ b/src/librustc/hir/upvars.rs @@ -1,12 +1,12 @@ //! Upvar (closure capture) collection from cross-body HIR uses of `Res::Local`s. -use crate::hir::{self, HirId}; use crate::hir::def::Res; -use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; -use crate::ty::TyCtxt; +use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; +use crate::hir::{self, HirId}; use crate::ty::query::Providers; +use crate::ty::TyCtxt; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use syntax_pos::Span; -use rustc_data_structures::fx::{FxIndexMap, FxHashSet}; pub fn provide(providers: &mut Providers<'_>) { providers.upvars = |tcx, def_id| { diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index af5e167faa8b7..9442392ea9e31 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -1,23 +1,21 @@ use crate::hir; use crate::hir::def_id::{DefId, DefIndex}; -use crate::hir::map::DefPathHash; use crate::hir::map::definitions::Definitions; +use crate::hir::map::DefPathHash; use crate::ich::{self, CachingSourceMapView}; use crate::middle::cstore::CrateStore; -use crate::ty::{TyCtxt, fast_reject}; use crate::session::Session; +use crate::ty::{fast_reject, TyCtxt}; use std::cmp::Ord; use syntax::ast; use syntax::source_map::SourceMap; use syntax::symbol::Symbol; -use syntax_pos::{SourceFile, BytePos}; +use syntax_pos::{BytePos, SourceFile}; -use rustc_data_structures::stable_hasher::{ - HashStable, StableHasher, ToStableHashKey, -}; -use rustc_data_structures::fx::{FxHashSet, FxHashMap}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use rustc_data_structures::sync::Lrc; use smallvec::SmallVec; @@ -71,11 +69,12 @@ impl<'a> StableHashingContext<'a> { /// Don't use it for anything else or you'll run the risk of /// leaking data out of the tracking system. #[inline] - pub fn new(sess: &'a Session, - krate: &'a hir::Crate<'a>, - definitions: &'a Definitions, - cstore: &'a dyn CrateStore) - -> Self { + pub fn new( + sess: &'a Session, + krate: &'a hir::Crate<'a>, + definitions: &'a Definitions, + cstore: &'a dyn CrateStore, + ) -> Self { let hash_spans_initial = !sess.opts.debugging_opts.incremental_ignore_spans; StableHashingContext { @@ -97,9 +96,7 @@ impl<'a> StableHashingContext<'a> { } #[inline] - pub fn while_hashing_hir_bodies(&mut self, - hash_bodies: bool, - f: F) { + pub fn while_hashing_hir_bodies(&mut self, hash_bodies: bool, f: F) { let prev_hash_bodies = self.hash_bodies; self.hash_bodies = hash_bodies; f(self); @@ -107,9 +104,7 @@ impl<'a> StableHashingContext<'a> { } #[inline] - pub fn while_hashing_spans(&mut self, - hash_spans: bool, - f: F) { + pub fn while_hashing_spans(&mut self, hash_spans: bool, f: F) { let prev_hash_spans = self.hash_spans; self.hash_spans = hash_spans; f(self); @@ -117,9 +112,11 @@ impl<'a> StableHashingContext<'a> { } #[inline] - pub fn with_node_id_hashing_mode(&mut self, - mode: NodeIdHashingMode, - f: F) { + pub fn with_node_id_hashing_mode( + &mut self, + mode: NodeIdHashingMode, + f: F, + ) { let prev = self.node_id_hashing_mode; self.node_id_hashing_mode = mode; f(self); @@ -153,9 +150,7 @@ impl<'a> StableHashingContext<'a> { #[inline] pub fn source_map(&mut self) -> &mut CachingSourceMapView<'a> { match self.caching_source_map { - Some(ref mut cm) => { - cm - } + Some(ref mut cm) => cm, ref mut none => { *none = Some(CachingSourceMapView::new(self.raw_source_map)); none.as_mut().unwrap() @@ -186,15 +181,13 @@ pub trait StableHashingContextProvider<'a> { fn get_stable_hashing_context(&self) -> StableHashingContext<'a>; } -impl<'a, 'b, T: StableHashingContextProvider<'a>> StableHashingContextProvider<'a> -for &'b T { +impl<'a, 'b, T: StableHashingContextProvider<'a>> StableHashingContextProvider<'a> for &'b T { fn get_stable_hashing_context(&self) -> StableHashingContext<'a> { (**self).get_stable_hashing_context() } } -impl<'a, 'b, T: StableHashingContextProvider<'a>> StableHashingContextProvider<'a> -for &'b mut T { +impl<'a, 'b, T: StableHashingContextProvider<'a>> StableHashingContextProvider<'a> for &'b mut T { fn get_stable_hashing_context(&self) -> StableHashingContext<'a> { (**self).get_stable_hashing_context() } @@ -230,10 +223,7 @@ impl<'a> HashStable> for hir::HirId { // Don't do anything. } NodeIdHashingMode::HashDefPath => { - let hir::HirId { - owner, - local_id, - } = *self; + let hir::HirId { owner, local_id } = *self; hcx.local_def_path_hash(owner).hash_stable(hcx, hasher); local_id.hash_stable(hcx, hasher); @@ -246,9 +236,10 @@ impl<'a> ToStableHashKey> for hir::HirId { type KeyType = (DefPathHash, hir::ItemLocalId); #[inline] - fn to_stable_hash_key(&self, - hcx: &StableHashingContext<'a>) - -> (DefPathHash, hir::ItemLocalId) { + fn to_stable_hash_key( + &self, + hcx: &StableHashingContext<'a>, + ) -> (DefPathHash, hir::ItemLocalId) { let def_path_hash = hcx.local_def_path_hash(self.owner); (def_path_hash, self.local_id) } @@ -271,9 +262,10 @@ impl<'a> ToStableHashKey> for ast::NodeId { type KeyType = (DefPathHash, hir::ItemLocalId); #[inline] - fn to_stable_hash_key(&self, - hcx: &StableHashingContext<'a>) - -> (DefPathHash, hir::ItemLocalId) { + fn to_stable_hash_key( + &self, + hcx: &StableHashingContext<'a>, + ) -> (DefPathHash, hir::ItemLocalId) { hcx.definitions.node_to_hir_id(*self).to_stable_hash_key(hcx) } } @@ -283,9 +275,10 @@ impl<'a> syntax_pos::HashStableContext for StableHashingContext<'a> { self.hash_spans } - fn byte_pos_to_line_and_col(&mut self, byte: BytePos) - -> Option<(Lrc, usize, BytePos)> - { + fn byte_pos_to_line_and_col( + &mut self, + byte: BytePos, + ) -> Option<(Lrc, usize, BytePos)> { self.source_map().byte_pos_to_line_and_col(byte) } } @@ -297,10 +290,8 @@ pub fn hash_stable_trait_impls<'a>( non_blanket_impls: &FxHashMap>, ) { { - let mut blanket_impls: SmallVec<[_; 8]> = blanket_impls - .iter() - .map(|&def_id| hcx.def_path_hash(def_id)) - .collect(); + let mut blanket_impls: SmallVec<[_; 8]> = + blanket_impls.iter().map(|&def_id| hcx.def_path_hash(def_id)).collect(); if blanket_impls.len() > 1 { blanket_impls.sort_unstable(); @@ -311,17 +302,13 @@ pub fn hash_stable_trait_impls<'a>( { let mut keys: SmallVec<[_; 8]> = - non_blanket_impls.keys() - .map(|k| (k, k.map_def(|d| hcx.def_path_hash(d)))) - .collect(); + non_blanket_impls.keys().map(|k| (k, k.map_def(|d| hcx.def_path_hash(d)))).collect(); keys.sort_unstable_by(|&(_, ref k1), &(_, ref k2)| k1.cmp(k2)); keys.len().hash_stable(hcx, hasher); for (key, ref stable_key) in keys { stable_key.hash_stable(hcx, hasher); - let mut impls : SmallVec<[_; 8]> = non_blanket_impls[key] - .iter() - .map(|&impl_id| hcx.def_path_hash(impl_id)) - .collect(); + let mut impls: SmallVec<[_; 8]> = + non_blanket_impls[key].iter().map(|&impl_id| hcx.def_path_hash(impl_id)).collect(); if impls.len() > 1 { impls.sort_unstable(); diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 1f96f4c65ef69..360fa99c6208f 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -2,11 +2,11 @@ //! types in no particular order. use crate::hir; +use crate::hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX}; use crate::hir::map::DefPathHash; -use crate::hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX}; -use crate::ich::{StableHashingContext, NodeIdHashingMode, Fingerprint}; +use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext}; -use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use smallvec::SmallVec; use std::mem; use syntax::attr; @@ -46,10 +46,7 @@ impl<'a> ToStableHashKey> for LocalDefId { impl<'a> HashStable> for CrateNum { #[inline] fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - hcx.def_path_hash(DefId { - krate: *self, - index: CRATE_DEF_INDEX - }).hash_stable(hcx, hasher); + hcx.def_path_hash(DefId { krate: *self, index: CRATE_DEF_INDEX }).hash_stable(hcx, hasher); } } @@ -63,14 +60,11 @@ impl<'a> ToStableHashKey> for CrateNum { } } -impl<'a> ToStableHashKey> -for hir::ItemLocalId { +impl<'a> ToStableHashKey> for hir::ItemLocalId { type KeyType = hir::ItemLocalId; #[inline] - fn to_stable_hash_key(&self, - _: &StableHashingContext<'a>) - -> hir::ItemLocalId { + fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> hir::ItemLocalId { *self } } @@ -84,9 +78,7 @@ for hir::ItemLocalId { impl<'a> HashStable> for hir::ItemId { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let hir::ItemId { - id - } = *self; + let hir::ItemId { id } = *self; hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { id.hash_stable(hcx, hasher); @@ -96,9 +88,7 @@ impl<'a> HashStable> for hir::ItemId { impl<'a> HashStable> for hir::TraitItemId { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let hir::TraitItemId { - hir_id - } = * self; + let hir::TraitItemId { hir_id } = *self; hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { hir_id.hash_stable(hcx, hasher); @@ -108,9 +98,7 @@ impl<'a> HashStable> for hir::TraitItemId { impl<'a> HashStable> for hir::ImplItemId { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let hir::ImplItemId { - hir_id - } = * self; + let hir::ImplItemId { hir_id } = *self; hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { hir_id.hash_stable(hcx, hasher); @@ -121,11 +109,7 @@ impl<'a> HashStable> for hir::ImplItemId { impl<'a> HashStable> for hir::Ty { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { hcx.while_hashing_hir_bodies(true, |hcx| { - let hir::Ty { - hir_id: _, - ref kind, - ref span, - } = *self; + let hir::Ty { hir_id: _, ref kind, ref span } = *self; kind.hash_stable(hcx, hasher); span.hash_stable(hcx, hasher); @@ -136,12 +120,7 @@ impl<'a> HashStable> for hir::Ty { impl<'a> HashStable> for hir::Expr { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { hcx.while_hashing_hir_bodies(true, |hcx| { - let hir::Expr { - hir_id: _, - ref span, - ref kind, - ref attrs - } = *self; + let hir::Expr { hir_id: _, ref span, ref kind, ref attrs } = *self; span.hash_stable(hcx, hasher); kind.hash_stable(hcx, hasher); @@ -152,14 +131,7 @@ impl<'a> HashStable> for hir::Expr { impl<'a> HashStable> for hir::TraitItem<'_> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let hir::TraitItem { - hir_id: _, - ident, - ref attrs, - ref generics, - ref kind, - span - } = *self; + let hir::TraitItem { hir_id: _, ident, ref attrs, ref generics, ref kind, span } = *self; hcx.hash_hir_item_like(|hcx| { ident.name.hash_stable(hcx, hasher); @@ -171,7 +143,6 @@ impl<'a> HashStable> for hir::TraitItem<'_> { } } - impl<'a> HashStable> for hir::ImplItem<'_> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { let hir::ImplItem { @@ -182,7 +153,7 @@ impl<'a> HashStable> for hir::ImplItem<'_> { ref attrs, ref generics, ref kind, - span + span, } = *self; hcx.hash_hir_item_like(|hcx| { @@ -201,8 +172,7 @@ impl<'a> HashStable> for hir::VisibilityKind { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { - hir::VisibilityKind::Public | - hir::VisibilityKind::Inherited => { + hir::VisibilityKind::Public | hir::VisibilityKind::Inherited => { // No fields to hash. } hir::VisibilityKind::Crate(sugar) => { @@ -220,10 +190,7 @@ impl<'a> HashStable> for hir::VisibilityKind { impl<'a> HashStable> for hir::Mod<'_> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let hir::Mod { - inner: ref inner_span, - ref item_ids, - } = *self; + let hir::Mod { inner: ref inner_span, ref item_ids } = *self; inner_span.hash_stable(hcx, hasher); @@ -236,9 +203,8 @@ impl<'a> HashStable> for hir::Mod<'_> { let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx); debug_assert_eq!(local_id, hir::ItemLocalId::from_u32(0)); def_path_hash.0 - }).fold(Fingerprint::ZERO, |a, b| { - a.combine_commutative(b) - }); + }) + .fold(Fingerprint::ZERO, |a, b| a.combine_commutative(b)); item_ids.len().hash_stable(hcx, hasher); item_ids_hash.hash_stable(hcx, hasher); @@ -247,14 +213,7 @@ impl<'a> HashStable> for hir::Mod<'_> { impl<'a> HashStable> for hir::Item<'_> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let hir::Item { - ident, - ref attrs, - hir_id: _, - ref kind, - ref vis, - span - } = *self; + let hir::Item { ident, ref attrs, hir_id: _, ref kind, ref vis, span } = *self; hcx.hash_hir_item_like(|hcx| { ident.name.hash_stable(hcx, hasher); @@ -268,11 +227,7 @@ impl<'a> HashStable> for hir::Item<'_> { impl<'a> HashStable> for hir::Body<'_> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let hir::Body { - params, - value, - generator_kind, - } = self; + let hir::Body { params, value, generator_kind } = self; hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| { params.hash_stable(hcx, hasher); @@ -286,16 +241,16 @@ impl<'a> ToStableHashKey> for hir::BodyId { type KeyType = (DefPathHash, hir::ItemLocalId); #[inline] - fn to_stable_hash_key(&self, - hcx: &StableHashingContext<'a>) - -> (DefPathHash, hir::ItemLocalId) { + fn to_stable_hash_key( + &self, + hcx: &StableHashingContext<'a>, + ) -> (DefPathHash, hir::ItemLocalId) { let hir::BodyId { hir_id } = *self; hir_id.to_stable_hash_key(hcx) } } impl<'a> HashStable> for hir::def_id::DefIndex { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { hcx.local_def_path_hash(*self).hash_stable(hcx, hasher); } @@ -306,7 +261,7 @@ impl<'a> ToStableHashKey> for hir::def_id::DefIndex { #[inline] fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash { - hcx.local_def_path_hash(*self) + hcx.local_def_path_hash(*self) } } @@ -319,10 +274,7 @@ impl<'a> HashStable> for crate::middle::lang_items::Lan impl<'a> HashStable> for hir::TraitCandidate { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { - let hir::TraitCandidate { - def_id, - import_ids, - } = self; + let hir::TraitCandidate { def_id, import_ids } = self; def_id.hash_stable(hcx, hasher); import_ids.hash_stable(hcx, hasher); @@ -333,17 +285,14 @@ impl<'a> HashStable> for hir::TraitCandidate { impl<'a> ToStableHashKey> for hir::TraitCandidate { type KeyType = (DefPathHash, SmallVec<[(DefPathHash, hir::ItemLocalId); 1]>); - fn to_stable_hash_key(&self, - hcx: &StableHashingContext<'a>) - -> Self::KeyType { - let hir::TraitCandidate { - def_id, - import_ids, - } = self; - - let import_keys = import_ids.iter().map(|node_id| hcx.node_to_hir_id(*node_id)) - .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner), - hir_id.local_id)).collect(); + fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Self::KeyType { + let hir::TraitCandidate { def_id, import_ids } = self; + + let import_keys = import_ids + .iter() + .map(|node_id| hcx.node_to_hir_id(*node_id)) + .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner), hir_id.local_id)) + .collect(); (hcx.def_path_hash(*def_id), import_keys) } } diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 6499e56325a42..e13822aed4de7 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -6,10 +6,10 @@ use crate::ich::StableHashingContext; use syntax::ast; use syntax_pos::SourceFile; -use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX}; +use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; -use smallvec::SmallVec; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use smallvec::SmallVec; impl<'ctx> rustc_target::HashStableContext for StableHashingContext<'ctx> {} @@ -24,15 +24,15 @@ impl<'a> HashStable> for [ast::Attribute] { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { if self.len() == 0 { self.len().hash_stable(hcx, hasher); - return + return; } // Some attributes are always ignored during hashing. let filtered: SmallVec<[&ast::Attribute; 8]> = self .iter() .filter(|attr| { - !attr.is_doc_comment() && - !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)) + !attr.is_doc_comment() + && !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)) }) .collect(); @@ -85,10 +85,8 @@ impl<'a> HashStable> for SourceFile { (name_hash as u64).hash_stable(hcx, hasher); name_was_remapped.hash_stable(hcx, hasher); - DefId { - krate: CrateNum::from_u32(crate_of_origin), - index: CRATE_DEF_INDEX, - }.hash_stable(hcx, hasher); + DefId { krate: CrateNum::from_u32(crate_of_origin), index: CRATE_DEF_INDEX } + .hash_stable(hcx, hasher); src_hash.hash_stable(hcx, hasher); @@ -113,48 +111,41 @@ impl<'a> HashStable> for SourceFile { for &char_pos in normalized_pos.iter() { stable_normalized_pos(char_pos, start_pos).hash_stable(hcx, hasher); } - } } -fn stable_byte_pos(pos: ::syntax_pos::BytePos, - source_file_start: ::syntax_pos::BytePos) - -> u32 { +fn stable_byte_pos(pos: ::syntax_pos::BytePos, source_file_start: ::syntax_pos::BytePos) -> u32 { pos.0 - source_file_start.0 } -fn stable_multibyte_char(mbc: ::syntax_pos::MultiByteChar, - source_file_start: ::syntax_pos::BytePos) - -> (u32, u32) { - let ::syntax_pos::MultiByteChar { - pos, - bytes, - } = mbc; +fn stable_multibyte_char( + mbc: ::syntax_pos::MultiByteChar, + source_file_start: ::syntax_pos::BytePos, +) -> (u32, u32) { + let ::syntax_pos::MultiByteChar { pos, bytes } = mbc; (pos.0 - source_file_start.0, bytes as u32) } -fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar, - source_file_start: ::syntax_pos::BytePos) - -> (u32, u32) { +fn stable_non_narrow_char( + swc: ::syntax_pos::NonNarrowChar, + source_file_start: ::syntax_pos::BytePos, +) -> (u32, u32) { let pos = swc.pos(); let width = swc.width(); (pos.0 - source_file_start.0, width as u32) } -fn stable_normalized_pos(np: ::syntax_pos::NormalizedPos, - source_file_start: ::syntax_pos::BytePos) - -> (u32, u32) { - let ::syntax_pos::NormalizedPos { - pos, - diff - } = np; +fn stable_normalized_pos( + np: ::syntax_pos::NormalizedPos, + source_file_start: ::syntax_pos::BytePos, +) -> (u32, u32) { + let ::syntax_pos::NormalizedPos { pos, diff } = np; (pos.0 - source_file_start.0, diff) } - impl<'tcx> HashStable> for rustc_feature::Features { fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) { // Unfortunately we cannot exhaustively list fields here, since the diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 7f50d859cde3a..6af0cee948d86 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1,14 +1,14 @@ //! This module contains `HashStable` implementations for various data types //! from rustc::ty in no particular order. -use crate::ich::{Fingerprint, StableHashingContext, NodeIdHashingMode}; +use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext}; +use crate::middle::region; +use crate::mir; +use crate::ty; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use std::cell::RefCell; use std::mem; -use crate::middle::region; -use crate::ty; -use crate::mir; impl<'a, 'tcx, T> HashStable> for &'tcx ty::List where @@ -59,14 +59,11 @@ impl<'a, 'tcx> HashStable> for ty::subst::GenericArg<'t } } -impl<'a> HashStable> -for ty::RegionKind { +impl<'a> HashStable> for ty::RegionKind { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { - ty::ReErased | - ty::ReStatic | - ty::ReEmpty => { + ty::ReErased | ty::ReStatic | ty::ReEmpty => { // No variant fields to hash for these ... } ty::ReLateBound(db, ty::BrAnon(i)) => { @@ -95,8 +92,7 @@ for ty::RegionKind { ty::ReClosureBound(vid) => { vid.hash_stable(hcx, hasher); } - ty::ReVar(..) | - ty::RePlaceholder(..) => { + ty::ReVar(..) | ty::RePlaceholder(..) => { bug!("StableHasher: unexpected region {:?}", *self) } } @@ -146,8 +142,7 @@ impl<'a> HashStable> for mir::interpret::AllocId { } // `Relocations` with default type parameters is a sorted map. -impl<'a, Tag> HashStable> -for mir::interpret::Relocations +impl<'a, Tag> HashStable> for mir::interpret::Relocations where Tag: HashStable>, { @@ -201,13 +196,10 @@ where } } -impl<'a> HashStable> -for crate::middle::privacy::AccessLevels { +impl<'a> HashStable> for crate::middle::privacy::AccessLevels { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { - let crate::middle::privacy::AccessLevels { - ref map - } = *self; + let crate::middle::privacy::AccessLevels { ref map } = *self; map.hash_stable(hcx, hasher); }); diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs index cd2e32de9d5c4..4ad3e9482ded8 100644 --- a/src/librustc/ich/mod.rs +++ b/src/librustc/ich/mod.rs @@ -1,16 +1,17 @@ //! ICH - Incremental Compilation Hash +pub use self::hcx::{ + hash_stable_trait_impls, NodeIdHashingMode, StableHashingContext, StableHashingContextProvider, +}; crate use rustc_data_structures::fingerprint::Fingerprint; +use syntax::symbol::{sym, Symbol}; pub use syntax_pos::CachingSourceMapView; -pub use self::hcx::{StableHashingContextProvider, StableHashingContext, NodeIdHashingMode, - hash_stable_trait_impls}; -use syntax::symbol::{Symbol, sym}; mod hcx; mod impls_hir; -mod impls_ty; mod impls_syntax; +mod impls_ty; pub const IGNORED_ATTRIBUTES: &[Symbol] = &[ sym::cfg, diff --git a/src/librustc/infer/at.rs b/src/librustc/infer/at.rs index e4aec59c1f64f..c58f1bd87bd8d 100644 --- a/src/librustc/infer/at.rs +++ b/src/librustc/infer/at.rs @@ -27,8 +27,8 @@ use super::*; -use crate::ty::Const; use crate::ty::relate::{Relate, TypeRelation}; +use crate::ty::Const; pub struct At<'a, 'tcx> { pub infcx: &'a InferCtxt<'a, 'tcx>, @@ -54,38 +54,33 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } pub trait ToTrace<'tcx>: Relate<'tcx> + Copy { - fn to_trace(cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self) - -> TypeTrace<'tcx>; + fn to_trace( + cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self, + ) -> TypeTrace<'tcx>; } impl<'a, 'tcx> At<'a, 'tcx> { /// Hacky routine for equating two impl headers in coherence. - pub fn eq_impl_headers(self, - expected: &ty::ImplHeader<'tcx>, - actual: &ty::ImplHeader<'tcx>) - -> InferResult<'tcx, ()> - { + pub fn eq_impl_headers( + self, + expected: &ty::ImplHeader<'tcx>, + actual: &ty::ImplHeader<'tcx>, + ) -> InferResult<'tcx, ()> { debug!("eq_impl_header({:?} = {:?})", expected, actual); match (expected.trait_ref, actual.trait_ref) { - (Some(a_ref), Some(b_ref)) => - self.eq(a_ref, b_ref), - (None, None) => - self.eq(expected.self_ty, actual.self_ty), - _ => - bug!("mk_eq_impl_headers given mismatched impl kinds"), + (Some(a_ref), Some(b_ref)) => self.eq(a_ref, b_ref), + (None, None) => self.eq(expected.self_ty, actual.self_ty), + _ => bug!("mk_eq_impl_headers given mismatched impl kinds"), } } /// Makes `a <: b`, where `a` may or may not be expected. - pub fn sub_exp(self, - a_is_expected: bool, - a: T, - b: T) - -> InferResult<'tcx, ()> - where T: ToTrace<'tcx> + pub fn sub_exp(self, a_is_expected: bool, a: T, b: T) -> InferResult<'tcx, ()> + where + T: ToTrace<'tcx>, { self.trace_exp(a_is_expected, a, b).sub(&a, &b) } @@ -94,53 +89,40 @@ impl<'a, 'tcx> At<'a, 'tcx> { /// call like `foo(x)`, where `foo: fn(i32)`, you might have /// `sup(i32, x)`, since the "expected" type is the type that /// appears in the signature. - pub fn sup(self, - expected: T, - actual: T) - -> InferResult<'tcx, ()> - where T: ToTrace<'tcx> + pub fn sup(self, expected: T, actual: T) -> InferResult<'tcx, ()> + where + T: ToTrace<'tcx>, { self.sub_exp(false, actual, expected) } /// Makes `expected <: actual`. - pub fn sub(self, - expected: T, - actual: T) - -> InferResult<'tcx, ()> - where T: ToTrace<'tcx> + pub fn sub(self, expected: T, actual: T) -> InferResult<'tcx, ()> + where + T: ToTrace<'tcx>, { self.sub_exp(true, expected, actual) } /// Makes `expected <: actual`. - pub fn eq_exp(self, - a_is_expected: bool, - a: T, - b: T) - -> InferResult<'tcx, ()> - where T: ToTrace<'tcx> + pub fn eq_exp(self, a_is_expected: bool, a: T, b: T) -> InferResult<'tcx, ()> + where + T: ToTrace<'tcx>, { self.trace_exp(a_is_expected, a, b).eq(&a, &b) } /// Makes `expected <: actual`. - pub fn eq(self, - expected: T, - actual: T) - -> InferResult<'tcx, ()> - where T: ToTrace<'tcx> + pub fn eq(self, expected: T, actual: T) -> InferResult<'tcx, ()> + where + T: ToTrace<'tcx>, { self.trace(expected, actual).eq(&expected, &actual) } - pub fn relate( - self, - expected: T, - variance: ty::Variance, - actual: T, - ) -> InferResult<'tcx, ()> - where T: ToTrace<'tcx> + pub fn relate(self, expected: T, variance: ty::Variance, actual: T) -> InferResult<'tcx, ()> + where + T: ToTrace<'tcx>, { match variance { ty::Variance::Covariant => self.sub(expected, actual), @@ -161,11 +143,9 @@ impl<'a, 'tcx> At<'a, 'tcx> { /// this can result in an error (e.g., if asked to compute LUB of /// u32 and i32), it is meaningful to call one of them the /// "expected type". - pub fn lub(self, - expected: T, - actual: T) - -> InferResult<'tcx, T> - where T: ToTrace<'tcx> + pub fn lub(self, expected: T, actual: T) -> InferResult<'tcx, T> + where + T: ToTrace<'tcx>, { self.trace(expected, actual).lub(&expected, &actual) } @@ -173,11 +153,9 @@ impl<'a, 'tcx> At<'a, 'tcx> { /// Computes the greatest-lower-bound, or mutual subtype, of two /// values. As with `lub` order doesn't matter, except for error /// cases. - pub fn glb(self, - expected: T, - actual: T) - -> InferResult<'tcx, T> - where T: ToTrace<'tcx> + pub fn glb(self, expected: T, actual: T) -> InferResult<'tcx, T> + where + T: ToTrace<'tcx>, { self.trace(expected, actual).glb(&expected, &actual) } @@ -209,139 +187,126 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { /// Makes `a <: b` where `a` may or may not be expected (if /// `a_is_expected` is true, then `a` is expected). /// Makes `expected <: actual`. - pub fn sub(self, - a: &T, - b: &T) - -> InferResult<'tcx, ()> - where T: Relate<'tcx> + pub fn sub(self, a: &T, b: &T) -> InferResult<'tcx, ()> + where + T: Relate<'tcx>, { debug!("sub({:?} <: {:?})", a, b); let Trace { at, trace, a_is_expected } = self; at.infcx.commit_if_ok(|_| { let mut fields = at.infcx.combine_fields(trace, at.param_env); - fields.sub(a_is_expected) - .relate(a, b) - .map(move |_| InferOk { value: (), obligations: fields.obligations }) + fields + .sub(a_is_expected) + .relate(a, b) + .map(move |_| InferOk { value: (), obligations: fields.obligations }) }) } /// Makes `a == b`; the expectation is set by the call to /// `trace()`. - pub fn eq(self, - a: &T, - b: &T) - -> InferResult<'tcx, ()> - where T: Relate<'tcx> + pub fn eq(self, a: &T, b: &T) -> InferResult<'tcx, ()> + where + T: Relate<'tcx>, { debug!("eq({:?} == {:?})", a, b); let Trace { at, trace, a_is_expected } = self; at.infcx.commit_if_ok(|_| { let mut fields = at.infcx.combine_fields(trace, at.param_env); - fields.equate(a_is_expected) - .relate(a, b) - .map(move |_| InferOk { value: (), obligations: fields.obligations }) + fields + .equate(a_is_expected) + .relate(a, b) + .map(move |_| InferOk { value: (), obligations: fields.obligations }) }) } - pub fn lub(self, - a: &T, - b: &T) - -> InferResult<'tcx, T> - where T: Relate<'tcx> + pub fn lub(self, a: &T, b: &T) -> InferResult<'tcx, T> + where + T: Relate<'tcx>, { debug!("lub({:?} \\/ {:?})", a, b); let Trace { at, trace, a_is_expected } = self; at.infcx.commit_if_ok(|_| { let mut fields = at.infcx.combine_fields(trace, at.param_env); - fields.lub(a_is_expected) - .relate(a, b) - .map(move |t| InferOk { value: t, obligations: fields.obligations }) + fields + .lub(a_is_expected) + .relate(a, b) + .map(move |t| InferOk { value: t, obligations: fields.obligations }) }) } - pub fn glb(self, - a: &T, - b: &T) - -> InferResult<'tcx, T> - where T: Relate<'tcx> + pub fn glb(self, a: &T, b: &T) -> InferResult<'tcx, T> + where + T: Relate<'tcx>, { debug!("glb({:?} /\\ {:?})", a, b); let Trace { at, trace, a_is_expected } = self; at.infcx.commit_if_ok(|_| { let mut fields = at.infcx.combine_fields(trace, at.param_env); - fields.glb(a_is_expected) - .relate(a, b) - .map(move |t| InferOk { value: t, obligations: fields.obligations }) + fields + .glb(a_is_expected) + .relate(a, b) + .map(move |t| InferOk { value: t, obligations: fields.obligations }) }) } } impl<'tcx> ToTrace<'tcx> for Ty<'tcx> { - fn to_trace(cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self) - -> TypeTrace<'tcx> - { - TypeTrace { - cause: cause.clone(), - values: Types(ExpectedFound::new(a_is_expected, a, b)) - } + fn to_trace( + cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self, + ) -> TypeTrace<'tcx> { + TypeTrace { cause: cause.clone(), values: Types(ExpectedFound::new(a_is_expected, a, b)) } } } impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> { - fn to_trace(cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self) - -> TypeTrace<'tcx> - { - TypeTrace { - cause: cause.clone(), - values: Regions(ExpectedFound::new(a_is_expected, a, b)) - } + fn to_trace( + cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self, + ) -> TypeTrace<'tcx> { + TypeTrace { cause: cause.clone(), values: Regions(ExpectedFound::new(a_is_expected, a, b)) } } } impl<'tcx> ToTrace<'tcx> for &'tcx Const<'tcx> { - fn to_trace(cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self) - -> TypeTrace<'tcx> - { - TypeTrace { - cause: cause.clone(), - values: Consts(ExpectedFound::new(a_is_expected, a, b)) - } + fn to_trace( + cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self, + ) -> TypeTrace<'tcx> { + TypeTrace { cause: cause.clone(), values: Consts(ExpectedFound::new(a_is_expected, a, b)) } } } impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> { - fn to_trace(cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self) - -> TypeTrace<'tcx> - { + fn to_trace( + cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self, + ) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: TraitRefs(ExpectedFound::new(a_is_expected, a, b)) + values: TraitRefs(ExpectedFound::new(a_is_expected, a, b)), } } } impl<'tcx> ToTrace<'tcx> for ty::PolyTraitRef<'tcx> { - fn to_trace(cause: &ObligationCause<'tcx>, - a_is_expected: bool, - a: Self, - b: Self) - -> TypeTrace<'tcx> - { + fn to_trace( + cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self, + ) -> TypeTrace<'tcx> { TypeTrace { cause: cause.clone(), - values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a, b)) + values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a, b)), } } } diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index 1fa814dc14efb..d5666f6975bc7 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -10,11 +10,11 @@ use crate::infer::canonical::{ OriginalQueryValues, }; use crate::infer::InferCtxt; -use std::sync::atomic::Ordering; +use crate::ty::flags::FlagComputation; use crate::ty::fold::{TypeFoldable, TypeFolder}; use crate::ty::subst::GenericArg; use crate::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags}; -use crate::ty::flags::FlagComputation; +use std::sync::atomic::Ordering; use rustc_data_structures::fx::FxHashMap; use rustc_index::vec::Idx; @@ -44,11 +44,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { where V: TypeFoldable<'tcx>, { - self.tcx - .sess - .perf_stats - .queries_canonicalized - .fetch_add(1, Ordering::Relaxed); + self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed); Canonicalizer::canonicalize( value, @@ -133,11 +129,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { where V: TypeFoldable<'tcx>, { - self.tcx - .sess - .perf_stats - .queries_canonicalized - .fetch_add(1, Ordering::Relaxed); + self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed); Canonicalizer::canonicalize( value, @@ -177,17 +169,13 @@ impl CanonicalizeRegionMode for CanonicalizeQueryResponse { match r { ty::ReFree(_) | ty::ReEmpty | ty::ReErased | ty::ReStatic | ty::ReEarlyBound(..) => r, ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region( - CanonicalVarInfo { - kind: CanonicalVarKind::PlaceholderRegion(*placeholder), - }, + CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderRegion(*placeholder) }, r, ), ty::ReVar(vid) => { let universe = canonicalizer.region_var_universe(*vid); canonicalizer.canonical_var_for_region( - CanonicalVarInfo { - kind: CanonicalVarKind::Region(universe), - }, + CanonicalVarInfo { kind: CanonicalVarKind::Region(universe) }, r, ) } @@ -203,7 +191,8 @@ impl CanonicalizeRegionMode for CanonicalizeQueryResponse { ty::tls::with_context(|c| { c.tcx.sess.delay_span_bug( syntax_pos::DUMMY_SP, - &format!("unexpected region in query response: `{:?}`", r)); + &format!("unexpected region in query response: `{:?}`", r), + ); }); r } @@ -294,7 +283,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { } fn fold_binder(&mut self, t: &ty::Binder) -> ty::Binder - where T: TypeFoldable<'tcx> + where + T: TypeFoldable<'tcx>, { self.binder_index.shift_in(1); let t = t.super_fold_with(self); @@ -313,7 +303,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { } ty::ReVar(vid) => { - let r = self.infcx + let r = self + .infcx .unwrap() .borrow_region_constraints() .opportunistic_resolve_var(self.tcx, vid); @@ -322,8 +313,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { opportunistically resolved to {:?}", vid, r ); - self.canonicalize_region_mode - .canonicalize_free_region(self, r) + self.canonicalize_region_mode.canonicalize_free_region(self, r) } ty::ReStatic @@ -332,8 +322,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { | ty::ReScope(_) | ty::RePlaceholder(..) | ty::ReEmpty - | ty::ReErased => self.canonicalize_region_mode - .canonicalize_free_region(self, r), + | ty::ReErased => self.canonicalize_region_mode.canonicalize_free_region(self, r), ty::ReClosureBound(..) => { bug!("closure bound region encountered during canonicalization"); @@ -361,26 +350,22 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { } self.canonicalize_ty_var( CanonicalVarInfo { - kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) + kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)), }, - t + t, ) } } } ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var( - CanonicalVarInfo { - kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) - }, - t + CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) }, + t, ), ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var( - CanonicalVarInfo { - kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) - }, - t + CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) }, + t, ), ty::Infer(ty::FreshTy(_)) @@ -390,10 +375,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { } ty::Placeholder(placeholder) => self.canonicalize_ty_var( - CanonicalVarInfo { - kind: CanonicalVarKind::PlaceholderTy(placeholder) - }, - t + CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderTy(placeholder) }, + t, ), ty::Bound(debruijn, _) => { @@ -456,9 +439,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { ui = ty::UniverseIndex::ROOT; } return self.canonicalize_const_var( - CanonicalVarInfo { - kind: CanonicalVarKind::Const(ui), - }, + CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) }, ct, ); } @@ -476,9 +457,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { } ty::ConstKind::Placeholder(placeholder) => { return self.canonicalize_const_var( - CanonicalVarInfo { - kind: CanonicalVarKind::PlaceholderConst(placeholder), - }, + CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderConst(placeholder) }, ct, ); } @@ -486,11 +465,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { } let flags = FlagComputation::for_const(ct); - if flags.intersects(self.needs_canonical_flags) { - ct.super_fold_with(self) - } else { - ct - } + if flags.intersects(self.needs_canonical_flags) { ct.super_fold_with(self) } else { ct } } } @@ -513,10 +488,10 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { TypeFlags::HAS_TY_PLACEHOLDER | TypeFlags::HAS_CT_PLACEHOLDER } else { - TypeFlags::KEEP_IN_LOCAL_TCX | - TypeFlags::HAS_RE_PLACEHOLDER | - TypeFlags::HAS_TY_PLACEHOLDER | - TypeFlags::HAS_CT_PLACEHOLDER + TypeFlags::KEEP_IN_LOCAL_TCX + | TypeFlags::HAS_RE_PLACEHOLDER + | TypeFlags::HAS_TY_PLACEHOLDER + | TypeFlags::HAS_CT_PLACEHOLDER }; // Fast path: nothing that needs to be canonicalized. @@ -554,11 +529,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { .max() .unwrap_or(ty::UniverseIndex::ROOT); - Canonical { - max_universe, - variables: canonical_variables, - value: out_value, - } + Canonical { max_universe, variables: canonical_variables, value: out_value } } /// Creates a canonical variable replacing `kind` from the input, @@ -566,12 +537,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { /// seen. `kind` is expected to be an unbound variable (or /// potentially a free region). fn canonical_var(&mut self, info: CanonicalVarInfo, kind: GenericArg<'tcx>) -> BoundVar { - let Canonicalizer { - variables, - query_state, - indices, - .. - } = self; + let Canonicalizer { variables, query_state, indices, .. } = self; let var_values = &mut query_state.var_values; @@ -637,19 +603,14 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { self.canonical_var_for_region( - CanonicalVarInfo { - kind: CanonicalVarKind::Region(ty::UniverseIndex::ROOT), - }, + CanonicalVarInfo { kind: CanonicalVarKind::Region(ty::UniverseIndex::ROOT) }, r, ) } /// Returns the universe in which `vid` is defined. fn region_var_universe(&self, vid: ty::RegionVid) -> ty::UniverseIndex { - self.infcx - .unwrap() - .borrow_region_constraints() - .var_universe(vid) + self.infcx.unwrap().borrow_region_constraints().var_universe(vid) } /// Creates a canonical variable (with the given `info`) @@ -660,10 +621,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { let var = self.canonical_var(info, r.into()); - let region = ty::ReLateBound( - self.binder_index, - ty::BoundRegion::BrAnon(var.as_u32()) - ); + let region = ty::ReLateBound(self.binder_index, ty::BoundRegion::BrAnon(var.as_u32())); self.tcx().mk_region(region) } @@ -689,7 +647,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { fn canonicalize_const_var( &mut self, info: CanonicalVarInfo, - const_var: &'tcx ty::Const<'tcx> + const_var: &'tcx ty::Const<'tcx>, ) -> &'tcx ty::Const<'tcx> { let infcx = self.infcx.expect("encountered const-var without infcx"); let bound_to = infcx.shallow_resolve(const_var); @@ -697,12 +655,10 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { self.fold_const(bound_to) } else { let var = self.canonical_var(info, const_var.into()); - self.tcx().mk_const( - ty::Const { - val: ty::ConstKind::Bound(self.binder_index, var.into()), - ty: self.fold_ty(const_var.ty), - } - ) + self.tcx().mk_const(ty::Const { + val: ty::ConstKind::Bound(self.binder_index, var.into()), + ty: self.fold_ty(const_var.ty), + }) } } } diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs index b0f65ac6e1b34..f6a716a120469 100644 --- a/src/librustc/infer/canonical/mod.rs +++ b/src/librustc/infer/canonical/mod.rs @@ -21,18 +21,18 @@ //! //! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html -use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind}; -use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind}; use crate::infer::region_constraints::MemberConstraint; +use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind}; +use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind}; +use crate::ty::fold::TypeFoldable; +use crate::ty::subst::GenericArg; +use crate::ty::{self, BoundVar, List, Region, TyCtxt}; use rustc_index::vec::IndexVec; use rustc_macros::HashStable; use rustc_serialize::UseSpecializedDecodable; use smallvec::SmallVec; use std::ops::Index; use syntax::source_map::Span; -use crate::ty::fold::TypeFoldable; -use crate::ty::subst::GenericArg; -use crate::ty::{self, BoundVar, List, Region, TyCtxt}; mod canonicalizer; @@ -92,10 +92,7 @@ impl Default for OriginalQueryValues<'tcx> { let mut universe_map = SmallVec::default(); universe_map.push(ty::UniverseIndex::ROOT); - Self { - universe_map, - var_values: SmallVec::default(), - } + Self { universe_map, var_values: SmallVec::default() } } } @@ -157,7 +154,7 @@ impl CanonicalVarKind { CanonicalVarKind::Ty(kind) => match kind { CanonicalTyVarKind::General(ui) => ui, CanonicalTyVarKind::Float | CanonicalTyVarKind::Int => ty::UniverseIndex::ROOT, - } + }, CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe, CanonicalVarKind::Region(ui) => ui, @@ -212,8 +209,7 @@ impl QueryRegionConstraints<'_> { pub type Canonicalized<'tcx, V> = Canonical<'tcx, V>; -pub type CanonicalizedQueryResponse<'tcx, T> = - &'tcx Canonical<'tcx, QueryResponse<'tcx, T>>; +pub type CanonicalizedQueryResponse<'tcx, T> = &'tcx Canonical<'tcx, QueryResponse<'tcx, T>>; /// Indicates whether or not we were able to prove the query to be /// true. @@ -295,16 +291,8 @@ impl<'tcx, V> Canonical<'tcx, V> { /// let b: Canonical<'tcx, (T, Ty<'tcx>)> = a.unchecked_map(|v| (v, ty)); /// ``` pub fn unchecked_map(self, map_op: impl FnOnce(V) -> W) -> Canonical<'tcx, W> { - let Canonical { - max_universe, - variables, - value, - } = self; - Canonical { - max_universe, - variables, - value: map_op(value), - } + let Canonical { max_universe, variables, value } = self; + Canonical { max_universe, variables, value: map_op(value) } } } @@ -381,15 +369,10 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { match cv_info.kind { CanonicalVarKind::Ty(ty_kind) => { let ty = match ty_kind { - CanonicalTyVarKind::General(ui) => { - self.next_ty_var_in_universe( - TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - }, - universe_map(ui) - ) - } + CanonicalTyVarKind::General(ui) => self.next_ty_var_in_universe( + TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span }, + universe_map(ui), + ), CanonicalTyVarKind::Int => self.next_int_var(), @@ -400,58 +383,43 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { CanonicalVarKind::PlaceholderTy(ty::PlaceholderType { universe, name }) => { let universe_mapped = universe_map(universe); - let placeholder_mapped = ty::PlaceholderType { - universe: universe_mapped, - name, - }; + let placeholder_mapped = ty::PlaceholderType { universe: universe_mapped, name }; self.tcx.mk_ty(ty::Placeholder(placeholder_mapped)).into() } - CanonicalVarKind::Region(ui) => self.next_region_var_in_universe( - RegionVariableOrigin::MiscVariable(span), - universe_map(ui), - ).into(), + CanonicalVarKind::Region(ui) => self + .next_region_var_in_universe( + RegionVariableOrigin::MiscVariable(span), + universe_map(ui), + ) + .into(), CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion { universe, name }) => { let universe_mapped = universe_map(universe); - let placeholder_mapped = ty::PlaceholderRegion { - universe: universe_mapped, - name, - }; + let placeholder_mapped = ty::PlaceholderRegion { universe: universe_mapped, name }; self.tcx.mk_region(ty::RePlaceholder(placeholder_mapped)).into() } - CanonicalVarKind::Const(ui) => { - self.next_const_var_in_universe( + CanonicalVarKind::Const(ui) => self + .next_const_var_in_universe( self.next_ty_var_in_universe( - TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - }, + TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span }, universe_map(ui), ), - ConstVariableOrigin { - kind: ConstVariableOriginKind::MiscVariable, - span, - }, + ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span }, universe_map(ui), - ).into() - } + ) + .into(), - CanonicalVarKind::PlaceholderConst( - ty::PlaceholderConst { universe, name }, - ) => { + CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, name }) => { let universe_mapped = universe_map(universe); - let placeholder_mapped = ty::PlaceholderConst { - universe: universe_mapped, - name, - }; - self.tcx.mk_const( - ty::Const { + let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, name }; + self.tcx + .mk_const(ty::Const { val: ty::ConstKind::Placeholder(placeholder_mapped), ty: self.tcx.types.err, // FIXME(const_generics) - } - ).into() + }) + .into() } } } @@ -484,23 +452,25 @@ impl<'tcx> CanonicalVarValues<'tcx> { use crate::ty::subst::GenericArgKind; CanonicalVarValues { - var_values: self.var_values.iter() + var_values: self + .var_values + .iter() .zip(0..) .map(|(kind, i)| match kind.unpack() { - GenericArgKind::Type(..) => tcx.mk_ty( - ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i).into()) - ).into(), - GenericArgKind::Lifetime(..) => tcx.mk_region( - ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i)) - ).into(), - GenericArgKind::Const(ct) => { - tcx.mk_const(ty::Const { + GenericArgKind::Type(..) => { + tcx.mk_ty(ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i).into())).into() + } + GenericArgKind::Lifetime(..) => tcx + .mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i))) + .into(), + GenericArgKind::Const(ct) => tcx + .mk_const(ty::Const { ty: ct.ty, val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)), - }).into() - } + }) + .into(), }) - .collect() + .collect(), } } } diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs index 825e98cedb9e0..f35bec0c81d5b 100644 --- a/src/librustc/infer/canonical/query_response.rs +++ b/src/librustc/infer/canonical/query_response.rs @@ -10,16 +10,12 @@ use crate::arena::ArenaAllocatable; use crate::infer::canonical::substitute::substitute_value; use crate::infer::canonical::{ - Canonical, CanonicalVarValues, CanonicalizedQueryResponse, Certainty, - OriginalQueryValues, QueryRegionConstraints, QueryOutlivesConstraint, QueryResponse, + Canonical, CanonicalVarValues, CanonicalizedQueryResponse, Certainty, OriginalQueryValues, + QueryOutlivesConstraint, QueryRegionConstraints, QueryResponse, }; use crate::infer::region_constraints::{Constraint, RegionConstraintData}; use crate::infer::InferCtxtBuilder; use crate::infer::{InferCtxt, InferOk, InferResult}; -use rustc_index::vec::Idx; -use rustc_index::vec::IndexVec; -use std::fmt::Debug; -use syntax_pos::DUMMY_SP; use crate::traits::query::{Fallible, NoSolution}; use crate::traits::TraitEngine; use crate::traits::{Obligation, ObligationCause, PredicateObligation}; @@ -27,6 +23,10 @@ use crate::ty::fold::TypeFoldable; use crate::ty::subst::{GenericArg, GenericArgKind}; use crate::ty::{self, BoundVar, Ty, TyCtxt}; use crate::util::captures::Captures; +use rustc_index::vec::Idx; +use rustc_index::vec::IndexVec; +use std::fmt::Debug; +use syntax_pos::DUMMY_SP; impl<'tcx> InferCtxtBuilder<'tcx> { /// The "main method" for a canonicalized trait query. Given the @@ -64,7 +64,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { infcx.make_canonicalized_query_response( canonical_inference_vars, value, - &mut *fulfill_cx + &mut *fulfill_cx, ) }, ) @@ -104,10 +104,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?; let canonical_result = self.canonicalize_response(&query_response); - debug!( - "make_canonicalized_query_response: canonical_result = {:#?}", - canonical_result - ); + debug!("make_canonicalized_query_response: canonical_result = {:#?}", canonical_result); Ok(self.tcx.arena.alloc(canonical_result)) } @@ -175,18 +172,13 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { let region_constraints = self.with_region_constraints(|region_constraints| { make_query_region_constraints( tcx, - region_obligations - .iter() - .map(|(_, r_o)| (r_o.sup_type, r_o.sub_region)), + region_obligations.iter().map(|(_, r_o)| (r_o.sup_type, r_o.sub_region)), region_constraints, ) }); - let certainty = if ambig_errors.is_empty() { - Certainty::Proven - } else { - Certainty::Ambiguous - }; + let certainty = + if ambig_errors.is_empty() { Certainty::Proven } else { Certainty::Ambiguous }; Ok(QueryResponse { var_values: inference_vars, @@ -216,10 +208,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { where R: Debug + TypeFoldable<'tcx>, { - let InferOk { - value: result_subst, - mut obligations, - } = self.query_response_substitution(cause, param_env, original_values, query_response)?; + let InferOk { value: result_subst, mut obligations } = + self.query_response_substitution(cause, param_env, original_values, query_response)?; obligations.extend(self.query_outlives_constraints_into_obligations( cause, @@ -231,10 +221,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { let user_result: R = query_response.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value); - Ok(InferOk { - value: user_result, - obligations, - }) + Ok(InferOk { value: user_result, obligations }) } /// An alternative to @@ -327,11 +314,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { } _ => { - bug!( - "kind mismatch, cannot unify {:?} and {:?}", - original_value, - result_value - ); + bug!("kind mismatch, cannot unify {:?} and {:?}", original_value, result_value); } } } @@ -345,28 +328,24 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { // only compare the inner values to one another, so they are still at // consistent binding levels. let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder(); - if k1 != r2.into() { - Some(r_c) - } else { - None - } - }) + if k1 != r2.into() { Some(r_c) } else { None } + }), ); // ...also include the query member constraints. output_query_region_constraints.member_constraints.extend( - query_response.value.region_constraints.member_constraints.iter().map(|p_c| { - substitute_value(self.tcx, &result_subst, p_c) - }) + query_response + .value + .region_constraints + .member_constraints + .iter() + .map(|p_c| substitute_value(self.tcx, &result_subst, p_c)), ); let user_result: R = query_response.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value); - Ok(InferOk { - value: user_result, - obligations, - }) + Ok(InferOk { value: user_result, obligations }) } /// Given the original values and the (canonicalized) result from @@ -397,19 +376,17 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { let result_subst = self.query_response_substitution_guess(cause, original_values, query_response); - let obligations = self.unify_query_response_substitution_guess( - cause, - param_env, - original_values, - &result_subst, - query_response, - )? + let obligations = self + .unify_query_response_substitution_guess( + cause, + param_env, + original_values, + &result_subst, + query_response, + )? .into_obligations(); - Ok(InferOk { - value: result_subst, - obligations, - }) + Ok(InferOk { value: result_subst, obligations }) } /// Given the original values and the (canonicalized) result from @@ -445,10 +422,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { universe_map.push(self.create_next_universe()); } assert!(universe_map.len() >= 1); // always have the root universe - assert_eq!( - universe_map[ty::UniverseIndex::ROOT.as_usize()], - ty::UniverseIndex::ROOT - ); + assert_eq!(universe_map[ty::UniverseIndex::ROOT.as_usize()], ty::UniverseIndex::ROOT); // Every canonical query result includes values for each of // the inputs to the query. Therefore, we begin by unifying @@ -575,34 +549,28 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { unsubstituted_region_constraints: &'a [QueryOutlivesConstraint<'tcx>], result_subst: &'a CanonicalVarValues<'tcx>, ) -> impl Iterator> + 'a + Captures<'tcx> { - unsubstituted_region_constraints - .iter() - .map(move |constraint| { - let constraint = substitute_value(self.tcx, result_subst, constraint); - let &ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below - - Obligation::new( - cause.clone(), - param_env, - match k1.unpack() { - GenericArgKind::Lifetime(r1) => ty::Predicate::RegionOutlives( - ty::Binder::bind( - ty::OutlivesPredicate(r1, r2) - ) - ), - GenericArgKind::Type(t1) => ty::Predicate::TypeOutlives( - ty::Binder::bind( - ty::OutlivesPredicate(t1, r2) - ) - ), - GenericArgKind::Const(..) => { - // Consts cannot outlive one another, so we don't expect to - // ecounter this branch. - span_bug!(cause.span, "unexpected const outlives {:?}", constraint); - } + unsubstituted_region_constraints.iter().map(move |constraint| { + let constraint = substitute_value(self.tcx, result_subst, constraint); + let &ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below + + Obligation::new( + cause.clone(), + param_env, + match k1.unpack() { + GenericArgKind::Lifetime(r1) => ty::Predicate::RegionOutlives( + ty::Binder::bind(ty::OutlivesPredicate(r1, r2)), + ), + GenericArgKind::Type(t1) => { + ty::Predicate::TypeOutlives(ty::Binder::bind(ty::OutlivesPredicate(t1, r2))) } - ) - }) + GenericArgKind::Const(..) => { + // Consts cannot outlive one another, so we don't expect to + // ecounter this branch. + span_bug!(cause.span, "unexpected const outlives {:?}", constraint); + } + }, + ) + }) } /// Given two sets of values for the same set of canonical variables, unify them. @@ -643,10 +611,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { } } } - Ok(InferOk { - value: (), - obligations, - }) + Ok(InferOk { value: (), obligations }) }) } } @@ -658,12 +623,8 @@ pub fn make_query_region_constraints<'tcx>( outlives_obligations: impl Iterator, ty::Region<'tcx>)>, region_constraints: &RegionConstraintData<'tcx>, ) -> QueryRegionConstraints<'tcx> { - let RegionConstraintData { - constraints, - verifys, - givens, - member_constraints, - } = region_constraints; + let RegionConstraintData { constraints, verifys, givens, member_constraints } = + region_constraints; assert!(verifys.is_empty()); assert!(givens.is_empty()); @@ -689,7 +650,7 @@ pub fn make_query_region_constraints<'tcx>( .chain( outlives_obligations .map(|(ty, r)| ty::OutlivesPredicate(ty.into(), r)) - .map(ty::Binder::dummy) // no bound vars in the code above + .map(ty::Binder::dummy), // no bound vars in the code above ) .collect(); diff --git a/src/librustc/infer/canonical/substitute.rs b/src/librustc/infer/canonical/substitute.rs index 4f5bb09c9167a..92516345633f2 100644 --- a/src/librustc/infer/canonical/substitute.rs +++ b/src/librustc/infer/canonical/substitute.rs @@ -56,25 +56,20 @@ where if var_values.var_values.is_empty() { value.clone() } else { - let fld_r = |br: ty::BoundRegion| { - match var_values.var_values[br.assert_bound_var()].unpack() { + let fld_r = + |br: ty::BoundRegion| match var_values.var_values[br.assert_bound_var()].unpack() { GenericArgKind::Lifetime(l) => l, r => bug!("{:?} is a region but value is {:?}", br, r), - } - }; + }; - let fld_t = |bound_ty: ty::BoundTy| { - match var_values.var_values[bound_ty.var].unpack() { - GenericArgKind::Type(ty) => ty, - r => bug!("{:?} is a type but value is {:?}", bound_ty, r), - } + let fld_t = |bound_ty: ty::BoundTy| match var_values.var_values[bound_ty.var].unpack() { + GenericArgKind::Type(ty) => ty, + r => bug!("{:?} is a type but value is {:?}", bound_ty, r), }; - let fld_c = |bound_ct: ty::BoundVar, _| { - match var_values.var_values[bound_ct].unpack() { - GenericArgKind::Const(ct) => ct, - c => bug!("{:?} is a const but value is {:?}", bound_ct, c), - } + let fld_c = |bound_ct: ty::BoundVar, _| match var_values.var_values[bound_ct].unpack() { + GenericArgKind::Const(ct) => ct, + c => bug!("{:?} is a const but value is {:?}", bound_ct, c), }; tcx.replace_escaping_bound_vars(value, fld_r, fld_t, fld_c).0 diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index a2f0531f0af36..9e47c178415a5 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -24,21 +24,21 @@ use super::equate::Equate; use super::glb::Glb; -use super::{InferCtxt, MiscVariable, TypeTrace}; use super::lub::Lub; use super::sub::Sub; use super::type_variable::TypeVariableValue; +use super::unify_key::replace_if_possible; use super::unify_key::{ConstVarValue, ConstVariableValue}; use super::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use super::unify_key::replace_if_possible; +use super::{InferCtxt, MiscVariable, TypeTrace}; use crate::hir::def_id::DefId; -use crate::ty::{IntType, UintType}; -use crate::ty::{self, Ty, TyCtxt, InferConst}; +use crate::traits::{Obligation, PredicateObligations}; use crate::ty::error::TypeError; use crate::ty::relate::{self, Relate, RelateResult, TypeRelation}; use crate::ty::subst::SubstsRef; -use crate::traits::{Obligation, PredicateObligations}; +use crate::ty::{self, InferConst, Ty, TyCtxt}; +use crate::ty::{IntType, UintType}; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; @@ -54,7 +54,9 @@ pub struct CombineFields<'infcx, 'tcx> { #[derive(Copy, Clone, Debug)] pub enum RelationDir { - SubtypeOf, SupertypeOf, EqTo + SubtypeOf, + SupertypeOf, + EqTo, } impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { @@ -107,14 +109,11 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { } // All other cases of inference are errors - (&ty::Infer(_), _) | - (_, &ty::Infer(_)) => { + (&ty::Infer(_), _) | (_, &ty::Infer(_)) => { Err(TypeError::Sorts(ty::relate::expected_found(relation, &a, &b))) } - _ => { - ty::relate::super_relate_tys(relation, a, b) - } + _ => ty::relate::super_relate_tys(relation, a, b), } } @@ -128,7 +127,9 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { R: TypeRelation<'tcx>, { debug!("{}.consts({:?}, {:?})", relation.tag(), a, b); - if a == b { return Ok(a); } + if a == b { + return Ok(a); + } let a = replace_if_possible(self.const_unification_table.borrow_mut(), a); let b = replace_if_possible(self.const_unification_table.borrow_mut(), b); @@ -136,8 +137,10 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { let a_is_expected = relation.a_is_expected(); match (a.val, b.val) { - (ty::ConstKind::Infer(InferConst::Var(a_vid)), - ty::ConstKind::Infer(InferConst::Var(b_vid))) => { + ( + ty::ConstKind::Infer(InferConst::Var(a_vid)), + ty::ConstKind::Infer(InferConst::Var(b_vid)), + ) => { self.const_unification_table .borrow_mut() .unify_var_var(a_vid, b_vid) @@ -146,8 +149,8 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { } // All other cases of inference with other variables are errors. - (ty::ConstKind::Infer(InferConst::Var(_)), ty::ConstKind::Infer(_)) | - (ty::ConstKind::Infer(_), ty::ConstKind::Infer(InferConst::Var(_))) => { + (ty::ConstKind::Infer(InferConst::Var(_)), ty::ConstKind::Infer(_)) + | (ty::ConstKind::Infer(_), ty::ConstKind::Infer(InferConst::Var(_))) => { bug!("tried to combine ConstKind::Infer/ConstKind::Infer(InferConst::Var)") } @@ -173,23 +176,26 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { self.const_unification_table .borrow_mut() - .unify_var_value(vid, ConstVarValue { - origin: ConstVariableOrigin { - kind: ConstVariableOriginKind::ConstInference, - span: DUMMY_SP, + .unify_var_value( + vid, + ConstVarValue { + origin: ConstVariableOrigin { + kind: ConstVariableOriginKind::ConstInference, + span: DUMMY_SP, + }, + val: ConstVariableValue::Known { value }, }, - val: ConstVariableValue::Known { value }, - }) + ) .map_err(|e| const_unification_error(vid_is_expected, e))?; Ok(value) } - fn unify_integral_variable(&self, - vid_is_expected: bool, - vid: ty::IntVid, - val: ty::IntVarValue) - -> RelateResult<'tcx, Ty<'tcx>> - { + fn unify_integral_variable( + &self, + vid_is_expected: bool, + vid: ty::IntVid, + val: ty::IntVarValue, + ) -> RelateResult<'tcx, Ty<'tcx>> { self.int_unification_table .borrow_mut() .unify_var_value(vid, Some(val)) @@ -200,12 +206,12 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> { } } - fn unify_float_variable(&self, - vid_is_expected: bool, - vid: ty::FloatVid, - val: ast::FloatTy) - -> RelateResult<'tcx, Ty<'tcx>> - { + fn unify_float_variable( + &self, + vid_is_expected: bool, + vid: ty::FloatVid, + val: ast::FloatTy, + ) -> RelateResult<'tcx, Ty<'tcx>> { self.float_unification_table .borrow_mut() .unify_var_value(vid, Some(ty::FloatVarValue(val))) @@ -244,13 +250,13 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { /// will first instantiate `b_vid` with a *generalized* version /// of `a_ty`. Generalization introduces other inference /// variables wherever subtyping could occur. - pub fn instantiate(&mut self, - a_ty: Ty<'tcx>, - dir: RelationDir, - b_vid: ty::TyVid, - a_is_expected: bool) - -> RelateResult<'tcx, ()> - { + pub fn instantiate( + &mut self, + a_ty: Ty<'tcx>, + dir: RelationDir, + b_vid: ty::TyVid, + a_is_expected: bool, + ) -> RelateResult<'tcx, ()> { use self::RelationDir::*; // Get the actual variable that b_vid has been inferred to @@ -270,14 +276,18 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { // variables. (Down below, we will relate `a_ty <: b_ty`, // adding constraints like `'x: '?2` and `?1 <: ?3`.) let Generalization { ty: b_ty, needs_wf } = self.generalize(a_ty, b_vid, dir)?; - debug!("instantiate(a_ty={:?}, dir={:?}, b_vid={:?}, generalized b_ty={:?})", - a_ty, dir, b_vid, b_ty); + debug!( + "instantiate(a_ty={:?}, dir={:?}, b_vid={:?}, generalized b_ty={:?})", + a_ty, dir, b_vid, b_ty + ); self.infcx.type_variables.borrow_mut().instantiate(b_vid, b_ty); if needs_wf { - self.obligations.push(Obligation::new(self.trace.cause.clone(), - self.param_env, - ty::Predicate::WellFormed(b_ty))); + self.obligations.push(Obligation::new( + self.trace.cause.clone(), + self.param_env, + ty::Predicate::WellFormed(b_ty), + )); } // Finally, relate `b_ty` to `a_ty`, as described in previous comment. @@ -289,8 +299,9 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { match dir { EqTo => self.equate(a_is_expected).relate(&a_ty, &b_ty), SubtypeOf => self.sub(a_is_expected).relate(&a_ty, &b_ty), - SupertypeOf => self.sub(a_is_expected).relate_with_variance( - ty::Contravariant, &a_ty, &b_ty), + SupertypeOf => { + self.sub(a_is_expected).relate_with_variance(ty::Contravariant, &a_ty, &b_ty) + } }?; Ok(()) @@ -305,12 +316,12 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { /// Preconditions: /// /// - `for_vid` is a "root vid" - fn generalize(&self, - ty: Ty<'tcx>, - for_vid: ty::TyVid, - dir: RelationDir) - -> RelateResult<'tcx, Generalization<'tcx>> - { + fn generalize( + &self, + ty: Ty<'tcx>, + for_vid: ty::TyVid, + dir: RelationDir, + ) -> RelateResult<'tcx, Generalization<'tcx>> { debug!("generalize(ty={:?}, for_vid={:?}, dir={:?}", ty, for_vid, dir); // Determine the ambient variance within which `ty` appears. // The surrounding equation is: @@ -328,11 +339,9 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { debug!("generalize: ambient_variance = {:?}", ambient_variance); let for_universe = match self.infcx.type_variables.borrow_mut().probe(for_vid) { - v @ TypeVariableValue::Known { .. } => panic!( - "instantiating {:?} which has a known value {:?}", - for_vid, - v, - ), + v @ TypeVariableValue::Known { .. } => { + panic!("instantiating {:?} which has a known value {:?}", for_vid, v,) + } TypeVariableValue::Unknown { universe } => universe, }; @@ -428,7 +437,9 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } - fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } + fn param_env(&self) -> ty::ParamEnv<'tcx> { + self.param_env + } fn tag(&self) -> &'static str { "Generalizer" @@ -438,19 +449,23 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { true } - fn binders(&mut self, a: &ty::Binder, b: &ty::Binder) - -> RelateResult<'tcx, ty::Binder> - where T: Relate<'tcx> + fn binders( + &mut self, + a: &ty::Binder, + b: &ty::Binder, + ) -> RelateResult<'tcx, ty::Binder> + where + T: Relate<'tcx>, { Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?)) } - fn relate_item_substs(&mut self, - item_def_id: DefId, - a_subst: SubstsRef<'tcx>, - b_subst: SubstsRef<'tcx>) - -> RelateResult<'tcx, SubstsRef<'tcx>> - { + fn relate_item_substs( + &mut self, + item_def_id: DefId, + a_subst: SubstsRef<'tcx>, + b_subst: SubstsRef<'tcx>, + ) -> RelateResult<'tcx, SubstsRef<'tcx>> { if self.ambient_variance == ty::Variance::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles @@ -462,12 +477,12 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { } } - fn relate_with_variance>(&mut self, - variance: ty::Variance, - a: &T, - b: &T) - -> RelateResult<'tcx, T> - { + fn relate_with_variance>( + &mut self, + variance: ty::Variance, + a: &T, + b: &T, + ) -> RelateResult<'tcx, T> { let old_ambient_variance = self.ambient_variance; self.ambient_variance = self.ambient_variance.xform(variance); @@ -524,28 +539,27 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { let origin = *variables.var_origin(vid); let new_var_id = variables.new_var(self.for_universe, false, origin); let u = self.tcx().mk_ty_var(new_var_id); - debug!("generalize: replacing original vid={:?} with new={:?}", - vid, u); + debug!("generalize: replacing original vid={:?} with new={:?}", vid, u); Ok(u) } } } } - ty::Infer(ty::IntVar(_)) | - ty::Infer(ty::FloatVar(_)) => { + ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) => { // No matter what mode we are in, // integer/floating-point types must be equal to be // relatable. Ok(t) } - _ => { - relate::super_relate_tys(self, t, t) - } + _ => relate::super_relate_tys(self, t, t), } } - fn regions(&mut self, r: ty::Region<'tcx>, r2: ty::Region<'tcx>) - -> RelateResult<'tcx, ty::Region<'tcx>> { + fn regions( + &mut self, + r: ty::Region<'tcx>, + r2: ty::Region<'tcx>, + ) -> RelateResult<'tcx, ty::Region<'tcx>> { assert_eq!(r, r2); // we are abusing TypeRelation here; both LHS and RHS ought to be == debug!("generalize: regions r={:?}", r); @@ -553,26 +567,21 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { match *r { // Never make variables for regions bound within the type itself, // nor for erased regions. - ty::ReLateBound(..) | - ty::ReErased => { + ty::ReLateBound(..) | ty::ReErased => { return Ok(r); } ty::ReClosureBound(..) => { - span_bug!( - self.span, - "encountered unexpected ReClosureBound: {:?}", - r, - ); + span_bug!(self.span, "encountered unexpected ReClosureBound: {:?}", r,); } - ty::RePlaceholder(..) | - ty::ReVar(..) | - ty::ReEmpty | - ty::ReStatic | - ty::ReScope(..) | - ty::ReEarlyBound(..) | - ty::ReFree(..) => { + ty::RePlaceholder(..) + | ty::ReVar(..) + | ty::ReEmpty + | ty::ReStatic + | ty::ReScope(..) + | ty::ReEarlyBound(..) + | ty::ReFree(..) => { // see common code below } } @@ -597,7 +606,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { fn consts( &mut self, c: &'tcx ty::Const<'tcx>, - c2: &'tcx ty::Const<'tcx> + c2: &'tcx ty::Const<'tcx>, ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { assert_eq!(c, c2); // we are abusing TypeRelation here; both LHS and RHS ought to be == @@ -626,21 +635,17 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { } pub trait RelateResultCompare<'tcx, T> { - fn compare(&self, t: T, f: F) -> RelateResult<'tcx, T> where + fn compare(&self, t: T, f: F) -> RelateResult<'tcx, T> + where F: FnOnce() -> TypeError<'tcx>; } -impl<'tcx, T:Clone + PartialEq> RelateResultCompare<'tcx, T> for RelateResult<'tcx, T> { - fn compare(&self, t: T, f: F) -> RelateResult<'tcx, T> where +impl<'tcx, T: Clone + PartialEq> RelateResultCompare<'tcx, T> for RelateResult<'tcx, T> { + fn compare(&self, t: T, f: F) -> RelateResult<'tcx, T> + where F: FnOnce() -> TypeError<'tcx>, { - self.clone().and_then(|s| { - if s == t { - self.clone() - } else { - Err(f()) - } - }) + self.clone().and_then(|s| if s == t { self.clone() } else { Err(f()) }) } } @@ -651,17 +656,18 @@ pub fn const_unification_error<'tcx>( TypeError::ConstMismatch(ty::relate::expected_found_bool(a_is_expected, &a, &b)) } -fn int_unification_error<'tcx>(a_is_expected: bool, v: (ty::IntVarValue, ty::IntVarValue)) - -> TypeError<'tcx> -{ +fn int_unification_error<'tcx>( + a_is_expected: bool, + v: (ty::IntVarValue, ty::IntVarValue), +) -> TypeError<'tcx> { let (a, b) = v; TypeError::IntMismatch(ty::relate::expected_found_bool(a_is_expected, &a, &b)) } -fn float_unification_error<'tcx>(a_is_expected: bool, - v: (ty::FloatVarValue, ty::FloatVarValue)) - -> TypeError<'tcx> -{ +fn float_unification_error<'tcx>( + a_is_expected: bool, + v: (ty::FloatVarValue, ty::FloatVarValue), +) -> TypeError<'tcx> { let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v; TypeError::FloatMismatch(ty::relate::expected_found_bool(a_is_expected, &a, &b)) } diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs index aea58acab5450..6a7707b3c0ad1 100644 --- a/src/librustc/infer/equate.rs +++ b/src/librustc/infer/equate.rs @@ -3,10 +3,10 @@ use super::Subtype; use crate::hir::def_id::DefId; -use crate::ty::{self, Ty, TyCtxt}; -use crate::ty::TyVar; -use crate::ty::subst::SubstsRef; use crate::ty::relate::{self, Relate, RelateResult, TypeRelation}; +use crate::ty::subst::SubstsRef; +use crate::ty::TyVar; +use crate::ty::{self, Ty, TyCtxt}; /// Ensures `a` is made equal to `b`. Returns `a` on success. pub struct Equate<'combine, 'infcx, 'tcx> { @@ -24,20 +24,28 @@ impl<'combine, 'infcx, 'tcx> Equate<'combine, 'infcx, 'tcx> { } impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> { - fn tag(&self) -> &'static str { "Equate" } + fn tag(&self) -> &'static str { + "Equate" + } - fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() } + fn tcx(&self) -> TyCtxt<'tcx> { + self.fields.tcx() + } - fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env } + fn param_env(&self) -> ty::ParamEnv<'tcx> { + self.fields.param_env + } - fn a_is_expected(&self) -> bool { self.a_is_expected } + fn a_is_expected(&self) -> bool { + self.a_is_expected + } - fn relate_item_substs(&mut self, - _item_def_id: DefId, - a_subst: SubstsRef<'tcx>, - b_subst: SubstsRef<'tcx>) - -> RelateResult<'tcx, SubstsRef<'tcx>> - { + fn relate_item_substs( + &mut self, + _item_def_id: DefId, + a_subst: SubstsRef<'tcx>, + b_subst: SubstsRef<'tcx>, + ) -> RelateResult<'tcx, SubstsRef<'tcx>> { // N.B., once we are equating types, we don't care about // variance, so don't try to lookup the variance here. This // also avoids some cycles (e.g., #41849) since looking up @@ -48,19 +56,20 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> { relate::relate_substs(self, None, a_subst, b_subst) } - fn relate_with_variance>(&mut self, - _: ty::Variance, - a: &T, - b: &T) - -> RelateResult<'tcx, T> - { + fn relate_with_variance>( + &mut self, + _: ty::Variance, + a: &T, + b: &T, + ) -> RelateResult<'tcx, T> { self.relate(a, b) } fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { - debug!("{}.tys({:?}, {:?})", self.tag(), - a, b); - if a == b { return Ok(a); } + debug!("{}.tys({:?}, {:?})", self.tag(), a, b); + if a == b { + return Ok(a); + } let infcx = self.fields.infcx; let a = infcx.type_variables.borrow_mut().replace_if_possible(a); @@ -89,15 +98,14 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> { Ok(a) } - fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) - -> RelateResult<'tcx, ty::Region<'tcx>> { - debug!("{}.regions({:?}, {:?})", - self.tag(), - a, - b); + fn regions( + &mut self, + a: ty::Region<'tcx>, + b: ty::Region<'tcx>, + ) -> RelateResult<'tcx, ty::Region<'tcx>> { + debug!("{}.regions({:?}, {:?})", self.tag(), a, b); let origin = Subtype(box self.fields.trace.clone()); - self.fields.infcx.borrow_region_constraints() - .make_eqregion(origin, a, b); + self.fields.infcx.borrow_region_constraints().make_eqregion(origin, a, b); Ok(a) } @@ -109,9 +117,13 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> { self.fields.infcx.super_combine_consts(self, a, b) } - fn binders(&mut self, a: &ty::Binder, b: &ty::Binder) - -> RelateResult<'tcx, ty::Binder> - where T: Relate<'tcx> + fn binders( + &mut self, + a: &ty::Binder, + b: &ty::Binder, + ) -> RelateResult<'tcx, ty::Binder> + where + T: Relate<'tcx>, { self.fields.higher_ranked_sub(a, b, self.a_is_expected)?; self.fields.higher_ranked_sub(b, a, self.a_is_expected) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 052f33dc2a65f..027143a3d22c0 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -52,20 +52,24 @@ use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePa use crate::hir; use crate::hir::def_id::DefId; use crate::hir::Node; -use crate::infer::{self, SuppressRegionErrors}; use crate::infer::opaque_types; +use crate::infer::{self, SuppressRegionErrors}; use crate::middle::region; use crate::traits::{ IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, }; use crate::ty::error::TypeError; -use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{ + self, + subst::{Subst, SubstsRef}, + Region, Ty, TyCtxt, TypeFoldable, +}; use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; use rustc_error_codes::*; use rustc_target::spec::abi; -use syntax_pos::{Pos, Span}; use std::{cmp, fmt}; +use syntax_pos::{Pos, Span}; mod note; @@ -87,10 +91,7 @@ impl<'tcx> TyCtxt<'tcx> { ty::ReScope(scope) => { let new_string; let unknown_scope = || { - format!( - "{}unknown scope: {:?}{}. Please report a bug.", - prefix, scope, suffix - ) + format!("{}unknown scope: {:?}{}. Please report a bug.", prefix, scope, suffix) }; let span = scope.span(self, region_scope_tree); let tag = match self.hir().find(scope.hir_id(region_scope_tree)) { @@ -199,22 +200,19 @@ impl<'tcx> TyCtxt<'tcx> { let (prefix, span) = match *region { ty::ReEarlyBound(ref br) => { let mut sp = cm.def_span(self.hir().span(node)); - if let Some(param) = self.hir() - .get_generics(scope) - .and_then(|generics| generics.get_named(br.name)) + if let Some(param) = + self.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name)) { sp = param.span; } (format!("the lifetime `{}` as defined on", br.name), sp) } ty::ReFree(ty::FreeRegion { - bound_region: ty::BoundRegion::BrNamed(_, name), - .. + bound_region: ty::BoundRegion::BrNamed(_, name), .. }) => { let mut sp = cm.def_span(self.hir().span(node)); - if let Some(param) = self.hir() - .get_generics(scope) - .and_then(|generics| generics.get_named(name)) + if let Some(param) = + self.hir().get_generics(scope).and_then(|generics| generics.get_named(name)) { sp = param.span; } @@ -282,10 +280,7 @@ impl<'tcx> TyCtxt<'tcx> { fn explain_span(self, heading: &str, span: Span) -> (String, Option) { let lo = self.sess.source_map().lookup_char_pos(span.lo()); - ( - format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize() + 1), - Some(span), - ) + (format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize() + 1), Some(span)) } } @@ -310,10 +305,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // together into a `ProcessedErrors` group: let errors = self.process_errors(errors); - debug!( - "report_region_errors: {} errors after preprocessing", - errors.len() - ); + debug!("report_region_errors: {} errors after preprocessing", errors.len()); for error in errors { debug!("report_region_errors: error = {:?}", error); @@ -362,7 +354,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { sub_r, sup_r, ) - .emit(); + .emit(); } else if sup_r.is_placeholder() { self.report_placeholder_failure( region_scope_tree, @@ -370,7 +362,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { sub_r, sup_r, ) - .emit(); + .emit(); } else { self.report_sub_sup_conflict( region_scope_tree, @@ -397,7 +389,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { opaque_type_def_id, hidden_ty, member_region, - ).emit(); + ) + .emit(); } } } @@ -435,18 +428,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let is_bound_failure = |e: &RegionResolutionError<'tcx>| match *e { RegionResolutionError::GenericBoundFailure(..) => true, RegionResolutionError::ConcreteFailure(..) - | RegionResolutionError::SubSupConflict(..) - | RegionResolutionError::MemberConstraintFailure { .. } => false, + | RegionResolutionError::SubSupConflict(..) + | RegionResolutionError::MemberConstraintFailure { .. } => false, }; let mut errors = if errors.iter().all(|e| is_bound_failure(e)) { errors.clone() } else { - errors - .iter() - .filter(|&e| !is_bound_failure(e)) - .cloned() - .collect() + errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect() }; // sort the errors by span, for better error message stability. @@ -489,17 +478,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.tcx } - fn print_region( - self, - _region: ty::Region<'_>, - ) -> Result { + fn print_region(self, _region: ty::Region<'_>) -> Result { Err(NonTrivialPath) } - fn print_type( - self, - _ty: Ty<'tcx>, - ) -> Result { + fn print_type(self, _ty: Ty<'tcx>) -> Result { Err(NonTrivialPath) } @@ -510,17 +493,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { Err(NonTrivialPath) } - fn print_const( - self, - _ct: &'tcx ty::Const<'tcx>, - ) -> Result { + fn print_const(self, _ct: &'tcx ty::Const<'tcx>) -> Result { Err(NonTrivialPath) } - fn path_crate( - self, - cnum: CrateNum, - ) -> Result { + fn path_crate(self, cnum: CrateNum) -> Result { Ok(vec![self.tcx.original_crate_name(cnum).to_string()]) } fn path_qualified( @@ -562,18 +539,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Only external crates, if either is from a local // module we could have false positives if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { - let abs_path = |def_id| { - AbsolutePathPrinter { tcx: self.tcx } - .print_def_path(def_id, &[]) - }; + let abs_path = + |def_id| AbsolutePathPrinter { tcx: self.tcx }.print_def_path(def_id, &[]); // We compare strings because DefPath can be different // for imported and non-imported crates let same_path = || -> Result<_, NonTrivialPath> { - Ok( - self.tcx.def_path_str(did1) == self.tcx.def_path_str(did2) || - abs_path(did1)? == abs_path(did2)? - ) + Ok(self.tcx.def_path_str(did1) == self.tcx.def_path_str(did2) + || abs_path(did1)? == abs_path(did2)?) }; if same_path().unwrap_or(false) { let crate_name = self.tcx.crate_name(did1.krate); @@ -588,8 +561,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { TypeError::Sorts(ref exp_found) => { // if they are both "path types", there's a chance of ambiguity // due to different versions of the same crate - if let (&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _)) - = (&exp_found.expected.kind, &exp_found.found.kind) + if let (&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _)) = + (&exp_found.expected.kind, &exp_found.found.kind) { report_path_match(err, exp_adt.did, found_adt.did); } @@ -609,7 +582,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) { match cause.code { ObligationCauseCode::MatchExpressionArmPattern { span, ty } => { - if ty.is_suggestable() { // don't show type `_` + if ty.is_suggestable() { + // don't show type `_` err.span_label(span, format!("this match expression has type `{}`", ty)); } if let Some(ty::error::ExpectedFound { found, .. }) = exp_found { @@ -641,9 +615,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let discrim_expr = self.tcx.hir().expect_expr(discrim_hir_id); let discrim_ty = if let hir::ExprKind::Call(_, args) = &discrim_expr.kind { let arg_expr = args.first().expect("try desugaring call w/out arg"); - self.in_progress_tables.and_then(|tables| { - tables.borrow().expr_ty_opt(arg_expr) - }) + self.in_progress_tables + .and_then(|tables| tables.borrow().expr_ty_opt(arg_expr)) } else { bug!("try desugaring w/out call expr as discriminant"); }; @@ -657,8 +630,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "".to_string(), Applicability::MachineApplicable, ); - }, - _ => {}, + } + _ => {} } } } @@ -672,7 +645,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.span_label(cause.span, msg); if prior_arms.len() <= 4 { for sp in prior_arms { - err.span_label( *sp, format!("this is found to be of type `{}`", t)); + err.span_label(*sp, format!("this is found to be of type `{}`", t)); } } else if let Some(sp) = prior_arms.last() { err.span_label( @@ -729,14 +702,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } // Output the lifetimes for the first type - let lifetimes = sub.regions() + let lifetimes = sub + .regions() .map(|lifetime| { let s = lifetime.to_string(); - if s.is_empty() { - "'_".to_string() - } else { - s - } + if s.is_empty() { "'_".to_string() } else { s } }) .collect::>() .join(", "); @@ -836,11 +806,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) -> SubstsRef<'tcx> { let generics = self.tcx.generics_of(def_id); let mut num_supplied_defaults = 0; - let mut type_params = generics.params.iter().rev().filter_map(|param| match param.kind { - ty::GenericParamDefKind::Lifetime => None, - ty::GenericParamDefKind::Type { has_default, .. } => Some((param.def_id, has_default)), - ty::GenericParamDefKind::Const => None, // FIXME(const_generics:defaults) - }).peekable(); + let mut type_params = generics + .params + .iter() + .rev() + .filter_map(|param| match param.kind { + ty::GenericParamDefKind::Lifetime => None, + ty::GenericParamDefKind::Type { has_default, .. } => { + Some((param.def_id, has_default)) + } + ty::GenericParamDefKind::Const => None, // FIXME(const_generics:defaults) + }) + .peekable(); let has_default = { let has_default = type_params.peek().map(|(_, has_default)| has_default); *has_default.unwrap_or(&false) @@ -876,11 +853,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .name_all_regions(sig) .unwrap(); let lts: Vec = reg.into_iter().map(|(_, kind)| kind.to_string()).collect(); - (if lts.is_empty() { - String::new() - } else { - format!("for<{}> ", lts.join(", ")) - }, sig) + (if lts.is_empty() { String::new() } else { format!("for<{}> ", lts.join(", ")) }, sig) }; let (lt1, sig1) = get_lifetimes(sig1); @@ -1058,11 +1031,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { fn lifetime_display(lifetime: Region<'_>) -> String { let s = lifetime.to_string(); - if s.is_empty() { - "'_".to_string() - } else { - s - } + if s.is_empty() { "'_".to_string() } else { s } } // At one point we'd like to elide all lifetimes here, they are irrelevant for // all diagnostics that use this output @@ -1137,14 +1106,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Foo // ------- this type argument is exactly the same as the other type // Bar - if self.cmp_type_arg( - &mut values.0, - &mut values.1, - path1.clone(), - sub_no_defaults_1, - path2.clone(), - &t2, - ).is_some() + if self + .cmp_type_arg( + &mut values.0, + &mut values.1, + path1.clone(), + sub_no_defaults_1, + path2.clone(), + &t2, + ) + .is_some() { return values; } @@ -1153,14 +1124,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Bar // Foo> // ------- this type argument is exactly the same as the other type - if self.cmp_type_arg( - &mut values.1, - &mut values.0, - path2, - sub_no_defaults_2, - path1, - &t1, - ).is_some() + if self + .cmp_type_arg( + &mut values.1, + &mut values.0, + path2, + sub_no_defaults_2, + path1, + &t1, + ) + .is_some() { return values; } @@ -1177,14 +1150,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { const SEPARATOR: &str = "::"; let separator_len = SEPARATOR.len(); - let split_idx: usize = - t1_str.split(SEPARATOR) - .zip(t2_str.split(SEPARATOR)) - .take_while(|(mod1_str, mod2_str)| mod1_str == mod2_str) - .map(|(mod_str, _)| mod_str.len() + separator_len) - .sum(); - - debug!("cmp: separator_len={}, split_idx={}, min_len={}", + let split_idx: usize = t1_str + .split(SEPARATOR) + .zip(t2_str.split(SEPARATOR)) + .take_while(|(mod1_str, mod2_str)| mod1_str == mod2_str) + .map(|(mod_str, _)| mod_str.len() + separator_len) + .sum(); + + debug!( + "cmp: separator_len={}, split_idx={}, min_len={}", separator_len, split_idx, min_len ); @@ -1192,7 +1166,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // paths are identical, highlight everything ( DiagnosticStyledString::highlighted(t1_str), - DiagnosticStyledString::highlighted(t2_str) + DiagnosticStyledString::highlighted(t2_str), ) } else { let (common, uniq1) = t1_str.split_at(split_idx); @@ -1235,10 +1209,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // When encountering tuples of the same size, highlight only the differing types (&ty::Tuple(substs1), &ty::Tuple(substs2)) if substs1.len() == substs2.len() => { - let mut values = ( - DiagnosticStyledString::normal("("), - DiagnosticStyledString::normal("("), - ); + let mut values = + (DiagnosticStyledString::normal("("), DiagnosticStyledString::normal("(")); let len = substs1.len(); for (i, (left, right)) in substs1.types().zip(substs2.types()).enumerate() { let (x1, x2) = self.cmp(left, right); @@ -1246,7 +1218,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { (values.1).0.extend(x2.0); self.push_comma(&mut values.0, &mut values.1, len, i); } - if len == 1 { // Keep the output for single element tuples as `(ty,)`. + if len == 1 { + // Keep the output for single element tuples as `(ty,)`. values.0.push_normal(","); values.1.push_normal(","); } @@ -1272,8 +1245,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let mut values = self.cmp_fn_sig(&sig1, sig2); values.0.push_normal(format!( " {{{}}}", - self.tcx.def_path_str_with_substs(*did1, substs1)), - ); + self.tcx.def_path_str_with_substs(*did1, substs1) + )); values } @@ -1282,22 +1255,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let mut values = self.cmp_fn_sig(sig1, &sig2); values.1.push_normal(format!( " {{{}}}", - self.tcx.def_path_str_with_substs(*did2, substs2)), - ); + self.tcx.def_path_str_with_substs(*did2, substs2) + )); values } - (ty::FnPtr(sig1), ty::FnPtr(sig2)) => { - self.cmp_fn_sig(sig1, sig2) - } + (ty::FnPtr(sig1), ty::FnPtr(sig2)) => self.cmp_fn_sig(sig1, sig2), _ => { if t1 == t2 { // The two types are the same, elide and don't highlight. - ( - DiagnosticStyledString::normal("_"), - DiagnosticStyledString::normal("_"), - ) + (DiagnosticStyledString::normal("_"), DiagnosticStyledString::normal("_")) } else { // We couldn't find anything in common, highlight everything. ( @@ -1332,8 +1300,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { Some(values) => { let (is_simple_error, exp_found) = match values { ValuePairs::Types(exp_found) => { - let is_simple_err = exp_found.expected.is_simple_text() - && exp_found.found.is_simple_text(); + let is_simple_err = + exp_found.expected.is_simple_text() && exp_found.found.is_simple_text(); (is_simple_err, Some(exp_found)) } @@ -1373,14 +1341,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let sort_string = |ty: Ty<'tcx>| match (extra, &ty.kind) { (true, ty::Opaque(def_id, _)) => format!( " (opaque type at {})", - self.tcx.sess.source_map() + self.tcx + .sess + .source_map() .mk_substr_filename(self.tcx.def_span(*def_id)), ), (true, _) => format!(" ({})", ty.sort_string(self.tcx)), (false, _) => "".to_string(), }; - if !(values.expected.is_simple_text() && values.found.is_simple_text()) || ( - exp_found.map_or(false, |ef| { + if !(values.expected.is_simple_text() && values.found.is_simple_text()) + || (exp_found.map_or(false, |ef| { // This happens when the type error is a subset of the expectation, // like when you have two references but one is `usize` and the other // is `f32`. In those cases we still want to show the `note`. If the @@ -1392,8 +1362,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } else { false } - }) - ) { + })) + { diag.note_expected_found_extra( &expected_label, expected, @@ -1426,8 +1396,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // it's a actual definition. According to the comments (e.g. in // librustc_typeck/check/compare_method.rs:compare_predicate_entailment) the latter // is relied upon by some other code. This might (or might not) need cleanup. - let body_owner_def_id = self.tcx.hir().opt_local_def_id(cause.body_id) - .unwrap_or_else(|| { + let body_owner_def_id = + self.tcx.hir().opt_local_def_id(cause.body_id).unwrap_or_else(|| { self.tcx.hir().body_owner_def_id(hir::BodyId { hir_id: cause.body_id }) }); self.check_and_note_conflicting_crates(diag, terr); @@ -1461,22 +1431,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ("std::result::Result", result_msg), ("core::result::Result", result_msg), ]; - if let Some(msg) = have_as_ref.iter() - .filter_map(|(path, msg)| if &path_str == path { - Some(msg) - } else { - None - }).next() + if let Some(msg) = have_as_ref + .iter() + .filter_map( + |(path, msg)| if &path_str == path { Some(msg) } else { None }, + ) + .next() { let mut show_suggestion = true; for (exp_ty, found_ty) in exp_substs.types().zip(found_substs.types()) { match exp_ty.kind { ty::Ref(_, exp_ty, _) => { match (&exp_ty.kind, &found_ty.kind) { - (_, ty::Param(_)) | - (_, ty::Infer(_)) | - (ty::Param(_), _) | - (ty::Infer(_), _) => {} + (_, ty::Param(_)) + | (_, ty::Infer(_)) + | (ty::Param(_), _) + | (ty::Infer(_), _) => {} _ if ty::TyS::same_type(exp_ty, found_ty) => {} _ => show_suggestion = false, }; @@ -1485,10 +1455,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => show_suggestion = false, } } - if let (Ok(snippet), true) = ( - self.tcx.sess.source_map().span_to_snippet(span), - show_suggestion, - ) { + if let (Ok(snippet), true) = + (self.tcx.sess.source_map().span_to_snippet(span), show_suggestion) + { diag.span_suggestion( span, msg, @@ -1509,10 +1478,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { trace: TypeTrace<'tcx>, terr: &TypeError<'tcx>, ) -> DiagnosticBuilder<'tcx> { - debug!( - "report_and_explain_type_error(trace={:?}, terr={:?})", - trace, terr - ); + debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr); let span = trace.cause.span(self.tcx); let failure_code = trace.cause.as_failure_code(terr); @@ -1549,17 +1515,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { infer::TraitRefs(ref exp_found) => { let pretty_exp_found = ty::error::ExpectedFound { expected: exp_found.expected.print_only_trait_path(), - found: exp_found.found.print_only_trait_path() + found: exp_found.found.print_only_trait_path(), }; self.expected_found_str(&pretty_exp_found) - }, + } infer::PolyTraitRefs(ref exp_found) => { let pretty_exp_found = ty::error::ExpectedFound { expected: exp_found.expected.print_only_trait_path(), - found: exp_found.found.print_only_trait_path() + found: exp_found.found.print_only_trait_path(), }; self.expected_found_str(&pretty_exp_found) - }, + } } } @@ -1636,7 +1602,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // `T:` when appropriate let is_impl_trait = bound_kind.to_string().starts_with("impl "); let sp = if has_bounds && !is_impl_trait { - sp.to(self.tcx + sp.to(self + .tcx .sess .source_map() .next_point(self.tcx.sess.source_map().next_point(sp))) @@ -1708,10 +1675,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let mut err = match *sub { ty::ReEarlyBound(_) - | ty::ReFree(ty::FreeRegion { - bound_region: ty::BrNamed(..), - .. - }) => { + | ty::ReFree(ty::FreeRegion { bound_region: ty::BrNamed(..), .. }) => { // Does the required lifetime have a nice name we can print? let mut err = struct_span_err!( self.tcx.sess, @@ -1798,10 +1762,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { debug!("report_sub_sup_conflict: sup_trace.values={:?}", sup_trace.values); debug!("report_sub_sup_conflict: sub_trace.values={:?}", sub_trace.values); - if let (Some((sup_expected, sup_found)), Some((sub_expected, sub_found))) = ( - self.values_str(&sup_trace.values), - self.values_str(&sub_trace.values), - ) { + if let (Some((sup_expected, sup_found)), Some((sub_expected, sub_found))) = + (self.values_str(&sup_trace.values), self.values_str(&sub_trace.values)) + { if sub_expected == sup_expected && sub_found == sup_found { self.tcx.note_and_explain_region( region_scope_tree, @@ -1810,17 +1773,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { sub_region, "...", ); - err.span_note(sup_trace.cause.span, &format!( - "...so that the {}", - sup_trace.cause.as_requirement_str() - )); - - err.note_expected_found( - &"", - sup_expected, - &"", - sup_found + err.span_note( + sup_trace.cause.span, + &format!("...so that the {}", sup_trace.cause.as_requirement_str()), ); + + err.note_expected_found(&"", sup_expected, &"", sup_found); err.emit(); return; } @@ -1913,15 +1871,17 @@ impl<'tcx> ObligationCause<'tcx> { match self.code { CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"), CompareImplTypeObligation { .. } => Error0308("type not compatible with trait"), - MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => + MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => { Error0308(match source { - hir::MatchSource::IfLetDesugar { .. } => - "`if let` arms have incompatible types", + hir::MatchSource::IfLetDesugar { .. } => { + "`if let` arms have incompatible types" + } hir::MatchSource::TryDesugar => { "try expression alternatives have incompatible types" } _ => "match arms have incompatible types", - }), + }) + } IfExpression { .. } => Error0308("if and else have incompatible types"), IfExpressionWithNoElse => Error0317("if may be missing an else clause"), MainFunctionType => Error0580("main function has wrong type"), diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 378d6d78d3203..9954c35433c31 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -1,15 +1,15 @@ use crate::hir::def::{DefKind, Namespace}; -use crate::hir::{self, Body, FunctionRetTy, Expr, ExprKind, HirId, Local, Pat}; -use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; -use crate::infer::InferCtxt; +use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; +use crate::hir::{self, Body, Expr, ExprKind, FunctionRetTy, HirId, Local, Pat}; use crate::infer::type_variable::TypeVariableOriginKind; -use crate::ty::{self, Ty, Infer, TyVar, DefIdTree}; +use crate::infer::InferCtxt; use crate::ty::print::Print; +use crate::ty::{self, DefIdTree, Infer, Ty, TyVar}; +use errors::{Applicability, DiagnosticBuilder}; +use std::borrow::Cow; use syntax::source_map::DesugaringKind; use syntax::symbol::kw; use syntax_pos::Span; -use errors::{Applicability, DiagnosticBuilder}; -use std::borrow::Cow; use rustc_error_codes::*; @@ -43,22 +43,19 @@ impl<'a, 'tcx> FindLocalByTypeVisitor<'a, 'tcx> { } fn node_matches_type(&mut self, hir_id: HirId) -> Option> { - let ty_opt = self.infcx.in_progress_tables.and_then(|tables| { - tables.borrow().node_type_opt(hir_id) - }); + let ty_opt = + self.infcx.in_progress_tables.and_then(|tables| tables.borrow().node_type_opt(hir_id)); match ty_opt { Some(ty) => { let ty = self.infcx.resolve_vars_if_possible(&ty); if ty.walk().any(|inner_ty| { - inner_ty == self.target_ty || match (&inner_ty.kind, &self.target_ty.kind) { - (&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => { - self.infcx - .type_variables - .borrow_mut() - .sub_unified(a_vid, b_vid) + inner_ty == self.target_ty + || match (&inner_ty.kind, &self.target_ty.kind) { + (&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => { + self.infcx.type_variables.borrow_mut().sub_unified(a_vid, b_vid) + } + _ => false, } - _ => false, - } }) { Some(ty) } else { @@ -85,10 +82,8 @@ impl<'a, 'tcx> Visitor<'tcx> for FindLocalByTypeVisitor<'a, 'tcx> { fn visit_body(&mut self, body: &'tcx Body<'tcx>) { for param in body.params { - if let (None, Some(ty)) = ( - self.found_arg_pattern, - self.node_matches_type(param.hir_id), - ) { + if let (None, Some(ty)) = (self.found_arg_pattern, self.node_matches_type(param.hir_id)) + { self.found_arg_pattern = Some(&*param.pat); self.found_ty = Some(ty); } @@ -125,38 +120,28 @@ fn closure_return_type_suggestion( _ => ("", ""), }; let suggestion = match body.value.kind { - ExprKind::Block(..) => { - vec![(output.span(), format!("{}{}{}", arrow, ret, post))] - } - _ => { - vec![ - (output.span(), format!("{}{}{}{{ ", arrow, ret, post)), - (body.value.span.shrink_to_hi(), " }".to_string()), - ] - } + ExprKind::Block(..) => vec![(output.span(), format!("{}{}{}", arrow, ret, post))], + _ => vec![ + (output.span(), format!("{}{}{}{{ ", arrow, ret, post)), + (body.value.span.shrink_to_hi(), " }".to_string()), + ], }; err.multipart_suggestion( "give this closure an explicit return type without `_` placeholders", suggestion, Applicability::HasPlaceholders, ); - err.span_label(span, InferCtxt::missing_type_msg( - &name, - &descr, - parent_name, - parent_descr - )); + err.span_label(span, InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr)); } /// Given a closure signature, return a `String` containing a list of all its argument types. fn closure_args(fn_sig: &ty::PolyFnSig<'_>) -> String { - fn_sig.inputs() + fn_sig + .inputs() .skip_binder() .iter() .next() - .map(|args| args.tuple_fields() - .map(|arg| arg.to_string()) - .collect::>().join(", ")) + .map(|args| args.tuple_fields().map(|arg| arg.to_string()).collect::>().join(", ")) .unwrap_or_default() } @@ -191,10 +176,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind { let parent_def_id = def_id.and_then(|def_id| self.tcx.parent(def_id)); let (parent_name, parent_desc) = if let Some(parent_def_id) = parent_def_id { - let parent_name = self.tcx.def_key(parent_def_id).disambiguated_data.data - .get_opt_name().map(|parent_symbol| parent_symbol.to_string()); - - let type_parent_desc = self.tcx.def_kind(parent_def_id) + let parent_name = self + .tcx + .def_key(parent_def_id) + .disambiguated_data + .data + .get_opt_name() + .map(|parent_symbol| parent_symbol.to_string()); + + let type_parent_desc = self + .tcx + .def_kind(parent_def_id) .map(|parent_def_kind| parent_def_kind.descr(parent_def_id)); (parent_name, type_parent_desc) @@ -233,7 +225,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let ty = self.resolve_vars_if_possible(&ty); let (name, name_sp, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None); - let mut local_visitor = FindLocalByTypeVisitor::new(&self, ty, &self.tcx.hir()); let ty_to_string = |ty: Ty<'tcx>| -> String { let mut s = String::new(); @@ -265,9 +256,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // 3 | let _ = x.sum() as f64; // | ^^^ cannot infer type for `S` span - } else if let Some( - ExprKind::MethodCall(_, call_span, _), - ) = local_visitor.found_method_call.map(|e| &e.kind) { + } else if let Some(ExprKind::MethodCall(_, call_span, _)) = + local_visitor.found_method_call.map(|e| &e.kind) + { // Point at the call instead of the whole expression: // error[E0284]: type annotations needed // --> file.rs:2:5 @@ -276,11 +267,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // | ^^^^^^^ cannot infer type // | // = note: cannot resolve `<_ as std::ops::Try>::Ok == _` - if span.contains(*call_span) { - *call_span - } else { - span - } + if span.contains(*call_span) { *call_span } else { span } } else { span }; @@ -364,8 +351,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let ty = ty_to_string(ty); format!( "the explicit type `{}`, where the type parameter `{}` is specified", - ty, - name, + ty, name, ) } _ => "a type".to_string(), @@ -395,9 +381,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } else if let Some(pattern) = local_visitor.found_local_pattern { let msg = if let Some(simple_ident) = pattern.simple_ident() { match pattern.span.desugaring_kind() { - None => { - format!("consider giving `{}` {}", simple_ident, suffix) - } + None => format!("consider giving `{}` {}", simple_ident, suffix), Some(DesugaringKind::ForLoop) => { "the element type for this iterator is not specified".to_string() } @@ -455,14 +439,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // | // = note: type must be known at this point let span = name_sp.unwrap_or(err_span); - if !err.span.span_labels().iter().any(|span_label| { - span_label.label.is_some() && span_label.span == span - }) && local_visitor.found_arg_pattern.is_none() + if !err + .span + .span_labels() + .iter() + .any(|span_label| span_label.label.is_some() && span_label.span == span) + && local_visitor.found_arg_pattern.is_none() { // Avoid multiple labels pointing at `span`. err.span_label( span, - InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr) + InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr), ); } @@ -490,16 +477,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { segment.ident.span, &format!( "consider specifying the type argument{} in the method call", - if generics.params.len() > 1 { - "s" - } else { - "" - }, + if generics.params.len() > 1 { "s" } else { "" }, + ), + format!( + "{}::<{}>", + snippet, + generics + .params + .iter() + .map(|p| p.name.to_string()) + .collect::>() + .join(", ") ), - format!("{}::<{}>", snippet, generics.params.iter() - .map(|p| p.name.to_string()) - .collect::>() - .join(", ")), Applicability::HasPlaceholders, ); } else { @@ -528,14 +517,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let (name, _, descr, parent_name, parent_descr) = self.extract_type_name(&ty, None); let mut err = struct_span_err!( - self.tcx.sess, span, E0698, "type inside {} must be known in this context", kind, + self.tcx.sess, + span, + E0698, + "type inside {} must be known in this context", + kind, ); - err.span_label(span, InferCtxt::missing_type_msg( - &name, - &descr, - parent_name, - parent_descr - )); + err.span_label(span, InferCtxt::missing_type_msg(&name, &descr, parent_name, parent_descr)); err } diff --git a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs index a431b541fa42f..cfb6d5bd244b9 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -1,8 +1,8 @@ //! Error Reporting for Anonymous Region Lifetime Errors //! where both the regions are anonymous. -use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo; +use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::util::common::ErrorReported; use rustc_error_codes::*; @@ -62,26 +62,20 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { debug!( "try_report_anon_anon_conflict: found_param1={:?} sup={:?} br1={:?}", - ty_sub, - sup, - bregion_sup + ty_sub, sup, bregion_sup ); debug!( "try_report_anon_anon_conflict: found_param2={:?} sub={:?} br2={:?}", - ty_sup, - sub, - bregion_sub + ty_sup, sub, bregion_sub ); let (ty_sup, ty_fndecl_sup) = ty_sup; let (ty_sub, ty_fndecl_sub) = ty_sub; - let AnonymousParamInfo { - param: anon_param_sup, .. - } = self.find_param_with_region(sup, sup)?; - let AnonymousParamInfo { - param: anon_param_sub, .. - } = self.find_param_with_region(sub, sub)?; + let AnonymousParamInfo { param: anon_param_sup, .. } = + self.find_param_with_region(sup, sup)?; + let AnonymousParamInfo { param: anon_param_sub, .. } = + self.find_param_with_region(sub, sub)?; let sup_is_ret_type = self.is_return_type_anon(scope_def_id_sup, bregion_sup, ty_fndecl_sup); @@ -103,16 +97,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let (main_label_1, span_label_1) = if ty_sup.hir_id == ty_sub.hir_id { ( "this type is declared with multiple lifetimes...".to_owned(), - "...but data with one lifetime flows into the other here".to_owned() + "...but data with one lifetime flows into the other here".to_owned(), ) } else { ( "these two types are declared with different lifetimes...".to_owned(), - format!( - "...but data{} flows{} here", - span_label_var1, - span_label_var2 - ), + format!("...but data{} flows{} here", span_label_var1, span_label_var2), ) }; (ty_sup.span, ty_sub.span, main_label_1, span_label_1) @@ -122,21 +112,20 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ty_sub.span, ret_span, "this parameter and the return type are declared \ - with different lifetimes...".to_owned() - , + with different lifetimes..." + .to_owned(), format!("...but data{} is returned here", span_label_var1), ), (_, Some(ret_span)) => ( ty_sup.span, ret_span, "this parameter and the return type are declared \ - with different lifetimes...".to_owned() - , + with different lifetimes..." + .to_owned(), format!("...but data{} is returned here", span_label_var1), ), }; - struct_span_err!(self.tcx().sess, span, E0623, "lifetime mismatch") .span_label(span_1, main_label) .span_label(span_2, String::new()) diff --git a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs index db5557204e4da..decc00826dd9c 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -1,9 +1,9 @@ use crate::hir; -use crate::ty::{self, Region, TyCtxt}; -use crate::hir::Node; -use crate::middle::resolve_lifetime as rl; use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; +use crate::hir::Node; use crate::infer::error_reporting::nice_region_error::NiceRegionError; +use crate::middle::resolve_lifetime as rl; +use crate::ty::{self, Region, TyCtxt}; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// This function calls the `visit_ty` method for the parameters @@ -30,10 +30,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let def_id = anon_reg.def_id; if let Some(hir_id) = self.tcx().hir().as_local_hir_id(def_id) { let fndecl = match self.tcx().hir().get(hir_id) { - Node::Item(&hir::Item { - kind: hir::ItemKind::Fn(ref m, ..), - .. - }) + Node::Item(&hir::Item { kind: hir::ItemKind::Fn(ref m, ..), .. }) | Node::TraitItem(&hir::TraitItem { kind: hir::TraitItemKind::Method(ref m, ..), .. @@ -106,11 +103,13 @@ impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { return; } - hir::TyKind::TraitObject(ref bounds, _) => for bound in bounds { - self.current_index.shift_in(1); - self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None); - self.current_index.shift_out(1); - }, + hir::TyKind::TraitObject(ref bounds, _) => { + for bound in bounds { + self.current_index.shift_in(1); + self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None); + self.current_index.shift_out(1); + } + } hir::TyKind::Rptr(ref lifetime, _) => { // the lifetime of the TyRptr @@ -125,9 +124,7 @@ impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { ) => { debug!( "LateBoundAnon depth = {:?} anon_index = {:?} br_index={:?}", - debruijn_index, - anon_index, - br_index + debruijn_index, anon_index, br_index ); if debruijn_index == self.current_index && anon_index == br_index { self.found_type = Some(arg); @@ -183,7 +180,7 @@ impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { current_index: self.current_index, }; intravisit::walk_ty(subvisitor, arg); // call walk_ty; as visit_ty is empty, - // this will visit only outermost type + // this will visit only outermost type if subvisitor.found_it { self.found_type = Some(arg); } @@ -233,10 +230,7 @@ impl Visitor<'tcx> for TyPathVisitor<'tcx> { } (Some(rl::Region::LateBound(debruijn_index, id, _)), ty::BrNamed(def_id, _)) => { - debug!( - "FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", - debruijn_index, - ); + debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", debruijn_index,); debug!("id={:?}", id); debug!("def_id={:?}", def_id); if debruijn_index == self.current_index && id == def_id { diff --git a/src/librustc/infer/error_reporting/nice_region_error/mod.rs b/src/librustc/infer/error_reporting/nice_region_error/mod.rs index 09cfbf850a57d..023d9f89b039c 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/mod.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/mod.rs @@ -1,6 +1,6 @@ -use crate::infer::InferCtxt; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::lexical_region_resolve::RegionResolutionError::*; +use crate::infer::InferCtxt; use crate::ty::{self, TyCtxt}; use crate::util::common::ErrorReported; use errors::DiagnosticBuilder; @@ -9,8 +9,8 @@ use syntax::source_map::Span; mod different_lifetimes; mod find_anon_type; mod named_anon_conflict; -mod placeholder_error; mod outlives_closure; +mod placeholder_error; mod static_impl_trait; mod trait_impl_difference; mod util; @@ -19,7 +19,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { pub fn try_report_nice_region_error(&self, error: &RegionResolutionError<'tcx>) -> bool { match *error { ConcreteFailure(..) | SubSupConflict(..) => {} - _ => return false, // inapplicable + _ => return false, // inapplicable } if let Some(tables) = self.in_progress_tables { @@ -64,13 +64,15 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> { pub fn try_report_from_nll(&self) -> Option> { // Due to the improved diagnostics returned by the MIR borrow checker, only a subset of // the nice region errors are required when running under the MIR borrow checker. - self.try_report_named_anon_conflict() - .or_else(|| self.try_report_placeholder_conflict()) + self.try_report_named_anon_conflict().or_else(|| self.try_report_placeholder_conflict()) } pub fn try_report(&self) -> Option { self.try_report_from_nll() - .map(|mut diag| { diag.emit(); ErrorReported }) + .map(|mut diag| { + diag.emit(); + ErrorReported + }) .or_else(|| self.try_report_anon_anon_conflict()) .or_else(|| self.try_report_outlives_closure()) .or_else(|| self.try_report_static_impl_trait()) diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 0abdeb7199344..94b8d16668a3f 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -1,7 +1,7 @@ //! Error Reporting for Anonymous Region Lifetime Errors //! where one region is named and the other is anonymous. -use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::hir::{FunctionRetTy, TyKind}; +use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::ty; use errors::{Applicability, DiagnosticBuilder}; @@ -15,9 +15,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { debug!( "try_report_named_anon_conflict(sub={:?}, sup={:?}, error={:?})", - sub, - sup, - self.error, + sub, sup, self.error, ); // Determine whether the sub and sup consist of one named region ('a) @@ -36,7 +34,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { self.find_param_with_region(sup, sub).unwrap(), self.tcx().is_suitable_region(sup).unwrap(), ) - } else if self.is_named_region(sup) && self.tcx().is_suitable_region(sub).is_some() + } else if self.is_named_region(sup) + && self.tcx().is_suitable_region(sub).is_some() && self.find_param_with_region(sub, sup).is_some() { ( @@ -50,14 +49,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { }; debug!("try_report_named_anon_conflict: named = {:?}", named); - debug!( - "try_report_named_anon_conflict: anon_param_info = {:?}", - anon_param_info - ); - debug!( - "try_report_named_anon_conflict: region_info = {:?}", - region_info - ); + debug!("try_report_named_anon_conflict: anon_param_info = {:?}", anon_param_info); + debug!("try_report_named_anon_conflict: region_info = {:?}", region_info); let (param, new_ty, new_ty_span, br, is_first, scope_def_id, is_impl_item) = ( anon_param_info.param, diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 3b4d06aab27ef..e6758f6596d50 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -1,4 +1,3 @@ -use errors::DiagnosticBuilder; use crate::hir::def::Namespace; use crate::hir::def_id::DefId; use crate::infer::error_reporting::nice_region_error::NiceRegionError; @@ -6,10 +5,11 @@ use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::ValuePairs; use crate::infer::{SubregionOrigin, TypeTrace}; use crate::traits::{ObligationCause, ObligationCauseCode}; -use crate::ty::{self, TyCtxt}; use crate::ty::error::ExpectedFound; +use crate::ty::print::{FmtPrinter, Print, RegionHighlightMode}; use crate::ty::subst::SubstsRef; -use crate::ty::print::{Print, RegionHighlightMode, FmtPrinter}; +use crate::ty::{self, TyCtxt}; +use errors::DiagnosticBuilder; use std::fmt::{self, Write}; @@ -259,24 +259,16 @@ impl NiceRegionError<'me, 'tcx> { } }); - let actual_self_ty_has_vid = self - .tcx() - .any_free_region_meets(&actual_trait_ref.self_ty(), |r| Some(r) == vid); + let actual_self_ty_has_vid = + self.tcx().any_free_region_meets(&actual_trait_ref.self_ty(), |r| Some(r) == vid); - let expected_self_ty_has_vid = self - .tcx() - .any_free_region_meets(&expected_trait_ref.self_ty(), |r| Some(r) == vid); + let expected_self_ty_has_vid = + self.tcx().any_free_region_meets(&expected_trait_ref.self_ty(), |r| Some(r) == vid); let any_self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid; - debug!( - "try_report_placeholders_trait: actual_has_vid={:?}", - actual_has_vid - ); - debug!( - "try_report_placeholders_trait: expected_has_vid={:?}", - expected_has_vid - ); + debug!("try_report_placeholders_trait: actual_has_vid={:?}", actual_has_vid); + debug!("try_report_placeholders_trait: expected_has_vid={:?}", expected_has_vid); debug!("try_report_placeholders_trait: has_sub={:?}", has_sub); debug!("try_report_placeholders_trait: has_sup={:?}", has_sup); debug!( @@ -336,11 +328,7 @@ impl NiceRegionError<'me, 'tcx> { impl<'tcx, T> Highlighted<'tcx, T> { fn map(self, f: impl FnOnce(T) -> U) -> Highlighted<'tcx, U> { - Highlighted { - tcx: self.tcx, - highlight: self.highlight, - value: f(self.value), - } + Highlighted { tcx: self.tcx, highlight: self.highlight, value: f(self.value) } } } @@ -415,24 +403,21 @@ impl NiceRegionError<'me, 'tcx> { match (has_sub, has_sup) { (Some(n1), Some(n2)) => { - let _ = write!(note, + let _ = write!( + note, ", for any two lifetimes `'{}` and `'{}`...", std::cmp::min(n1, n2), std::cmp::max(n1, n2), ); } (Some(n), _) | (_, Some(n)) => { - let _ = write!(note, - ", for any lifetime `'{}`...", - n, - ); + let _ = write!(note, ", for any lifetime `'{}`...", n,); + } + (None, None) => { + if let Some(n) = expected_has_vid { + let _ = write!(note, ", for some specific lifetime `'{}`...", n,); + } } - (None, None) => if let Some(n) = expected_has_vid { - let _ = write!(note, - ", for some specific lifetime `'{}`...", - n, - ); - }, } note diff --git a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs index 01ba748c4e1f9..8f6fbd27a58af 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -11,51 +11,43 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { pub(super) fn try_report_static_impl_trait(&self) -> Option { if let Some(ref error) = self.error { if let RegionResolutionError::SubSupConflict( - _, - var_origin, - sub_origin, - sub_r, - sup_origin, - sup_r, - ) = error.clone() + _, + var_origin, + sub_origin, + sub_r, + sup_origin, + sup_r, + ) = error.clone() { let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?; let return_ty = self.tcx().return_type_impl_trait(anon_reg_sup.def_id); - if sub_r == &RegionKind::ReStatic && - return_ty.is_some() - { + if sub_r == &RegionKind::ReStatic && return_ty.is_some() { let sp = var_origin.span(); let return_sp = sub_origin.span(); - let mut err = self.tcx().sess.struct_span_err( - sp, - "cannot infer an appropriate lifetime", - ); + let mut err = + self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime"); err.span_label( return_sp, "this return type evaluates to the `'static` lifetime...", ); - err.span_label( - sup_origin.span(), - "...but this borrow...", - ); + err.span_label(sup_origin.span(), "...but this borrow..."); let (lifetime, lt_sp_opt) = self.tcx().msg_span_from_free_region(sup_r); if let Some(lifetime_sp) = lt_sp_opt { - err.span_note( - lifetime_sp, - &format!("...can't outlive {}", lifetime), - ); + err.span_note(lifetime_sp, &format!("...can't outlive {}", lifetime)); } let lifetime_name = match sup_r { RegionKind::ReFree(FreeRegion { - bound_region: BoundRegion::BrNamed(_, ref name), .. + bound_region: BoundRegion::BrNamed(_, ref name), + .. }) => name.to_string(), _ => "'_".to_owned(), }; let fn_return_span = return_ty.unwrap().1; if let Ok(snippet) = - self.tcx().sess.source_map().span_to_snippet(fn_return_span) { + self.tcx().sess.source_map().span_to_snippet(fn_return_span) + { // only apply this suggestion onto functions with // explicit non-desugar'able return. if fn_return_span.desugaring_kind().is_none() { @@ -64,7 +56,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { &format!( "you can add a constraint to the return type to make it last \ less than `'static` and match {}", - lifetime, + lifetime, ), format!("{} + {}", snippet, lifetime_name), Applicability::Unspecified, diff --git a/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 0194300c50721..6f9fe25b63058 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -1,12 +1,12 @@ //! Error Reporting for `impl` items that do not match the obligations from their `trait`. -use syntax_pos::Span; -use crate::ty::Ty; -use crate::infer::{ValuePairs, Subtype}; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; -use crate::util::common::ErrorReported; +use crate::infer::{Subtype, ValuePairs}; use crate::traits::ObligationCauseCode::CompareImplMethodObligation; +use crate::ty::Ty; +use crate::util::common::ErrorReported; +use syntax_pos::Span; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`. @@ -20,14 +20,16 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { _sub, sup_origin, _sup, - ) = error.clone() { + ) = error.clone() + { match (&sup_origin, &sub_origin) { (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) => { if let ( ValuePairs::Types(sub_expected_found), ValuePairs::Types(sup_expected_found), CompareImplMethodObligation { trait_item_def_id, .. }, - ) = (&sub_trace.values, &sup_trace.values, &sub_trace.cause.code) { + ) = (&sub_trace.values, &sup_trace.values, &sub_trace.cause.code) + { if sup_expected_found == sub_expected_found { self.emit_err( var_origin.span(), @@ -47,10 +49,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, impl_sp: Span) { - let mut err = self.tcx().sess.struct_span_err( - sp, - "`impl` item signature doesn't match `trait` item signature", - ); + let mut err = self + .tcx() + .sess + .struct_span_err(sp, "`impl` item signature doesn't match `trait` item signature"); err.note(&format!("expected `{:?}`\n found `{:?}`", expected, found)); err.span_label(sp, &format!("found {:?}", found)); err.span_label(impl_sp, &format!("expected {:?}", expected)); diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs index a2e48cf07cb7c..36e91fa3e37a9 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/util.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs @@ -2,9 +2,9 @@ //! anonymous regions. use crate::hir; +use crate::hir::def_id::DefId; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::ty::{self, DefIdTree, Region, Ty}; -use crate::hir::def_id::DefId; use syntax_pos::Span; // The struct contains the information about the anonymous region @@ -18,7 +18,7 @@ pub(super) struct AnonymousParamInfo<'tcx> { // the ty::BoundRegion corresponding to the anonymous region pub bound_region: ty::BoundRegion, // param_ty_span contains span of parameter type - pub param_ty_span : Span, + pub param_ty_span: Span, // corresponds to id the argument is the first parameter // in the declaration pub is_first: bool, @@ -79,7 +79,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { Some(AnonymousParamInfo { param: param, param_ty: new_param_ty, - param_ty_span : param_ty_span, + param_ty_span: param_ty_span, bound_region: bound_region, is_first: is_first, }) @@ -111,8 +111,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let ret_ty = self.tcx().type_of(scope_def_id); if let ty::FnDef(_, _) = ret_ty.kind { let sig = ret_ty.fn_sig(self.tcx()); - let late_bound_regions = self.tcx() - .collect_referenced_late_bound_regions(&sig.output()); + let late_bound_regions = + self.tcx().collect_referenced_late_bound_regions(&sig.output()); if late_bound_regions.iter().any(|r| *r == br) { return Some(decl.output.span()); } @@ -126,9 +126,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // enable E0621 for it. pub(super) fn is_self_anon(&self, is_first: bool, scope_def_id: DefId) -> bool { is_first - && self.tcx() - .opt_associated_item(scope_def_id) - .map(|i| i.method_has_self_argument) == Some(true) + && self.tcx().opt_associated_item(scope_def_id).map(|i| i.method_has_self_argument) + == Some(true) } - } diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs index 4b933735fc75f..979bcca619c2f 100644 --- a/src/librustc/infer/error_reporting/note.rs +++ b/src/librustc/infer/error_reporting/note.rs @@ -1,66 +1,62 @@ use crate::infer::{self, InferCtxt, SubregionOrigin}; use crate::middle::region; -use crate::ty::{self, Region}; use crate::ty::error::TypeError; +use crate::ty::{self, Region}; use errors::DiagnosticBuilder; use rustc_error_codes::*; impl<'a, 'tcx> InferCtxt<'a, 'tcx> { - pub(super) fn note_region_origin(&self, - err: &mut DiagnosticBuilder<'_>, - origin: &SubregionOrigin<'tcx>) { + pub(super) fn note_region_origin( + &self, + err: &mut DiagnosticBuilder<'_>, + origin: &SubregionOrigin<'tcx>, + ) { match *origin { infer::Subtype(ref trace) => { if let Some((expected, found)) = self.values_str(&trace.values) { err.span_note( trace.cause.span, - &format!( - "...so that the {}", - trace.cause.as_requirement_str() - ) + &format!("...so that the {}", trace.cause.as_requirement_str()), ); - err.note_expected_found( - &"", - expected, - &"", - found - ); + err.note_expected_found(&"", expected, &"", found); } else { // FIXME: this really should be handled at some earlier stage. Our // handling of region checking when type errors are present is // *terrible*. - err.span_note(trace.cause.span, - &format!("...so that {}", trace.cause.as_requirement_str())); + err.span_note( + trace.cause.span, + &format!("...so that {}", trace.cause.as_requirement_str()), + ); } } infer::Reborrow(span) => { - err.span_note(span, - "...so that reference does not outlive borrowed content"); + err.span_note(span, "...so that reference does not outlive borrowed content"); } infer::ReborrowUpvar(span, ref upvar_id) => { let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); - err.span_note(span, - &format!("...so that closure can access `{}`", var_name)); + err.span_note(span, &format!("...so that closure can access `{}`", var_name)); } infer::InfStackClosure(span) => { err.span_note(span, "...so that closure does not outlive its stack frame"); } infer::InvokeClosure(span) => { - err.span_note(span, - "...so that closure is not invoked outside its lifetime"); + err.span_note(span, "...so that closure is not invoked outside its lifetime"); } infer::DerefPointer(span) => { - err.span_note(span, - "...so that pointer is not dereferenced outside its lifetime"); + err.span_note(span, "...so that pointer is not dereferenced outside its lifetime"); } infer::ClosureCapture(span, id) => { - err.span_note(span, - &format!("...so that captured variable `{}` does not outlive the \ + err.span_note( + span, + &format!( + "...so that captured variable `{}` does not outlive the \ enclosing closure", - self.tcx.hir().name(id))); + self.tcx.hir().name(id) + ), + ); } infer::IndexSlice(span) => { err.span_note(span, "...so that slice is not indexed outside the lifetime"); @@ -69,8 +65,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.span_note(span, "...so that it can be closed over into an object"); } infer::CallRcvr(span) => { - err.span_note(span, - "...so that method receiver is valid for the method call"); + err.span_note(span, "...so that method receiver is valid for the method call"); } infer::CallArg(span) => { err.span_note(span, "...so that argument is valid for the call"); @@ -85,369 +80,572 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.span_note(span, "...so that reference is valid at the time of borrow"); } infer::AutoBorrow(span) => { - err.span_note(span, - "...so that auto-reference is valid at the time of borrow"); + err.span_note(span, "...so that auto-reference is valid at the time of borrow"); } infer::ExprTypeIsNotInScope(t, span) => { - err.span_note(span, - &format!("...so type `{}` of expression is valid during the \ + err.span_note( + span, + &format!( + "...so type `{}` of expression is valid during the \ expression", - self.ty_to_string(t))); + self.ty_to_string(t) + ), + ); } infer::BindingTypeIsNotValidAtDecl(span) => { - err.span_note(span, - "...so that variable is valid at time of its declaration"); + err.span_note(span, "...so that variable is valid at time of its declaration"); } infer::ParameterInScope(_, span) => { - err.span_note(span, - "...so that a type/lifetime parameter is in scope here"); + err.span_note(span, "...so that a type/lifetime parameter is in scope here"); } infer::DataBorrowed(ty, span) => { - err.span_note(span, - &format!("...so that the type `{}` is not borrowed for too long", - self.ty_to_string(ty))); + err.span_note( + span, + &format!( + "...so that the type `{}` is not borrowed for too long", + self.ty_to_string(ty) + ), + ); } infer::ReferenceOutlivesReferent(ty, span) => { - err.span_note(span, - &format!("...so that the reference type `{}` does not outlive the \ + err.span_note( + span, + &format!( + "...so that the reference type `{}` does not outlive the \ data it points at", - self.ty_to_string(ty))); + self.ty_to_string(ty) + ), + ); } infer::RelateParamBound(span, t) => { - err.span_note(span, - &format!("...so that the type `{}` will meet its required \ + err.span_note( + span, + &format!( + "...so that the type `{}` will meet its required \ lifetime bounds", - self.ty_to_string(t))); + self.ty_to_string(t) + ), + ); } infer::RelateDefaultParamBound(span, t) => { - err.span_note(span, - &format!("...so that type parameter instantiated with `{}`, will \ + err.span_note( + span, + &format!( + "...so that type parameter instantiated with `{}`, will \ meet its declared lifetime bounds", - self.ty_to_string(t))); + self.ty_to_string(t) + ), + ); } infer::RelateRegionParamBound(span) => { - err.span_note(span, - "...so that the declared lifetime parameter bounds are satisfied"); + err.span_note( + span, + "...so that the declared lifetime parameter bounds are satisfied", + ); } infer::SafeDestructor(span) => { - err.span_note(span, - "...so that references are valid when the destructor runs"); + err.span_note(span, "...so that references are valid when the destructor runs"); } infer::CompareImplMethodObligation { span, .. } => { - err.span_note(span, - "...so that the definition in impl matches the definition from the \ - trait"); + err.span_note( + span, + "...so that the definition in impl matches the definition from the \ + trait", + ); } } } - pub(super) fn report_concrete_failure(&self, - region_scope_tree: ®ion::ScopeTree, - origin: SubregionOrigin<'tcx>, - sub: Region<'tcx>, - sup: Region<'tcx>) - -> DiagnosticBuilder<'tcx> { + pub(super) fn report_concrete_failure( + &self, + region_scope_tree: ®ion::ScopeTree, + origin: SubregionOrigin<'tcx>, + sub: Region<'tcx>, + sup: Region<'tcx>, + ) -> DiagnosticBuilder<'tcx> { match origin { infer::Subtype(box trace) => { let terr = TypeError::RegionsDoesNotOutlive(sup, sub); let mut err = self.report_and_explain_type_error(trace, &terr); self.tcx.note_and_explain_region(region_scope_tree, &mut err, "", sup, "..."); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "...does not necessarily outlive ", sub, ""); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "...does not necessarily outlive ", + sub, + "", + ); err } infer::Reborrow(span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0312, - "lifetime of reference outlives lifetime of \ - borrowed content..."); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "...the reference is valid for ", - sub, - "..."); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "...but the borrowed content is only valid for ", - sup, - ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0312, + "lifetime of reference outlives lifetime of \ + borrowed content..." + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "...the reference is valid for ", + sub, + "...", + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "...but the borrowed content is only valid for ", + sup, + "", + ); err } infer::ReborrowUpvar(span, ref upvar_id) => { let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); - let mut err = struct_span_err!(self.tcx.sess, - span, - E0313, - "lifetime of borrowed pointer outlives lifetime \ + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0313, + "lifetime of borrowed pointer outlives lifetime \ of captured variable `{}`...", - var_name); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "...the borrowed pointer is valid for ", - sub, - "..."); + var_name + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "...the borrowed pointer is valid for ", + sub, + "...", + ); self.tcx.note_and_explain_region( region_scope_tree, &mut err, &format!("...but `{}` is only valid for ", var_name), sup, - ""); + "", + ); err } infer::InfStackClosure(span) => { let mut err = struct_span_err!(self.tcx.sess, span, E0314, "closure outlives stack frame"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "...the closure must be valid for ", - sub, - "..."); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "...but the closure's stack frame is only valid \ + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "...the closure must be valid for ", + sub, + "...", + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "...but the closure's stack frame is only valid \ for ", - sup, - ""); + sup, + "", + ); err } infer::InvokeClosure(span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0315, - "cannot invoke closure outside of its lifetime"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "the closure is only valid for ", sup, ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0315, + "cannot invoke closure outside of its lifetime" + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "the closure is only valid for ", + sup, + "", + ); err } infer::DerefPointer(span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0473, - "dereference of reference outside its lifetime"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "the reference is only valid for ", sup, ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0473, + "dereference of reference outside its lifetime" + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "the reference is only valid for ", + sup, + "", + ); err } infer::ClosureCapture(span, id) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0474, - "captured variable `{}` does not outlive the \ + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0474, + "captured variable `{}` does not outlive the \ enclosing closure", - self.tcx.hir().name(id)); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "captured variable is valid for ", sup, ""); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "closure is valid for ", sub, ""); + self.tcx.hir().name(id) + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "captured variable is valid for ", + sup, + "", + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "closure is valid for ", + sub, + "", + ); err } infer::IndexSlice(span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0475, - "index of slice outside its lifetime"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "the slice is only valid for ", sup, ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0475, + "index of slice outside its lifetime" + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "the slice is only valid for ", + sup, + "", + ); err } infer::RelateObjectBound(span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0476, - "lifetime of the source pointer does not outlive \ - lifetime bound of the object type"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "object type is valid for ", sub, ""); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "source pointer is only valid for ", - sup, - ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0476, + "lifetime of the source pointer does not outlive \ + lifetime bound of the object type" + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "object type is valid for ", + sub, + "", + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "source pointer is only valid for ", + sup, + "", + ); err } infer::RelateParamBound(span, ty) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0477, - "the type `{}` does not fulfill the required \ + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0477, + "the type `{}` does not fulfill the required \ lifetime", - self.ty_to_string(ty)); + self.ty_to_string(ty) + ); match *sub { - ty::ReStatic => { - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "type must satisfy ", sub, "") - } - _ => { - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "type must outlive ", sub, "") - } + ty::ReStatic => self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "type must satisfy ", + sub, + "", + ), + _ => self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "type must outlive ", + sub, + "", + ), } err } infer::RelateRegionParamBound(span) => { let mut err = struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "lifetime parameter instantiated with ", - sup, - ""); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "but lifetime parameter must outlive ", - sub, - ""); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "lifetime parameter instantiated with ", + sup, + "", + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "but lifetime parameter must outlive ", + sub, + "", + ); err } infer::RelateDefaultParamBound(span, ty) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0479, - "the type `{}` (provided as the value of a type \ + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0479, + "the type `{}` (provided as the value of a type \ parameter) is not valid at this point", - self.ty_to_string(ty)); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "type must outlive ", sub, ""); + self.ty_to_string(ty) + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "type must outlive ", + sub, + "", + ); err } infer::CallRcvr(span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0480, - "lifetime of method receiver does not outlive the \ - method call"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "the receiver is only valid for ", sup, ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0480, + "lifetime of method receiver does not outlive the \ + method call" + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "the receiver is only valid for ", + sup, + "", + ); err } infer::CallArg(span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0481, - "lifetime of function argument does not outlive \ - the function call"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "the function argument is only valid for ", - sup, - ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0481, + "lifetime of function argument does not outlive \ + the function call" + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "the function argument is only valid for ", + sup, + "", + ); err } infer::CallReturn(span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0482, - "lifetime of return value does not outlive the \ - function call"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "the return value is only valid for ", - sup, - ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0482, + "lifetime of return value does not outlive the \ + function call" + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "the return value is only valid for ", + sup, + "", + ); err } infer::Operand(span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0483, - "lifetime of operand does not outlive the \ - operation"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "the operand is only valid for ", sup, ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0483, + "lifetime of operand does not outlive the \ + operation" + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "the operand is only valid for ", + sup, + "", + ); err } infer::AddrOf(span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0484, - "reference is not valid at the time of borrow"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "the borrow is only valid for ", sup, ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0484, + "reference is not valid at the time of borrow" + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "the borrow is only valid for ", + sup, + "", + ); err } infer::AutoBorrow(span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0485, - "automatically reference is not valid at the time \ - of borrow"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "the automatic borrow is only valid for ", - sup, - ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0485, + "automatically reference is not valid at the time \ + of borrow" + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "the automatic borrow is only valid for ", + sup, + "", + ); err } infer::ExprTypeIsNotInScope(t, span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0486, - "type of expression contains references that are \ + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0486, + "type of expression contains references that are \ not valid during the expression: `{}`", - self.ty_to_string(t)); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "type is only valid for ", sup, ""); + self.ty_to_string(t) + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "type is only valid for ", + sup, + "", + ); err } infer::SafeDestructor(span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0487, - "unsafe use of destructor: destructor might be \ - called while references are dead"); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0487, + "unsafe use of destructor: destructor might be \ + called while references are dead" + ); // FIXME (22171): terms "super/subregion" are suboptimal - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "superregion: ", sup, ""); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "subregion: ", sub, ""); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "superregion: ", + sup, + "", + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "subregion: ", + sub, + "", + ); err } infer::BindingTypeIsNotValidAtDecl(span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0488, - "lifetime of variable does not enclose its \ - declaration"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "the variable is only valid for ", sup, ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0488, + "lifetime of variable does not enclose its \ + declaration" + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "the variable is only valid for ", + sup, + "", + ); err } infer::ParameterInScope(_, span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0489, - "type/lifetime parameter not in scope here"); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "the parameter is only valid for ", sub, ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0489, + "type/lifetime parameter not in scope here" + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "the parameter is only valid for ", + sub, + "", + ); err } infer::DataBorrowed(ty, span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0490, - "a value of type `{}` is borrowed for too long", - self.ty_to_string(ty)); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "the type is valid for ", sub, ""); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "but the borrow lasts for ", sup, ""); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0490, + "a value of type `{}` is borrowed for too long", + self.ty_to_string(ty) + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "the type is valid for ", + sub, + "", + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "but the borrow lasts for ", + sup, + "", + ); err } infer::ReferenceOutlivesReferent(ty, span) => { - let mut err = struct_span_err!(self.tcx.sess, - span, - E0491, - "in type `{}`, reference has a longer lifetime \ + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0491, + "in type `{}`, reference has a longer lifetime \ than the data it references", - self.ty_to_string(ty)); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "the pointer is valid for ", sub, ""); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, - "but the referenced data is only valid for ", - sup, - ""); + self.ty_to_string(ty) + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "the pointer is valid for ", + sub, + "", + ); + self.tcx.note_and_explain_region( + region_scope_tree, + &mut err, + "but the referenced data is only valid for ", + sup, + "", + ); err } - infer::CompareImplMethodObligation { span, - item_name, - impl_item_def_id, - trait_item_def_id } => { - self.report_extra_impl_obligation(span, - item_name, - impl_item_def_id, - trait_item_def_id, - &format!("`{}: {}`", sup, sub)) - } + infer::CompareImplMethodObligation { + span, + item_name, + impl_item_def_id, + trait_item_def_id, + } => self.report_extra_impl_obligation( + span, + item_name, + impl_item_def_id, + trait_item_def_id, + &format!("`{}: {}`", sup, sub), + ), } } @@ -465,9 +663,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.report_and_explain_type_error(trace, &terr) } - _ => { - self.report_concrete_failure(region_scope_tree, placeholder_origin, sub, sup) - } + _ => self.report_concrete_failure(region_scope_tree, placeholder_origin, sub, sup), } } } diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 32b51da920d66..f258968b2a31b 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -31,14 +31,14 @@ //! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type //! inferencer knows "so far". -use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; use crate::ty::fold::TypeFolder; +use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; use crate::util::nodemap::FxHashMap; use std::collections::hash_map::Entry; -use super::InferCtxt; use super::unify_key::ToType; +use super::InferCtxt; pub struct TypeFreshener<'a, 'tcx> { infcx: &'a InferCtxt<'a, 'tcx>, @@ -123,30 +123,29 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { r } - ty::ReStatic | - ty::ReEarlyBound(..) | - ty::ReFree(_) | - ty::ReScope(_) | - ty::ReVar(_) | - ty::RePlaceholder(..) | - ty::ReEmpty | - ty::ReErased => { + ty::ReStatic + | ty::ReEarlyBound(..) + | ty::ReFree(_) + | ty::ReScope(_) + | ty::ReVar(_) + | ty::RePlaceholder(..) + | ty::ReEmpty + | ty::ReErased => { // replace all free regions with 'erased self.tcx().lifetimes.re_erased } ty::ReClosureBound(..) => { - bug!( - "encountered unexpected region: {:?}", - r, - ); + bug!("encountered unexpected region: {:?}", r,); } } } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if !t.needs_infer() && !t.has_erasable_regions() && - !(t.has_closure_types() && self.infcx.in_progress_tables.is_some()) { + if !t.needs_infer() + && !t.has_erasable_regions() + && !(t.has_closure_types() && self.infcx.in_progress_tables.is_some()) + { return t; } @@ -155,83 +154,78 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { match t.kind { ty::Infer(ty::TyVar(v)) => { let opt_ty = self.infcx.type_variables.borrow_mut().probe(v).known(); - self.freshen_ty( - opt_ty, - ty::TyVar(v), - ty::FreshTy) + self.freshen_ty(opt_ty, ty::TyVar(v), ty::FreshTy) } - ty::Infer(ty::IntVar(v)) => { - self.freshen_ty( - self.infcx.int_unification_table.borrow_mut() - .probe_value(v) - .map(|v| v.to_type(tcx)), - ty::IntVar(v), - ty::FreshIntTy) - } + ty::Infer(ty::IntVar(v)) => self.freshen_ty( + self.infcx + .int_unification_table + .borrow_mut() + .probe_value(v) + .map(|v| v.to_type(tcx)), + ty::IntVar(v), + ty::FreshIntTy, + ), - ty::Infer(ty::FloatVar(v)) => { - self.freshen_ty( - self.infcx.float_unification_table.borrow_mut() - .probe_value(v) - .map(|v| v.to_type(tcx)), - ty::FloatVar(v), - ty::FreshFloatTy) - } + ty::Infer(ty::FloatVar(v)) => self.freshen_ty( + self.infcx + .float_unification_table + .borrow_mut() + .probe_value(v) + .map(|v| v.to_type(tcx)), + ty::FloatVar(v), + ty::FreshFloatTy, + ), - ty::Infer(ty::FreshTy(ct)) | - ty::Infer(ty::FreshIntTy(ct)) | - ty::Infer(ty::FreshFloatTy(ct)) => { + ty::Infer(ty::FreshTy(ct)) + | ty::Infer(ty::FreshIntTy(ct)) + | ty::Infer(ty::FreshFloatTy(ct)) => { if ct >= self.ty_freshen_count { - bug!("Encountered a freshend type with id {} \ + bug!( + "Encountered a freshend type with id {} \ but our counter is only at {}", - ct, - self.ty_freshen_count); + ct, + self.ty_freshen_count + ); } t } - ty::Generator(..) | - ty::Bool | - ty::Char | - ty::Int(..) | - ty::Uint(..) | - ty::Float(..) | - ty::Adt(..) | - ty::Str | - ty::Error | - ty::Array(..) | - ty::Slice(..) | - ty::RawPtr(..) | - ty::Ref(..) | - ty::FnDef(..) | - ty::FnPtr(_) | - ty::Dynamic(..) | - ty::Never | - ty::Tuple(..) | - ty::Projection(..) | - ty::UnnormalizedProjection(..) | - ty::Foreign(..) | - ty::Param(..) | - ty::Closure(..) | - ty::GeneratorWitness(..) | - ty::Opaque(..) => { - t.super_fold_with(self) - } + ty::Generator(..) + | ty::Bool + | ty::Char + | ty::Int(..) + | ty::Uint(..) + | ty::Float(..) + | ty::Adt(..) + | ty::Str + | ty::Error + | ty::Array(..) + | ty::Slice(..) + | ty::RawPtr(..) + | ty::Ref(..) + | ty::FnDef(..) + | ty::FnPtr(_) + | ty::Dynamic(..) + | ty::Never + | ty::Tuple(..) + | ty::Projection(..) + | ty::UnnormalizedProjection(..) + | ty::Foreign(..) + | ty::Param(..) + | ty::Closure(..) + | ty::GeneratorWitness(..) + | ty::Opaque(..) => t.super_fold_with(self), - ty::Placeholder(..) | - ty::Bound(..) => bug!("unexpected type {:?}", t), + ty::Placeholder(..) | ty::Bound(..) => bug!("unexpected type {:?}", t), } } fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { match ct.val { ty::ConstKind::Infer(ty::InferConst::Var(v)) => { - let opt_ct = self.infcx.const_unification_table - .borrow_mut() - .probe_value(v) - .val - .known(); + let opt_ct = + self.infcx.const_unification_table.borrow_mut().probe_value(v).val.known(); return self.freshen_const( opt_ct, ty::InferConst::Var(v), @@ -251,14 +245,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { return ct; } - ty::ConstKind::Bound(..) | - ty::ConstKind::Placeholder(_) => { + ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { bug!("unexpected const {:?}", ct) } - ty::ConstKind::Param(_) | - ty::ConstKind::Value(_) | - ty::ConstKind::Unevaluated(..) => {} + ty::ConstKind::Param(_) | ty::ConstKind::Value(_) | ty::ConstKind::Unevaluated(..) => {} } ct.super_fold_with(self) diff --git a/src/librustc/infer/fudge.rs b/src/librustc/infer/fudge.rs index 11f86a619b5c2..df265bf0147b6 100644 --- a/src/librustc/infer/fudge.rs +++ b/src/librustc/infer/fudge.rs @@ -1,9 +1,9 @@ -use crate::ty::{self, Ty, TyCtxt, TyVid, IntVid, FloatVid, RegionVid, ConstVid}; use crate::ty::fold::{TypeFoldable, TypeFolder}; +use crate::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid}; -use super::InferCtxt; -use super::{RegionVariableOrigin, ConstVariableOrigin}; use super::type_variable::TypeVariableOrigin; +use super::InferCtxt; +use super::{ConstVariableOrigin, RegionVariableOrigin}; use rustc_data_structures::unify as ut; use ut::UnifyKey; @@ -16,9 +16,12 @@ fn const_vars_since_snapshot<'tcx>( snapshot: &ut::Snapshot>>, ) -> (Range>, Vec) { let range = table.vars_since_snapshot(snapshot); - (range.start..range.end, (range.start.index..range.end.index).map(|index| { - table.probe_value(ConstVid::from_index(index)).origin.clone() - }).collect()) + ( + range.start..range.end, + (range.start.index..range.end.index) + .map(|index| table.probe_value(ConstVid::from_index(index)).origin.clone()) + .collect(), + ) } impl<'a, 'tcx> InferCtxt<'a, 'tcx> { @@ -61,10 +64,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// the actual types (`?T`, `Option`) -- and remember that /// after the snapshot is popped, the variable `?T` is no longer /// unified. - pub fn fudge_inference_if_ok( - &self, - f: F, - ) -> Result where + pub fn fudge_inference_if_ok(&self, f: F) -> Result + where F: FnOnce() -> Result, T: TypeFoldable<'tcx>, { @@ -81,18 +82,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // going to be popped, so we will have to // eliminate any references to them. - let type_vars = self.type_variables.borrow_mut().vars_since_snapshot( - &snapshot.type_snapshot, - ); - let int_vars = self.int_unification_table.borrow_mut().vars_since_snapshot( - &snapshot.int_snapshot, - ); - let float_vars = self.float_unification_table.borrow_mut().vars_since_snapshot( - &snapshot.float_snapshot, - ); - let region_vars = self.borrow_region_constraints().vars_since_snapshot( - &snapshot.region_constraints_snapshot, - ); + let type_vars = self + .type_variables + .borrow_mut() + .vars_since_snapshot(&snapshot.type_snapshot); + let int_vars = self + .int_unification_table + .borrow_mut() + .vars_since_snapshot(&snapshot.int_snapshot); + let float_vars = self + .float_unification_table + .borrow_mut() + .vars_since_snapshot(&snapshot.float_snapshot); + let region_vars = self + .borrow_region_constraints() + .vars_since_snapshot(&snapshot.region_constraints_snapshot); let const_vars = const_vars_since_snapshot( self.const_unification_table.borrow_mut(), &snapshot.const_snapshot, @@ -120,11 +124,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Micro-optimization: if no variables have been created, then // `value` can't refer to any of them. =) So we can just return it. - if fudger.type_vars.0.is_empty() && - fudger.int_vars.is_empty() && - fudger.float_vars.is_empty() && - fudger.region_vars.0.is_empty() && - fudger.const_vars.0.is_empty() { + if fudger.type_vars.0.is_empty() + && fudger.int_vars.is_empty() + && fudger.float_vars.is_empty() + && fudger.region_vars.0.is_empty() + && fudger.const_vars.0.is_empty() + { Ok(value) } else { Ok(value.fold_with(&mut fudger)) @@ -161,9 +166,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> { // variables to their binding anyhow, we know // that it is unbound, so we can just return // it. - debug_assert!(self.infcx.type_variables.borrow_mut() - .probe(vid) - .is_unknown()); + debug_assert!(self.infcx.type_variables.borrow_mut().probe(vid).is_unknown()); ty } } diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs index 37de54a7e8558..293dc80d983a9 100644 --- a/src/librustc/infer/glb.rs +++ b/src/librustc/infer/glb.rs @@ -1,11 +1,11 @@ use super::combine::CombineFields; -use super::InferCtxt; use super::lattice::{self, LatticeDir}; +use super::InferCtxt; use super::Subtype; use crate::traits::ObligationCause; -use crate::ty::{self, Ty, TyCtxt}; use crate::ty::relate::{Relate, RelateResult, TypeRelation}; +use crate::ty::{self, Ty, TyCtxt}; /// "Greatest lower bound" (common subtype) pub struct Glb<'combine, 'infcx, 'tcx> { @@ -23,20 +23,28 @@ impl<'combine, 'infcx, 'tcx> Glb<'combine, 'infcx, 'tcx> { } impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> { - fn tag(&self) -> &'static str { "Glb" } + fn tag(&self) -> &'static str { + "Glb" + } - fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() } + fn tcx(&self) -> TyCtxt<'tcx> { + self.fields.tcx() + } - fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env } + fn param_env(&self) -> ty::ParamEnv<'tcx> { + self.fields.param_env + } - fn a_is_expected(&self) -> bool { self.a_is_expected } + fn a_is_expected(&self) -> bool { + self.a_is_expected + } - fn relate_with_variance>(&mut self, - variance: ty::Variance, - a: &T, - b: &T) - -> RelateResult<'tcx, T> - { + fn relate_with_variance>( + &mut self, + variance: ty::Variance, + a: &T, + b: &T, + ) -> RelateResult<'tcx, T> { match variance { ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b), ty::Covariant => self.relate(a, b), @@ -50,12 +58,12 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> { lattice::super_lattice_tys(self, a, b) } - fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) - -> RelateResult<'tcx, ty::Region<'tcx>> { - debug!("{}.regions({:?}, {:?})", - self.tag(), - a, - b); + fn regions( + &mut self, + a: ty::Region<'tcx>, + b: ty::Region<'tcx>, + ) -> RelateResult<'tcx, ty::Region<'tcx>> { + debug!("{}.regions({:?}, {:?})", self.tag(), a, b); let origin = Subtype(box self.fields.trace.clone()); Ok(self.fields.infcx.borrow_region_constraints().glb_regions(self.tcx(), origin, a, b)) @@ -69,9 +77,13 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> { self.fields.infcx.super_combine_consts(self, a, b) } - fn binders(&mut self, a: &ty::Binder, b: &ty::Binder) - -> RelateResult<'tcx, ty::Binder> - where T: Relate<'tcx> + fn binders( + &mut self, + a: &ty::Binder, + b: &ty::Binder, + ) -> RelateResult<'tcx, ty::Binder> + where + T: Relate<'tcx>, { debug!("binders(a={:?}, b={:?})", a, b); diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index 49c095c69d6c4..bbca4823431e8 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -40,8 +40,7 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> { // but no other pre-existing region variables -- can name // the placeholders. let (a_prime, _) = - self.infcx - .replace_bound_vars_with_fresh_vars(span, HigherRankedType, a); + self.infcx.replace_bound_vars_with_fresh_vars(span, HigherRankedType, a); debug!("a_prime={:?}", a_prime); debug!("b_prime={:?}", b_prime); @@ -49,8 +48,7 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> { // Compare types now that bound regions have been replaced. let result = self.sub(a_is_expected).relate(&a_prime, &b_prime)?; - self.infcx - .leak_check(!a_is_expected, &placeholder_map, snapshot)?; + self.infcx.leak_check(!a_is_expected, &placeholder_map, snapshot)?; debug!("higher_ranked_sub: OK result={:?}", result); @@ -100,15 +98,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; let fld_c = |bound_var: ty::BoundVar, ty| { - self.tcx.mk_const( - ty::Const { - val: ty::ConstKind::Placeholder(ty::PlaceholderConst { - universe: next_universe, - name: bound_var, - }), - ty, - } - ) + self.tcx.mk_const(ty::Const { + val: ty::ConstKind::Placeholder(ty::PlaceholderConst { + universe: next_universe, + name: bound_var, + }), + ty, + }) }; let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t, fld_c); @@ -132,7 +128,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { placeholder_map: &PlaceholderMap<'tcx>, snapshot: &CombinedSnapshot<'_, 'tcx>, ) -> RelateResult<'tcx, ()> { - self.borrow_region_constraints() - .leak_check(self.tcx, overly_polymorphic, placeholder_map, snapshot) + self.borrow_region_constraints().leak_check( + self.tcx, + overly_polymorphic, + placeholder_map, + snapshot, + ) } } diff --git a/src/librustc/infer/lattice.rs b/src/librustc/infer/lattice.rs index 39701231aad7e..3e0aa4727ae1a 100644 --- a/src/librustc/infer/lattice.rs +++ b/src/librustc/infer/lattice.rs @@ -19,13 +19,13 @@ //! over a `LatticeValue`, which is a value defined with respect to //! a lattice. -use super::InferCtxt; use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use super::InferCtxt; use crate::traits::ObligationCause; +use crate::ty::relate::{RelateResult, TypeRelation}; use crate::ty::TyVar; use crate::ty::{self, Ty}; -use crate::ty::relate::{RelateResult, TypeRelation}; pub trait LatticeDir<'f, 'tcx>: TypeRelation<'tcx> { fn infcx(&self) -> &'f InferCtxt<'f, 'tcx>; @@ -49,10 +49,7 @@ pub fn super_lattice_tys<'a, 'tcx: 'a, L>( where L: LatticeDir<'a, 'tcx>, { - debug!("{}.lattice_tys({:?}, {:?})", - this.tag(), - a, - b); + debug!("{}.lattice_tys({:?}, {:?})", this.tag(), a, b); if a == b { return Ok(a); @@ -97,8 +94,6 @@ where Ok(v) } - _ => { - infcx.super_combine_tys(this, a, b) - } + _ => infcx.super_combine_tys(this, a, b), } } diff --git a/src/librustc/infer/lexical_region_resolve/graphviz.rs b/src/librustc/infer/lexical_region_resolve/graphviz.rs index ad481417d5e5f..2a3187afd7100 100644 --- a/src/librustc/infer/lexical_region_resolve/graphviz.rs +++ b/src/librustc/infer/lexical_region_resolve/graphviz.rs @@ -8,25 +8,26 @@ /// For clarity, rename the graphviz crate locally to dot. use graphviz as dot; +use super::Constraint; use crate::hir::def_id::DefIndex; -use crate::ty; +use crate::infer::region_constraints::RegionConstraintData; +use crate::infer::SubregionOrigin; use crate::middle::free_region::RegionRelations; use crate::middle::region; -use super::Constraint; -use crate::infer::SubregionOrigin; -use crate::infer::region_constraints::RegionConstraintData; +use crate::ty; use crate::util::nodemap::{FxHashMap, FxHashSet}; use std::borrow::Cow; -use std::collections::hash_map::Entry::Vacant; use std::collections::btree_map::BTreeMap; +use std::collections::hash_map::Entry::Vacant; use std::env; use std::fs; use std::io; use std::sync::atomic::{AtomicBool, Ordering}; fn print_help_message() { - println!("\ + println!( + "\ -Z print-region-graph by default prints a region constraint graph for every \n\ function body, to the path `constraints.nodeXXX.dot`, where the XXX is \n\ replaced with the node id of the function under analysis. \n\ @@ -41,7 +42,8 @@ the node id of the function under analysis. \n\ \n\ (Since you requested help via RUST_REGION_GRAPH=help, no region constraint \n\ graphs will be printed. \n\ -"); +" + ); } pub fn maybe_print_constraints_for<'a, 'tcx>( @@ -56,16 +58,15 @@ pub fn maybe_print_constraints_for<'a, 'tcx>( } let requested_node = env::var("RUST_REGION_GRAPH_NODE") - .ok().and_then(|s| s.parse().map(DefIndex::from_u32).ok()); + .ok() + .and_then(|s| s.parse().map(DefIndex::from_u32).ok()); if requested_node.is_some() && requested_node != Some(context.index) { return; } let requested_output = env::var("RUST_REGION_GRAPH"); - debug!("requested_output: {:?} requested_node: {:?}", - requested_output, - requested_node); + debug!("requested_output: {:?} requested_node: {:?}", requested_output, requested_node); let output_path = { let output_template = match requested_output { @@ -153,12 +154,7 @@ impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> { }); } - ConstraintGraph { - map, - node_ids, - region_rels, - graph_name: name, - } + ConstraintGraph { map, node_ids, region_rels, graph_name: name } } } @@ -175,8 +171,8 @@ impl<'a, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'tcx> { }; let name = || format!("node_{}", node_id); - dot::Id::new(name()).unwrap_or_else(|_| - bug!("failed to create graphviz node identified by {}", name())) + dot::Id::new(name()) + .unwrap_or_else(|_| bug!("failed to create graphviz node identified by {}", name())) } fn node_label(&self, n: &Node) -> dot::LabelText<'_> { match *n { @@ -186,8 +182,9 @@ impl<'a, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'tcx> { } fn edge_label(&self, e: &Edge<'_>) -> dot::LabelText<'_> { match *e { - Edge::Constraint(ref c) => - dot::LabelText::label(format!("{:?}", self.map.get(c).unwrap())), + Edge::Constraint(ref c) => { + dot::LabelText::label(format!("{:?}", self.map.get(c).unwrap())) + } Edge::EnclScope(..) => dot::LabelText::label("(enclosed)".to_owned()), } } @@ -195,14 +192,10 @@ impl<'a, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'tcx> { fn constraint_to_nodes(c: &Constraint<'_>) -> (Node, Node) { match *c { - Constraint::VarSubVar(rv_1, rv_2) => - (Node::RegionVid(rv_1), Node::RegionVid(rv_2)), - Constraint::RegSubVar(r_1, rv_2) => - (Node::Region(*r_1), Node::RegionVid(rv_2)), - Constraint::VarSubReg(rv_1, r_2) => - (Node::RegionVid(rv_1), Node::Region(*r_2)), - Constraint::RegSubReg(r_1, r_2) => - (Node::Region(*r_1), Node::Region(*r_2)), + Constraint::VarSubVar(rv_1, rv_2) => (Node::RegionVid(rv_1), Node::RegionVid(rv_2)), + Constraint::RegSubVar(r_1, rv_2) => (Node::Region(*r_1), Node::RegionVid(rv_2)), + Constraint::VarSubReg(rv_1, r_2) => (Node::RegionVid(rv_1), Node::Region(*r_2)), + Constraint::RegSubReg(r_1, r_2) => (Node::Region(*r_1), Node::Region(*r_2)), } } @@ -210,8 +203,7 @@ fn edge_to_nodes(e: &Edge<'_>) -> (Node, Node) { match *e { Edge::Constraint(ref c) => constraint_to_nodes(c), Edge::EnclScope(sub, sup) => { - (Node::Region(ty::ReScope(sub)), - Node::Region(ty::ReScope(sup))) + (Node::Region(ty::ReScope(sub)), Node::Region(ty::ReScope(sup))) } } } @@ -227,9 +219,9 @@ impl<'a, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'tcx> { fn edges(&self) -> dot::Edges<'_, Edge<'tcx>> { debug!("constraint graph has {} edges", self.map.len()); let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect(); - self.region_rels.region_scope_tree.each_encl_scope(|sub, sup| { - v.push(Edge::EnclScope(sub, sup)) - }); + self.region_rels + .region_scope_tree + .each_encl_scope(|sub, sup| v.push(Edge::EnclScope(sub, sup))); debug!("region graph has {} edges", v.len()); Cow::Owned(v) } @@ -252,9 +244,7 @@ fn dump_region_data_to<'a, 'tcx>( map: &ConstraintMap<'tcx>, path: &str, ) -> io::Result<()> { - debug!("dump_region_data map (len: {}) path: {}", - map.len(), - path); + debug!("dump_region_data map (len: {}) path: {}", map.len(), path); let g = ConstraintGraph::new("region_data".to_string(), region_rels, map); debug!("dump_region_data calling render"); let mut v = Vec::new(); diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index f30f19d41509d..723169b9f5fc5 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -155,10 +155,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } fn dump_constraints(&self, free_regions: &RegionRelations<'_, 'tcx>) { - debug!( - "----() Start constraint listing (context={:?}) ()----", - free_regions.context - ); + debug!("----() Start constraint listing (context={:?}) ()----", free_regions.context); for (idx, (constraint, _)) in self.data.constraints.iter().enumerate() { debug!("Constraint {} => {:?}", idx, constraint); } @@ -255,12 +252,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // Find all the "upper bounds" -- that is, each region `b` such that // `r0 <= b` must hold. - let (member_upper_bounds, _) = self.collect_concrete_regions( - graph, - member_vid, - OUTGOING, - None, - ); + let (member_upper_bounds, _) = + self.collect_concrete_regions(graph, member_vid, OUTGOING, None); // Get an iterator over the *available choice* -- that is, // each choice region `c` where `lb <= c` and `c <= ub` for all the @@ -799,13 +792,13 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // resolution errors here; delay ICE in favor of those errors. self.tcx().sess.delay_span_bug( self.var_infos[node_idx].origin.span(), - &format!("collect_error_for_expanding_node() could not find \ + &format!( + "collect_error_for_expanding_node() could not find \ error for var {:?} in universe {:?}, lower_bounds={:#?}, \ upper_bounds={:#?}", - node_idx, - node_universe, - lower_bounds, - upper_bounds)); + node_idx, node_universe, lower_bounds, upper_bounds + ), + ); } fn collect_concrete_regions( diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs index a1a94865e74e3..b512d3df3e8df 100644 --- a/src/librustc/infer/lub.rs +++ b/src/librustc/infer/lub.rs @@ -1,11 +1,11 @@ use super::combine::CombineFields; -use super::InferCtxt; use super::lattice::{self, LatticeDir}; +use super::InferCtxt; use super::Subtype; use crate::traits::ObligationCause; -use crate::ty::{self, Ty, TyCtxt}; use crate::ty::relate::{Relate, RelateResult, TypeRelation}; +use crate::ty::{self, Ty, TyCtxt}; /// "Least upper bound" (common supertype) pub struct Lub<'combine, 'infcx, 'tcx> { @@ -23,20 +23,28 @@ impl<'combine, 'infcx, 'tcx> Lub<'combine, 'infcx, 'tcx> { } impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> { - fn tag(&self) -> &'static str { "Lub" } + fn tag(&self) -> &'static str { + "Lub" + } - fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() } + fn tcx(&self) -> TyCtxt<'tcx> { + self.fields.tcx() + } - fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env } + fn param_env(&self) -> ty::ParamEnv<'tcx> { + self.fields.param_env + } - fn a_is_expected(&self) -> bool { self.a_is_expected } + fn a_is_expected(&self) -> bool { + self.a_is_expected + } - fn relate_with_variance>(&mut self, - variance: ty::Variance, - a: &T, - b: &T) - -> RelateResult<'tcx, T> - { + fn relate_with_variance>( + &mut self, + variance: ty::Variance, + a: &T, + b: &T, + ) -> RelateResult<'tcx, T> { match variance { ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b), ty::Covariant => self.relate(a, b), @@ -50,12 +58,12 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> { lattice::super_lattice_tys(self, a, b) } - fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) - -> RelateResult<'tcx, ty::Region<'tcx>> { - debug!("{}.regions({:?}, {:?})", - self.tag(), - a, - b); + fn regions( + &mut self, + a: ty::Region<'tcx>, + b: ty::Region<'tcx>, + ) -> RelateResult<'tcx, ty::Region<'tcx>> { + debug!("{}.regions({:?}, {:?})", self.tag(), a, b); let origin = Subtype(box self.fields.trace.clone()); Ok(self.fields.infcx.borrow_region_constraints().lub_regions(self.tcx(), origin, a, b)) @@ -69,9 +77,13 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> { self.fields.infcx.super_combine_consts(self, a, b) } - fn binders(&mut self, a: &ty::Binder, b: &ty::Binder) - -> RelateResult<'tcx, ty::Binder> - where T: Relate<'tcx> + fn binders( + &mut self, + a: &ty::Binder, + b: &ty::Binder, + ) -> RelateResult<'tcx, ty::Binder> + where + T: Relate<'tcx>, { debug!("binders(a={:?}, b={:?})", a, b); diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 996a722e157fa..e563f986f57e1 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -17,11 +17,11 @@ use crate::middle::region; use crate::session::config::BorrowckMode; use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine}; use crate::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; -use crate::ty::fold::{TypeFolder, TypeFoldable}; +use crate::ty::fold::{TypeFoldable, TypeFolder}; use crate::ty::relate::RelateResult; use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef}; -use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, InferConst}; -use crate::ty::{FloatVid, IntVid, TyVid, ConstVid}; +use crate::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt}; +use crate::ty::{ConstVid, FloatVid, IntVid, TyVid}; use crate::util::nodemap::{FxHashMap, FxHashSet}; use errors::DiagnosticBuilder; @@ -40,7 +40,7 @@ use self::outlives::env::OutlivesEnvironment; use self::region_constraints::{GenericKind, RegionConstraintData, VarInfos, VerifyBound}; use self::region_constraints::{RegionConstraintCollector, RegionSnapshot}; use self::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use self::unify_key::{ToType, ConstVariableOrigin, ConstVariableOriginKind}; +use self::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType}; pub mod at; pub mod canonical; @@ -428,7 +428,7 @@ pub enum NLLRegionVariableOrigin { /// determine whether there is any valid instantiation of a `'a` variable that meets /// some constraint C, we want to blame the "source" of that `for` type, /// rather than blaming the source of the constraint C. - from_forall: bool + from_forall: bool, }, } @@ -437,7 +437,7 @@ impl NLLRegionVariableOrigin { match self { NLLRegionVariableOrigin::FreeRegion => true, NLLRegionVariableOrigin::Placeholder(..) => true, - NLLRegionVariableOrigin::Existential{ .. } => false, + NLLRegionVariableOrigin::Existential { .. } => false, } } @@ -493,10 +493,7 @@ pub struct InferCtxtBuilder<'tcx> { impl TyCtxt<'tcx> { pub fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> { - InferCtxtBuilder { - global_tcx: self, - fresh_tables: None, - } + InferCtxtBuilder { global_tcx: self, fresh_tables: None } } } @@ -532,10 +529,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { } pub fn enter(&mut self, f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>) -> R) -> R { - let InferCtxtBuilder { - global_tcx, - ref fresh_tables, - } = *self; + let InferCtxtBuilder { global_tcx, ref fresh_tables } = *self; let in_progress_tables = fresh_tables.as_ref(); global_tcx.enter_local(|tcx| { f(InferCtxt { @@ -565,25 +559,16 @@ impl<'tcx> InferCtxtBuilder<'tcx> { impl ExpectedFound { pub fn new(a_is_expected: bool, a: T, b: T) -> Self { if a_is_expected { - ExpectedFound { - expected: a, - found: b, - } + ExpectedFound { expected: a, found: b } } else { - ExpectedFound { - expected: b, - found: a, - } + ExpectedFound { expected: b, found: a } } } } impl<'tcx, T> InferOk<'tcx, T> { pub fn unit(self) -> InferOk<'tcx, ()> { - InferOk { - value: (), - obligations: self.obligations, - } + InferOk { value: (), obligations: self.obligations } } /// Extracts `value`, registering any obligations into `fulfill_cx`. @@ -645,22 +630,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { use crate::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt}; match ty.kind { ty::Infer(ty::IntVar(vid)) => { - if self.int_unification_table - .borrow_mut() - .probe_value(vid) - .is_some() - { + if self.int_unification_table.borrow_mut().probe_value(vid).is_some() { Neither } else { UnconstrainedInt } } ty::Infer(ty::FloatVar(vid)) => { - if self.float_unification_table - .borrow_mut() - .probe_value(vid) - .is_some() - { + if self.float_unification_table.borrow_mut().probe_value(vid).is_some() { Neither } else { UnconstrainedFloat @@ -863,9 +840,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { &self, snapshot: &CombinedSnapshot<'a, 'tcx>, ) -> Option { - self.borrow_region_constraints().region_constraints_added_in_snapshot( - &snapshot.region_constraints_snapshot, - ) + self.borrow_region_constraints() + .region_constraints_added_in_snapshot(&snapshot.region_constraints_snapshot) } pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) { @@ -878,12 +854,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { { let origin = &ObligationCause::dummy(); self.probe(|_| { - self.at(origin, param_env) - .sub(a, b) - .map(|InferOk { obligations: _, .. }| { - // Ignore obligations, since we are unrolling - // everything anyway. - }) + self.at(origin, param_env).sub(a, b).map(|InferOk { obligations: _, .. }| { + // Ignore obligations, since we are unrolling + // everything anyway. + }) }) } @@ -893,12 +867,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { { let origin = &ObligationCause::dummy(); self.probe(|_| { - self.at(origin, param_env) - .eq(a, b) - .map(|InferOk { obligations: _, .. }| { - // Ignore obligations, since we are unrolling - // everything anyway. - }) + self.at(origin, param_env).eq(a, b).map(|InferOk { obligations: _, .. }| { + // Ignore obligations, since we are unrolling + // everything anyway. + }) }) } @@ -909,8 +881,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { b: ty::Region<'tcx>, ) { debug!("sub_regions({:?} <: {:?})", a, b); - self.borrow_region_constraints() - .make_subregion(origin, a, b); + self.borrow_region_constraints().make_subregion(origin, a, b); } /// Require that the region `r` be equal to one of the regions in @@ -924,8 +895,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { in_regions: &Lrc>>, ) { debug!("member_constraint({:?} <: {:?})", region, in_regions); - self.borrow_region_constraints() - .member_constraint(opaque_type_def_id, definition_span, hidden_ty, region, in_regions); + self.borrow_region_constraints().member_constraint( + opaque_type_def_id, + definition_span, + hidden_ty, + region, + in_regions, + ); } pub fn subtype_predicate( @@ -954,17 +930,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } Some(self.commit_if_ok(|snapshot| { - let ( - ty::SubtypePredicate { - a_is_expected, - a, - b, - }, - placeholder_map, - ) = self.replace_bound_vars_with_placeholders(predicate); - - let ok = self.at(cause, param_env) - .sub_exp(a_is_expected, a, b)?; + let (ty::SubtypePredicate { a_is_expected, a, b }, placeholder_map) = + self.replace_bound_vars_with_placeholders(predicate); + + let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?; self.leak_check(false, &placeholder_map, snapshot)?; @@ -980,10 +949,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.commit_if_ok(|snapshot| { let (ty::OutlivesPredicate(r_a, r_b), placeholder_map) = self.replace_bound_vars_with_placeholders(predicate); - let origin = SubregionOrigin::from_obligation_cause( - cause, - || RelateRegionParamBound(cause.span), - ); + let origin = SubregionOrigin::from_obligation_cause(cause, || { + RelateRegionParamBound(cause.span) + }); self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b` self.leak_check(false, &placeholder_map, snapshot)?; Ok(()) @@ -991,9 +959,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid { - self.type_variables - .borrow_mut() - .new_var(self.universe(), diverging, origin) + self.type_variables.borrow_mut().new_var(self.universe(), diverging, origin) } pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { @@ -1003,11 +969,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn next_ty_var_in_universe( &self, origin: TypeVariableOrigin, - universe: ty::UniverseIndex + universe: ty::UniverseIndex, ) -> Ty<'tcx> { - let vid = self.type_variables - .borrow_mut() - .new_var(universe, false, origin); + let vid = self.type_variables.borrow_mut().new_var(universe, false, origin); self.tcx.mk_ty_var(vid) } @@ -1018,7 +982,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn next_const_var( &self, ty: Ty<'tcx>, - origin: ConstVariableOrigin + origin: ConstVariableOrigin, ) -> &'tcx ty::Const<'tcx> { self.tcx.mk_const_var(self.next_const_var_id(origin), ty) } @@ -1029,22 +993,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { origin: ConstVariableOrigin, universe: ty::UniverseIndex, ) -> &'tcx ty::Const<'tcx> { - let vid = self.const_unification_table + let vid = self + .const_unification_table .borrow_mut() - .new_key(ConstVarValue { - origin, - val: ConstVariableValue::Unknown { universe }, - }); + .new_key(ConstVarValue { origin, val: ConstVariableValue::Unknown { universe } }); self.tcx.mk_const_var(vid, ty) } pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid<'tcx> { - self.const_unification_table - .borrow_mut() - .new_key(ConstVarValue { - origin, - val: ConstVariableValue::Unknown { universe: self.universe() }, - }) + self.const_unification_table.borrow_mut().new_key(ConstVarValue { + origin, + val: ConstVariableValue::Unknown { universe: self.universe() }, + }) } fn next_int_var_id(&self) -> IntVid { @@ -1078,8 +1038,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { origin: RegionVariableOrigin, universe: ty::UniverseIndex, ) -> ty::Region<'tcx> { - let region_var = self.borrow_region_constraints() - .new_region_var(universe, origin); + let region_var = self.borrow_region_constraints().new_region_var(universe, origin); self.tcx.mk_region(ty::ReVar(region_var)) } @@ -1088,10 +1047,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// etc) this is the root universe U0. For inference variables or /// placeholders, however, it will return the universe which which /// they are associated. - fn universe_of_region( - &self, - r: ty::Region<'tcx>, - ) -> ty::UniverseIndex { + fn universe_of_region(&self, r: ty::Region<'tcx>) -> ty::UniverseIndex { self.borrow_region_constraints().universe(r) } @@ -1119,8 +1075,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { GenericParamDefKind::Lifetime => { // Create a region inference variable for the given // region parameter definition. - self.next_region_var(EarlyBoundRegion(span, param.name)) - .into() + self.next_region_var(EarlyBoundRegion(span, param.name)).into() } GenericParamDefKind::Type { .. } => { // Create a type inference variable for the given @@ -1137,7 +1092,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { TypeVariableOrigin { kind: TypeVariableOriginKind::TypeParameterDefinition( param.name, - Some(param.def_id) + Some(param.def_id), ), span, }, @@ -1151,12 +1106,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { span, }; let const_var_id = - self.const_unification_table - .borrow_mut() - .new_key(ConstVarValue { - origin, - val: ConstVariableValue::Unknown { universe: self.universe() }, - }); + self.const_unification_table.borrow_mut().new_key(ConstVarValue { + origin, + val: ConstVariableValue::Unknown { universe: self.universe() }, + }); self.tcx.mk_const_var(const_var_id, self.tcx.type_of(param.def_id)).into() } } @@ -1218,7 +1171,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { region_map, outlives_env.free_region_map(), ); - let (var_infos, data) = self.region_constraints + let (var_infos, data) = self + .region_constraints .borrow_mut() .take() .expect("regions already resolved") @@ -1226,8 +1180,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let (lexical_region_resolutions, errors) = lexical_region_resolve::resolve(region_rels, var_infos, data); - let old_value = self.lexical_region_resolutions - .replace(Some(lexical_region_resolutions)); + let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions)); assert!(old_value.is_none()); if !self.is_tainted_by_errors() { @@ -1276,7 +1229,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// called. This is used only during NLL processing to "hand off" ownership /// of the set of region variables into the NLL region context. pub fn take_region_var_origins(&self) -> VarInfos { - let (var_infos, data) = self.region_constraints + let (var_infos, data) = self + .region_constraints .borrow_mut() .take() .expect("regions already resolved") @@ -1362,7 +1316,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn probe_const_var( &self, - vid: ty::ConstVid<'tcx> + vid: ty::ConstVid<'tcx>, ) -> Result<&'tcx ty::Const<'tcx>, ty::UniverseIndex> { match self.const_unification_table.borrow_mut().probe_value(vid).val { ConstVariableValue::Known { value } => Ok(value), @@ -1430,10 +1384,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { &self, span: Span, lbrct: LateBoundRegionConversionTime, - value: &ty::Binder + value: &ty::Binder, ) -> (T, BTreeMap>) where - T: TypeFoldable<'tcx> + T: TypeFoldable<'tcx>, { let fld_r = |br| self.next_region_var(LateBoundRegion(span, br, lbrct)); let fld_t = |_| { @@ -1442,10 +1396,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { span, }) }; - let fld_c = |_, ty| self.next_const_var(ty, ConstVariableOrigin { - kind: ConstVariableOriginKind:: MiscVariable, - span, - }); + let fld_c = |_, ty| { + self.next_const_var( + ty, + ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span }, + ) + }; self.tcx.replace_bound_vars(value, fld_r, fld_t, fld_c) } @@ -1459,8 +1415,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) { debug!("verify_generic_bound({:?}, {:?} <: {:?})", kind, a, bound); - self.borrow_region_constraints() - .verify_generic_bound(origin, kind, a, bound); + self.borrow_region_constraints().verify_generic_bound(origin, kind, a, bound); } pub fn type_is_copy_modulo_regions( @@ -1505,11 +1460,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// `tcx.fn_sig(def_id)`, this method will work during the /// type-checking of the enclosing function and return the closure /// signature in its partially inferred state. - pub fn closure_sig( - &self, - def_id: DefId, - substs: SubstsRef<'tcx>, - ) -> ty::PolyFnSig<'tcx> { + pub fn closure_sig(&self, def_id: DefId, substs: SubstsRef<'tcx>) -> ty::PolyFnSig<'tcx> { let closure_sig_ty = substs.as_closure().sig_ty(def_id, self.tcx); let closure_sig_ty = self.shallow_resolve(closure_sig_ty); closure_sig_ty.fn_sig(self.tcx) @@ -1592,7 +1543,8 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> { // structurally), and we prevent cycles in any case, // so this recursion should always be of very limited // depth. - self.infcx.type_variables + self.infcx + .type_variables .borrow_mut() .probe(v) .known() @@ -1600,13 +1552,17 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> { .unwrap_or(typ) } - ty::Infer(ty::IntVar(v)) => self.infcx.int_unification_table + ty::Infer(ty::IntVar(v)) => self + .infcx + .int_unification_table .borrow_mut() .probe_value(v) .map(|v| v.to_type(self.infcx.tcx)) .unwrap_or(typ), - ty::Infer(ty::FloatVar(v)) => self.infcx.float_unification_table + ty::Infer(ty::FloatVar(v)) => self + .infcx + .float_unification_table .borrow_mut() .probe_value(v) .map(|v| v.to_type(self.infcx.tcx)) @@ -1665,12 +1621,13 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = ct { - self.infcx.const_unification_table - .borrow_mut() - .probe_value(*vid) - .val - .known() - .unwrap_or(ct) + self.infcx + .const_unification_table + .borrow_mut() + .probe_value(*vid) + .val + .known() + .unwrap_or(ct) } else { ct } @@ -1688,19 +1645,13 @@ impl<'tcx> TypeTrace<'tcx> { a: Ty<'tcx>, b: Ty<'tcx>, ) -> TypeTrace<'tcx> { - TypeTrace { - cause: cause.clone(), - values: Types(ExpectedFound::new(a_is_expected, a, b)), - } + TypeTrace { cause: cause.clone(), values: Types(ExpectedFound::new(a_is_expected, a, b)) } } pub fn dummy(tcx: TyCtxt<'tcx>) -> TypeTrace<'tcx> { TypeTrace { cause: ObligationCause::dummy(), - values: Types(ExpectedFound { - expected: tcx.types.err, - found: tcx.types.err, - }), + values: Types(ExpectedFound { expected: tcx.types.err, found: tcx.types.err }), } } } diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs index 1e0feb6a7da8d..74f1c26b0f21d 100644 --- a/src/librustc/infer/nll_relate/mod.rs +++ b/src/librustc/infer/nll_relate/mod.rs @@ -22,13 +22,13 @@ //! constituents) use crate::infer::InferCtxt; +use crate::infer::{ConstVarValue, ConstVariableValue}; use crate::traits::DomainGoal; use crate::ty::error::TypeError; use crate::ty::fold::{TypeFoldable, TypeVisitor}; use crate::ty::relate::{self, Relate, RelateResult, TypeRelation}; use crate::ty::subst::GenericArg; -use crate::ty::{self, Ty, TyCtxt, InferConst}; -use crate::infer::{ConstVariableValue, ConstVarValue}; +use crate::ty::{self, InferConst, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; use std::fmt::Debug; @@ -144,13 +144,7 @@ where delegate: D, ambient_variance: ty::Variance, ) -> Self { - Self { - infcx, - delegate, - ambient_variance, - a_scopes: vec![], - b_scopes: vec![], - } + Self { infcx, delegate, ambient_variance, a_scopes: vec![], b_scopes: vec![] } } fn ambient_covariance(&self) -> bool { @@ -286,10 +280,7 @@ where } _ => { - let projection = ty::ProjectionPredicate { - projection_ty, - ty: value_ty, - }; + let projection = ty::ProjectionPredicate { projection_ty, ty: value_ty }; self.delegate .push_domain_goal(DomainGoal::Holds(WhereClause::ProjectionEq(projection))); value_ty @@ -331,10 +322,7 @@ where match value_ty.kind { ty::Infer(ty::TyVar(value_vid)) => { // Two type variables: just equate them. - self.infcx - .type_variables - .borrow_mut() - .equate(vid, value_vid); + self.infcx.type_variables.borrow_mut().equate(vid, value_vid); return Ok(value_ty); } @@ -355,10 +343,7 @@ where assert!(!generalized_ty.has_infer_types()); } - self.infcx - .type_variables - .borrow_mut() - .instantiate(vid, generalized_ty); + self.infcx.type_variables.borrow_mut().instantiate(vid, generalized_ty); // The generalized values we extract from `canonical_var_values` have // been fully instantiated and hence the set of scopes we have @@ -503,7 +488,9 @@ where } // FIXME(oli-obk): not sure how to get the correct ParamEnv - fn param_env(&self) -> ty::ParamEnv<'tcx> { ty::ParamEnv::empty() } + fn param_env(&self) -> ty::ParamEnv<'tcx> { + ty::ParamEnv::empty() + } fn tag(&self) -> &'static str { "nll::subtype" @@ -519,18 +506,12 @@ where a: &T, b: &T, ) -> RelateResult<'tcx, T> { - debug!( - "relate_with_variance(variance={:?}, a={:?}, b={:?})", - variance, a, b - ); + debug!("relate_with_variance(variance={:?}, a={:?}, b={:?})", variance, a, b); let old_ambient_variance = self.ambient_variance; self.ambient_variance = self.ambient_variance.xform(variance); - debug!( - "relate_with_variance: ambient_variance = {:?}", - self.ambient_variance - ); + debug!("relate_with_variance: ambient_variance = {:?}", self.ambient_variance); let r = self.relate(a, b)?; @@ -573,10 +554,7 @@ where } _ => { - debug!( - "tys(a={:?}, b={:?}, variance={:?})", - a, b, self.ambient_variance - ); + debug!("tys(a={:?}, b={:?}, variance={:?})", a, b, self.ambient_variance); // Will also handle unification of `IntVar` and `FloatVar`. self.infcx.super_combine_tys(self, a, b) @@ -589,10 +567,7 @@ where a: ty::Region<'tcx>, b: ty::Region<'tcx>, ) -> RelateResult<'tcx, ty::Region<'tcx>> { - debug!( - "regions(a={:?}, b={:?}, variance={:?})", - a, b, self.ambient_variance - ); + debug!("regions(a={:?}, b={:?}, variance={:?})", a, b, self.ambient_variance); let v_a = self.replace_bound_region(a, ty::INNERMOST, &self.a_scopes); let v_b = self.replace_bound_region(b, ty::INNERMOST, &self.b_scopes); @@ -630,7 +605,7 @@ where bug!("unexpected inference var {:?}", b) } // FIXME(invariance): see the related FIXME above. - _ => self.infcx.super_combine_consts(self, a, b) + _ => self.infcx.super_combine_consts(self, a, b), } } @@ -661,10 +636,7 @@ where // - Instantiate binders on `b` universally, yielding a universe U1. // - Instantiate binders on `a` existentially in U1. - debug!( - "binders({:?}: {:?}, ambient_variance={:?})", - a, b, self.ambient_variance - ); + debug!("binders({:?}: {:?}, ambient_variance={:?})", a, b, self.ambient_variance); if self.ambient_covariance() { // Covariance, so we want `for<..> A <: for<..> B` -- @@ -767,18 +739,11 @@ impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> { } fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { - let ScopeInstantiator { - bound_region_scope, - next_region, - .. - } = self; + let ScopeInstantiator { bound_region_scope, next_region, .. } = self; match r { ty::ReLateBound(debruijn, br) if *debruijn == self.target_index => { - bound_region_scope - .map - .entry(*br) - .or_insert_with(|| next_region(*br)); + bound_region_scope.map.entry(*br).or_insert_with(|| next_region(*br)); } _ => {} @@ -841,7 +806,9 @@ where } // FIXME(oli-obk): not sure how to get the correct ParamEnv - fn param_env(&self) -> ty::ParamEnv<'tcx> { ty::ParamEnv::empty() } + fn param_env(&self) -> ty::ParamEnv<'tcx> { + ty::ParamEnv::empty() + } fn tag(&self) -> &'static str { "nll::generalizer" @@ -888,10 +855,7 @@ where ty::Infer(ty::TyVar(_)) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) if D::forbid_inference_vars() => { - bug!( - "unexpected inference variable encountered in NLL generalization: {:?}", - a - ); + bug!("unexpected inference variable encountered in NLL generalization: {:?}", a); } ty::Infer(ty::TyVar(vid)) => { @@ -909,9 +873,7 @@ where drop(variables); self.relate(&u, &u) } - TypeVariableValue::Unknown { - universe: _universe, - } => { + TypeVariableValue::Unknown { universe: _universe } => { if self.ambient_variance == ty::Bivariant { // FIXME: we may need a WF predicate (related to #54105). } @@ -924,10 +886,7 @@ where let new_var_id = variables.new_var(self.universe, false, origin); let u = self.tcx().mk_ty_var(new_var_id); - debug!( - "generalize: replacing original vid={:?} with new={:?}", - vid, u - ); + debug!("generalize: replacing original vid={:?} with new={:?}", vid, u); return Ok(u); } } @@ -999,10 +958,7 @@ where ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { match a.val { ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => { - bug!( - "unexpected inference variable encountered in NLL generalization: {:?}", - a - ); + bug!("unexpected inference variable encountered in NLL generalization: {:?}", a); } ty::ConstKind::Infer(InferConst::Var(vid)) => { let mut variable_table = self.infcx.const_unification_table.borrow_mut(); diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 9b197c1ecb140..3e9f68cebefae 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -6,7 +6,7 @@ use crate::infer::{self, InferCtxt, InferOk, TypeVariableOrigin, TypeVariableOri use crate::middle::region; use crate::traits::{self, PredicateObligation}; use crate::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor}; -use crate::ty::subst::{InternalSubsts, GenericArg, SubstsRef, GenericArgKind}; +use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}; use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt}; use crate::util::nodemap::DefIdMap; use errors::DiagnosticBuilder; @@ -24,7 +24,6 @@ pub type OpaqueTypeMap<'tcx> = DefIdMap>; /// appear in the return type). #[derive(Copy, Clone, Debug)] pub struct OpaqueTypeDecl<'tcx> { - /// The opaque type (`ty::Opaque`) for this declaration. pub opaque_type: Ty<'tcx>, @@ -467,13 +466,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { tcx: self.tcx, - op: |r| self.member_constraint( - opaque_type_def_id, - opaque_defn.definition_span, - concrete_ty, - r, - &choice_regions, - ), + op: |r| { + self.member_constraint( + opaque_type_def_id, + opaque_defn.definition_span, + concrete_ty, + r, + &choice_regions, + ) + }, }); } @@ -522,9 +523,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.span_label(span, label); if nightly_options::is_nightly_build() { - help!(err, - "add #![feature(member_constraints)] to the crate attributes \ - to enable"); + help!( + err, + "add #![feature(member_constraints)] to the crate attributes \ + to enable" + ); } err.emit(); @@ -839,26 +842,28 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { self.opaque_type_def_id, hidden_ty, r, - ).emit(); + ) + .emit(); } } self.tcx.lifetimes.re_empty } None => { - self.tcx.sess - .struct_span_err( - self.span, - "non-defining opaque type use in defining scope" - ) + self.tcx + .sess + .struct_span_err(self.span, "non-defining opaque type use in defining scope") .span_label( self.span, - format!("lifetime `{}` is part of concrete type but not used in \ - parameter list of the `impl Trait` type alias", r), + format!( + "lifetime `{}` is part of concrete type but not used in \ + parameter list of the `impl Trait` type alias", + r + ), ) .emit(); self.tcx().mk_region(ty::ReStatic) - }, + } } } @@ -890,32 +895,30 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { // during codegen. let generics = self.tcx.generics_of(def_id); - let substs = - self.tcx.mk_substs(substs.iter().enumerate().map(|(index, &kind)| { - if index < generics.parent_count { - // Accommodate missing regions in the parent kinds... - self.fold_kind_mapping_missing_regions_to_empty(kind) - } else { - // ...but not elsewhere. - self.fold_kind_normally(kind) - } - })); + let substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(index, &kind)| { + if index < generics.parent_count { + // Accommodate missing regions in the parent kinds... + self.fold_kind_mapping_missing_regions_to_empty(kind) + } else { + // ...but not elsewhere. + self.fold_kind_normally(kind) + } + })); self.tcx.mk_closure(def_id, substs) } ty::Generator(def_id, substs, movability) => { let generics = self.tcx.generics_of(def_id); - let substs = - self.tcx.mk_substs(substs.iter().enumerate().map(|(index, &kind)| { - if index < generics.parent_count { - // Accommodate missing regions in the parent kinds... - self.fold_kind_mapping_missing_regions_to_empty(kind) - } else { - // ...but not elsewhere. - self.fold_kind_normally(kind) - } - })); + let substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(index, &kind)| { + if index < generics.parent_count { + // Accommodate missing regions in the parent kinds... + self.fold_kind_mapping_missing_regions_to_empty(kind) + } else { + // ...but not elsewhere. + self.fold_kind_normally(kind) + } + })); self.tcx.mk_generator(def_id, substs, movability) } @@ -928,12 +931,15 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { Some(GenericArgKind::Type(t1)) => t1, Some(u) => panic!("type mapped to unexpected kind: {:?}", u), None => { - self.tcx.sess + self.tcx + .sess .struct_span_err( self.span, - &format!("type parameter `{}` is part of concrete type but not \ + &format!( + "type parameter `{}` is part of concrete type but not \ used in parameter list for the `impl Trait` type alias", - ty), + ty + ), ) .emit(); @@ -958,12 +964,15 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { Some(GenericArgKind::Const(c1)) => c1, Some(u) => panic!("const mapped to unexpected kind: {:?}", u), None => { - self.tcx.sess + self.tcx + .sess .struct_span_err( self.span, - &format!("const parameter `{}` is part of concrete type but not \ + &format!( + "const parameter `{}` is part of concrete type but not \ used in parameter list for the `impl Trait` type alias", - ct) + ct + ), ) .emit(); @@ -1035,8 +1044,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { let parent_def_id = self.parent_def_id; let def_scope_default = || { let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id); - parent_def_id == tcx.hir() - .local_def_id(opaque_parent_hir_id) + parent_def_id == tcx.hir().local_def_id(opaque_parent_hir_id) }; let (in_definition_scope, origin) = match tcx.hir().find(opaque_hir_id) { Some(Node::Item(item)) => match item.kind { @@ -1052,29 +1060,17 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { origin, .. }) => ( - may_define_opaque_type( - tcx, - self.parent_def_id, - opaque_hir_id, - ), + may_define_opaque_type(tcx, self.parent_def_id, opaque_hir_id), origin, ), - _ => { - (def_scope_default(), hir::OpaqueTyOrigin::TypeAlias) - } + _ => (def_scope_default(), hir::OpaqueTyOrigin::TypeAlias), }, Some(Node::ImplItem(item)) => match item.kind { hir::ImplItemKind::OpaqueTy(_) => ( - may_define_opaque_type( - tcx, - self.parent_def_id, - opaque_hir_id, - ), + may_define_opaque_type(tcx, self.parent_def_id, opaque_hir_id), hir::OpaqueTyOrigin::TypeAlias, ), - _ => { - (def_scope_default(), hir::OpaqueTyOrigin::TypeAlias) - } + _ => (def_scope_default(), hir::OpaqueTyOrigin::TypeAlias), }, _ => bug!( "expected (impl) item, found {}", @@ -1211,11 +1207,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { /// Here, `def_id` is the `DefId` of the defining use of the opaque type (e.g., `f1` or `f2`), /// and `opaque_hir_id` is the `HirId` of the definition of the opaque type `Baz`. /// For the above example, this function returns `true` for `f1` and `false` for `f2`. -pub fn may_define_opaque_type( - tcx: TyCtxt<'_>, - def_id: DefId, - opaque_hir_id: hir::HirId, -) -> bool { +pub fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: DefId, opaque_hir_id: hir::HirId) -> bool { let mut hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); // Named opaque types can be defined by any siblings or children of siblings. diff --git a/src/librustc/infer/outlives/env.rs b/src/librustc/infer/outlives/env.rs index e6155454d46f1..a49b770ceb845 100644 --- a/src/librustc/infer/outlives/env.rs +++ b/src/librustc/infer/outlives/env.rs @@ -1,10 +1,10 @@ +use crate::hir; use crate::infer::outlives::free_region_map::FreeRegionMap; use crate::infer::{GenericKind, InferCtxt}; -use crate::hir; -use rustc_data_structures::fx::FxHashMap; -use syntax_pos::Span; use crate::traits::query::outlives_bounds::{self, OutlivesBound}; use crate::ty::{self, Ty}; +use rustc_data_structures::fx::FxHashMap; +use syntax_pos::Span; /// The `OutlivesEnvironment` collects information about what outlives /// what in a given type-checking setting. For example, if we have a @@ -177,10 +177,8 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> { /// Save the current set of region-bound pairs under the given `body_id`. pub fn save_implied_bounds(&mut self, body_id: hir::HirId) { - let old = self.region_bound_pairs_map.insert( - body_id, - self.region_bound_pairs_accum.clone(), - ); + let old = + self.region_bound_pairs_map.insert(body_id, self.region_bound_pairs_accum.clone()); assert!(old.is_none()); } @@ -201,13 +199,10 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> { match outlives_bound { OutlivesBound::RegionSubRegion(r_a @ &ty::ReEarlyBound(_), &ty::ReVar(vid_b)) | OutlivesBound::RegionSubRegion(r_a @ &ty::ReFree(_), &ty::ReVar(vid_b)) => { - infcx - .expect("no infcx provided but region vars found") - .add_given(r_a, vid_b); + infcx.expect("no infcx provided but region vars found").add_given(r_a, vid_b); } OutlivesBound::RegionSubParam(r_a, param_b) => { - self.region_bound_pairs_accum - .push((r_a, GenericKind::Param(param_b))); + self.region_bound_pairs_accum.push((r_a, GenericKind::Param(param_b))); } OutlivesBound::RegionSubProjection(r_a, projection_b) => { self.region_bound_pairs_accum diff --git a/src/librustc/infer/outlives/free_region_map.rs b/src/librustc/infer/outlives/free_region_map.rs index fd8ccce683352..42f506606e69a 100644 --- a/src/librustc/infer/outlives/free_region_map.rs +++ b/src/librustc/infer/outlives/free_region_map.rs @@ -1,4 +1,4 @@ -use crate::ty::{self, Lift, TyCtxt, Region}; +use crate::ty::{self, Lift, Region, TyCtxt}; use rustc_data_structures::transitive_relation::TransitiveRelation; #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Default, HashStable)] @@ -7,11 +7,11 @@ pub struct FreeRegionMap<'tcx> { // // Invariant: only free regions like `'x` or `'static` are stored // in this relation, not scopes. - relation: TransitiveRelation> + relation: TransitiveRelation>, } impl<'tcx> FreeRegionMap<'tcx> { - pub fn elements(&self) -> impl Iterator> { + pub fn elements(&self) -> impl Iterator> { self.relation.elements() } @@ -41,7 +41,9 @@ impl<'tcx> FreeRegionMap<'tcx> { debug!("lub_free_regions(r_a={:?}, r_b={:?})", r_a, r_b); assert!(is_free(r_a)); assert!(is_free(r_b)); - let result = if r_a == r_b { r_a } else { + let result = if r_a == r_b { + r_a + } else { match self.relation.postdom_upper_bound(&r_a, &r_b) { None => tcx.mk_region(ty::ReStatic), Some(r) => *r, @@ -62,10 +64,7 @@ pub trait FreeRegionRelations<'tcx> { } impl<'tcx> FreeRegionRelations<'tcx> for FreeRegionMap<'tcx> { - fn sub_free_regions(&self, - r_a: Region<'tcx>, - r_b: Region<'tcx>) - -> bool { + fn sub_free_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> bool { assert!(is_free_or_static(r_a) && is_free_or_static(r_b)); if let ty::ReStatic = r_b { true // `'a <= 'static` is just always true, and not stored in the relation explicitly @@ -78,7 +77,7 @@ impl<'tcx> FreeRegionRelations<'tcx> for FreeRegionMap<'tcx> { fn is_free(r: Region<'_>) -> bool { match *r { ty::ReEarlyBound(_) | ty::ReFree(_) => true, - _ => false + _ => false, } } @@ -92,7 +91,6 @@ fn is_free_or_static(r: Region<'_>) -> bool { impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> { type Lifted = FreeRegionMap<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option> { - self.relation.maybe_map(|&fr| tcx.lift(&fr)) - .map(|relation| FreeRegionMap { relation }) + self.relation.maybe_map(|&fr| tcx.lift(&fr)).map(|relation| FreeRegionMap { relation }) } } diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs index f9443376a935a..4bafd2ebf40a1 100644 --- a/src/librustc/infer/outlives/obligations.rs +++ b/src/librustc/infer/outlives/obligations.rs @@ -59,15 +59,15 @@ //! might later infer `?U` to something like `&'b u32`, which would //! imply that `'b: 'a`. +use crate::hir; use crate::infer::outlives::env::RegionBoundPairs; use crate::infer::outlives::verify::VerifyBoundCx; use crate::infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound}; -use rustc_data_structures::fx::FxHashMap; -use crate::hir; use crate::traits::ObligationCause; use crate::ty::outlives::Component; -use crate::ty::{self, Region, Ty, TyCtxt, TypeFoldable}; use crate::ty::subst::GenericArgKind; +use crate::ty::{self, Region, Ty, TyCtxt, TypeFoldable}; +use rustc_data_structures::fx::FxHashMap; impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// Registers that the given region obligation must be resolved @@ -80,14 +80,9 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { body_id: hir::HirId, obligation: RegionObligation<'tcx>, ) { - debug!( - "register_region_obligation(body_id={:?}, obligation={:?})", - body_id, obligation - ); + debug!("register_region_obligation(body_id={:?}, obligation={:?})", body_id, obligation); - self.region_obligations - .borrow_mut() - .push((body_id, obligation)); + self.region_obligations.borrow_mut().push((body_id, obligation)); } pub fn register_region_obligation_with_cause( @@ -102,11 +97,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { self.register_region_obligation( cause.body_id, - RegionObligation { - sup_type, - sub_region, - origin, - }, + RegionObligation { sup_type, sub_region, origin }, ); } @@ -163,15 +154,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { let my_region_obligations = self.take_registered_region_obligations(); - for ( - body_id, - RegionObligation { - sup_type, - sub_region, - origin, - }, - ) in my_region_obligations - { + for (body_id, RegionObligation { sup_type, sub_region, origin }) in my_region_obligations { debug!( "process_registered_region_obligations: sup_type={:?} sub_region={:?} origin={:?}", sup_type, sub_region, origin @@ -291,10 +274,7 @@ where ty: Ty<'tcx>, region: ty::Region<'tcx>, ) { - debug!( - "type_must_outlive(ty={:?}, region={:?}, origin={:?})", - ty, region, origin - ); + debug!("type_must_outlive(ty={:?}, region={:?}, origin={:?})", ty, region, origin); assert!(!ty.has_escaping_bound_vars()); @@ -313,8 +293,7 @@ where let origin = origin.clone(); match component { Component::Region(region1) => { - self.delegate - .push_sub_region_constraint(origin, region, region1); + self.delegate.push_sub_region_constraint(origin, region, region1); } Component::Param(param_ty) => { self.param_ty_must_outlive(origin, region, *param_ty); @@ -351,8 +330,7 @@ where let generic = GenericKind::Param(param_ty); let verify_bound = self.verify_bound.generic_bound(generic); - self.delegate - .push_verify(origin, generic, region, verify_bound); + self.delegate.push_verify(origin, generic, region, verify_bound); } fn projection_must_outlive( @@ -383,34 +361,28 @@ where // Compute the bounds we can derive from the trait definition. // These are guaranteed to apply, no matter the inference // results. - let trait_bounds: Vec<_> = self.verify_bound - .projection_declared_bounds_from_trait(projection_ty) - .collect(); + let trait_bounds: Vec<_> = + self.verify_bound.projection_declared_bounds_from_trait(projection_ty).collect(); // Compute the bounds we can derive from the environment. This // is an "approximate" match -- in some cases, these bounds // may not apply. - let mut approx_env_bounds = self.verify_bound - .projection_approx_declared_bounds_from_env(projection_ty); - debug!( - "projection_must_outlive: approx_env_bounds={:?}", - approx_env_bounds - ); + let mut approx_env_bounds = + self.verify_bound.projection_approx_declared_bounds_from_env(projection_ty); + debug!("projection_must_outlive: approx_env_bounds={:?}", approx_env_bounds); // Remove outlives bounds that we get from the environment but // which are also deducable from the trait. This arises (cc // #55756) in cases where you have e.g., `>::Item: // 'a` in the environment but `trait Foo<'b> { type Item: 'b // }` in the trait definition. - approx_env_bounds.retain(|bound| { - match bound.0.kind { - ty::Projection(projection_ty) => { - self.verify_bound.projection_declared_bounds_from_trait(projection_ty) - .all(|r| r != bound.1) - } + approx_env_bounds.retain(|bound| match bound.0.kind { + ty::Projection(projection_ty) => self + .verify_bound + .projection_declared_bounds_from_trait(projection_ty) + .all(|r| r != bound.1), - _ => panic!("expected only projection types from env, not {:?}", bound.0), - } + _ => panic!("expected only projection types from env, not {:?}", bound.0), }); // If declared bounds list is empty, the only applicable rule is @@ -465,13 +437,9 @@ where .all(|b| *b == trait_bounds[0]) { let unique_bound = trait_bounds[0]; - debug!( - "projection_must_outlive: unique trait bound = {:?}", - unique_bound - ); + debug!("projection_must_outlive: unique trait bound = {:?}", unique_bound); debug!("projection_must_outlive: unique declared bound appears in trait ref"); - self.delegate - .push_sub_region_constraint(origin, region, unique_bound); + self.delegate.push_sub_region_constraint(origin, region, unique_bound); return; } @@ -482,8 +450,7 @@ where // even though a satisfactory solution exists. let generic = GenericKind::Projection(projection_ty); let verify_bound = self.verify_bound.generic_bound(generic); - self.delegate - .push_verify(origin, generic.clone(), region, verify_bound); + self.delegate.push_verify(origin, generic.clone(), region, verify_bound); } } diff --git a/src/librustc/infer/outlives/verify.rs b/src/librustc/infer/outlives/verify.rs index 3e28145c0fa0a..828d4c2e0e760 100644 --- a/src/librustc/infer/outlives/verify.rs +++ b/src/librustc/infer/outlives/verify.rs @@ -2,7 +2,7 @@ use crate::hir::def_id::DefId; use crate::infer::outlives::env::RegionBoundPairs; use crate::infer::{GenericKind, VerifyBound}; use crate::traits; -use crate::ty::subst::{Subst, InternalSubsts}; +use crate::ty::subst::{InternalSubsts, Subst}; use crate::ty::{self, Ty, TyCtxt}; use crate::util::captures::Captures; @@ -26,12 +26,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { implicit_region_bound: Option>, param_env: ty::ParamEnv<'tcx>, ) -> Self { - Self { - tcx, - region_bound_pairs, - implicit_region_bound, - param_env, - } + Self { tcx, region_bound_pairs, implicit_region_bound, param_env } } /// Returns a "verify bound" that encodes what we know about @@ -56,7 +51,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // Start with anything like `T: 'a` we can scrape from the // environment - let param_bounds = self.declared_generic_bounds_from_env(GenericKind::Param(param_ty)) + let param_bounds = self + .declared_generic_bounds_from_env(GenericKind::Param(param_ty)) .into_iter() .map(|outlives| outlives.1); @@ -113,7 +109,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { self.tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs); // Search the env for where clauses like `P: 'a`. - let env_bounds = self.projection_approx_declared_bounds_from_env(projection_ty) + let env_bounds = self + .projection_approx_declared_bounds_from_env(projection_ty) .into_iter() .map(|ty::OutlivesPredicate(ty, r)| { let vb = VerifyBound::OutlivedBy(r); @@ -128,41 +125,32 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { }); // Extend with bounds that we can find from the trait. - let trait_bounds = self.projection_declared_bounds_from_trait(projection_ty) + let trait_bounds = self + .projection_declared_bounds_from_trait(projection_ty) .into_iter() .map(|r| VerifyBound::OutlivedBy(r)); // see the extensive comment in projection_must_outlive - let ty = self.tcx - .mk_projection(projection_ty.item_def_id, projection_ty.substs); + let ty = self.tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs); let recursive_bound = self.recursive_type_bound(ty); VerifyBound::AnyBound(env_bounds.chain(trait_bounds).collect()).or(recursive_bound) } fn recursive_type_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> { - let mut bounds = ty.walk_shallow() - .map(|subty| self.type_bound(subty)) - .collect::>(); + let mut bounds = ty.walk_shallow().map(|subty| self.type_bound(subty)).collect::>(); let mut regions = smallvec![]; ty.push_regions(&mut regions); regions.retain(|r| !r.is_late_bound()); // ignore late-bound regions bounds.push(VerifyBound::AllBounds( - regions - .into_iter() - .map(|r| VerifyBound::OutlivedBy(r)) - .collect(), + regions.into_iter().map(|r| VerifyBound::OutlivedBy(r)).collect(), )); // remove bounds that must hold, since they are not interesting bounds.retain(|b| !b.must_hold()); - if bounds.len() == 1 { - bounds.pop().unwrap() - } else { - VerifyBound::AllBounds(bounds) - } + if bounds.len() == 1 { bounds.pop().unwrap() } else { VerifyBound::AllBounds(bounds) } } /// Searches the environment for where-clauses like `G: 'a` where @@ -284,16 +272,15 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { let tcx = self.tcx; let assoc_item = tcx.associated_item(assoc_item_def_id); let trait_def_id = assoc_item.container.assert_trait(); - let trait_predicates = tcx.predicates_of(trait_def_id).predicates - .iter() - .map(|(p, _)| *p) - .collect(); + let trait_predicates = + tcx.predicates_of(trait_def_id).predicates.iter().map(|(p, _)| *p).collect(); let identity_substs = InternalSubsts::identity_for_item(tcx, assoc_item_def_id); let identity_proj = tcx.mk_projection(assoc_item_def_id, identity_substs); self.collect_outlives_from_predicate_list( move |ty| ty == identity_proj, traits::elaborate_predicates(tcx, trait_predicates), - ).map(|b| b.1) + ) + .map(|b| b.1) } /// Searches through a predicate list for a predicate `T: 'a`. diff --git a/src/librustc/infer/region_constraints/leak_check.rs b/src/librustc/infer/region_constraints/leak_check.rs index 3d069425685c7..3b3a464ba557a 100644 --- a/src/librustc/infer/region_constraints/leak_check.rs +++ b/src/librustc/infer/region_constraints/leak_check.rs @@ -50,19 +50,13 @@ impl<'tcx> RegionConstraintCollector<'tcx> { // Find the universe this placeholder inhabits. let placeholder = match placeholder_region { ty::RePlaceholder(p) => p, - _ => bug!( - "leak_check: expected placeholder found {:?}", - placeholder_region, - ), + _ => bug!("leak_check: expected placeholder found {:?}", placeholder_region,), }; // Find all regions that are related to this placeholder // in some way. This means any region that either outlives // or is outlived by a placeholder. - let mut taint_set = TaintSet::new( - TaintDirections::both(), - placeholder_region, - ); + let mut taint_set = TaintSet::new(TaintDirections::both(), placeholder_region); taint_set.fixed_point(tcx, &self.undo_log, &self.data.verifys); let tainted_regions = taint_set.into_set(); @@ -103,10 +97,7 @@ impl<'tcx> TaintSet<'tcx> { fn new(directions: TaintDirections, initial_region: ty::Region<'tcx>) -> Self { let mut regions = FxHashSet::default(); regions.insert(initial_region); - TaintSet { - directions: directions, - regions: regions, - } + TaintSet { directions: directions, regions: regions } } fn fixed_point( @@ -117,11 +108,7 @@ impl<'tcx> TaintSet<'tcx> { ) { let mut prev_len = 0; while prev_len < self.len() { - debug!( - "tainted: prev_len = {:?} new_len = {:?}", - prev_len, - self.len() - ); + debug!("tainted: prev_len = {:?} new_len = {:?}", prev_len, self.len()); prev_len = self.len(); diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 402449ce6cc20..19b3c30e53733 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -6,20 +6,20 @@ use self::UndoLog::*; use super::unify_key; use super::{MiscVariable, RegionVariableOrigin, SubregionOrigin}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_index::vec::IndexVec; -use rustc_data_structures::sync::Lrc; -use rustc_data_structures::unify as ut; use crate::hir::def_id::DefId; use crate::ty::ReStatic; use crate::ty::{self, Ty, TyCtxt}; use crate::ty::{ReLateBound, ReVar}; use crate::ty::{Region, RegionVid}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::sync::Lrc; +use rustc_data_structures::unify as ut; +use rustc_index::vec::IndexVec; use syntax_pos::Span; use std::collections::BTreeMap; -use std::{cmp, fmt, mem}; use std::ops::Range; +use std::{cmp, fmt, mem}; mod leak_check; @@ -346,24 +346,15 @@ pub struct TaintDirections { impl TaintDirections { pub fn incoming() -> Self { - TaintDirections { - incoming: true, - outgoing: false, - } + TaintDirections { incoming: true, outgoing: false } } pub fn outgoing() -> Self { - TaintDirections { - incoming: false, - outgoing: true, - } + TaintDirections { incoming: false, outgoing: true } } pub fn both() -> Self { - TaintDirections { - incoming: true, - outgoing: true, - } + TaintDirections { incoming: true, outgoing: true } } } @@ -529,17 +520,12 @@ impl<'tcx> RegionConstraintCollector<'tcx> { ) -> RegionVid { let vid = self.var_infos.push(RegionVariableInfo { origin, universe }); - let u_vid = self - .unification_table - .new_key(unify_key::RegionVidKey { min_vid: vid }); + let u_vid = self.unification_table.new_key(unify_key::RegionVidKey { min_vid: vid }); assert_eq!(vid, u_vid); if self.in_snapshot() { self.undo_log.push(AddVar(vid)); } - debug!( - "created new region variable {:?} in {:?} with origin {:?}", - vid, universe, origin - ); + debug!("created new region variable {:?} in {:?} with origin {:?}", vid, universe, origin); return vid; } @@ -601,10 +587,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { fn add_constraint(&mut self, constraint: Constraint<'tcx>, origin: SubregionOrigin<'tcx>) { // cannot add constraints once regions are resolved - debug!( - "RegionConstraintCollector: add_constraint({:?})", - constraint - ); + debug!("RegionConstraintCollector: add_constraint({:?})", constraint); // never overwrite an existing (constraint, origin) - only insert one if it isn't // present in the map yet. This prevents origins from outside the snapshot being @@ -687,9 +670,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> { definition_span, hidden_ty, member_region, - choice_regions: choice_regions.clone() + choice_regions: choice_regions.clone(), }); - } pub fn make_subregion( @@ -706,12 +688,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { match (sub, sup) { (&ReLateBound(..), _) | (_, &ReLateBound(..)) => { - span_bug!( - origin.span(), - "cannot relate bound region: {:?} <= {:?}", - sub, - sup - ); + span_bug!(origin.span(), "cannot relate bound region: {:?} <= {:?}", sub, sup); } (_, &ReStatic) => { // all regions are subregions of static, so we can ignore this @@ -739,12 +716,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { sub: Region<'tcx>, bound: VerifyBound<'tcx>, ) { - self.add_verify(Verify { - kind, - origin, - region: sub, - bound, - }); + self.add_verify(Verify { kind, origin, region: sub, bound }); } pub fn lub_regions( @@ -857,9 +829,12 @@ impl<'tcx> RegionConstraintCollector<'tcx> { mark: &RegionSnapshot, ) -> (Range, Vec) { let range = self.unification_table.vars_since_snapshot(&mark.region_snapshot); - (range.clone(), (range.start.index()..range.end.index()).map(|index| { - self.var_infos[ty::RegionVid::from(index)].origin.clone() - }).collect()) + ( + range.clone(), + (range.start.index()..range.end.index()) + .map(|index| self.var_infos[ty::RegionVid::from(index)].origin.clone()) + .collect(), + ) } /// See [`RegionInference::region_constraints_added_in_snapshot`]. @@ -869,7 +844,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> { .map(|&elt| match elt { AddConstraint(constraint) => Some(constraint.involves_placeholders()), _ => None, - }).max() + }) + .max() .unwrap_or(None) } } @@ -953,15 +929,10 @@ impl<'tcx> RegionConstraintData<'tcx> { /// Returns `true` if this region constraint data contains no constraints, and `false` /// otherwise. pub fn is_empty(&self) -> bool { - let RegionConstraintData { - constraints, - member_constraints, - verifys, - givens, - } = self; - constraints.is_empty() && - member_constraints.is_empty() && - verifys.is_empty() && - givens.is_empty() + let RegionConstraintData { constraints, member_constraints, verifys, givens } = self; + constraints.is_empty() + && member_constraints.is_empty() + && verifys.is_empty() + && givens.is_empty() } } diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs index ea4a28c22a9e7..d7dc607044222 100644 --- a/src/librustc/infer/resolve.rs +++ b/src/librustc/infer/resolve.rs @@ -1,7 +1,7 @@ -use super::{InferCtxt, FixupError, FixupResult, Span}; use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use crate::ty::{self, Ty, Const, TyCtxt, TypeFoldable, InferConst}; +use super::{FixupError, FixupResult, InferCtxt, Span}; use crate::ty::fold::{TypeFolder, TypeVisitor}; +use crate::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable}; /////////////////////////////////////////////////////////////////////////// // OPPORTUNISTIC VAR RESOLVER @@ -75,11 +75,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticTypeAndRegionResolver<'a, 'tcx> fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { - ty::ReVar(rid) => - self.infcx.borrow_region_constraints() - .opportunistic_resolve_var(self.tcx(), rid), - _ => - r, + ty::ReVar(rid) => { + self.infcx.borrow_region_constraints().opportunistic_resolve_var(self.tcx(), rid) + } + _ => r, } } @@ -120,8 +119,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> { if let ty::Infer(infer_ty) = t.kind { // Since we called `shallow_resolve` above, this must // be an (as yet...) unresolved inference variable. - let ty_var_span = - if let ty::TyVar(ty_vid) = infer_ty { + let ty_var_span = if let ty::TyVar(ty_vid) = infer_ty { let ty_vars = self.infcx.type_variables.borrow(); if let TypeVariableOrigin { kind: TypeVariableOriginKind::TypeParameterDefinition(_, _), @@ -136,7 +134,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> { None }; self.first_unresolved = Some((t, ty_var_span)); - true // Halt visiting. + true // Halt visiting. } else { // Otherwise, visit its contents. t.super_visit_with(self) @@ -149,7 +147,6 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> { } } - /////////////////////////////////////////////////////////////////////////// // FULL TYPE RESOLUTION @@ -183,8 +180,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { if !t.needs_infer() && !ty::keep_local(&t) { t // micro-optimize -- if there is nothing in this type that this fold affects... - // ^ we need to have the `keep_local` check to un-default - // defaulted tuples. + // ^ we need to have the `keep_local` check to un-default + // defaulted tuples. } else { let t = self.infcx.shallow_resolve(t); match t.kind { @@ -203,20 +200,20 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { ty::Infer(_) => { bug!("Unexpected type in full type resolver: {:?}", t); } - _ => { - t.super_fold_with(self) - } + _ => t.super_fold_with(self), } } } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { - ty::ReVar(rid) => self.infcx.lexical_region_resolutions - .borrow() - .as_ref() - .expect("region resolution not performed") - .resolve_var(rid), + ty::ReVar(rid) => self + .infcx + .lexical_region_resolutions + .borrow() + .as_ref() + .expect("region resolution not performed") + .resolve_var(rid), _ => r, } } @@ -224,8 +221,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { if !c.needs_infer() && !ty::keep_local(&c) { c // micro-optimize -- if there is nothing in this const that this fold affects... - // ^ we need to have the `keep_local` check to un-default - // defaulted tuples. + // ^ we need to have the `keep_local` check to un-default + // defaulted tuples. } else { let c = self.infcx.shallow_resolve(c); match c.val { diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs index 21c847e80f413..f355ffe196202 100644 --- a/src/librustc/infer/sub.rs +++ b/src/librustc/infer/sub.rs @@ -1,11 +1,11 @@ -use super::SubregionOrigin; use super::combine::{CombineFields, RelationDir}; +use super::SubregionOrigin; use crate::traits::Obligation; -use crate::ty::{self, Ty, TyCtxt}; -use crate::ty::TyVar; use crate::ty::fold::TypeFoldable; use crate::ty::relate::{Cause, Relate, RelateResult, TypeRelation}; +use crate::ty::TyVar; +use crate::ty::{self, Ty, TyCtxt}; use std::mem; /// Ensures `a` is made a subtype of `b`. Returns `a` on success. @@ -31,15 +31,24 @@ impl<'combine, 'infcx, 'tcx> Sub<'combine, 'infcx, 'tcx> { } impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> { - fn tag(&self) -> &'static str { "Sub" } - fn tcx(&self) -> TyCtxt<'tcx> { self.fields.infcx.tcx } + fn tag(&self) -> &'static str { + "Sub" + } + fn tcx(&self) -> TyCtxt<'tcx> { + self.fields.infcx.tcx + } - fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env } + fn param_env(&self) -> ty::ParamEnv<'tcx> { + self.fields.param_env + } - fn a_is_expected(&self) -> bool { self.a_is_expected } + fn a_is_expected(&self) -> bool { + self.a_is_expected + } - fn with_cause(&mut self, cause: Cause, f: F) -> R - where F: FnOnce(&mut Self) -> R + fn with_cause(&mut self, cause: Cause, f: F) -> R + where + F: FnOnce(&mut Self) -> R, { debug!("sub with_cause={:?}", cause); let old_cause = mem::replace(&mut self.fields.cause, Some(cause)); @@ -49,24 +58,26 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> { r } - fn relate_with_variance>(&mut self, - variance: ty::Variance, - a: &T, - b: &T) - -> RelateResult<'tcx, T> - { + fn relate_with_variance>( + &mut self, + variance: ty::Variance, + a: &T, + b: &T, + ) -> RelateResult<'tcx, T> { match variance { ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b), ty::Covariant => self.relate(a, b), ty::Bivariant => Ok(a.clone()), - ty::Contravariant => self.with_expected_switched(|this| { this.relate(b, a) }), + ty::Contravariant => self.with_expected_switched(|this| this.relate(b, a)), } } fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { debug!("{}.tys({:?}, {:?})", self.tag(), a, b); - if a == b { return Ok(a); } + if a == b { + return Ok(a); + } let infcx = self.fields.infcx; let a = infcx.type_variables.borrow_mut().replace_if_possible(a); @@ -85,22 +96,20 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> { // the two variables are equal modulo subtyping, which // is important to the occurs check later on. infcx.type_variables.borrow_mut().sub(a_vid, b_vid); - self.fields.obligations.push( - Obligation::new( - self.fields.trace.cause.clone(), - self.fields.param_env, - ty::Predicate::Subtype( - ty::Binder::dummy(ty::SubtypePredicate { - a_is_expected: self.a_is_expected, - a, - b, - })))); + self.fields.obligations.push(Obligation::new( + self.fields.trace.cause.clone(), + self.fields.param_env, + ty::Predicate::Subtype(ty::Binder::dummy(ty::SubtypePredicate { + a_is_expected: self.a_is_expected, + a, + b, + })), + )); Ok(a) } (&ty::Infer(TyVar(a_id)), _) => { - self.fields - .instantiate(b, RelationDir::SupertypeOf, a_id, !self.a_is_expected)?; + self.fields.instantiate(b, RelationDir::SupertypeOf, a_id, !self.a_is_expected)?; Ok(a) } (_, &ty::Infer(TyVar(b_id))) => { @@ -120,17 +129,18 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> { } } - fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) - -> RelateResult<'tcx, ty::Region<'tcx>> { - debug!("{}.regions({:?}, {:?}) self.cause={:?}", - self.tag(), a, b, self.fields.cause); + fn regions( + &mut self, + a: ty::Region<'tcx>, + b: ty::Region<'tcx>, + ) -> RelateResult<'tcx, ty::Region<'tcx>> { + debug!("{}.regions({:?}, {:?}) self.cause={:?}", self.tag(), a, b, self.fields.cause); // FIXME -- we have more fine-grained information available // from the "cause" field, we could perhaps give more tailored // error messages. let origin = SubregionOrigin::Subtype(box self.fields.trace.clone()); - self.fields.infcx.borrow_region_constraints() - .make_subregion(origin, a, b); + self.fields.infcx.borrow_region_constraints().make_subregion(origin, a, b); Ok(a) } @@ -143,9 +153,13 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> { self.fields.infcx.super_combine_consts(self, a, b) } - fn binders(&mut self, a: &ty::Binder, b: &ty::Binder) - -> RelateResult<'tcx, ty::Binder> - where T: Relate<'tcx> + fn binders( + &mut self, + a: &ty::Binder, + b: &ty::Binder, + ) -> RelateResult<'tcx, ty::Binder> + where + T: Relate<'tcx>, { self.fields.higher_ranked_sub(a, b, self.a_is_expected) } diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index 5a12de25f4b75..fb301037fa5d1 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -1,14 +1,14 @@ +use crate::hir::def_id::DefId; +use crate::ty::{self, Ty, TyVid}; use syntax::symbol::Symbol; use syntax_pos::Span; -use crate::ty::{self, Ty, TyVid}; -use crate::hir::def_id::DefId; +use rustc_data_structures::snapshot_vec as sv; +use rustc_data_structures::unify as ut; use std::cmp; use std::marker::PhantomData; -use std::u32; use std::ops::Range; -use rustc_data_structures::snapshot_vec as sv; -use rustc_data_structures::unify as ut; +use std::u32; pub struct TypeVariableTable<'tcx> { values: sv::SnapshotVec, @@ -153,9 +153,13 @@ impl<'tcx> TypeVariableTable<'tcx> { pub fn instantiate(&mut self, vid: ty::TyVid, ty: Ty<'tcx>) { let vid = self.root_var(vid); debug_assert!(self.probe(vid).is_unknown()); - debug_assert!(self.eq_relations.probe_value(vid).is_unknown(), - "instantiating type variable `{:?}` twice: new-value = {:?}, old-value={:?}", - vid, ty, self.eq_relations.probe_value(vid)); + debug_assert!( + self.eq_relations.probe_value(vid).is_unknown(), + "instantiating type variable `{:?}` twice: new-value = {:?}, old-value={:?}", + vid, + ty, + self.eq_relations.probe_value(vid) + ); self.eq_relations.union_value(vid, TypeVariableValue::Known { value: ty }); // Hack: we only need this so that `types_escaping_snapshot` @@ -174,28 +178,23 @@ impl<'tcx> TypeVariableTable<'tcx> { /// - `origin`: indicates *why* the type variable was created. /// The code in this module doesn't care, but it can be useful /// for improving error messages. - pub fn new_var(&mut self, - universe: ty::UniverseIndex, - diverging: bool, - origin: TypeVariableOrigin) - -> ty::TyVid { + pub fn new_var( + &mut self, + universe: ty::UniverseIndex, + diverging: bool, + origin: TypeVariableOrigin, + ) -> ty::TyVid { let eq_key = self.eq_relations.new_key(TypeVariableValue::Unknown { universe }); let sub_key = self.sub_relations.new_key(()); assert_eq!(eq_key.vid, sub_key); - let index = self.values.push(TypeVariableData { - origin, - diverging, - }); + let index = self.values.push(TypeVariableData { origin, diverging }); assert_eq!(eq_key.vid.index, index as u32); debug!( "new_var(index={:?}, universe={:?}, diverging={:?}, origin={:?}", - eq_key.vid, - universe, - diverging, - origin, + eq_key.vid, universe, diverging, origin, ); eq_key.vid @@ -249,12 +248,10 @@ impl<'tcx> TypeVariableTable<'tcx> { /// instantiated. Otherwise, returns `t`. pub fn replace_if_possible(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { match t.kind { - ty::Infer(ty::TyVar(v)) => { - match self.probe(v) { - TypeVariableValue::Unknown { .. } => t, - TypeVariableValue::Known { value } => value, - } - } + ty::Infer(ty::TyVar(v)) => match self.probe(v) { + TypeVariableValue::Unknown { .. } => t, + TypeVariableValue::Known { value } => value, + }, _ => t, } } @@ -306,9 +303,12 @@ impl<'tcx> TypeVariableTable<'tcx> { s: &Snapshot<'tcx>, ) -> (Range, Vec) { let range = self.eq_relations.vars_since_snapshot(&s.eq_snapshot); - (range.start.vid..range.end.vid, (range.start.vid.index..range.end.vid.index).map(|index| { - self.values.get(index as usize).origin.clone() - }).collect()) + ( + range.start.vid..range.end.vid, + (range.start.vid.index..range.end.vid.index) + .map(|index| self.values.get(index as usize).origin.clone()) + .collect(), + ) } /// Finds the set of type variables that existed *before* `s` @@ -347,7 +347,7 @@ impl<'tcx> TypeVariableTable<'tcx> { debug!("SpecifyVar({:?}) new_elem_threshold={}", vid, new_elem_threshold); } - _ => { } + _ => {} } } @@ -410,9 +410,15 @@ impl<'tcx> From for TyVidEqKey<'tcx> { impl<'tcx> ut::UnifyKey for TyVidEqKey<'tcx> { type Value = TypeVariableValue<'tcx>; - fn index(&self) -> u32 { self.vid.index } - fn from_index(i: u32) -> Self { TyVidEqKey::from(ty::TyVid { index: i }) } - fn tag() -> &'static str { "TyVidEqKey" } + fn index(&self) -> u32 { + self.vid.index + } + fn from_index(i: u32) -> Self { + TyVidEqKey::from(ty::TyVid { index: i }) + } + fn tag() -> &'static str { + "TyVidEqKey" + } } impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> { @@ -432,8 +438,10 @@ impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> { (&TypeVariableValue::Unknown { .. }, &TypeVariableValue::Known { .. }) => Ok(*value2), // If both sides are *unknown*, it hardly matters, does it? - (&TypeVariableValue::Unknown { universe: universe1 }, - &TypeVariableValue::Unknown { universe: universe2 }) => { + ( + &TypeVariableValue::Unknown { universe: universe1 }, + &TypeVariableValue::Unknown { universe: universe2 }, + ) => { // If we unify two unbound variables, ?T and ?U, then whatever // value they wind up taking (which must be the same value) must // be nameable by both universes. Therefore, the resulting @@ -450,7 +458,13 @@ impl<'tcx> ut::UnifyValue for TypeVariableValue<'tcx> { /// they carry no values. impl ut::UnifyKey for ty::TyVid { type Value = (); - fn index(&self) -> u32 { self.index } - fn from_index(i: u32) -> ty::TyVid { ty::TyVid { index: i } } - fn tag() -> &'static str { "TyVid" } + fn index(&self) -> u32 { + self.index + } + fn from_index(i: u32) -> ty::TyVid { + ty::TyVid { index: i } + } + fn tag() -> &'static str { + "TyVid" + } } diff --git a/src/librustc/infer/unify_key.rs b/src/librustc/infer/unify_key.rs index 8ad6990a75daf..023b15f7943e6 100644 --- a/src/librustc/infer/unify_key.rs +++ b/src/librustc/infer/unify_key.rs @@ -1,12 +1,12 @@ -use crate::ty::{self, FloatVarValue, IntVarValue, Ty, TyCtxt, InferConst}; -use rustc_data_structures::unify::{NoError, EqUnifyValue, UnifyKey, UnifyValue, UnificationTable}; +use crate::ty::{self, FloatVarValue, InferConst, IntVarValue, Ty, TyCtxt}; use rustc_data_structures::unify::InPlace; -use syntax_pos::{Span, DUMMY_SP}; +use rustc_data_structures::unify::{EqUnifyValue, NoError, UnificationTable, UnifyKey, UnifyValue}; use syntax::symbol::Symbol; +use syntax_pos::{Span, DUMMY_SP}; +use std::cell::RefMut; use std::cmp; use std::marker::PhantomData; -use std::cell::RefMut; pub trait ToType { fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>; @@ -14,9 +14,15 @@ pub trait ToType { impl UnifyKey for ty::IntVid { type Value = Option; - fn index(&self) -> u32 { self.index } - fn from_index(i: u32) -> ty::IntVid { ty::IntVid { index: i } } - fn tag() -> &'static str { "IntVid" } + fn index(&self) -> u32 { + self.index + } + fn from_index(i: u32) -> ty::IntVid { + ty::IntVid { index: i } + } + fn tag() -> &'static str { + "IntVid" + } } impl EqUnifyValue for IntVarValue {} @@ -26,7 +32,7 @@ pub struct RegionVidKey { /// The minimum region vid in the unification set. This is needed /// to have a canonical name for a type to prevent infinite /// recursion. - pub min_vid: ty::RegionVid + pub min_vid: ty::RegionVid, } impl UnifyValue for RegionVidKey { @@ -45,9 +51,15 @@ impl UnifyValue for RegionVidKey { impl UnifyKey for ty::RegionVid { type Value = RegionVidKey; - fn index(&self) -> u32 { u32::from(*self) } - fn from_index(i: u32) -> ty::RegionVid { ty::RegionVid::from(i) } - fn tag() -> &'static str { "RegionVid" } + fn index(&self) -> u32 { + u32::from(*self) + } + fn from_index(i: u32) -> ty::RegionVid { + ty::RegionVid::from(i) + } + fn tag() -> &'static str { + "RegionVid" + } } impl ToType for IntVarValue { @@ -63,9 +75,15 @@ impl ToType for IntVarValue { impl UnifyKey for ty::FloatVid { type Value = Option; - fn index(&self) -> u32 { self.index } - fn from_index(i: u32) -> ty::FloatVid { ty::FloatVid { index: i } } - fn tag() -> &'static str { "FloatVid" } + fn index(&self) -> u32 { + self.index + } + fn from_index(i: u32) -> ty::FloatVid { + ty::FloatVid { index: i } + } + fn tag() -> &'static str { + "FloatVid" + } } impl EqUnifyValue for FloatVarValue {} @@ -125,9 +143,15 @@ pub struct ConstVarValue<'tcx> { impl<'tcx> UnifyKey for ty::ConstVid<'tcx> { type Value = ConstVarValue<'tcx>; - fn index(&self) -> u32 { self.index } - fn from_index(i: u32) -> Self { ty::ConstVid { index: i, phantom: PhantomData } } - fn tag() -> &'static str { "ConstVid" } + fn index(&self) -> u32 { + self.index + } + fn from_index(i: u32) -> Self { + ty::ConstVid { index: i, phantom: PhantomData } + } + fn tag() -> &'static str { + "ConstVid" + } } impl<'tcx> UnifyValue for ConstVarValue<'tcx> { @@ -135,10 +159,7 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> { fn unify_values(value1: &Self, value2: &Self) -> Result { let val = match (value1.val, value2.val) { - ( - ConstVariableValue::Known { .. }, - ConstVariableValue::Known { .. } - ) => { + (ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => { bug!("equating two const variables, both of which have known values") } @@ -151,8 +172,10 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> { } // If both sides are *unknown*, it hardly matters, does it? - (ConstVariableValue::Unknown { universe: universe1 }, - ConstVariableValue::Unknown { universe: universe2 }) => { + ( + ConstVariableValue::Unknown { universe: universe1 }, + ConstVariableValue::Unknown { universe: universe2 }, + ) => { // If we unify two unbound variables, ?T and ?U, then whatever // value they wind up taking (which must be the same value) must // be nameable by both universes. Therefore, the resulting @@ -177,7 +200,7 @@ impl<'tcx> EqUnifyValue for &'tcx ty::Const<'tcx> {} pub fn replace_if_possible( mut table: RefMut<'_, UnificationTable>>>, - c: &'tcx ty::Const<'tcx> + c: &'tcx ty::Const<'tcx>, ) -> &'tcx ty::Const<'tcx> { if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = c { match table.probe_value(*vid).val.known() { diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 641e6a4f61489..55713aedbcb67 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -27,7 +27,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] - #![feature(arbitrary_self_types)] #![feature(bool_to_option)] #![feature(box_patterns)] @@ -61,18 +60,24 @@ #![feature(associated_type_bounds)] #![feature(rustc_attrs)] #![feature(hash_raw_entry)] +#![recursion_limit = "512"] -#![recursion_limit="512"] - -#[macro_use] extern crate bitflags; -#[macro_use] extern crate scoped_tls; +#[macro_use] +extern crate bitflags; +#[macro_use] +extern crate scoped_tls; #[cfg(windows)] extern crate libc; -#[macro_use] extern crate rustc_macros; -#[macro_use] extern crate rustc_data_structures; -#[macro_use] extern crate log; -#[macro_use] extern crate syntax; -#[macro_use] extern crate smallvec; +#[macro_use] +extern crate rustc_macros; +#[macro_use] +extern crate rustc_data_structures; +#[macro_use] +extern crate log; +#[macro_use] +extern crate syntax; +#[macro_use] +extern crate smallvec; #[cfg(test)] mod tests; @@ -97,12 +102,12 @@ pub mod middle { pub mod diagnostic_items; pub mod exported_symbols; pub mod free_region; - pub mod lib_features; pub mod lang_items; + pub mod lib_features; pub mod privacy; pub mod reachable; - pub mod region; pub mod recursion_limit; + pub mod region; pub mod resolve_lifetime; pub mod stability; pub mod weak_lang_items; @@ -114,10 +119,10 @@ pub mod traits; pub mod ty; pub mod util { + pub mod bug; pub mod captures; pub mod common; pub mod nodemap; - pub mod bug; } // Allows macros to refer to this crate as `::rustc` diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index c4bc9773d2312..1da9661cbf270 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -4,16 +4,16 @@ //! compiler code, rather than using their own custom pass. Those //! lints are all available in `rustc_lint::builtin`. -use crate::lint::{LintPass, LateLintPass, LintArray, FutureIncompatibleInfo}; +use crate::lint::{FutureIncompatibleInfo, LateLintPass, LintArray, LintPass}; use crate::middle::stability; use crate::session::Session; -use errors::{Applicability, DiagnosticBuilder, pluralize}; +use errors::{pluralize, Applicability, DiagnosticBuilder}; +use rustc_session::declare_lint; use syntax::ast; +use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE}; use syntax::edition::Edition; use syntax::source_map::Span; use syntax::symbol::Symbol; -use syntax::early_buffered_lints::{ILL_FORMED_ATTRIBUTE_INPUT, META_VARIABLE_MISUSE}; -use rustc_session::declare_lint; declare_lint! { pub EXCEEDING_BITSHIFTS, @@ -561,7 +561,7 @@ pub(crate) fn add_elided_lifetime_in_path_suggestion( replace_span, &format!("indicate the anonymous lifetime{}", pluralize!(n)), suggestion, - Applicability::MachineApplicable + Applicability::MachineApplicable, ); } @@ -571,10 +571,11 @@ impl BuiltinLintDiagnostics { BuiltinLintDiagnostics::Normal => (), BuiltinLintDiagnostics::BareTraitObject(span, is_global) => { let (sugg, app) = match sess.source_map().span_to_snippet(span) { - Ok(ref s) if is_global => (format!("dyn ({})", s), - Applicability::MachineApplicable), + Ok(ref s) if is_global => { + (format!("dyn ({})", s), Applicability::MachineApplicable) + } Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable), - Err(_) => ("dyn ".to_string(), Applicability::HasPlaceholders) + Err(_) => ("dyn ".to_string(), Applicability::HasPlaceholders), }; db.span_suggestion(span, "use `dyn`", sugg, app); } @@ -583,27 +584,30 @@ impl BuiltinLintDiagnostics { Ok(ref s) => { // FIXME(Manishearth) ideally the emitting code // can tell us whether or not this is global - let opt_colon = if s.trim_start().starts_with("::") { - "" - } else { - "::" - }; + let opt_colon = if s.trim_start().starts_with("::") { "" } else { "::" }; (format!("crate{}{}", opt_colon, s), Applicability::MachineApplicable) } - Err(_) => ("crate::".to_string(), Applicability::HasPlaceholders) + Err(_) => ("crate::".to_string(), Applicability::HasPlaceholders), }; db.span_suggestion(span, "use `crate`", sugg, app); } BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => { - db.span_label(span, "names from parent modules are not \ - accessible without an explicit import"); + db.span_label( + span, + "names from parent modules are not \ + accessible without an explicit import", + ); } BuiltinLintDiagnostics::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => { db.span_note(span_def, "the macro is defined here"); } BuiltinLintDiagnostics::ElidedLifetimesInPaths( - n, path_span, incl_angl_brckt, insertion_span, anon_lts + n, + path_span, + incl_angl_brckt, + insertion_span, + anon_lts, ) => { add_elided_lifetime_in_path_suggestion( sess, @@ -632,12 +636,13 @@ impl BuiltinLintDiagnostics { let introduced = if is_imported { "imported" } else { "defined" }; db.span_label( span, - format!("the item `{}` is already {} here", ident, introduced) + format!("the item `{}` is already {} here", ident, introduced), ); } } - BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => - stability::deprecation_suggestion(db, suggestion, span), + BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => { + stability::deprecation_suggestion(db, suggestion, span) + } } } } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index b7d013063438d..113084e7b7e0e 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -21,24 +21,24 @@ use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use crate::hir::intravisit as hir_visit; use crate::hir::intravisit::Visitor; use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; -use crate::lint::{EarlyLintPass, LateLintPass, EarlyLintPassObject, LateLintPassObject}; -use crate::lint::{Level, Lint, LintId, LintPass, LintBuffer, FutureIncompatibleInfo}; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; +use crate::lint::{EarlyLintPass, EarlyLintPassObject, LateLintPass, LateLintPassObject}; +use crate::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId, LintPass}; use crate::middle::privacy::AccessLevels; use crate::session::Session; -use crate::ty::{self, print::Printer, subst::GenericArg, TyCtxt, Ty}; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; -use crate::util::nodemap::FxHashMap; +use crate::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt}; use crate::util::common::time; +use crate::util::nodemap::FxHashMap; use errors::DiagnosticBuilder; +use rustc_data_structures::sync::{self, join, par_iter, ParallelIterator}; use std::slice; -use rustc_data_structures::sync::{self, ParallelIterator, join, par_iter}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; use syntax::visit as ast_visit; -use syntax_pos::{MultiSpan, Span, symbol::Symbol}; +use syntax_pos::{symbol::Symbol, MultiSpan, Span}; use rustc_error_codes::*; @@ -143,7 +143,8 @@ impl LintStore { } pub fn get_lint_groups<'t>(&'t self) -> Vec<(&'static str, Vec, bool)> { - self.lint_groups.iter() + self.lint_groups + .iter() .filter(|(_, LintGroup { depr, .. })| { // Don't display deprecated lint groups. depr.is_none() @@ -156,7 +157,7 @@ impl LintStore { pub fn register_early_pass( &mut self, - pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync, ) { self.early_passes.push(Box::new(pass)); } @@ -194,36 +195,39 @@ impl LintStore { if let Some(FutureIncompatibleInfo { edition, .. }) = lint.future_incompatible { if let Some(edition) = edition { - self.lint_groups.entry(edition.lint_name()) + self.lint_groups + .entry(edition.lint_name()) .or_insert(LintGroup { lint_ids: vec![], from_plugin: lint.is_plugin, depr: None, }) - .lint_ids.push(id); + .lint_ids + .push(id); } - self.lint_groups.entry("future_incompatible") + self.lint_groups + .entry("future_incompatible") .or_insert(LintGroup { lint_ids: vec![], from_plugin: lint.is_plugin, depr: None, }) - .lint_ids.push(id); + .lint_ids + .push(id); } } } - pub fn register_group_alias( - &mut self, - lint_name: &'static str, - alias: &'static str, - ) { - self.lint_groups.insert(alias, LintGroup { - lint_ids: vec![], - from_plugin: false, - depr: Some(LintAlias { name: lint_name, silent: true }), - }); + pub fn register_group_alias(&mut self, lint_name: &'static str, alias: &'static str) { + self.lint_groups.insert( + alias, + LintGroup { + lint_ids: vec![], + from_plugin: false, + depr: Some(LintAlias { name: lint_name, silent: true }), + }, + ); } pub fn register_group( @@ -235,18 +239,17 @@ impl LintStore { ) { let new = self .lint_groups - .insert(name, LintGroup { - lint_ids: to, - from_plugin, - depr: None, - }) + .insert(name, LintGroup { lint_ids: to, from_plugin, depr: None }) .is_none(); if let Some(deprecated) = deprecated_name { - self.lint_groups.insert(deprecated, LintGroup { - lint_ids: vec![], - from_plugin, - depr: Some(LintAlias { name, silent: false }), - }); + self.lint_groups.insert( + deprecated, + LintGroup { + lint_ids: vec![], + from_plugin, + depr: Some(LintAlias { name, silent: false }), + }, + ); } if !new { @@ -257,7 +260,7 @@ impl LintStore { pub fn register_renamed(&mut self, old_name: &str, new_name: &str) { let target = match self.by_name.get(new_name) { Some(&Id(lint_id)) => lint_id.clone(), - _ => bug!("invalid lint renaming of {} to {}", old_name, new_name) + _ => bug!("invalid lint renaming of {} to {}", old_name, new_name), }; self.by_name.insert(old_name.to_string(), Renamed(new_name.to_string(), target)); } @@ -269,39 +272,28 @@ impl LintStore { pub fn find_lints(&self, mut lint_name: &str) -> Result, FindLintError> { match self.by_name.get(lint_name) { Some(&Id(lint_id)) => Ok(vec![lint_id]), - Some(&Renamed(_, lint_id)) => { - Ok(vec![lint_id]) - }, - Some(&Removed(_)) => { - Err(FindLintError::Removed) - }, - None => { - loop { - return match self.lint_groups.get(lint_name) { - Some(LintGroup {lint_ids, depr, .. }) => { - if let Some(LintAlias { name, .. }) = depr { - lint_name = name; - continue; - } - Ok(lint_ids.clone()) + Some(&Renamed(_, lint_id)) => Ok(vec![lint_id]), + Some(&Removed(_)) => Err(FindLintError::Removed), + None => loop { + return match self.lint_groups.get(lint_name) { + Some(LintGroup { lint_ids, depr, .. }) => { + if let Some(LintAlias { name, .. }) = depr { + lint_name = name; + continue; } - None => Err(FindLintError::Removed) - }; - } - } + Ok(lint_ids.clone()) + } + None => Err(FindLintError::Removed), + }; + }, } } /// Checks the validity of lint names derived from the command line - pub fn check_lint_name_cmdline(&self, - sess: &Session, - lint_name: &str, - level: Level) { + pub fn check_lint_name_cmdline(&self, sess: &Session, lint_name: &str, level: Level) { let db = match self.check_lint_name(lint_name, None) { CheckLintNameResult::Ok(_) => None, - CheckLintNameResult::Warning(ref msg, _) => { - Some(sess.struct_warn(msg)) - }, + CheckLintNameResult::Warning(ref msg, _) => Some(sess.struct_warn(msg)), CheckLintNameResult::NoLint(suggestion) => { let mut err = struct_err!(sess, E0602, "unknown lint: `{}`", lint_name); @@ -323,14 +315,16 @@ impl LintStore { }; if let Some(mut db) = db { - let msg = format!("requested on the command line with `{} {}`", - match level { - Level::Allow => "-A", - Level::Warn => "-W", - Level::Deny => "-D", - Level::Forbid => "-F", - }, - lint_name); + let msg = format!( + "requested on the command line with `{} {}`", + match level { + Level::Allow => "-A", + Level::Warn => "-W", + Level::Deny => "-D", + Level::Forbid => "-F", + }, + lint_name + ); db.note(&msg); db.emit(); } @@ -370,10 +364,7 @@ impl LintStore { } match self.by_name.get(&complete_name) { Some(&Renamed(ref new_name, _)) => CheckLintNameResult::Warning( - format!( - "lint `{}` has been renamed to `{}`", - complete_name, new_name - ), + format!("lint `{}` has been renamed to `{}`", complete_name, new_name), Some(new_name.to_owned()), ), Some(&Removed(ref reason)) => CheckLintNameResult::Warning( @@ -391,10 +382,7 @@ impl LintStore { return if *silent { CheckLintNameResult::Ok(&lint_ids) } else { - CheckLintNameResult::Tool(Err(( - Some(&lint_ids), - name.to_string(), - ))) + CheckLintNameResult::Tool(Err((Some(&lint_ids), name.to_string()))) }; } CheckLintNameResult::Ok(&lint_ids) @@ -414,9 +402,8 @@ impl LintStore { None => match self.lint_groups.get(&*complete_name) { // Now we are sure, that this lint exists nowhere None => { - let symbols = self.by_name.keys() - .map(|name| Symbol::intern(&name)) - .collect::>(); + let symbols = + self.by_name.keys().map(|name| Symbol::intern(&name)).collect::>(); let suggestion = find_best_match_for_name(symbols.iter(), &lint_name.to_lowercase(), None); @@ -430,10 +417,7 @@ impl LintStore { return if *silent { CheckLintNameResult::Tool(Err((Some(&lint_ids), complete_name))) } else { - CheckLintNameResult::Tool(Err(( - Some(&lint_ids), - name.to_string(), - ))) + CheckLintNameResult::Tool(Err((Some(&lint_ids), name.to_string()))) }; } CheckLintNameResult::Tool(Err((Some(&lint_ids), complete_name))) @@ -513,45 +497,52 @@ pub trait LintContext: Sized { fn sess(&self) -> &Session; fn lints(&self) -> &LintStore; - fn lookup_and_emit>(&self, - lint: &'static Lint, - span: Option, - msg: &str) { + fn lookup_and_emit>(&self, lint: &'static Lint, span: Option, msg: &str) { self.lookup(lint, span, msg).emit(); } - fn lookup_and_emit_with_diagnostics>(&self, - lint: &'static Lint, - span: Option, - msg: &str, - diagnostic: BuiltinLintDiagnostics) { + fn lookup_and_emit_with_diagnostics>( + &self, + lint: &'static Lint, + span: Option, + msg: &str, + diagnostic: BuiltinLintDiagnostics, + ) { let mut db = self.lookup(lint, span, msg); diagnostic.run(self.sess(), &mut db); db.emit(); } - fn lookup>(&self, - lint: &'static Lint, - span: Option, - msg: &str) - -> DiagnosticBuilder<'_>; + fn lookup>( + &self, + lint: &'static Lint, + span: Option, + msg: &str, + ) -> DiagnosticBuilder<'_>; /// Emit a lint at the appropriate level, for a particular span. fn span_lint>(&self, lint: &'static Lint, span: S, msg: &str) { self.lookup_and_emit(lint, Some(span), msg); } - fn struct_span_lint>(&self, - lint: &'static Lint, - span: S, - msg: &str) - -> DiagnosticBuilder<'_> { + fn struct_span_lint>( + &self, + lint: &'static Lint, + span: S, + msg: &str, + ) -> DiagnosticBuilder<'_> { self.lookup(lint, Some(span), msg) } /// Emit a lint and note at the appropriate level, for a particular span. - fn span_lint_note(&self, lint: &'static Lint, span: Span, msg: &str, - note_span: Span, note: &str) { + fn span_lint_note( + &self, + lint: &'static Lint, + span: Span, + msg: &str, + note_span: Span, + note: &str, + ) { let mut err = self.lookup(lint, Some(span), msg); if note_span == span { err.note(note); @@ -562,8 +553,7 @@ pub trait LintContext: Sized { } /// Emit a lint and help at the appropriate level, for a particular span. - fn span_lint_help(&self, lint: &'static Lint, span: Span, - msg: &str, help: &str) { + fn span_lint_help(&self, lint: &'static Lint, span: Span, msg: &str, help: &str) { let mut err = self.lookup(lint, Some(span), msg); self.span_lint(lint, span, msg); err.span_help(span, help); @@ -576,7 +566,6 @@ pub trait LintContext: Sized { } } - impl<'a> EarlyContext<'a> { fn new( sess: &'a Session, @@ -610,7 +599,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { early_lint.lint_id.lint, Some(early_lint.span.clone()), &early_lint.msg, - early_lint.diagnostic + early_lint.diagnostic, ); } } @@ -618,11 +607,9 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { /// Merge the lints specified by any lint attributes into the /// current lint context, call the provided function, then reset the /// lints in effect to their previous state. - fn with_lint_attrs(&mut self, - id: ast::NodeId, - attrs: &'a [ast::Attribute], - f: F) - where F: FnOnce(&mut Self) + fn with_lint_attrs(&mut self, id: ast::NodeId, attrs: &'a [ast::Attribute], f: F) + where + F: FnOnce(&mut Self), { let push = self.context.builder.push(attrs, &self.context.lint_store); self.check_id(id); @@ -655,18 +642,17 @@ impl LintContext for LateContext<'_, '_> { &*self.lint_store } - fn lookup>(&self, - lint: &'static Lint, - span: Option, - msg: &str) - -> DiagnosticBuilder<'_> { + fn lookup>( + &self, + lint: &'static Lint, + span: Option, + msg: &str, + ) -> DiagnosticBuilder<'_> { let hir_id = self.last_node_with_lint_attrs; match span { Some(s) => self.tcx.struct_span_lint_hir(lint, hir_id, s, msg), - None => { - self.tcx.struct_lint_node(lint, hir_id, msg) - }, + None => self.tcx.struct_lint_node(lint, hir_id, msg), } } } @@ -683,11 +669,12 @@ impl LintContext for EarlyContext<'_> { &*self.lint_store } - fn lookup>(&self, - lint: &'static Lint, - span: Option, - msg: &str) - -> DiagnosticBuilder<'_> { + fn lookup>( + &self, + lint: &'static Lint, + span: Option, + msg: &str, + ) -> DiagnosticBuilder<'_> { self.builder.struct_lint(lint, span.map(|s| s.into()), msg) } } @@ -758,10 +745,7 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { Ok(()) } - fn print_const( - self, - _ct: &'tcx ty::Const<'tcx>, - ) -> Result { + fn print_const(self, _ct: &'tcx ty::Const<'tcx>) -> Result { Ok(()) } @@ -798,15 +782,11 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { // This shouldn't ever be needed, but just in case: path.push(match trait_ref { - Some(trait_ref) => { - Symbol::intern( - &format!( - "", - trait_ref.print_only_trait_path(), - self_ty - ) - ) - }, + Some(trait_ref) => Symbol::intern(&format!( + "", + trait_ref.print_only_trait_path(), + self_ty + )), None => Symbol::intern(&format!("", self_ty)), }); @@ -839,9 +819,7 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { } } - AbsolutePathPrinter { tcx: self.tcx } - .print_def_path(def_id, &[]) - .unwrap() + AbsolutePathPrinter { tcx: self.tcx }.print_def_path(def_id, &[]).unwrap() } } @@ -858,11 +836,9 @@ impl<'a, 'tcx, T: LateLintPass<'a, 'tcx>> LateContextAndPass<'a, 'tcx, T> { /// Merge the lints specified by any lint attributes into the /// current lint context, call the provided function, then reset the /// lints in effect to their previous state. - fn with_lint_attrs(&mut self, - id: hir::HirId, - attrs: &'tcx [ast::Attribute], - f: F) - where F: FnOnce(&mut Self) + fn with_lint_attrs(&mut self, id: hir::HirId, attrs: &'tcx [ast::Attribute], f: F) + where + F: FnOnce(&mut Self), { let prev = self.context.last_node_with_lint_attrs; self.context.last_node_with_lint_attrs = id; @@ -873,12 +849,12 @@ impl<'a, 'tcx, T: LateLintPass<'a, 'tcx>> LateContextAndPass<'a, 'tcx, T> { } fn with_param_env(&mut self, id: hir::HirId, f: F) - where F: FnOnce(&mut Self), + where + F: FnOnce(&mut Self), { let old_param_env = self.context.param_env; - self.context.param_env = self.context.tcx.param_env( - self.context.tcx.hir().local_def_id(id) - ); + self.context.param_env = + self.context.tcx.param_env(self.context.tcx.hir().local_def_id(id)); f(self); self.context.param_env = old_param_env; } @@ -901,7 +877,8 @@ impl<'a, 'tcx, T: LateLintPass<'a, 'tcx>> LateContextAndPass<'a, 'tcx, T> { } impl<'a, 'tcx, T: LateLintPass<'a, 'tcx>> hir_visit::Visitor<'tcx> -for LateContextAndPass<'a, 'tcx, T> { + for LateContextAndPass<'a, 'tcx, T> +{ /// Because lints are scoped lexically, we want to walk nested /// items in the context of the outer item, so enable /// deep-walking. @@ -976,8 +953,14 @@ for LateContextAndPass<'a, 'tcx, T> { hir_visit::walk_stmt(self, s); } - fn visit_fn(&mut self, fk: hir_visit::FnKind<'tcx>, decl: &'tcx hir::FnDecl, - body_id: hir::BodyId, span: Span, id: hir::HirId) { + fn visit_fn( + &mut self, + fk: hir_visit::FnKind<'tcx>, + decl: &'tcx hir::FnDecl, + body_id: hir::BodyId, + span: Span, + id: hir::HirId, + ) { // Wrap in tables here, not just in visit_nested_body, // in order for `check_fn` to be able to use them. let old_tables = self.context.tables; @@ -989,12 +972,14 @@ for LateContextAndPass<'a, 'tcx, T> { self.context.tables = old_tables; } - fn visit_variant_data(&mut self, - s: &'tcx hir::VariantData<'tcx>, - _: ast::Name, - _: &'tcx hir::Generics, - _: hir::HirId, - _: Span) { + fn visit_variant_data( + &mut self, + s: &'tcx hir::VariantData<'tcx>, + _: ast::Name, + _: &'tcx hir::Generics, + _: hir::HirId, + _: Span, + ) { lint_callback!(self, check_struct_def, s); hir_visit::walk_struct_def(self, s); lint_callback!(self, check_struct_def_post, s); @@ -1007,10 +992,12 @@ for LateContextAndPass<'a, 'tcx, T> { }) } - fn visit_variant(&mut self, - v: &'tcx hir::Variant<'tcx>, - g: &'tcx hir::Generics, - item_id: hir::HirId) { + fn visit_variant( + &mut self, + v: &'tcx hir::Variant<'tcx>, + g: &'tcx hir::Generics, + item_id: hir::HirId, + ) { self.with_lint_attrs(v.id, &v.attrs, |cx| { lint_callback!(cx, check_variant, v); hir_visit::walk_variant(cx, v, g, item_id); @@ -1066,8 +1053,7 @@ for LateContextAndPass<'a, 'tcx, T> { hir_visit::walk_where_predicate(self, p); } - fn visit_poly_trait_ref(&mut self, t: &'tcx hir::PolyTraitRef, - m: hir::TraitBoundModifier) { + fn visit_poly_trait_ref(&mut self, t: &'tcx hir::PolyTraitRef, m: hir::TraitBoundModifier) { lint_callback!(self, check_poly_trait_ref, t, m); hir_visit::walk_poly_trait_ref(self, t, m); } @@ -1157,8 +1143,13 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> ast_visit::walk_stmt(self, s); } - fn visit_fn(&mut self, fk: ast_visit::FnKind<'a>, decl: &'a ast::FnDecl, - span: Span, id: ast::NodeId) { + fn visit_fn( + &mut self, + fk: ast_visit::FnKind<'a>, + decl: &'a ast::FnDecl, + span: Span, + id: ast::NodeId, + ) { run_early_pass!(self, check_fn, fk, decl, span, id); self.check_id(id); ast_visit::walk_fn(self, fk, decl, span); @@ -1346,10 +1337,7 @@ fn late_lint_mod_pass<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( only_module: true, }; - let mut cx = LateContextAndPass { - context, - pass - }; + let mut cx = LateContextAndPass { context, pass }; let (module, span, hir_id) = tcx.hir().get_module(module_def_id); cx.process_mod(module, span, hir_id); @@ -1372,8 +1360,8 @@ pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( late_lint_mod_pass(tcx, module_def_id, builtin_lints); - let mut passes: Vec<_> = tcx.lint_store.late_module_passes - .iter().map(|pass| (pass)()).collect(); + let mut passes: Vec<_> = + tcx.lint_store.late_module_passes.iter().map(|pass| (pass)()).collect(); if !passes.is_empty() { late_lint_mod_pass(tcx, module_def_id, LateLintPassObjects { lints: &mut passes[..] }); @@ -1396,10 +1384,7 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc only_module: false, }; - let mut cx = LateContextAndPass { - context, - pass - }; + let mut cx = LateContextAndPass { context, pass }; // Visit the whole crate. cx.with_lint_attrs(hir::CRATE_HIR_ID, &krate.attrs, |cx| { @@ -1414,8 +1399,7 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc } fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) { - let mut passes = tcx.lint_store - .late_passes.iter().map(|p| (p)()).collect::>(); + let mut passes = tcx.lint_store.late_passes.iter().map(|p| (p)()).collect::>(); if !tcx.sess.opts.debugging_opts.no_interleave_lints { if !passes.is_empty() { @@ -1430,8 +1414,8 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b }); } - let mut passes: Vec<_> = tcx.lint_store.late_module_passes - .iter().map(|pass| (pass)()).collect(); + let mut passes: Vec<_> = + tcx.lint_store.late_module_passes.iter().map(|pass| (pass)()).collect(); for pass in &mut passes { time(tcx.sess, &format!("running late module lint: {}", pass.name()), || { @@ -1446,19 +1430,22 @@ pub fn check_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( tcx: TyCtxt<'tcx>, builtin_lints: impl FnOnce() -> T + Send, ) { - join(|| { - time(tcx.sess, "crate lints", || { - // Run whole crate non-incremental lints - late_lint_crate(tcx, builtin_lints()); - }); - }, || { - time(tcx.sess, "module lints", || { - // Run per-module lints - par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { - tcx.ensure().lint_mod(tcx.hir().local_def_id(module)); + join( + || { + time(tcx.sess, "crate lints", || { + // Run whole crate non-incremental lints + late_lint_crate(tcx, builtin_lints()); }); - }); - }); + }, + || { + time(tcx.sess, "module lints", || { + // Run per-module lints + par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { + tcx.ensure().lint_mod(tcx.hir().local_def_id(module)); + }); + }); + }, + ); } struct EarlyLintPassObjects<'a> { @@ -1534,8 +1521,8 @@ pub fn check_ast_crate( let mut buffered = lint_buffer.unwrap_or_default(); if !sess.opts.debugging_opts.no_interleave_lints { - buffered = early_lint_crate(sess, lint_store, krate, builtin_lints, buffered, - pre_expansion); + buffered = + early_lint_crate(sess, lint_store, krate, builtin_lints, buffered, pre_expansion); if !passes.is_empty() { buffered = early_lint_crate( diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs index f80a72365e361..55ed46e774ded 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc/lint/internal.rs @@ -7,9 +7,9 @@ use crate::lint::{ }; use errors::Applicability; use rustc_data_structures::fx::FxHashMap; +use rustc_session::declare_tool_lint; use syntax::ast::{Ident, Item, ItemKind}; use syntax::symbol::{sym, Symbol}; -use rustc_session::declare_tool_lint; declare_tool_lint! { pub rustc::DEFAULT_HASH_TYPES, @@ -224,8 +224,9 @@ impl EarlyLintPass for LintPassImpl { if last.ident.name == sym::LintPass { let expn_data = lint_pass.path.span.ctxt().outer_expn_data(); let call_site = expn_data.call_site; - if expn_data.kind.descr() != sym::impl_lint_pass && - call_site.ctxt().outer_expn_data().kind.descr() != sym::declare_lint_pass { + if expn_data.kind.descr() != sym::impl_lint_pass + && call_site.ctxt().outer_expn_data().kind.descr() != sym::declare_lint_pass + { cx.struct_span_lint( LINT_PASS_IMPL_WITHOUT_MACRO, lint_pass.path.span, diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index f29d1a3789aea..edf7df16c87fa 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -3,8 +3,8 @@ use std::cmp; use crate::hir::HirId; use crate::ich::StableHashingContext; use crate::lint::builtin; -use crate::lint::context::{LintStore, CheckLintNameResult}; -use crate::lint::{self, Lint, LintId, Level, LintSource}; +use crate::lint::context::{CheckLintNameResult, LintStore}; +use crate::lint::{self, Level, Lint, LintId, LintSource}; use crate::session::Session; use crate::util::nodemap::FxHashMap; use errors::{Applicability, DiagnosticBuilder}; @@ -14,7 +14,7 @@ use syntax::attr; use syntax::feature_gate; use syntax::print::pprust; use syntax::source_map::MultiSpan; -use syntax::symbol::{Symbol, sym}; +use syntax::symbol::{sym, Symbol}; use rustc_error_codes::*; @@ -38,12 +38,9 @@ enum LintSet { impl LintLevelSets { pub fn new(sess: &Session, lint_store: &LintStore) -> LintLevelSets { - let mut me = LintLevelSets { - list: Vec::new(), - lint_cap: Level::Forbid, - }; + let mut me = LintLevelSets { list: Vec::new(), lint_cap: Level::Forbid }; me.process_command_line(sess, lint_store); - return me + return me; } pub fn builder<'a>( @@ -77,18 +74,16 @@ impl LintLevelSets { } } - self.list.push(LintSet::CommandLine { - specs: specs, - }); + self.list.push(LintSet::CommandLine { specs: specs }); } - fn get_lint_level(&self, - lint: &'static Lint, - idx: u32, - aux: Option<&FxHashMap>, - sess: &Session) - -> (Level, LintSource) - { + fn get_lint_level( + &self, + lint: &'static Lint, + idx: u32, + aux: Option<&FxHashMap>, + sess: &Session, + ) -> (Level, LintSource) { let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx, aux); // If `level` is none then we actually assume the default level for this @@ -100,9 +95,7 @@ impl LintLevelSets { // `allow(warnings)` in scope then we want to respect that instead. if level == Level::Warn { let (warnings_level, warnings_src) = - self.get_lint_id_level(LintId::of(lint::builtin::WARNINGS), - idx, - aux); + self.get_lint_id_level(LintId::of(lint::builtin::WARNINGS), idx, aux); if let Some(configured_warning_level) = warnings_level { if configured_warning_level != Level::Warn { level = configured_warning_level; @@ -119,31 +112,31 @@ impl LintLevelSets { level = cmp::min(*driver_level, level); } - return (level, src) + return (level, src); } - fn get_lint_id_level(&self, - id: LintId, - mut idx: u32, - aux: Option<&FxHashMap>) - -> (Option, LintSource) - { + fn get_lint_id_level( + &self, + id: LintId, + mut idx: u32, + aux: Option<&FxHashMap>, + ) -> (Option, LintSource) { if let Some(specs) = aux { if let Some(&(level, src)) = specs.get(&id) { - return (Some(level), src) + return (Some(level), src); } } loop { match self.list[idx as usize] { LintSet::CommandLine { ref specs } => { if let Some(&(level, src)) = specs.get(&id) { - return (Some(level), src) + return (Some(level), src); } - return (None, LintSource::Default) + return (None, LintSource::Default); } LintSet::Node { ref specs, parent } => { if let Some(&(level, src)) = specs.get(&id) { - return (Some(level), src) + return (Some(level), src); } idx = parent; } @@ -198,9 +191,7 @@ impl<'a> LintLevelsBuilder<'a> { pub fn push(&mut self, attrs: &[ast::Attribute], store: &LintStore) -> BuilderPush { let mut specs = FxHashMap::default(); let sess = self.sess; - let bad_attr = |span| { - struct_span_err!(sess, span, E0452, "malformed lint attribute input") - }; + let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input"); for attr in attrs { let level = match Level::from_symbol(attr.name_or_empty()) { None => continue, @@ -220,14 +211,14 @@ impl<'a> LintLevelsBuilder<'a> { // Before processing the lint names, look for a reason (RFC 2383) // at the end. let mut reason = None; - let tail_li = &metas[metas.len()-1]; + let tail_li = &metas[metas.len() - 1]; if let Some(item) = tail_li.meta_item() { match item.kind { - ast::MetaItemKind::Word => {} // actual lint names handled later + ast::MetaItemKind::Word => {} // actual lint names handled later ast::MetaItemKind::NameValue(ref name_value) => { if item.path == sym::reason { // found reason, reslice meta list to exclude it - metas = &metas[0..metas.len()-1]; + metas = &metas[0..metas.len() - 1]; // FIXME (#55112): issue unused-attributes lint if we thereby // don't have any lint names (`#[level(reason = "foo")]`) if let ast::LitKind::Str(rationale, _) = name_value.kind { @@ -236,7 +227,7 @@ impl<'a> LintLevelsBuilder<'a> { &self.sess.parse_sess, sym::lint_reasons, item.span, - "lint reasons are experimental" + "lint reasons are experimental", ) .emit(); } @@ -251,11 +242,9 @@ impl<'a> LintLevelsBuilder<'a> { .span_label(item.span, "bad attribute argument") .emit(); } - }, + } ast::MetaItemKind::List(_) => { - bad_attr(item.span) - .span_label(item.span, "bad attribute argument") - .emit(); + bad_attr(item.span).span_label(item.span, "bad attribute argument").emit(); } } } @@ -313,7 +302,9 @@ impl<'a> LintLevelsBuilder<'a> { Ok(ids) => { let complete_name = &format!("{}::{}", tool_name.unwrap(), name); let src = LintSource::Node( - Symbol::intern(complete_name), li.span(), reason + Symbol::intern(complete_name), + li.span(), + reason, ); for id in ids { specs.insert(*id, (level, src)); @@ -322,8 +313,7 @@ impl<'a> LintLevelsBuilder<'a> { Err((Some(ids), new_lint_name)) => { let lint = builtin::RENAMED_AND_REMOVED_LINTS; let (lvl, src) = - self.sets - .get_lint_level(lint, self.cur, Some(&specs), &sess); + self.sets.get_lint_level(lint, self.cur, Some(&specs), &sess); let msg = format!( "lint name `{}` is deprecated \ and may not have an effect in the future. \ @@ -337,15 +327,19 @@ impl<'a> LintLevelsBuilder<'a> { src, Some(li.span().into()), &msg, - ).span_suggestion( + ) + .span_suggestion( li.span(), "change it to", new_lint_name.to_string(), Applicability::MachineApplicable, - ).emit(); + ) + .emit(); let src = LintSource::Node( - Symbol::intern(&new_lint_name), li.span(), reason + Symbol::intern(&new_lint_name), + li.span(), + reason, ); for id in ids { specs.insert(*id, (level, src)); @@ -364,39 +358,39 @@ impl<'a> LintLevelsBuilder<'a> { CheckLintNameResult::Warning(msg, renamed) => { let lint = builtin::RENAMED_AND_REMOVED_LINTS; - let (level, src) = self.sets.get_lint_level(lint, - self.cur, - Some(&specs), - &sess); - let mut err = lint::struct_lint_level(self.sess, - lint, - level, - src, - Some(li.span().into()), - &msg); + let (level, src) = + self.sets.get_lint_level(lint, self.cur, Some(&specs), &sess); + let mut err = lint::struct_lint_level( + self.sess, + lint, + level, + src, + Some(li.span().into()), + &msg, + ); if let Some(new_name) = renamed { err.span_suggestion( li.span(), "use the new name", new_name, - Applicability::MachineApplicable + Applicability::MachineApplicable, ); } err.emit(); } CheckLintNameResult::NoLint(suggestion) => { let lint = builtin::UNKNOWN_LINTS; - let (level, src) = self.sets.get_lint_level(lint, - self.cur, - Some(&specs), - self.sess); + let (level, src) = + self.sets.get_lint_level(lint, self.cur, Some(&specs), self.sess); let msg = format!("unknown lint: `{}`", name); - let mut db = lint::struct_lint_level(self.sess, - lint, - level, - src, - Some(li.span().into()), - &msg); + let mut db = lint::struct_lint_level( + self.sess, + lint, + level, + src, + Some(li.span().into()), + &msg, + ); if let Some(suggestion) = suggestion { db.span_suggestion( @@ -415,7 +409,7 @@ impl<'a> LintLevelsBuilder<'a> { for (id, &(level, ref src)) in specs.iter() { if level == Level::Forbid { - continue + continue; } let forbid_src = match self.sets.get_lint_id_level(*id, self.cur, None) { (Some(Level::Forbid), src) => src, @@ -430,45 +424,40 @@ impl<'a> LintLevelsBuilder<'a> { LintSource::Node(name, span, _) => (name, span), _ => continue, }; - let mut diag_builder = struct_span_err!(self.sess, - lint_attr_span, - E0453, - "{}({}) overruled by outer forbid({})", - level.as_str(), - lint_attr_name, - forbidden_lint_name); + let mut diag_builder = struct_span_err!( + self.sess, + lint_attr_span, + E0453, + "{}({}) overruled by outer forbid({})", + level.as_str(), + lint_attr_name, + forbidden_lint_name + ); diag_builder.span_label(lint_attr_span, "overruled by previous forbid"); match forbid_src { - LintSource::Default => {}, + LintSource::Default => {} LintSource::Node(_, forbid_source_span, reason) => { - diag_builder.span_label(forbid_source_span, - "`forbid` level set here"); + diag_builder.span_label(forbid_source_span, "`forbid` level set here"); if let Some(rationale) = reason { diag_builder.note(&rationale.as_str()); } - }, + } LintSource::CommandLine(_) => { diag_builder.note("`forbid` lint level was set on command line"); } } diag_builder.emit(); // don't set a separate error for every lint in the group - break + break; } let prev = self.cur; if specs.len() > 0 { self.cur = self.sets.list.len() as u32; - self.sets.list.push(LintSet::Node { - specs: specs, - parent: prev, - }); + self.sets.list.push(LintSet::Node { specs: specs, parent: prev }); } - BuilderPush { - prev: prev, - changed: prev != self.cur, - } + BuilderPush { prev: prev, changed: prev != self.cur } } /// Called after `push` when the scope of a set of attributes are exited. @@ -478,12 +467,12 @@ impl<'a> LintLevelsBuilder<'a> { /// Used to emit a lint-related diagnostic based on the current state of /// this lint context. - pub fn struct_lint(&self, - lint: &'static Lint, - span: Option, - msg: &str) - -> DiagnosticBuilder<'a> - { + pub fn struct_lint( + &self, + lint: &'static Lint, + span: Option, + msg: &str, + ) -> DiagnosticBuilder<'a> { let (level, src) = self.sets.get_lint_level(lint, self.cur, None, self.sess); lint::struct_lint_level(self.sess, lint, level, src, span, msg) } @@ -499,10 +488,7 @@ impl<'a> LintLevelsBuilder<'a> { } pub fn build_map(self) -> LintLevelMap { - LintLevelMap { - sets: self.sets, - id_to_set: self.id_to_set, - } + LintLevelMap { sets: self.sets, id_to_set: self.id_to_set } } } @@ -519,29 +505,24 @@ impl LintLevelMap { /// If the `id` was not previously registered, returns `None`. If `None` is /// returned then the parent of `id` should be acquired and this function /// should be called again. - pub fn level_and_source(&self, lint: &'static Lint, id: HirId, session: &Session) - -> Option<(Level, LintSource)> - { - self.id_to_set.get(&id).map(|idx| { - self.sets.get_lint_level(lint, *idx, None, session) - }) + pub fn level_and_source( + &self, + lint: &'static Lint, + id: HirId, + session: &Session, + ) -> Option<(Level, LintSource)> { + self.id_to_set.get(&id).map(|idx| self.sets.get_lint_level(lint, *idx, None, session)) } } impl<'a> HashStable> for LintLevelMap { #[inline] fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let LintLevelMap { - ref sets, - ref id_to_set, - } = *self; + let LintLevelMap { ref sets, ref id_to_set } = *self; id_to_set.hash_stable(hcx, hasher); - let LintLevelSets { - ref list, - lint_cap, - } = *sets; + let LintLevelSets { ref list, lint_cap } = *sets; lint_cap.hash_stable(hcx, hasher); diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 324b01316fa4a..9dd913ab34588 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -5,23 +5,23 @@ use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use crate::hir::map as hir_map; use crate::hir::map::definitions::{DefKey, DefPathTable}; -use rustc_data_structures::svh::Svh; -use crate::ty::{self, TyCtxt}; -use crate::session::{Session, CrateDisambiguator}; use crate::session::search_paths::PathKind; +use crate::session::{CrateDisambiguator, Session}; +use crate::ty::{self, TyCtxt}; +use rustc_data_structures::svh::Svh; +use rustc_data_structures::sync::{self, MetadataRef}; +use rustc_macros::HashStable; +use rustc_target::spec::Target; use std::any::Any; use std::path::{Path, PathBuf}; use syntax::ast; +use syntax::expand::allocator::AllocatorKind; use syntax::symbol::Symbol; use syntax_pos::Span; -use syntax::expand::allocator::AllocatorKind; -use rustc_target::spec::Target; -use rustc_data_structures::sync::{self, MetadataRef}; -use rustc_macros::HashStable; -pub use rustc_session::utils::NativeLibraryKind; pub use self::NativeLibraryKind::*; +pub use rustc_session::utils::NativeLibraryKind; // lonely orphan structs and enums looking for a better home @@ -40,8 +40,18 @@ impl CrateSource { } } -#[derive(RustcEncodable, RustcDecodable, Copy, Clone, - Ord, PartialOrd, Eq, PartialEq, Debug, HashStable)] +#[derive( + RustcEncodable, + RustcDecodable, + Copy, + Clone, + Ord, + PartialOrd, + Eq, + PartialEq, + Debug, + HashStable +)] pub enum DepKind { /// A dependency that is only used for its macros, none of which are visible from other crates. /// These are included in the metadata only as placeholders and are ignored when decoding. @@ -74,11 +84,7 @@ pub enum LibSource { impl LibSource { pub fn is_some(&self) -> bool { - if let LibSource::Some(_) = *self { - true - } else { - false - } + if let LibSource::Some(_) = *self { true } else { false } } pub fn option(&self) -> Option { @@ -155,14 +161,12 @@ pub enum ExternCrateSource { } pub struct EncodedMetadata { - pub raw_data: Vec + pub raw_data: Vec, } impl EncodedMetadata { pub fn new() -> EncodedMetadata { - EncodedMetadata { - raw_data: Vec::new(), - } + EncodedMetadata { raw_data: Vec::new() } } } @@ -175,14 +179,8 @@ impl EncodedMetadata { /// metadata in library -- this trait just serves to decouple rustc_metadata from /// the archive reader, which depends on LLVM. pub trait MetadataLoader { - fn get_rlib_metadata(&self, - target: &Target, - filename: &Path) - -> Result; - fn get_dylib_metadata(&self, - target: &Target, - filename: &Path) - -> Result; + fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result; + fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result; } pub type MetadataLoaderDyn = dyn MetadataLoader + Sync; @@ -234,12 +232,13 @@ pub type CrateStoreDyn = dyn CrateStore + sync::Sync; // topological sort of all crates putting the leaves at the right-most // positions. pub fn used_crates(tcx: TyCtxt<'_>, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> { - let mut libs = tcx.crates() + let mut libs = tcx + .crates() .iter() .cloned() .filter_map(|cnum| { if tcx.dep_kind(cnum).macros_only() { - return None + return None; } let source = tcx.used_crate_source(cnum); let path = match prefer { @@ -261,8 +260,6 @@ pub fn used_crates(tcx: TyCtxt<'_>, prefer: LinkagePreference) -> Vec<(CrateNum, .collect::>(); let mut ordering = tcx.postorder_cnums(LOCAL_CRATE).to_owned(); ordering.reverse(); - libs.sort_by_cached_key(|&(a, _)| { - ordering.iter().position(|x| *x == a) - }); + libs.sort_by_cached_key(|&(a, _)| ordering.iter().position(|x| *x == a)); libs } diff --git a/src/librustc/middle/diagnostic_items.rs b/src/librustc/middle/diagnostic_items.rs index 96faf567463bf..32ef1338712bb 100644 --- a/src/librustc/middle/diagnostic_items.rs +++ b/src/librustc/middle/diagnostic_items.rs @@ -13,10 +13,10 @@ use crate::hir::def_id::{DefId, LOCAL_CRATE}; use crate::ty::TyCtxt; use crate::util::nodemap::FxHashMap; -use syntax::ast; -use syntax::symbol::{Symbol, sym}; -use crate::hir::itemlikevisit::ItemLikeVisitor; use crate::hir; +use crate::hir::itemlikevisit::ItemLikeVisitor; +use syntax::ast; +use syntax::symbol::{sym, Symbol}; struct DiagnosticItemCollector<'tcx> { // items from this crate @@ -40,10 +40,7 @@ impl<'v, 'tcx> ItemLikeVisitor<'v> for DiagnosticItemCollector<'tcx> { impl<'tcx> DiagnosticItemCollector<'tcx> { fn new(tcx: TyCtxt<'tcx>) -> DiagnosticItemCollector<'tcx> { - DiagnosticItemCollector { - tcx, - items: Default::default(), - } + DiagnosticItemCollector { tcx, items: Default::default() } } fn observe_item(&mut self, attrs: &[ast::Attribute], hir_id: hir::HirId) { @@ -67,17 +64,21 @@ fn collect_item( let mut err = match tcx.hir().span_if_local(item_def_id) { Some(span) => tcx.sess.struct_span_err( span, - &format!("duplicate diagnostic item found: `{}`.", name)), + &format!("duplicate diagnostic item found: `{}`.", name), + ), None => tcx.sess.struct_err(&format!( - "duplicate diagnostic item in crate `{}`: `{}`.", - tcx.crate_name(item_def_id.krate), - name)), + "duplicate diagnostic item in crate `{}`: `{}`.", + tcx.crate_name(item_def_id.krate), + name + )), }; if let Some(span) = tcx.hir().span_if_local(original_def_id) { span_note!(&mut err, span, "first defined here."); } else { - err.note(&format!("first defined in crate `{}`.", - tcx.crate_name(original_def_id.krate))); + err.note(&format!( + "first defined in crate `{}`.", + tcx.crate_name(original_def_id.krate) + )); } err.emit(); } @@ -87,11 +88,7 @@ fn collect_item( /// Extract the first `rustc_diagnostic_item = "$name"` out of a list of attributes. fn extract(attrs: &[ast::Attribute]) -> Option { attrs.iter().find_map(|attr| { - if attr.check_name(sym::rustc_diagnostic_item) { - attr.value_str() - } else { - None - } + if attr.check_name(sym::rustc_diagnostic_item) { attr.value_str() } else { None } }) } @@ -106,7 +103,6 @@ pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> &'tcx FxHashMap { tcx.arena.alloc(collector.items) } - /// Traverse and collect all the diagnostic items in all crates. pub fn collect_all<'tcx>(tcx: TyCtxt<'tcx>) -> &'tcx FxHashMap { // Initialize the collector. diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs index 7182f03182402..756af9be6573f 100644 --- a/src/librustc/middle/exported_symbols.rs +++ b/src/librustc/middle/exported_symbols.rs @@ -1,10 +1,10 @@ use crate::hir::def_id::{DefId, LOCAL_CRATE}; use crate::ich::StableHashingContext; -use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; +use crate::ty::subst::SubstsRef; +use crate::ty::{self, TyCtxt}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use std::cmp; use std::mem; -use crate::ty::{self, TyCtxt}; -use crate::ty::subst::SubstsRef; /// The SymbolExportLevel of a symbols specifies from which kinds of crates /// the symbol will be exported. `C` symbols will be exported from any @@ -34,15 +34,11 @@ pub enum ExportedSymbol<'tcx> { impl<'tcx> ExportedSymbol<'tcx> { pub fn symbol_name(&self, tcx: TyCtxt<'tcx>) -> ty::SymbolName { match *self { - ExportedSymbol::NonGeneric(def_id) => { - tcx.symbol_name(ty::Instance::mono(tcx, def_id)) - } + ExportedSymbol::NonGeneric(def_id) => tcx.symbol_name(ty::Instance::mono(tcx, def_id)), ExportedSymbol::Generic(def_id, substs) => { tcx.symbol_name(ty::Instance::new(def_id, substs)) } - ExportedSymbol::NoDefId(symbol_name) => { - symbol_name - } + ExportedSymbol::NoDefId(symbol_name) => symbol_name, } } @@ -52,39 +48,31 @@ impl<'tcx> ExportedSymbol<'tcx> { ExportedSymbol::NonGeneric(other_def_id) => { tcx.def_path_hash(self_def_id).cmp(&tcx.def_path_hash(other_def_id)) } - ExportedSymbol::Generic(..) | - ExportedSymbol::NoDefId(_) => { - cmp::Ordering::Less - } - } + ExportedSymbol::Generic(..) | ExportedSymbol::NoDefId(_) => cmp::Ordering::Less, + }, ExportedSymbol::Generic(..) => match *other { - ExportedSymbol::NonGeneric(_) => { - cmp::Ordering::Greater - } - ExportedSymbol::Generic(..) => { - self.symbol_name(tcx).cmp(&other.symbol_name(tcx)) - } - ExportedSymbol::NoDefId(_) => { - cmp::Ordering::Less - } - } + ExportedSymbol::NonGeneric(_) => cmp::Ordering::Greater, + ExportedSymbol::Generic(..) => self.symbol_name(tcx).cmp(&other.symbol_name(tcx)), + ExportedSymbol::NoDefId(_) => cmp::Ordering::Less, + }, ExportedSymbol::NoDefId(self_symbol_name) => match *other { - ExportedSymbol::NonGeneric(_) | - ExportedSymbol::Generic(..) => { + ExportedSymbol::NonGeneric(_) | ExportedSymbol::Generic(..) => { cmp::Ordering::Greater } ExportedSymbol::NoDefId(ref other_symbol_name) => { self_symbol_name.cmp(other_symbol_name) } - } + }, } } } pub fn metadata_symbol_name(tcx: TyCtxt<'_>) -> String { - format!("rust_metadata_{}_{}", - tcx.original_crate_name(LOCAL_CRATE), - tcx.crate_disambiguator(LOCAL_CRATE).to_fingerprint().to_hex()) + format!( + "rust_metadata_{}_{}", + tcx.original_crate_name(LOCAL_CRATE), + tcx.crate_disambiguator(LOCAL_CRATE).to_fingerprint().to_hex() + ) } impl<'a, 'tcx> HashStable> for ExportedSymbol<'tcx> { diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs index 60e41f7eb0f7b..e6c51cc7c0844 100644 --- a/src/librustc/middle/free_region.rs +++ b/src/librustc/middle/free_region.rs @@ -3,10 +3,10 @@ //! or explicit bounds. In that case, we track the bounds using the `TransitiveRelation` type, //! and use that to decide when one free region outlives another, and so forth. -use crate::infer::outlives::free_region_map::{FreeRegionMap, FreeRegionRelations}; use crate::hir::def_id::DefId; +use crate::infer::outlives::free_region_map::{FreeRegionMap, FreeRegionRelations}; use crate::middle::region; -use crate::ty::{self, TyCtxt, Region}; +use crate::ty::{self, Region, TyCtxt}; /// Combines a `region::ScopeTree` (which governs relationships between /// scopes) and a `FreeRegionMap` (which governs relationships between @@ -35,28 +35,23 @@ impl<'a, 'tcx> RegionRelations<'a, 'tcx> { region_scope_tree: &'a region::ScopeTree, free_regions: &'a FreeRegionMap<'tcx>, ) -> Self { - Self { - tcx, - context, - region_scope_tree, - free_regions, - } + Self { tcx, context, region_scope_tree, free_regions } } /// Determines whether one region is a subregion of another. This is intended to run *after /// inference* and sadly the logic is somewhat duplicated with the code in infer.rs. - pub fn is_subregion_of(&self, - sub_region: ty::Region<'tcx>, - super_region: ty::Region<'tcx>) - -> bool { + pub fn is_subregion_of( + &self, + sub_region: ty::Region<'tcx>, + super_region: ty::Region<'tcx>, + ) -> bool { let result = sub_region == super_region || { match (sub_region, super_region) { - (ty::ReEmpty, _) | - (_, ty::ReStatic) => - true, + (ty::ReEmpty, _) | (_, ty::ReStatic) => true, - (ty::ReScope(sub_scope), ty::ReScope(super_scope)) => - self.region_scope_tree.is_subscope_of(*sub_scope, *super_scope), + (ty::ReScope(sub_scope), ty::ReScope(super_scope)) => { + self.region_scope_tree.is_subscope_of(*sub_scope, *super_scope) + } (ty::ReScope(sub_scope), ty::ReEarlyBound(ref br)) => { let fr_scope = self.region_scope_tree.early_free_scope(self.tcx, br); @@ -68,19 +63,21 @@ impl<'a, 'tcx> RegionRelations<'a, 'tcx> { self.region_scope_tree.is_subscope_of(*sub_scope, fr_scope) } - (ty::ReEarlyBound(_), ty::ReEarlyBound(_)) | - (ty::ReFree(_), ty::ReEarlyBound(_)) | - (ty::ReEarlyBound(_), ty::ReFree(_)) | - (ty::ReFree(_), ty::ReFree(_)) => - self.free_regions.sub_free_regions(sub_region, super_region), + (ty::ReEarlyBound(_), ty::ReEarlyBound(_)) + | (ty::ReFree(_), ty::ReEarlyBound(_)) + | (ty::ReEarlyBound(_), ty::ReFree(_)) + | (ty::ReFree(_), ty::ReFree(_)) => { + self.free_regions.sub_free_regions(sub_region, super_region) + } - _ => - false, + _ => false, } }; let result = result || self.is_static(super_region); - debug!("is_subregion_of(sub_region={:?}, super_region={:?}) = {:?}", - sub_region, super_region, result); + debug!( + "is_subregion_of(sub_region={:?}, super_region={:?}) = {:?}", + sub_region, super_region, result + ); result } @@ -93,14 +90,11 @@ impl<'a, 'tcx> RegionRelations<'a, 'tcx> { let re_static = self.tcx.mk_region(ty::ReStatic); self.free_regions.sub_free_regions(&re_static, &super_region) } - _ => false + _ => false, } } - pub fn lub_free_regions(&self, - r_a: Region<'tcx>, - r_b: Region<'tcx>) - -> Region<'tcx> { + pub fn lub_free_regions(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> Region<'tcx> { self.free_regions.lub_free_regions(self.tcx, r_a, r_b) } } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index d87eec0586614..5881b82f7549e 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -9,19 +9,19 @@ pub use self::LangItem::*; -use crate::hir::def_id::DefId; use crate::hir::check_attr::Target; -use crate::ty::{self, TyCtxt}; -use crate::middle::weak_lang_items; +use crate::hir::def_id::DefId; use crate::middle::cstore::ExternCrate; +use crate::middle::weak_lang_items; +use crate::ty::{self, TyCtxt}; use crate::util::nodemap::FxHashMap; +use crate::hir; +use crate::hir::itemlikevisit::ItemLikeVisitor; +use rustc_macros::HashStable; use syntax::ast; -use syntax::symbol::{Symbol, sym}; +use syntax::symbol::{sym, Symbol}; use syntax_pos::Span; -use rustc_macros::HashStable; -use crate::hir::itemlikevisit::ItemLikeVisitor; -use crate::hir; use rustc_error_codes::*; diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs index c38ab525ce455..b4ddb09861df5 100644 --- a/src/librustc/middle/lib_features.rs +++ b/src/librustc/middle/lib_features.rs @@ -4,13 +4,13 @@ // and `#[unstable (..)]`), but are not declared in one single location // (unlike lang features), which means we need to collect them instead. -use crate::ty::TyCtxt; use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; -use syntax::symbol::Symbol; -use syntax::ast::{Attribute, MetaItem, MetaItemKind}; -use syntax_pos::{Span, sym}; -use rustc_data_structures::fx::{FxHashSet, FxHashMap}; +use crate::ty::TyCtxt; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_macros::HashStable; +use syntax::ast::{Attribute, MetaItem, MetaItemKind}; +use syntax::symbol::Symbol; +use syntax_pos::{sym, Span}; use rustc_error_codes::*; @@ -23,14 +23,14 @@ pub struct LibFeatures { impl LibFeatures { fn new() -> LibFeatures { - LibFeatures { - stable: Default::default(), - unstable: Default::default(), - } + LibFeatures { stable: Default::default(), unstable: Default::default() } } pub fn to_vec(&self) -> Vec<(Symbol, Option)> { - let mut all_features: Vec<_> = self.stable.iter().map(|(f, s)| (*f, Some(*s))) + let mut all_features: Vec<_> = self + .stable + .iter() + .map(|(f, s)| (*f, Some(*s))) .chain(self.unstable.iter().map(|f| (*f, None))) .collect(); all_features.sort_unstable_by_key(|f| f.0.as_str()); @@ -45,10 +45,7 @@ pub struct LibFeatureCollector<'tcx> { impl LibFeatureCollector<'tcx> { fn new(tcx: TyCtxt<'tcx>) -> LibFeatureCollector<'tcx> { - LibFeatureCollector { - tcx, - lib_features: LibFeatures::new(), - } + LibFeatureCollector { tcx, lib_features: LibFeatures::new() } } fn extract(&self, attr: &Attribute) -> Option<(Symbol, Option, Span)> { @@ -56,9 +53,7 @@ impl LibFeatureCollector<'tcx> { // Find a stability attribute (i.e., `#[stable (..)]`, `#[unstable (..)]`, // `#[rustc_const_unstable (..)]`). - if let Some(stab_attr) = stab_attrs.iter().find(|stab_attr| { - attr.check_name(**stab_attr) - }) { + if let Some(stab_attr) = stab_attrs.iter().find(|stab_attr| attr.check_name(**stab_attr)) { let meta_item = attr.meta(); if let Some(MetaItem { kind: MetaItemKind::List(ref metas), .. }) = meta_item { let mut feature = None; @@ -104,9 +99,7 @@ impl LibFeatureCollector<'tcx> { &format!( "feature `{}` is declared stable since {}, \ but was previously declared stable since {}", - feature, - since, - prev_since, + feature, since, prev_since, ), ); return; @@ -133,12 +126,7 @@ impl LibFeatureCollector<'tcx> { } fn span_feature_error(&self, span: Span, msg: &str) { - struct_span_err!( - self.tcx.sess, - span, - E0711, - "{}", &msg, - ).emit(); + struct_span_err!(self.tcx.sess, span, E0711, "{}", &msg,).emit(); } } diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 787ff8d48c119..fc48999115e86 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -5,9 +5,9 @@ use crate::hir::HirId; use crate::util::nodemap::{DefIdSet, FxHashMap}; -use std::hash::Hash; -use std::fmt; use rustc_macros::HashStable; +use std::fmt; +use std::hash::Hash; // Accessibility levels, sorted in ascending order #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, HashStable)] @@ -28,7 +28,7 @@ pub enum AccessLevel { // Accessibility levels for reachable HIR nodes #[derive(Clone)] pub struct AccessLevels { - pub map: FxHashMap + pub map: FxHashMap, } impl AccessLevels { diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 6746df6c7ded1..22af74c1361b2 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -5,39 +5,38 @@ // makes all other generics or inline functions that it references // reachable as well. -use crate::hir::{CodegenFnAttrs, CodegenFnAttrFlags}; +use crate::hir::def::{DefKind, Res}; +use crate::hir::def_id::{CrateNum, DefId}; use crate::hir::Node; -use crate::hir::def::{Res, DefKind}; -use crate::hir::def_id::{DefId, CrateNum}; -use rustc_data_structures::sync::Lrc; -use crate::ty::{self, TyCtxt}; -use crate::ty::query::Providers; +use crate::hir::{CodegenFnAttrFlags, CodegenFnAttrs}; use crate::middle::privacy; use crate::session::config; -use crate::util::nodemap::{HirIdSet, FxHashSet}; +use crate::ty::query::Providers; +use crate::ty::{self, TyCtxt}; +use crate::util::nodemap::{FxHashSet, HirIdSet}; +use rustc_data_structures::sync::Lrc; -use rustc_target::spec::abi::Abi; -use rustc_macros::HashStable; use crate::hir; use crate::hir::def_id::LOCAL_CRATE; -use crate::hir::intravisit::{Visitor, NestedVisitorMap}; -use crate::hir::itemlikevisit::ItemLikeVisitor; use crate::hir::intravisit; +use crate::hir::intravisit::{NestedVisitorMap, Visitor}; +use crate::hir::itemlikevisit::ItemLikeVisitor; +use rustc_macros::HashStable; +use rustc_target::spec::abi::Abi; // Returns true if the given item must be inlined because it may be // monomorphized or it was marked with `#[inline]`. This will only return // true for functions. fn item_might_be_inlined(tcx: TyCtxt<'tcx>, item: &hir::Item<'_>, attrs: CodegenFnAttrs) -> bool { if attrs.requests_inline() { - return true + return true; } match item.kind { hir::ItemKind::Fn(ref sig, ..) if sig.header.is_const() => { return true; } - hir::ItemKind::Impl(..) | - hir::ItemKind::Fn(..) => { + hir::ItemKind::Impl(..) | hir::ItemKind::Fn(..) => { let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id)); generics.requires_monomorphization(tcx) } @@ -53,19 +52,17 @@ fn method_might_be_inlined( let codegen_fn_attrs = tcx.codegen_fn_attrs(impl_item.hir_id.owner_def_id()); let generics = tcx.generics_of(tcx.hir().local_def_id(impl_item.hir_id)); if codegen_fn_attrs.requests_inline() || generics.requires_monomorphization(tcx) { - return true + return true; } if let hir::ImplItemKind::Method(method_sig, _) = &impl_item.kind { if method_sig.header.is_const() { - return true + return true; } } if let Some(impl_hir_id) = tcx.hir().as_local_hir_id(impl_src) { match tcx.hir().find(impl_hir_id) { - Some(Node::Item(item)) => - item_might_be_inlined(tcx, &item, codegen_fn_attrs), - Some(..) | None => - span_bug!(impl_item.span, "impl did is not an item") + Some(Node::Item(item)) => item_might_be_inlined(tcx, &item, codegen_fn_attrs), + Some(..) | None => span_bug!(impl_item.span, "impl did is not an item"), } } else { span_bug!(impl_item.span, "found a foreign impl as a parent of a local method") @@ -101,14 +98,12 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr) { let res = match expr.kind { - hir::ExprKind::Path(ref qpath) => { - Some(self.tables.qpath_res(qpath, expr.hir_id)) - } - hir::ExprKind::MethodCall(..) => { - self.tables.type_dependent_def(expr.hir_id) - .map(|(kind, def_id)| Res::Def(kind, def_id)) - } - _ => None + hir::ExprKind::Path(ref qpath) => Some(self.tables.qpath_res(qpath, expr.hir_id)), + hir::ExprKind::MethodCall(..) => self + .tables + .type_dependent_def(expr.hir_id) + .map(|(kind, def_id)| Res::Def(kind, def_id)), + _ => None, }; match res { @@ -152,25 +147,24 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { fn def_id_represents_local_inlined_item(&self, def_id: DefId) -> bool { let hir_id = match self.tcx.hir().as_local_hir_id(def_id) { Some(hir_id) => hir_id, - None => { return false; } + None => { + return false; + } }; match self.tcx.hir().find(hir_id) { - Some(Node::Item(item)) => { - match item.kind { - hir::ItemKind::Fn(..) => - item_might_be_inlined(self.tcx, &item, self.tcx.codegen_fn_attrs(def_id)), - _ => false, + Some(Node::Item(item)) => match item.kind { + hir::ItemKind::Fn(..) => { + item_might_be_inlined(self.tcx, &item, self.tcx.codegen_fn_attrs(def_id)) } - } - Some(Node::TraitItem(trait_method)) => { - match trait_method.kind { - hir::TraitItemKind::Const(_, ref default) => default.is_some(), - hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(_)) => true, - hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) | - hir::TraitItemKind::Type(..) => false, - } - } + _ => false, + }, + Some(Node::TraitItem(trait_method)) => match trait_method.kind { + hir::TraitItemKind::Const(_, ref default) => default.is_some(), + hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(_)) => true, + hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) + | hir::TraitItemKind::Type(..) => false, + }, Some(Node::ImplItem(impl_item)) => { match impl_item.kind { hir::ImplItemKind::Const(..) => true, @@ -180,9 +174,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { if generics.requires_monomorphization(self.tcx) || attrs.requests_inline() { true } else { - let impl_did = self.tcx - .hir() - .get_parent_did(hir_id); + let impl_did = self.tcx.hir().get_parent_did(hir_id); // Check the impl. If the generics on the self // type of the impl require inlining, this method // does too. @@ -192,16 +184,15 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { let generics = self.tcx.generics_of(impl_did); generics.requires_monomorphization(self.tcx) } - _ => false + _ => false, } } } - hir::ImplItemKind::OpaqueTy(..) | - hir::ImplItemKind::TyAlias(_) => false, + hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => false, } } Some(_) => false, - None => false // This will happen for default methods. + None => false, // This will happen for default methods. } } @@ -210,7 +201,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { let mut scanned = FxHashSet::default(); while let Some(search_item) = self.worklist.pop() { if !scanned.insert(search_item) { - continue + continue; } if let Some(ref item) = self.tcx.hir().find(search_item) { @@ -219,8 +210,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { } } - fn propagate_node(&mut self, node: &Node<'tcx>, - search_item: hir::HirId) { + fn propagate_node(&mut self, node: &Node<'tcx>, search_item: hir::HirId) { if !self.any_library { // If we are building an executable, only explicitly extern // types need to be exported. @@ -233,8 +223,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { let def_id = self.tcx.hir().local_def_id(item.hir_id); let codegen_attrs = self.tcx.codegen_fn_attrs(def_id); let is_extern = codegen_attrs.contains_extern_indicator(); - let std_internal = codegen_attrs.flags.contains( - CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); + let std_internal = + codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); if reachable || is_extern || std_internal { self.reachable_symbols.insert(search_item); } @@ -252,9 +242,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { match item.kind { hir::ItemKind::Fn(.., body) => { let def_id = self.tcx.hir().local_def_id(item.hir_id); - if item_might_be_inlined(self.tcx, - &item, - self.tcx.codegen_fn_attrs(def_id)) { + if item_might_be_inlined(self.tcx, &item, self.tcx.codegen_fn_attrs(def_id)) + { self.visit_nested_body(body); } } @@ -269,60 +258,57 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { // These are normal, nothing reachable about these // inherently and their children are already in the // worklist, as determined by the privacy pass - hir::ItemKind::ExternCrate(_) | - hir::ItemKind::Use(..) | - hir::ItemKind::OpaqueTy(..) | - hir::ItemKind::TyAlias(..) | - hir::ItemKind::Static(..) | - hir::ItemKind::Mod(..) | - hir::ItemKind::ForeignMod(..) | - hir::ItemKind::Impl(..) | - hir::ItemKind::Trait(..) | - hir::ItemKind::TraitAlias(..) | - hir::ItemKind::Struct(..) | - hir::ItemKind::Enum(..) | - hir::ItemKind::Union(..) | - hir::ItemKind::GlobalAsm(..) => {} + hir::ItemKind::ExternCrate(_) + | hir::ItemKind::Use(..) + | hir::ItemKind::OpaqueTy(..) + | hir::ItemKind::TyAlias(..) + | hir::ItemKind::Static(..) + | hir::ItemKind::Mod(..) + | hir::ItemKind::ForeignMod(..) + | hir::ItemKind::Impl(..) + | hir::ItemKind::Trait(..) + | hir::ItemKind::TraitAlias(..) + | hir::ItemKind::Struct(..) + | hir::ItemKind::Enum(..) + | hir::ItemKind::Union(..) + | hir::ItemKind::GlobalAsm(..) => {} } } Node::TraitItem(trait_method) => { match trait_method.kind { - hir::TraitItemKind::Const(_, None) | - hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) => { + hir::TraitItemKind::Const(_, None) + | hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) => { // Keep going, nothing to get exported } - hir::TraitItemKind::Const(_, Some(body_id)) | - hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(body_id)) => { + hir::TraitItemKind::Const(_, Some(body_id)) + | hir::TraitItemKind::Method(_, hir::TraitMethod::Provided(body_id)) => { self.visit_nested_body(body_id); } hir::TraitItemKind::Type(..) => {} } } - Node::ImplItem(impl_item) => { - match impl_item.kind { - hir::ImplItemKind::Const(_, body) => { - self.visit_nested_body(body); - } - hir::ImplItemKind::Method(_, body) => { - let did = self.tcx.hir().get_parent_did(search_item); - if method_might_be_inlined(self.tcx, impl_item, did) { - self.visit_nested_body(body) - } + Node::ImplItem(impl_item) => match impl_item.kind { + hir::ImplItemKind::Const(_, body) => { + self.visit_nested_body(body); + } + hir::ImplItemKind::Method(_, body) => { + let did = self.tcx.hir().get_parent_did(search_item); + if method_might_be_inlined(self.tcx, impl_item, did) { + self.visit_nested_body(body) } - hir::ImplItemKind::OpaqueTy(..) | - hir::ImplItemKind::TyAlias(_) => {} } - } + hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => {} + }, Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(.., body, _, _), .. }) => { self.visit_nested_body(body); } // Nothing to recurse on for these - Node::ForeignItem(_) | - Node::Variant(_) | - Node::Ctor(..) | - Node::Field(_) | - Node::Ty(_) | - Node::MacroDef(_) => {} + Node::ForeignItem(_) + | Node::Variant(_) + | Node::Ctor(..) + | Node::Field(_) + | Node::Ty(_) + | Node::MacroDef(_) => {} _ => { bug!( "found unexpected node kind in worklist: {} ({:?})", @@ -355,8 +341,9 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx // which are currently akin to allocator symbols. let def_id = self.tcx.hir().local_def_id(item.hir_id); let codegen_attrs = self.tcx.codegen_fn_attrs(def_id); - if codegen_attrs.contains_extern_indicator() || - codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) { + if codegen_attrs.contains_extern_indicator() + || codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) + { self.worklist.push(item.hir_id); } @@ -367,20 +354,17 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx let trait_def_id = match trait_ref.path.res { Res::Def(DefKind::Trait, def_id) => def_id, - _ => unreachable!() + _ => unreachable!(), }; if !trait_def_id.is_local() { - return + return; } let provided_trait_methods = self.tcx.provided_trait_methods(trait_def_id); self.worklist.reserve(provided_trait_methods.len()); for default_method in provided_trait_methods { - let hir_id = self.tcx - .hir() - .as_local_hir_id(default_method.def_id) - .unwrap(); + let hir_id = self.tcx.hir().as_local_hir_id(default_method.def_id).unwrap(); self.worklist.push(hir_id); } } @@ -405,8 +389,9 @@ fn reachable_set(tcx: TyCtxt<'_>, crate_num: CrateNum) -> ReachableSet { let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE); let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| { - *ty == config::CrateType::Rlib || *ty == config::CrateType::Dylib || - *ty == config::CrateType::ProcMacro + *ty == config::CrateType::Rlib + || *ty == config::CrateType::Dylib + || *ty == config::CrateType::ProcMacro }); let mut reachable_context = ReachableContext { tcx, @@ -421,8 +406,7 @@ fn reachable_set(tcx: TyCtxt<'_>, crate_num: CrateNum) -> ReachableSet { // If other crates link to us, they're going to expect to be able to // use the lang items, so we need to be sure to mark them as // exported. - reachable_context.worklist.extend( - access_levels.map.iter().map(|(id, _)| *id)); + reachable_context.worklist.extend(access_levels.map.iter().map(|(id, _)| *id)); for item in tcx.lang_items().items().iter() { if let Some(did) = *item { if let Some(hir_id) = tcx.hir().as_local_hir_id(did) { @@ -449,8 +433,5 @@ fn reachable_set(tcx: TyCtxt<'_>, crate_num: CrateNum) -> ReachableSet { } pub fn provide(providers: &mut Providers<'_>) { - *providers = Providers { - reachable_set, - ..*providers - }; + *providers = Providers { reachable_set, ..*providers }; } diff --git a/src/librustc/middle/recursion_limit.rs b/src/librustc/middle/recursion_limit.rs index 4063fee04c468..8f19494d388df 100644 --- a/src/librustc/middle/recursion_limit.rs +++ b/src/librustc/middle/recursion_limit.rs @@ -7,7 +7,7 @@ use crate::session::Session; use syntax::ast; -use syntax::symbol::{Symbol, sym}; +use syntax::symbol::{sym, Symbol}; use rustc_data_structures::sync::Once; diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index c5d5bc5811225..3e97beb7bce23 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -7,14 +7,14 @@ //! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html use crate::hir; -use crate::hir::Node; use crate::hir::def_id::DefId; -use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; -use crate::hir::{Block, Arm, Pat, PatKind, Stmt, Expr, Local}; -use crate::ich::{StableHashingContext, NodeIdHashingMode}; -use crate::util::nodemap::{FxHashMap, FxHashSet}; -use crate::ty::{self, DefIdTree, TyCtxt}; +use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; +use crate::hir::Node; +use crate::hir::{Arm, Block, Expr, Local, Pat, PatKind, Stmt}; +use crate::ich::{NodeIdHashingMode, StableHashingContext}; use crate::ty::query::Providers; +use crate::ty::{self, DefIdTree, TyCtxt}; +use crate::util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_index::vec::Idx; @@ -87,8 +87,18 @@ use std::mem; // placate the same deriving in `ty::FreeRegion`, but we may want to // actually attach a more meaningful ordering to scopes than the one // generated via deriving here. -#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Copy, - RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Clone, + PartialEq, + PartialOrd, + Eq, + Ord, + Hash, + Copy, + RustcEncodable, + RustcDecodable, + HashStable +)] pub struct Scope { pub id: hir::ItemLocalId, pub data: ScopeData, @@ -111,8 +121,19 @@ impl fmt::Debug for Scope { } } -#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Copy, - RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Clone, + PartialEq, + PartialOrd, + Eq, + Ord, + Hash, + Debug, + Copy, + RustcEncodable, + RustcDecodable, + HashStable +)] pub enum ScopeData { Node, @@ -128,7 +149,7 @@ pub enum ScopeData { Destruction, /// Scope following a `let id = expr;` binding in a block. - Remainder(FirstStatementIndex) + Remainder(FirstStatementIndex), } rustc_index::newtype_index! { @@ -168,13 +189,8 @@ impl Scope { pub fn hir_id(&self, scope_tree: &ScopeTree) -> hir::HirId { match scope_tree.root_body { - Some(hir_id) => { - hir::HirId { - owner: hir_id.owner, - local_id: self.item_local_id() - } - } - None => hir::DUMMY_HIR_ID + Some(hir_id) => hir::HirId { owner: hir_id.owner, local_id: self.item_local_id() }, + None => hir::DUMMY_HIR_ID, } } @@ -205,8 +221,8 @@ impl Scope { return Span::new(stmt_span.lo(), span.hi(), span.ctxt()); } } - } - span + } + span } } @@ -427,17 +443,13 @@ impl<'tcx> Visitor<'tcx> for ExprLocatorVisitor { } fn visit_expr(&mut self, expr: &'tcx Expr) { - debug!("ExprLocatorVisitor - pre-increment {} expr = {:?}", - self.expr_and_pat_count, - expr); + debug!("ExprLocatorVisitor - pre-increment {} expr = {:?}", self.expr_and_pat_count, expr); intravisit::walk_expr(self, expr); self.expr_and_pat_count += 1; - debug!("ExprLocatorVisitor - post-increment {} expr = {:?}", - self.expr_and_pat_count, - expr); + debug!("ExprLocatorVisitor - post-increment {} expr = {:?}", self.expr_and_pat_count, expr); if expr.hir_id == self.hir_id { self.result = Some(self.expr_and_pat_count); @@ -460,13 +472,19 @@ impl<'tcx> ScopeTree { } } - pub fn each_encl_scope(&self, mut e: E) where E: FnMut(Scope, Scope) { + pub fn each_encl_scope(&self, mut e: E) + where + E: FnMut(Scope, Scope), + { for (&child, &parent) in &self.parent_map { e(child, parent.0) } } - pub fn each_var_scope(&self, mut e: E) where E: FnMut(&hir::ItemLocalId, Scope) { + pub fn each_var_scope(&self, mut e: E) + where + E: FnMut(&hir::ItemLocalId, Scope), + { for (child, &parent) in self.var_map.iter() { e(child, parent) } @@ -479,11 +497,15 @@ impl<'tcx> ScopeTree { /// Records that `sub_closure` is defined within `sup_closure`. These IDs /// should be the ID of the block that is the fn body, which is /// also the root of the region hierarchy for that fn. - fn record_closure_parent(&mut self, - sub_closure: hir::ItemLocalId, - sup_closure: hir::ItemLocalId) { - debug!("record_closure_parent(sub_closure={:?}, sup_closure={:?})", - sub_closure, sup_closure); + fn record_closure_parent( + &mut self, + sub_closure: hir::ItemLocalId, + sup_closure: hir::ItemLocalId, + ) { + debug!( + "record_closure_parent(sub_closure={:?}, sup_closure={:?})", + sub_closure, sup_closure + ); assert!(sub_closure != sup_closure); let previous = self.closure_tree.insert(sub_closure, sup_closure); assert!(previous.is_none()); @@ -516,8 +538,10 @@ impl<'tcx> ScopeTree { /// Returns the lifetime of the local variable `var_id` pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Scope { - self.var_map.get(&var_id).cloned().unwrap_or_else(|| - bug!("no enclosing scope for id {:?}", var_id)) + self.var_map + .get(&var_id) + .cloned() + .unwrap_or_else(|| bug!("no enclosing scope for id {:?}", var_id)) } /// Returns the scope when the temp created by `expr_id` will be cleaned up. @@ -537,11 +561,10 @@ impl<'tcx> ScopeTree { while let Some(&(p, _)) = self.parent_map.get(&id) { match p.data { ScopeData::Destruction => { - debug!("temporary_scope({:?}) = {:?} [enclosing]", - expr_id, id); + debug!("temporary_scope({:?}) = {:?} [enclosing]", expr_id, id); return Some(id); } - _ => id = p + _ => id = p, } } @@ -557,26 +580,21 @@ impl<'tcx> ScopeTree { } pub fn scopes_intersect(&self, scope1: Scope, scope2: Scope) -> bool { - self.is_subscope_of(scope1, scope2) || - self.is_subscope_of(scope2, scope1) + self.is_subscope_of(scope1, scope2) || self.is_subscope_of(scope2, scope1) } /// Returns `true` if `subscope` is equal to or is lexically nested inside `superscope`, and /// `false` otherwise. - pub fn is_subscope_of(&self, - subscope: Scope, - superscope: Scope) - -> bool { + pub fn is_subscope_of(&self, subscope: Scope, superscope: Scope) -> bool { let mut s = subscope; debug!("is_subscope_of({:?}, {:?})", subscope, superscope); while superscope != s { match self.opt_encl_scope(s) { None => { - debug!("is_subscope_of({:?}, {:?}, s={:?})=false", - subscope, superscope, s); + debug!("is_subscope_of({:?}, {:?}, s={:?})=false", subscope, superscope, s); return false; } - Some(scope) => s = scope + Some(scope) => s = scope, } } @@ -600,7 +618,9 @@ impl<'tcx> ScopeTree { /// smallest scope which is greater than or equal to both `scope_a` and /// `scope_b`. pub fn nearest_common_ancestor(&self, scope_a: Scope, scope_b: Scope) -> Scope { - if scope_a == scope_b { return scope_a; } + if scope_a == scope_b { + return scope_a; + } let mut a = scope_a; let mut b = scope_b; @@ -648,7 +668,7 @@ impl<'tcx> ScopeTree { while a != b { a = self.parent_map.get(&a).unwrap().0; b = self.parent_map.get(&b).unwrap().0; - }; + } a } @@ -659,25 +679,30 @@ impl<'tcx> ScopeTree { let param_owner = tcx.parent(br.def_id).unwrap(); let param_owner_id = tcx.hir().as_local_hir_id(param_owner).unwrap(); - let scope = tcx.hir().maybe_body_owned_by(param_owner_id).map(|body_id| { - tcx.hir().body(body_id).value.hir_id.local_id - }).unwrap_or_else(|| { - // The lifetime was defined on node that doesn't own a body, - // which in practice can only mean a trait or an impl, that - // is the parent of a method, and that is enforced below. - if Some(param_owner_id) != self.root_parent { - tcx.sess.delay_span_bug( - DUMMY_SP, - &format!("free_scope: {:?} not recognized by the \ + let scope = tcx + .hir() + .maybe_body_owned_by(param_owner_id) + .map(|body_id| tcx.hir().body(body_id).value.hir_id.local_id) + .unwrap_or_else(|| { + // The lifetime was defined on node that doesn't own a body, + // which in practice can only mean a trait or an impl, that + // is the parent of a method, and that is enforced below. + if Some(param_owner_id) != self.root_parent { + tcx.sess.delay_span_bug( + DUMMY_SP, + &format!( + "free_scope: {:?} not recognized by the \ region scope tree for {:?} / {:?}", - param_owner, - self.root_parent.map(|id| tcx.hir().local_def_id(id)), - self.root_body.map(|hir_id| DefId::local(hir_id.owner)))); - } + param_owner, + self.root_parent.map(|id| tcx.hir().local_def_id(id)), + self.root_body.map(|hir_id| DefId::local(hir_id.owner)) + ), + ); + } - // The trait/impl lifetime is in scope for the method's body. - self.root_body.unwrap().local_id - }); + // The trait/impl lifetime is in scope for the method's body. + self.root_body.unwrap().local_id + }); Scope { id: scope, data: ScopeData::CallSite } } @@ -686,10 +711,8 @@ impl<'tcx> ScopeTree { /// returns the outermost `Scope` that the region outlives. pub fn free_scope(&self, tcx: TyCtxt<'tcx>, fr: &ty::FreeRegion) -> Scope { let param_owner = match fr.bound_region { - ty::BoundRegion::BrNamed(def_id, _) => { - tcx.parent(def_id).unwrap() - } - _ => fr.scope + ty::BoundRegion::BrNamed(def_id, _) => tcx.parent(def_id).unwrap(), + _ => fr.scope, }; // Ensure that the named late-bound lifetimes were defined @@ -712,22 +735,17 @@ impl<'tcx> ScopeTree { /// Checks whether the given scope contains a `yield` and if that yield could execute /// after `expr`. If so, it returns the span of that `yield`. /// `scope` must be inside the body. - pub fn yield_in_scope_for_expr(&self, - scope: Scope, - expr_hir_id: hir::HirId, - body: &'tcx hir::Body<'tcx>) -> Option { + pub fn yield_in_scope_for_expr( + &self, + scope: Scope, + expr_hir_id: hir::HirId, + body: &'tcx hir::Body<'tcx>, + ) -> Option { self.yield_in_scope(scope).and_then(|YieldData { span, expr_and_pat_count, .. }| { - let mut visitor = ExprLocatorVisitor { - hir_id: expr_hir_id, - result: None, - expr_and_pat_count: 0, - }; + let mut visitor = + ExprLocatorVisitor { hir_id: expr_hir_id, result: None, expr_and_pat_count: 0 }; visitor.visit_body(body); - if expr_and_pat_count >= visitor.result.unwrap() { - Some(span) - } else { - None - } + if expr_and_pat_count >= visitor.result.unwrap() { Some(span) } else { None } }) } @@ -751,8 +769,7 @@ fn record_var_lifetime( // // extern fn isalnum(c: c_int) -> c_int } - Some((parent_scope, _)) => - visitor.scope_tree.record_var_scope(var_id, parent_scope), + Some((parent_scope, _)) => visitor.scope_tree.record_var_scope(var_id, parent_scope), } } @@ -797,24 +814,20 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h for (i, statement) in blk.stmts.iter().enumerate() { match statement.kind { - hir::StmtKind::Local(..) | - hir::StmtKind::Item(..) => { + hir::StmtKind::Local(..) | hir::StmtKind::Item(..) => { // Each declaration introduces a subscope for bindings // introduced by the declaration; this subscope covers a // suffix of the block. Each subscope in a block has the // previous subscope in the block as a parent, except for // the first such subscope, which has the block itself as a // parent. - visitor.enter_scope( - Scope { - id: blk.hir_id.local_id, - data: ScopeData::Remainder(FirstStatementIndex::new(i)) - } - ); + visitor.enter_scope(Scope { + id: blk.hir_id.local_id, + data: ScopeData::Remainder(FirstStatementIndex::new(i)), + }); visitor.cx.var_parent = visitor.cx.parent; } - hir::StmtKind::Expr(..) | - hir::StmtKind::Semi(..) => {} + hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {} } visitor.visit_stmt(statement) } @@ -827,12 +840,7 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h fn resolve_arm<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, arm: &'tcx hir::Arm) { let prev_cx = visitor.cx; - visitor.enter_scope( - Scope { - id: arm.hir_id.local_id, - data: ScopeData::Node, - } - ); + visitor.enter_scope(Scope { id: arm.hir_id.local_id, data: ScopeData::Node }); visitor.cx.var_parent = visitor.cx.parent; visitor.terminating_scopes.insert(arm.body.hir_id.local_id); @@ -897,14 +905,19 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h // Conditional or repeating scopes are always terminating // scopes, meaning that temporaries cannot outlive them. // This ensures fixed size stacks. - hir::ExprKind::Binary( - source_map::Spanned { node: hir::BinOpKind::And, .. }, _, ref r) | - hir::ExprKind::Binary( - source_map::Spanned { node: hir::BinOpKind::Or, .. }, _, ref r) => { - // For shortcircuiting operators, mark the RHS as a terminating - // scope since it only executes conditionally. - terminating(r.hir_id.local_id); + source_map::Spanned { node: hir::BinOpKind::And, .. }, + _, + ref r, + ) + | hir::ExprKind::Binary( + source_map::Spanned { node: hir::BinOpKind::Or, .. }, + _, + ref r, + ) => { + // For shortcircuiting operators, mark the RHS as a terminating + // scope since it only executes conditionally. + terminating(r.hir_id.local_id); } hir::ExprKind::Loop(ref body, _, _) => { @@ -917,8 +930,11 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h terminating(expr.hir_id.local_id); } - hir::ExprKind::AssignOp(..) | hir::ExprKind::Index(..) | - hir::ExprKind::Unary(..) | hir::ExprKind::Call(..) | hir::ExprKind::MethodCall(..) => { + hir::ExprKind::AssignOp(..) + | hir::ExprKind::Index(..) + | hir::ExprKind::Unary(..) + | hir::ExprKind::Call(..) + | hir::ExprKind::MethodCall(..) => { // FIXME(https://github.com/rust-lang/rfcs/issues/811) Nested method calls // // The lifetimes for a call or method call look as follows: @@ -995,17 +1011,18 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h // when things are actually live. However, for typecheck to work // properly, we can't miss any types. - match expr.kind { // Manually recurse over closures, because they are the only // case of nested bodies that share the parent environment. hir::ExprKind::Closure(.., body, _, _) => { let body = visitor.tcx.hir().body(body); visitor.visit_body(body); - }, + } hir::ExprKind::AssignOp(_, ref left_expr, ref right_expr) => { - debug!("resolve_expr - enabling pessimistic_yield, was previously {}", - prev_pessimistic); + debug!( + "resolve_expr - enabling pessimistic_yield, was previously {}", + prev_pessimistic + ); let start_point = visitor.fixup_scopes.len(); visitor.pessimistic_yield = true; @@ -1034,19 +1051,24 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h // before walking the left-hand side, it should be impossible for the recorded // count to be greater than the left-hand side count. if count > visitor.expr_and_pat_count { - bug!("Encountered greater count {} at span {:?} - expected no greater than {}", - count, span, visitor.expr_and_pat_count); + bug!( + "Encountered greater count {} at span {:?} - expected no greater than {}", + count, + span, + visitor.expr_and_pat_count + ); } let new_count = visitor.expr_and_pat_count; - debug!("resolve_expr - increasing count for scope {:?} from {} to {} at span {:?}", - scope, count, new_count, span); + debug!( + "resolve_expr - increasing count for scope {:?} from {} to {} at span {:?}", + scope, count, new_count, span + ); yield_data.expr_and_pat_count = new_count; } - } - _ => intravisit::walk_expr(visitor, expr) + _ => intravisit::walk_expr(visitor, expr), } visitor.expr_and_pat_count += 1; @@ -1073,9 +1095,9 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h // Don't cross from closure bodies to their parent. Some(&(superscope, _)) => match superscope.data { ScopeData::CallSite => break, - _ => scope = superscope + _ => scope = superscope, }, - None => break + None => break, } } } @@ -1200,36 +1222,32 @@ fn resolve_local<'tcx>( // & expression, and its lifetime would be extended to the end of the block (due // to a different rule, not the below code). match pat.kind { - PatKind::Binding(hir::BindingAnnotation::Ref, ..) | - PatKind::Binding(hir::BindingAnnotation::RefMut, ..) => true, + PatKind::Binding(hir::BindingAnnotation::Ref, ..) + | PatKind::Binding(hir::BindingAnnotation::RefMut, ..) => true, PatKind::Struct(_, ref field_pats, _) => { field_pats.iter().any(|fp| is_binding_pat(&fp.pat)) } PatKind::Slice(ref pats1, ref pats2, ref pats3) => { - pats1.iter().any(|p| is_binding_pat(&p)) || - pats2.iter().any(|p| is_binding_pat(&p)) || - pats3.iter().any(|p| is_binding_pat(&p)) + pats1.iter().any(|p| is_binding_pat(&p)) + || pats2.iter().any(|p| is_binding_pat(&p)) + || pats3.iter().any(|p| is_binding_pat(&p)) } - PatKind::Or(ref subpats) | - PatKind::TupleStruct(_, ref subpats, _) | - PatKind::Tuple(ref subpats, _) => { - subpats.iter().any(|p| is_binding_pat(&p)) - } + PatKind::Or(ref subpats) + | PatKind::TupleStruct(_, ref subpats, _) + | PatKind::Tuple(ref subpats, _) => subpats.iter().any(|p| is_binding_pat(&p)), - PatKind::Box(ref subpat) => { - is_binding_pat(&subpat) - } + PatKind::Box(ref subpat) => is_binding_pat(&subpat), - PatKind::Ref(_, _) | - PatKind::Binding(hir::BindingAnnotation::Unannotated, ..) | - PatKind::Binding(hir::BindingAnnotation::Mutable, ..) | - PatKind::Wild | - PatKind::Path(_) | - PatKind::Lit(_) | - PatKind::Range(_, _, _) => false, + PatKind::Ref(_, _) + | PatKind::Binding(hir::BindingAnnotation::Unannotated, ..) + | PatKind::Binding(hir::BindingAnnotation::Mutable, ..) + | PatKind::Wild + | PatKind::Path(_) + | PatKind::Lit(_) + | PatKind::Range(_, _, _) => false, } } @@ -1255,15 +1273,12 @@ fn resolve_local<'tcx>( } hir::ExprKind::Struct(_, ref fields, _) => { for field in fields { - record_rvalue_scope_if_borrow_expr( - visitor, &field.expr, blk_id); + record_rvalue_scope_if_borrow_expr(visitor, &field.expr, blk_id); } } - hir::ExprKind::Array(ref subexprs) | - hir::ExprKind::Tup(ref subexprs) => { + hir::ExprKind::Array(ref subexprs) | hir::ExprKind::Tup(ref subexprs) => { for subexpr in subexprs { - record_rvalue_scope_if_borrow_expr( - visitor, &subexpr, blk_id); + record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id); } } hir::ExprKind::Cast(ref subexpr, _) => { @@ -1271,8 +1286,7 @@ fn resolve_local<'tcx>( } hir::ExprKind::Block(ref block, _) => { if let Some(ref subexpr) = block.expr { - record_rvalue_scope_if_borrow_expr( - visitor, &subexpr, blk_id); + record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id); } } _ => {} @@ -1309,10 +1323,10 @@ fn resolve_local<'tcx>( visitor.scope_tree.record_rvalue_scope(expr.hir_id.local_id, blk_scope); match expr.kind { - hir::ExprKind::AddrOf(_, _, ref subexpr) | - hir::ExprKind::Unary(hir::UnDeref, ref subexpr) | - hir::ExprKind::Field(ref subexpr, _) | - hir::ExprKind::Index(ref subexpr, _) => { + hir::ExprKind::AddrOf(_, _, ref subexpr) + | hir::ExprKind::Unary(hir::UnDeref, ref subexpr) + | hir::ExprKind::Field(ref subexpr, _) + | hir::ExprKind::Index(ref subexpr, _) => { expr = &subexpr; } _ => { @@ -1366,11 +1380,13 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { let body_id = body.id(); let owner_id = self.tcx.hir().body_owner(body_id); - debug!("visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})", - owner_id, - self.tcx.sess.source_map().span_to_string(body.value.span), - body_id, - self.cx.parent); + debug!( + "visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})", + owner_id, + self.tcx.sess.source_map().span_to_string(body.value.span), + body_id, + self.cx.parent + ); let outer_ec = mem::replace(&mut self.expr_and_pat_count, 0); let outer_cx = self.cx; @@ -1457,11 +1473,7 @@ fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { tcx, scope_tree: ScopeTree::default(), expr_and_pat_count: 0, - cx: Context { - root_id: None, - parent: None, - var_parent: None, - }, + cx: Context { root_id: None, parent: None, var_parent: None }, terminating_scopes: Default::default(), pessimistic_yield: false, fixup_scopes: vec![], @@ -1474,8 +1486,7 @@ fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { // record its impl/trait parent, as it can also have // lifetime parameters free in this body. match tcx.hir().get(id) { - Node::ImplItem(_) | - Node::TraitItem(_) => { + Node::ImplItem(_) | Node::TraitItem(_) => { visitor.scope_tree.root_parent = Some(tcx.hir().get_parent_item(id)); } _ => {} @@ -1492,10 +1503,7 @@ fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { } pub fn provide(providers: &mut Providers<'_>) { - *providers = Providers { - region_scope_tree, - ..*providers - }; + *providers = Providers { region_scope_tree, ..*providers }; } impl<'a> HashStable> for ScopeTree { diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index e1838b13fefb9..f1c07f36da5d0 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -3,25 +3,25 @@ pub use self::StabilityLevel::*; -use crate::lint::{self, Lint, in_derive_expansion}; +use crate::hir::def::{DefKind, Res}; +use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use crate::hir::intravisit::{self, NestedVisitorMap, Visitor}; +use crate::hir::{self, Generics, HirId, Item, StructField, Variant}; use crate::lint::builtin::BuiltinLintDiagnostics; -use crate::hir::{self, Item, Generics, StructField, Variant, HirId}; -use crate::hir::def::{Res, DefKind}; -use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE}; -use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; -use crate::ty::query::Providers; +use crate::lint::{self, in_derive_expansion, Lint}; use crate::middle::privacy::AccessLevels; use crate::session::{DiagnosticMessageId, Session}; +use crate::ty::query::Providers; +use crate::ty::{self, TyCtxt}; +use crate::util::nodemap::{FxHashMap, FxHashSet}; use errors::DiagnosticBuilder; use rustc_feature::GateIssue; -use syntax::symbol::{Symbol, sym}; -use syntax_pos::{Span, MultiSpan}; use syntax::ast::{Attribute, CRATE_NODE_ID}; +use syntax::attr::{self, ConstStability, Deprecation, RustcDeprecation, Stability}; use syntax::errors::Applicability; use syntax::feature_gate::{feature_err, feature_err_issue}; -use syntax::attr::{self, Stability, Deprecation, RustcDeprecation, ConstStability}; -use crate::ty::{self, TyCtxt}; -use crate::util::nodemap::{FxHashSet, FxHashMap}; +use syntax::symbol::{sym, Symbol}; +use syntax_pos::{MultiSpan, Span}; use std::cmp::Ordering; use std::mem::replace; @@ -29,7 +29,6 @@ use std::num::NonZeroU32; use rustc_error_codes::*; - #[derive(PartialEq, Clone, Copy, Debug)] pub enum StabilityLevel { Unstable, @@ -64,23 +63,17 @@ pub struct DeprecationEntry { impl DeprecationEntry { fn local(attr: Deprecation, id: HirId) -> DeprecationEntry { - DeprecationEntry { - attr, - origin: Some(id), - } + DeprecationEntry { attr, origin: Some(id) } } pub fn external(attr: Deprecation) -> DeprecationEntry { - DeprecationEntry { - attr, - origin: None, - } + DeprecationEntry { attr, origin: None } } pub fn same_origin(&self, other: &DeprecationEntry) -> bool { match (self.origin, other.origin) { (Some(o1), Some(o2)) => o1 == o2, - _ => false + _ => false, } } } @@ -113,30 +106,39 @@ struct Annotator<'a, 'tcx> { impl<'a, 'tcx> Annotator<'a, 'tcx> { // Determine the stability for a node based on its attributes and inherited // stability. The stability is recorded in the index and used as the parent. - fn annotate(&mut self, hir_id: HirId, attrs: &[Attribute], - item_sp: Span, kind: AnnotationKind, visit_children: F) - where F: FnOnce(&mut Self) + fn annotate( + &mut self, + hir_id: HirId, + attrs: &[Attribute], + item_sp: Span, + kind: AnnotationKind, + visit_children: F, + ) where + F: FnOnce(&mut Self), { if self.tcx.features().staged_api { // This crate explicitly wants staged API. debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs); if let Some(..) = attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp) { - self.tcx.sess.span_err(item_sp, "`#[deprecated]` cannot be used in staged API; \ - use `#[rustc_deprecated]` instead"); + self.tcx.sess.span_err( + item_sp, + "`#[deprecated]` cannot be used in staged API; \ + use `#[rustc_deprecated]` instead", + ); } - let (stab, const_stab) = attr::find_stability( - &self.tcx.sess.parse_sess, attrs, item_sp, - ); + let (stab, const_stab) = + attr::find_stability(&self.tcx.sess.parse_sess, attrs, item_sp); if let Some(const_stab) = const_stab { let const_stab = self.tcx.intern_const_stability(const_stab); self.index.const_stab_map.insert(hir_id, const_stab); } if let Some(mut stab) = stab { // Error if prohibited, or can't inherit anything from a container. - if kind == AnnotationKind::Prohibited || - (kind == AnnotationKind::Container && - stab.level.is_stable() && - stab.rustc_depr.is_none()) { + if kind == AnnotationKind::Prohibited + || (kind == AnnotationKind::Container + && stab.level.is_stable() + && stab.rustc_depr.is_none()) + { self.tcx.sess.span_err(item_sp, "This stability annotation is useless"); } @@ -153,19 +155,24 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { // Check if deprecated_since < stable_since. If it is, // this is *almost surely* an accident. - if let (&Some(attr::RustcDeprecation {since: dep_since, ..}), - &attr::Stable {since: stab_since}) = (&stab.rustc_depr, &stab.level) { + if let ( + &Some(attr::RustcDeprecation { since: dep_since, .. }), + &attr::Stable { since: stab_since }, + ) = (&stab.rustc_depr, &stab.level) + { // Explicit version of iter::order::lt to handle parse errors properly - for (dep_v, stab_v) in dep_since.as_str() - .split('.') - .zip(stab_since.as_str().split('.')) + for (dep_v, stab_v) in + dep_since.as_str().split('.').zip(stab_since.as_str().split('.')) { if let (Ok(dep_v), Ok(stab_v)) = (dep_v.parse::(), stab_v.parse()) { match dep_v.cmp(&stab_v) { Ordering::Less => { - self.tcx.sess.span_err(item_sp, "An API can't be stabilized \ - after it is deprecated"); - break + self.tcx.sess.span_err( + item_sp, + "An API can't be stabilized \ + after it is deprecated", + ); + break; } Ordering::Equal => continue, Ordering::Greater => break, @@ -173,9 +180,12 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } else { // Act like it isn't less because the question is now nonsensical, // and this makes us not do anything else interesting. - self.tcx.sess.span_err(item_sp, "Invalid stability or deprecation \ - version found"); - break + self.tcx.sess.span_err( + item_sp, + "Invalid stability or deprecation \ + version found", + ); + break; } } } @@ -197,7 +207,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } else { // Emit errors for non-staged-api crates. let unstable_attrs = [ - sym::unstable, sym::stable, + sym::unstable, + sym::stable, sym::rustc_deprecated, sym::rustc_const_unstable, sym::rustc_const_stable, @@ -211,7 +222,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { attr.span, E0734, "stability attributes may not be used outside of the standard library", - ).emit(); + ) + .emit(); } } @@ -232,8 +244,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { let depr_entry = DeprecationEntry::local(depr, hir_id); self.index.depr_map.insert(hir_id, depr_entry.clone()); - let orig_parent_depr = replace(&mut self.parent_depr, - Some(depr_entry)); + let orig_parent_depr = replace(&mut self.parent_depr, Some(depr_entry)); visit_children(self); self.parent_depr = orig_parent_depr; } else if let Some(parent_depr) = self.parent_depr.clone() { @@ -277,9 +288,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { _ => {} } - self.annotate(i.hir_id, &i.attrs, i.span, kind, |v| { - intravisit::walk_item(v, i) - }); + self.annotate(i.hir_id, &i.attrs, i.span, kind, |v| intravisit::walk_item(v, i)); self.in_trait_impl = orig_in_trait_impl; } @@ -290,26 +299,21 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { } fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) { - let kind = if self.in_trait_impl { - AnnotationKind::Prohibited - } else { - AnnotationKind::Required - }; + let kind = + if self.in_trait_impl { AnnotationKind::Prohibited } else { AnnotationKind::Required }; self.annotate(ii.hir_id, &ii.attrs, ii.span, kind, |v| { intravisit::walk_impl_item(v, ii); }); } fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics, item_id: HirId) { - self.annotate(var.id, &var.attrs, var.span, AnnotationKind::Required, - |v| { - if let Some(ctor_hir_id) = var.data.ctor_hir_id() { - v.annotate(ctor_hir_id, &var.attrs, var.span, AnnotationKind::Required, - |_| {}); - } + self.annotate(var.id, &var.attrs, var.span, AnnotationKind::Required, |v| { + if let Some(ctor_hir_id) = var.data.ctor_hir_id() { + v.annotate(ctor_hir_id, &var.attrs, var.span, AnnotationKind::Required, |_| {}); + } - intravisit::walk_variant(v, var, g, item_id) - }) + intravisit::walk_variant(v, var, g, item_id) + }) } fn visit_struct_field(&mut self, s: &'tcx StructField<'tcx>) { @@ -337,14 +341,10 @@ struct MissingStabilityAnnotations<'a, 'tcx> { impl<'a, 'tcx> MissingStabilityAnnotations<'a, 'tcx> { fn check_missing_stability(&self, hir_id: HirId, span: Span, name: &str) { let stab = self.tcx.stability().local_stability(hir_id); - let is_error = !self.tcx.sess.opts.test && - stab.is_none() && - self.access_levels.is_reachable(hir_id); + let is_error = + !self.tcx.sess.opts.test && stab.is_none() && self.access_levels.is_reachable(hir_id); if is_error { - self.tcx.sess.span_err( - span, - &format!("{} has missing stability attribute", name), - ); + self.tcx.sess.span_err(span, &format!("{} has missing stability attribute", name)); } } } @@ -362,7 +362,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { // optional. They inherit stability from their parents when unannotated. hir::ItemKind::Impl(.., None, _, _) | hir::ItemKind::ForeignMod(..) => {} - _ => self.check_missing_stability(i.hir_id, i.span, i.kind.descriptive_variant()) + _ => self.check_missing_stability(i.hir_id, i.span, i.kind.descriptive_variant()), } intravisit::walk_item(self, i) @@ -374,8 +374,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { } fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) { - let impl_def_id = self.tcx.hir().local_def_id( - self.tcx.hir().get_parent_item(ii.hir_id)); + let impl_def_id = self.tcx.hir().local_def_id(self.tcx.hir().get_parent_item(ii.hir_id)); if self.tcx.impl_trait_ref(impl_def_id).is_none() { self.check_missing_stability(ii.hir_id, ii.span, "item"); } @@ -405,8 +404,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { impl<'tcx> Index<'tcx> { pub fn new(tcx: TyCtxt<'tcx>) -> Index<'tcx> { let is_staged_api = - tcx.sess.opts.debugging_opts.force_unstable_if_unmarked || - tcx.features().staged_api; + tcx.sess.opts.debugging_opts.force_unstable_if_unmarked || tcx.features().staged_api; let mut staged_api = FxHashMap::default(); staged_api.insert(LOCAL_CRATE, is_staged_api); let mut index = Index { @@ -421,8 +419,9 @@ impl<'tcx> Index<'tcx> { let active_lang_features = &tcx.features().declared_lang_features; // Put the active features into a map for quick lookup. - index.active_features = - active_lib_features.iter().map(|&(ref s, ..)| s.clone()) + index.active_features = active_lib_features + .iter() + .map(|&(ref s, ..)| s.clone()) .chain(active_lang_features.iter().map(|&(ref s, ..)| s.clone())) .collect(); @@ -458,11 +457,13 @@ impl<'tcx> Index<'tcx> { annotator.parent_stab = Some(stability); } - annotator.annotate(hir::CRATE_HIR_ID, - &krate.attrs, - krate.span, - AnnotationKind::Required, - |v| intravisit::walk_crate(v, krate)); + annotator.annotate( + hir::CRATE_HIR_ID, + &krate.attrs, + krate.span, + AnnotationKind::Required, + |v| intravisit::walk_crate(v, krate), + ); } return index; } @@ -487,10 +488,7 @@ fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: DefId) { } pub fn provide(providers: &mut Providers<'_>) { - *providers = Providers { - check_mod_unstable_api_usage, - ..*providers - }; + *providers = Providers { check_mod_unstable_api_usage, ..*providers }; } pub fn report_unstable( @@ -504,23 +502,19 @@ pub fn report_unstable( ) { let msg = match reason { Some(r) => format!("use of unstable library feature '{}': {}", feature, r), - None => format!("use of unstable library feature '{}'", &feature) + None => format!("use of unstable library feature '{}'", &feature), }; let msp: MultiSpan = span.into(); let cm = &sess.parse_sess.source_map(); - let span_key = msp.primary_span().and_then(|sp: Span| + let span_key = msp.primary_span().and_then(|sp: Span| { if !sp.is_dummy() { let file = cm.lookup_char_pos(sp.lo()).file; - if file.name.is_macros() { - None - } else { - Some(span) - } + if file.name.is_macros() { None } else { Some(span) } } else { None } - ); + }); let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone()); let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id); @@ -559,7 +553,9 @@ pub fn deprecation_in_effect(since: &str) -> bool { } pub fn deprecation_suggestion( - diag: &mut DiagnosticBuilder<'_>, suggestion: Option, span: Span + diag: &mut DiagnosticBuilder<'_>, + suggestion: Option, + span: Span, ) { if let Some(suggestion) = suggestion { diag.span_suggestion( @@ -587,8 +583,13 @@ pub fn rustc_deprecation_message(depr: &RustcDeprecation, path: &str) -> (String let (message, lint) = if deprecation_in_effect(&depr.since.as_str()) { (format!("use of deprecated item '{}'", path), lint::builtin::DEPRECATED) } else { - (format!("use of item '{}' that will be deprecated in future version {}", path, depr.since), - lint::builtin::DEPRECATED_IN_FUTURE) + ( + format!( + "use of item '{}' that will be deprecated in future version {}", + path, depr.since + ), + lint::builtin::DEPRECATED_IN_FUTURE, + ) }; (deprecation_message_common(message, Some(depr.reason)), lint) } @@ -642,12 +643,7 @@ pub enum EvalResult { Allow, /// We cannot use the item because it is unstable and we did not provide the /// corresponding feature gate. - Deny { - feature: Symbol, - reason: Option, - issue: Option, - is_soft: bool, - }, + Deny { feature: Symbol, reason: Option, issue: Option, is_soft: bool }, /// The item does not have the `#[stable]` or `#[unstable]` marker assigned. Unmarked, } @@ -657,9 +653,7 @@ impl<'tcx> TyCtxt<'tcx> { fn skip_stability_check_due_to_privacy(self, mut def_id: DefId) -> bool { // Check if `def_id` is a trait method. match self.def_kind(def_id) { - Some(DefKind::Method) | - Some(DefKind::AssocTy) | - Some(DefKind::AssocConst) => { + Some(DefKind::Method) | Some(DefKind::AssocTy) | Some(DefKind::AssocConst) => { if let ty::TraitContainer(trait_def_id) = self.associated_item(def_id).container { // Trait methods do not declare visibility (even // for visibility info in cstore). Use containing @@ -679,8 +673,7 @@ impl<'tcx> TyCtxt<'tcx> { // These are not visible outside crate; therefore // stability markers are irrelevant, if even present. - ty::Visibility::Restricted(..) | - ty::Visibility::Invisible => true, + ty::Visibility::Restricted(..) | ty::Visibility::Invisible => true, } } @@ -697,10 +690,10 @@ impl<'tcx> TyCtxt<'tcx> { // Deprecated attributes apply in-crate and cross-crate. if let Some(id) = id { if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) { - let parent_def_id = self.hir().local_def_id( - self.hir().get_parent_item(id)); - let skip = self.lookup_deprecation_entry(parent_def_id) - .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry)); + let parent_def_id = self.hir().local_def_id(self.hir().get_parent_item(id)); + let skip = self + .lookup_deprecation_entry(parent_def_id) + .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry)); if !skip { let (message, lint) = @@ -710,17 +703,18 @@ impl<'tcx> TyCtxt<'tcx> { }; } - let is_staged_api = self.lookup_stability(DefId { - index: CRATE_DEF_INDEX, - ..def_id - }).is_some(); + let is_staged_api = + self.lookup_stability(DefId { index: CRATE_DEF_INDEX, ..def_id }).is_some(); if !is_staged_api { return EvalResult::Allow; } let stability = self.lookup_stability(def_id); - debug!("stability: \ - inspecting def_id={:?} span={:?} of stability={:?}", def_id, span, stability); + debug!( + "stability: \ + inspecting def_id={:?} span={:?} of stability={:?}", + def_id, span, stability + ); if let Some(id) = id { if let Some(stability) = stability { @@ -728,7 +722,13 @@ impl<'tcx> TyCtxt<'tcx> { let (message, lint) = rustc_deprecation_message(depr, &self.def_path_str(def_id)); late_report_deprecation( - self, &message, depr.suggestion, lint, span, def_id, id + self, + &message, + depr.suggestion, + lint, + span, + def_id, + id, ); } } @@ -779,9 +779,7 @@ impl<'tcx> TyCtxt<'tcx> { // handled by the lint emitting logic above. EvalResult::Allow } - None => { - EvalResult::Unmarked - } + None => EvalResult::Unmarked, } } @@ -797,8 +795,9 @@ impl<'tcx> TyCtxt<'tcx> { |lint, span, msg: &_| self.lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg); match self.eval_stability(def_id, id, span) { EvalResult::Allow => {} - EvalResult::Deny { feature, reason, issue, is_soft } => - report_unstable(self.sess, feature, reason, issue, is_soft, span, soft_handler), + EvalResult::Deny { feature, reason, issue, is_soft } => { + report_unstable(self.sess, feature, reason, issue, is_soft, span, soft_handler) + } EvalResult::Unmarked => { // The API could be uncallable for other reasons, for example when a private module // was referenced. @@ -820,7 +819,9 @@ impl Visitor<'tcx> for Checker<'tcx> { match item.kind { hir::ItemKind::ExternCrate(_) => { // compiler-generated `extern crate` items have a dummy span. - if item.span.is_dummy() { return } + if item.span.is_dummy() { + return; + } let def_id = self.tcx.hir().local_def_id(item.hir_id); let cnum = match self.tcx.extern_mod_stmt_cnum(def_id) { @@ -838,7 +839,9 @@ impl Visitor<'tcx> for Checker<'tcx> { if let Res::Def(DefKind::Trait, trait_did) = t.path.res { for impl_item_ref in impl_item_refs { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); - let trait_item_def_id = self.tcx.associated_items(trait_did) + let trait_item_def_id = self + .tcx + .associated_items(trait_did) .find(|item| item.ident.name == impl_item.ident.name) .map(|item| item.def_id); if let Some(def_id) = trait_item_def_id { @@ -858,23 +861,27 @@ impl Visitor<'tcx> for Checker<'tcx> { if adt_def.has_dtor(self.tcx) { feature_err( - &self.tcx.sess.parse_sess, sym::untagged_unions, item.span, - "unions with `Drop` implementations are unstable" + &self.tcx.sess.parse_sess, + sym::untagged_unions, + item.span, + "unions with `Drop` implementations are unstable", ) .emit(); } else { let param_env = self.tcx.param_env(def_id); if !param_env.can_type_implement_copy(self.tcx, ty).is_ok() { feature_err( - &self.tcx.sess.parse_sess, sym::untagged_unions, item.span, - "unions with non-`Copy` fields are unstable" + &self.tcx.sess.parse_sess, + sym::untagged_unions, + item.span, + "unions with non-`Copy` fields are unstable", ) .emit(); } } } - _ => (/* pass */) + _ => (/* pass */), } intravisit::walk_item(self, item); } @@ -901,10 +908,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { if tcx.stability().staged_api[&LOCAL_CRATE] { let krate = tcx.hir().krate(); - let mut missing = MissingStabilityAnnotations { - tcx, - access_levels, - }; + let mut missing = MissingStabilityAnnotations { tcx, access_levels }; missing.check_missing_stability(hir::CRATE_HIR_ID, krate.span, "crate"); intravisit::walk_crate(&mut missing, krate); krate.visit_all_item_likes(&mut missing.as_deep_visitor()); @@ -941,21 +945,20 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { remaining_lib_features.remove(&Symbol::intern("libc")); remaining_lib_features.remove(&sym::test); - let check_features = - |remaining_lib_features: &mut FxHashMap<_, _>, defined_features: &[_]| { - for &(feature, since) in defined_features { - if let Some(since) = since { - if let Some(span) = remaining_lib_features.get(&feature) { - // Warn if the user has enabled an already-stable lib feature. - unnecessary_stable_feature_lint(tcx, *span, feature, since); - } - } - remaining_lib_features.remove(&feature); - if remaining_lib_features.is_empty() { - break; + let check_features = |remaining_lib_features: &mut FxHashMap<_, _>, defined_features: &[_]| { + for &(feature, since) in defined_features { + if let Some(since) = since { + if let Some(span) = remaining_lib_features.get(&feature) { + // Warn if the user has enabled an already-stable lib feature. + unnecessary_stable_feature_lint(tcx, *span, feature, since); } } - }; + remaining_lib_features.remove(&feature); + if remaining_lib_features.is_empty() { + break; + } + } + }; // We always collect the lib features declared in the current crate, even if there are // no unknown features, because the collection also does feature attribute validation. @@ -979,17 +982,17 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { // don't lint about unused features. We should reenable this one day! } -fn unnecessary_stable_feature_lint( - tcx: TyCtxt<'_>, - span: Span, - feature: Symbol, - since: Symbol, -) { - tcx.lint_hir(lint::builtin::STABLE_FEATURES, +fn unnecessary_stable_feature_lint(tcx: TyCtxt<'_>, span: Span, feature: Symbol, since: Symbol) { + tcx.lint_hir( + lint::builtin::STABLE_FEATURES, hir::CRATE_HIR_ID, span, - &format!("the feature `{}` has been stable since {} and no longer requires \ - an attribute to enable", feature, since)); + &format!( + "the feature `{}` has been stable since {} and no longer requires \ + an attribute to enable", + feature, since + ), + ); } fn duplicate_feature_err(sess: &Session, span: Span, feature: Symbol) { diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index 2acea7c5b6859..600b05068cdc9 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -1,18 +1,18 @@ //! Validity checking for weak lang items -use crate::session::config; use crate::middle::lang_items; +use crate::session::config; +use crate::hir; +use crate::hir::def_id::DefId; +use crate::hir::intravisit; +use crate::hir::intravisit::{NestedVisitorMap, Visitor}; +use crate::ty::TyCtxt; use rustc_data_structures::fx::FxHashSet; use rustc_target::spec::PanicStrategy; use syntax::ast; -use syntax::symbol::{Symbol, sym}; +use syntax::symbol::{sym, Symbol}; use syntax_pos::Span; -use crate::hir::def_id::DefId; -use crate::hir::intravisit::{Visitor, NestedVisitorMap}; -use crate::hir::intravisit; -use crate::hir; -use crate::ty::TyCtxt; use rustc_error_codes::*; diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs index 0704771f6ee95..00ecc7a7a0aa1 100644 --- a/src/librustc/mir/cache.rs +++ b/src/librustc/mir/cache.rs @@ -1,10 +1,10 @@ -use rustc_index::vec::IndexVec; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; use crate::ich::StableHashingContext; use crate::mir::{BasicBlock, BasicBlockData, Body, LocalDecls, Location, Successors}; -use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors}; use rustc_data_structures::graph::dominators::{dominators, Dominators}; +use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_index::vec::IndexVec; +use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::iter; use std::ops::{Deref, DerefMut, Index, IndexMut}; use std::vec::IntoIter; @@ -34,9 +34,7 @@ impl<'a> HashStable> for Cache { impl Cache { pub fn new() -> Self { - Self { - predecessors: None, - } + Self { predecessors: None } } pub fn invalidate_predecessors(&mut self) { @@ -72,7 +70,7 @@ impl Cache { fn unwrap_predecessor_locations<'a>( &'a self, loc: Location, - body: &'a Body<'a> + body: &'a Body<'a>, ) -> impl Iterator + 'a { let if_zero_locations = if loc.statement_index == 0 { let predecessor_blocks = self.unwrap_predecessors_for(loc.block); @@ -97,7 +95,7 @@ impl Cache { pub fn basic_blocks_mut<'a, 'tcx>( &mut self, - body: &'a mut Body<'tcx> + body: &'a mut Body<'tcx>, ) -> &'a mut IndexVec> { debug!("bbm: Clearing predecessors cache for body at: {:?}", body.span.data()); self.invalidate_predecessors(); @@ -106,7 +104,7 @@ impl Cache { pub fn basic_blocks_and_local_decls_mut<'a, 'tcx>( &mut self, - body: &'a mut Body<'tcx> + body: &'a mut Body<'tcx>, ) -> (&'a mut IndexVec>, &'a mut LocalDecls<'tcx>) { debug!("bbaldm: Clearing predecessors cache for body at: {:?}", body.span.data()); self.invalidate_predecessors(); @@ -122,21 +120,16 @@ pub struct BodyAndCache<'tcx> { impl BodyAndCache<'tcx> { pub fn new(body: Body<'tcx>) -> Self { - Self { - body, - cache: Cache::new(), - } + Self { body, cache: Cache::new() } } } #[macro_export] macro_rules! read_only { - ($body:expr) => { - { - $body.ensure_predecessors(); - $body.unwrap_read_only() - } - }; + ($body:expr) => {{ + $body.ensure_predecessors(); + $body.unwrap_read_only() + }}; } impl BodyAndCache<'tcx> { @@ -157,7 +150,7 @@ impl BodyAndCache<'tcx> { } pub fn basic_blocks_and_local_decls_mut( - &mut self + &mut self, ) -> (&mut IndexVec>, &mut LocalDecls<'tcx>) { self.cache.basic_blocks_and_local_decls_mut(&mut self.body) } @@ -201,11 +194,9 @@ impl ReadOnlyBodyAndCache<'a, 'tcx> { fn new(body: &'a Body<'tcx>, cache: &'a Cache) -> Self { assert!( cache.predecessors.is_some(), - "Cannot construct ReadOnlyBodyAndCache without computed predecessors"); - Self { - body, - cache, - } + "Cannot construct ReadOnlyBodyAndCache without computed predecessors" + ); + Self { body, cache } } pub fn predecessors(&self) -> &IndexVec> { @@ -239,10 +230,7 @@ impl graph::GraphPredecessors<'graph> for ReadOnlyBodyAndCache<'a, 'tcx> { } impl graph::WithPredecessors for ReadOnlyBodyAndCache<'a, 'tcx> { - fn predecessors( - &self, - node: Self::Node, - ) -> >::Iter { + fn predecessors(&self, node: Self::Node) -> >::Iter { self.cache.unwrap_predecessors_for(node).to_vec().into_iter() } } @@ -260,10 +248,7 @@ impl graph::WithStartNode for ReadOnlyBodyAndCache<'a, 'tcx> { } impl graph::WithSuccessors for ReadOnlyBodyAndCache<'a, 'tcx> { - fn successors( - &self, - node: Self::Node, - ) -> >::Iter { + fn successors(&self, node: Self::Node) -> >::Iter { self.body.successors(node) } } @@ -273,7 +258,6 @@ impl<'a, 'b, 'tcx> graph::GraphSuccessors<'b> for ReadOnlyBodyAndCache<'a, 'tcx> type Iter = iter::Cloned>; } - impl Deref for ReadOnlyBodyAndCache<'a, 'tcx> { type Target = &'a Body<'tcx>; diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index a1bb80f6179e2..67f1c8072d680 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -1,17 +1,17 @@ //! The virtual memory representation of the MIR interpreter. use super::{ - Pointer, InterpResult, AllocId, ScalarMaybeUndef, write_target_uint, read_target_uint, Scalar, + read_target_uint, write_target_uint, AllocId, InterpResult, Pointer, Scalar, ScalarMaybeUndef, }; -use crate::ty::layout::{Size, Align}; +use crate::ty::layout::{Align, Size}; use rustc_data_structures::sorted_map::SortedMap; use rustc_target::abi::HasDataLayout; -use syntax::ast::Mutability; -use std::iter; -use std::ops::{Range, Deref, DerefMut}; use std::borrow::Cow; +use std::iter; +use std::ops::{Deref, DerefMut, Range}; +use syntax::ast::Mutability; // NOTE: When adding new fields, make sure to adjust the `Snapshot` impl in // `src/librustc_mir/interpret/snapshot.rs`. @@ -25,9 +25,9 @@ use std::borrow::Cow; Hash, RustcEncodable, RustcDecodable, - HashStable, + HashStable )] -pub struct Allocation { +pub struct Allocation { /// The actual bytes of the allocation. /// Note that the bytes of a pointer represent the offset of the pointer. bytes: Vec, @@ -92,7 +92,7 @@ pub trait AllocationExtra: ::std::fmt::Debug + Clone { } // For `Tag = ()` and no extra state, we have a trivial implementation. -impl AllocationExtra<()> for () { } +impl AllocationExtra<()> for () {} // The constructors are all without extra; the extra gets added by a machine hook later. impl Allocation { @@ -140,14 +140,15 @@ impl Allocation<(), ()> { bytes: self.bytes, size: self.size, relocations: Relocations::from_presorted( - self.relocations.iter() + self.relocations + .iter() // The allocations in the relocations (pointers stored *inside* this allocation) // all get the base pointer tag. .map(|&(offset, ((), alloc))| { let tag = tagger(alloc); (offset, (tag, alloc)) }) - .collect() + .collect(), ), undef_mask: self.undef_mask, align: self.align, @@ -189,21 +190,20 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { /// Just a small local helper function to avoid a bit of code repetition. /// Returns the range of this allocation that was meant. #[inline] - fn check_bounds( - &self, - offset: Size, - size: Size - ) -> Range { + fn check_bounds(&self, offset: Size, size: Size) -> Range { let end = offset + size; // This does overflow checking. assert_eq!( - end.bytes() as usize as u64, end.bytes(), + end.bytes() as usize as u64, + end.bytes(), "cannot handle this access on this host architecture" ); let end = end.bytes() as usize; assert!( end <= self.len(), "Out-of-bounds access at offset {}, size {} in allocation of size {}", - offset.bytes(), size.bytes(), self.len() + offset.bytes(), + size.bytes(), + self.len() ); (offset.bytes() as usize)..end } @@ -223,8 +223,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { ptr: Pointer, size: Size, check_defined_and_ptr: bool, - ) -> InterpResult<'tcx, &[u8]> - { + ) -> InterpResult<'tcx, &[u8]> { let range = self.check_bounds(ptr.offset, size); if check_defined_and_ptr { @@ -252,8 +251,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { cx: &impl HasDataLayout, ptr: Pointer, size: Size, - ) -> InterpResult<'tcx, &[u8]> - { + ) -> InterpResult<'tcx, &[u8]> { self.get_bytes_internal(cx, ptr, size, true) } @@ -267,8 +265,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { cx: &impl HasDataLayout, ptr: Pointer, size: Size, - ) -> InterpResult<'tcx, &[u8]> - { + ) -> InterpResult<'tcx, &[u8]> { self.get_bytes_internal(cx, ptr, size, false) } @@ -283,8 +280,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { cx: &impl HasDataLayout, ptr: Pointer, size: Size, - ) -> InterpResult<'tcx, &mut [u8]> - { + ) -> InterpResult<'tcx, &mut [u8]> { let range = self.check_bounds(ptr.offset, size); self.mark_definedness(ptr, size, true); @@ -306,8 +302,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { &self, cx: &impl HasDataLayout, ptr: Pointer, - ) -> InterpResult<'tcx, &[u8]> - { + ) -> InterpResult<'tcx, &[u8]> { assert_eq!(ptr.offset.bytes() as usize as u64, ptr.offset.bytes()); let offset = ptr.offset.bytes() as usize; Ok(match self.bytes[offset..].iter().position(|&c| c == 0) { @@ -332,8 +327,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { ptr: Pointer, size: Size, allow_ptr_and_undef: bool, - ) -> InterpResult<'tcx> - { + ) -> InterpResult<'tcx> { // Check bounds and relocations on the edges. self.get_bytes_with_undef_and_ptr(cx, ptr, size)?; // Check undef and ptr. @@ -352,9 +346,8 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { &mut self, cx: &impl HasDataLayout, ptr: Pointer, - src: impl IntoIterator, - ) -> InterpResult<'tcx> - { + src: impl IntoIterator, + ) -> InterpResult<'tcx> { let mut src = src.into_iter(); let (lower, upper) = src.size_hint(); let len = upper.expect("can only write bounded iterators"); @@ -382,9 +375,8 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { &self, cx: &impl HasDataLayout, ptr: Pointer, - size: Size - ) -> InterpResult<'tcx, ScalarMaybeUndef> - { + size: Size, + ) -> InterpResult<'tcx, ScalarMaybeUndef> { // `get_bytes_unchecked` tests relocation edges. let bytes = self.get_bytes_with_undef_and_ptr(cx, ptr, size)?; // Undef check happens *after* we established that the alignment is correct. @@ -404,9 +396,9 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { match self.relocations.get(&ptr.offset) { Some(&(tag, alloc_id)) => { let ptr = Pointer::new_with_tag(alloc_id, Size::from_bytes(bits as u64), tag); - return Ok(ScalarMaybeUndef::Scalar(ptr.into())) + return Ok(ScalarMaybeUndef::Scalar(ptr.into())); } - None => {}, + None => {} } } // We don't. Just return the bits. @@ -421,8 +413,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { &self, cx: &impl HasDataLayout, ptr: Pointer, - ) -> InterpResult<'tcx, ScalarMaybeUndef> - { + ) -> InterpResult<'tcx, ScalarMaybeUndef> { self.read_scalar(cx, ptr, cx.data_layout().pointer_size) } @@ -441,14 +432,13 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { ptr: Pointer, val: ScalarMaybeUndef, type_size: Size, - ) -> InterpResult<'tcx> - { + ) -> InterpResult<'tcx> { let val = match val { ScalarMaybeUndef::Scalar(scalar) => scalar, ScalarMaybeUndef::Undef => { self.mark_definedness(ptr, type_size, false); return Ok(()); - }, + } }; let bytes = match val.to_bits_or_ptr(type_size, cx) { @@ -463,10 +453,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { // See if we have to also write a relocation. match val { Scalar::Ptr(val) => { - self.relocations.insert( - ptr.offset, - (val.tag, val.alloc_id), - ); + self.relocations.insert(ptr.offset, (val.tag, val.alloc_id)); } _ => {} } @@ -482,9 +469,8 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { &mut self, cx: &impl HasDataLayout, ptr: Pointer, - val: ScalarMaybeUndef - ) -> InterpResult<'tcx> - { + val: ScalarMaybeUndef, + ) -> InterpResult<'tcx> { let ptr_size = cx.data_layout().pointer_size; self.write_scalar(cx, ptr.into(), val, ptr_size) } @@ -541,8 +527,10 @@ impl<'tcx, Tag: Copy, Extra> Allocation { return Ok(()); } - (relocations.first().unwrap().0, - relocations.last().unwrap().0 + cx.data_layout().pointer_size) + ( + relocations.first().unwrap().0, + relocations.last().unwrap().0 + cx.data_layout().pointer_size, + ) }; let start = ptr.offset; let end = start + size; @@ -577,33 +565,22 @@ impl<'tcx, Tag: Copy, Extra> Allocation { } } - /// Undefined bytes. impl<'tcx, Tag, Extra> Allocation { /// Checks that a range of bytes is defined. If not, returns the `ReadUndefBytes` /// error which will report the first byte which is undefined. #[inline] fn check_defined(&self, ptr: Pointer, size: Size) -> InterpResult<'tcx> { - self.undef_mask.is_range_defined( - ptr.offset, - ptr.offset + size, - ).or_else(|idx| throw_unsup!(ReadUndefBytes(idx))) + self.undef_mask + .is_range_defined(ptr.offset, ptr.offset + size) + .or_else(|idx| throw_unsup!(ReadUndefBytes(idx))) } - pub fn mark_definedness( - &mut self, - ptr: Pointer, - size: Size, - new_state: bool, - ) { + pub fn mark_definedness(&mut self, ptr: Pointer, size: Size, new_state: bool) { if size.bytes() == 0 { return; } - self.undef_mask.set_range( - ptr.offset, - ptr.offset + size, - new_state, - ); + self.undef_mask.set_range(ptr.offset, ptr.offset + size, new_state); } } @@ -614,17 +591,13 @@ pub struct AllocationDefinedness { initial: bool, /// The lengths of ranges that are run-length encoded. /// The definedness of the ranges alternate starting with `initial`. - ranges: smallvec::SmallVec::<[u64; 1]>, + ranges: smallvec::SmallVec<[u64; 1]>, } /// Transferring the definedness mask to other allocations. impl Allocation { /// Creates a run-length encoding of the undef mask. - pub fn compress_undef_range( - &self, - src: Pointer, - size: Size, - ) -> AllocationDefinedness { + pub fn compress_undef_range(&self, src: Pointer, size: Size) -> AllocationDefinedness { // Since we are copying `size` bytes from `src` to `dest + i * size` (`for i in 0..repeat`), // a naive undef mask copying algorithm would repeatedly have to read the undef mask from // the source and write it to the destination. Even if we optimized the memory accesses, @@ -655,7 +628,7 @@ impl Allocation { ranges.push(cur_len); - AllocationDefinedness { ranges, initial, } + AllocationDefinedness { ranges, initial } } /// Applies multiple instances of the run-length encoding to the undef mask. @@ -747,33 +720,24 @@ impl Allocation { let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize)); for i in 0..length { - new_relocations.extend( - relocations - .iter() - .map(|&(offset, reloc)| { - // compute offset for current repetition - let dest_offset = dest.offset + (i * size); - ( - // shift offsets from source allocation to destination allocation - offset + dest_offset - src.offset, - reloc, - ) - }) - ); + new_relocations.extend(relocations.iter().map(|&(offset, reloc)| { + // compute offset for current repetition + let dest_offset = dest.offset + (i * size); + ( + // shift offsets from source allocation to destination allocation + offset + dest_offset - src.offset, + reloc, + ) + })); } - AllocationRelocations { - relative_relocations: new_relocations, - } + AllocationRelocations { relative_relocations: new_relocations } } /// Applies a relocation copy. /// The affected range, as defined in the parameters to `prepare_relocation_copy` is expected /// to be clear of relocations. - pub fn mark_relocation_range( - &mut self, - relocations: AllocationRelocations, - ) { + pub fn mark_relocation_range(&mut self, relocations: AllocationRelocations) { self.relocations.insert_presorted(relocations.relative_relocations); } } @@ -786,8 +750,18 @@ type Block = u64; /// A bitmask where each bit refers to the byte with the same index. If the bit is `true`, the byte /// is defined. If it is `false` the byte is undefined. -#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, - RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Clone, + Debug, + Eq, + PartialEq, + PartialOrd, + Ord, + Hash, + RustcEncodable, + RustcDecodable, + HashStable +)] pub struct UndefMask { blocks: Vec, len: Size, @@ -797,10 +771,7 @@ impl UndefMask { pub const BLOCK_SIZE: u64 = 64; pub fn new(size: Size, state: bool) -> Self { - let mut m = UndefMask { - blocks: vec![], - len: Size::ZERO, - }; + let mut m = UndefMask { blocks: vec![], len: Size::ZERO }; m.grow(size, state); m } @@ -816,13 +787,11 @@ impl UndefMask { } // FIXME(oli-obk): optimize this for allocations larger than a block. - let idx = (start.bytes()..end.bytes()) - .map(|i| Size::from_bytes(i)) - .find(|&i| !self.get(i)); + let idx = (start.bytes()..end.bytes()).map(|i| Size::from_bytes(i)).find(|&i| !self.get(i)); match idx { Some(idx) => Err(idx), - None => Ok(()) + None => Ok(()), } } @@ -861,7 +830,7 @@ impl UndefMask { self.blocks[blockb] |= u64::max_value() >> (64 - bitb); } // Fill in all the other blocks (much faster than one bit at a time). - for block in (blocka + 1) .. blockb { + for block in (blocka + 1)..blockb { self.blocks[block] = u64::max_value(); } } else { @@ -872,7 +841,7 @@ impl UndefMask { self.blocks[blockb] &= !(u64::max_value() >> (64 - bitb)); } // Fill in all the other blocks (much faster than one bit at a time). - for block in (blocka + 1) .. blockb { + for block in (blocka + 1)..blockb { self.blocks[block] = 0; } } diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 0dec7c071bfee..843880200f3d7 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -1,20 +1,20 @@ -use super::{RawConst, Pointer, CheckInAllocMsg, ScalarMaybeUndef}; +use super::{CheckInAllocMsg, Pointer, RawConst, ScalarMaybeUndef}; use crate::hir; use crate::hir::map::definitions::DefPathData; use crate::mir; -use crate::ty::{self, Ty, layout}; -use crate::ty::layout::{Size, Align, LayoutError}; +use crate::ty::layout::{Align, LayoutError, Size}; use crate::ty::query::TyCtxtAt; +use crate::ty::{self, layout, Ty}; use backtrace::Backtrace; use errors::DiagnosticBuilder; +use hir::GeneratorKind; use rustc_macros::HashStable; use rustc_target::spec::abi::Abi; -use syntax_pos::{Pos, Span}; +use std::{any::Any, env, fmt}; use syntax::symbol::Symbol; -use hir::GeneratorKind; -use std::{fmt, env, any::Any}; +use syntax_pos::{Pos, Span}; use rustc_error_codes::*; @@ -30,9 +30,11 @@ pub enum ErrorHandled { impl ErrorHandled { pub fn assert_reported(self) { match self { - ErrorHandled::Reported => {}, - ErrorHandled::TooGeneric => bug!("MIR interpretation failed without reporting an error \ - even though it was fully monomorphized"), + ErrorHandled::Reported => {} + ErrorHandled::TooGeneric => bug!( + "MIR interpretation failed without reporting an error \ + even though it was fully monomorphized" + ), } } } @@ -93,7 +95,7 @@ impl<'tcx> ConstEvalErr<'tcx> { Ok(mut err) => { err.emit(); ErrorHandled::Reported - }, + } Err(err) => err, } } @@ -105,11 +107,7 @@ impl<'tcx> ConstEvalErr<'tcx> { lint_root: hir::HirId, span: Option, ) -> ErrorHandled { - let lint = self.struct_generic( - tcx, - message, - Some(lint_root), - ); + let lint = self.struct_generic(tcx, message, Some(lint_root)); match lint { Ok(mut lint) => { if let Some(span) = span { @@ -126,7 +124,7 @@ impl<'tcx> ConstEvalErr<'tcx> { } lint.emit(); ErrorHandled::Reported - }, + } Err(err) => err, } } @@ -139,17 +137,17 @@ impl<'tcx> ConstEvalErr<'tcx> { ) -> Result, ErrorHandled> { let must_error = match self.error { InterpError::MachineStop(_) => bug!("CTFE does not stop"), - err_inval!(Layout(LayoutError::Unknown(_))) | - err_inval!(TooGeneric) => - return Err(ErrorHandled::TooGeneric), - err_inval!(TypeckError) => - return Err(ErrorHandled::Reported), + err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { + return Err(ErrorHandled::TooGeneric); + } + err_inval!(TypeckError) => return Err(ErrorHandled::Reported), err_inval!(Layout(LayoutError::SizeOverflow(_))) => true, _ => false, }; trace!("reporting const eval failure at {:?}", self.span); let mut err = if let (Some(lint_root), false) = (lint_root, must_error) { - let hir_id = self.stacktrace + let hir_id = self + .stacktrace .iter() .rev() .filter_map(|frame| frame.lint_root) @@ -173,7 +171,7 @@ impl<'tcx> ConstEvalErr<'tcx> { // is sometimes empty because we create "fake" eval contexts in CTFE to do work // on constant values. if self.stacktrace.len() > 0 { - for frame_info in &self.stacktrace[..self.stacktrace.len()-1] { + for frame_info in &self.stacktrace[..self.stacktrace.len() - 1] { err.span_label(frame_info.call_site, frame_info.to_string()); } } @@ -196,7 +194,6 @@ pub struct InterpErrorInfo<'tcx> { backtrace: Option>, } - impl fmt::Display for InterpErrorInfo<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.kind) @@ -221,7 +218,8 @@ impl From for InterpErrorInfo<'tcx> { match err { ErrorHandled::Reported => err_inval!(ReferencedConstant), ErrorHandled::TooGeneric => err_inval!(TooGeneric), - }.into() + } + .into() } } @@ -239,28 +237,17 @@ impl<'tcx> From> for InterpErrorInfo<'tcx> { } else { Some(Box::new(backtrace)) } - }, + } _ => None, }; - InterpErrorInfo { - kind, - backtrace, - } + InterpErrorInfo { kind, backtrace } } } #[derive(Clone, RustcEncodable, RustcDecodable, HashStable, PartialEq)] pub enum PanicInfo { - Panic { - msg: Symbol, - line: u32, - col: u32, - file: Symbol, - }, - BoundsCheck { - len: O, - index: O, - }, + Panic { msg: Symbol, line: u32, col: u32, file: Symbol }, + BoundsCheck { len: O, index: O }, Overflow(mir::BinOp), OverflowNeg, DivisionByZero, @@ -279,38 +266,22 @@ impl PanicInfo { pub fn description(&self) -> &'static str { use PanicInfo::*; match self { - Overflow(mir::BinOp::Add) => - "attempt to add with overflow", - Overflow(mir::BinOp::Sub) => - "attempt to subtract with overflow", - Overflow(mir::BinOp::Mul) => - "attempt to multiply with overflow", - Overflow(mir::BinOp::Div) => - "attempt to divide with overflow", - Overflow(mir::BinOp::Rem) => - "attempt to calculate the remainder with overflow", - OverflowNeg => - "attempt to negate with overflow", - Overflow(mir::BinOp::Shr) => - "attempt to shift right with overflow", - Overflow(mir::BinOp::Shl) => - "attempt to shift left with overflow", - Overflow(op) => - bug!("{:?} cannot overflow", op), - DivisionByZero => - "attempt to divide by zero", - RemainderByZero => - "attempt to calculate the remainder with a divisor of zero", - ResumedAfterReturn(GeneratorKind::Gen) => - "generator resumed after completion", - ResumedAfterReturn(GeneratorKind::Async(_)) => - "`async fn` resumed after completion", - ResumedAfterPanic(GeneratorKind::Gen) => - "generator resumed after panicking", - ResumedAfterPanic(GeneratorKind::Async(_)) => - "`async fn` resumed after panicking", - Panic { .. } | BoundsCheck { .. } => - bug!("Unexpected PanicInfo"), + Overflow(mir::BinOp::Add) => "attempt to add with overflow", + Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow", + Overflow(mir::BinOp::Mul) => "attempt to multiply with overflow", + Overflow(mir::BinOp::Div) => "attempt to divide with overflow", + Overflow(mir::BinOp::Rem) => "attempt to calculate the remainder with overflow", + OverflowNeg => "attempt to negate with overflow", + Overflow(mir::BinOp::Shr) => "attempt to shift right with overflow", + Overflow(mir::BinOp::Shl) => "attempt to shift left with overflow", + Overflow(op) => bug!("{:?} cannot overflow", op), + DivisionByZero => "attempt to divide by zero", + RemainderByZero => "attempt to calculate the remainder with a divisor of zero", + ResumedAfterReturn(GeneratorKind::Gen) => "generator resumed after completion", + ResumedAfterReturn(GeneratorKind::Async(_)) => "`async fn` resumed after completion", + ResumedAfterPanic(GeneratorKind::Gen) => "generator resumed after panicking", + ResumedAfterPanic(GeneratorKind::Async(_)) => "`async fn` resumed after panicking", + Panic { .. } | BoundsCheck { .. } => bug!("Unexpected PanicInfo"), } } } @@ -319,12 +290,13 @@ impl fmt::Debug for PanicInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use PanicInfo::*; match self { - Panic { ref msg, line, col, ref file } => - write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col), - BoundsCheck { ref len, ref index } => - write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index), - _ => - write!(f, "{}", self.description()), + Panic { ref msg, line, col, ref file } => { + write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col) + } + BoundsCheck { ref len, ref index } => { + write!(f, "index out of bounds: the len is {:?} but the index is {:?}", len, index) + } + _ => write!(f, "{}", self.description()), } } } @@ -348,14 +320,10 @@ impl fmt::Debug for InvalidProgramInfo<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use InvalidProgramInfo::*; match self { - TooGeneric => - write!(f, "encountered overly generic constant"), - ReferencedConstant => - write!(f, "referenced constant has errors"), - TypeckError => - write!(f, "encountered constants with type errors, stopping evaluation"), - Layout(ref err) => - write!(f, "{}", err), + TooGeneric => write!(f, "encountered overly generic constant"), + ReferencedConstant => write!(f, "referenced constant has errors"), + TypeckError => write!(f, "encountered constants with type errors, stopping evaluation"), + Layout(ref err) => write!(f, "{}", err), } } } @@ -384,21 +352,17 @@ impl fmt::Debug for UndefinedBehaviorInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use UndefinedBehaviorInfo::*; match self { - Ub(msg) | UbExperimental(msg) => - write!(f, "{}", msg), - Unreachable => - write!(f, "entering unreachable code"), - InvalidDiscriminant(val) => - write!(f, "encountering invalid enum discriminant {}", val), - BoundsCheckFailed { ref len, ref index } => - write!(f, "indexing out of bounds: the len is {:?} but the index is {:?}", - len, index), - DivisionByZero => - write!(f, "dividing by zero"), - RemainderByZero => - write!(f, "calculating the remainder with a divisor of zero"), - PointerArithOverflow => - write!(f, "overflowing in-bounds pointer arithmetic"), + Ub(msg) | UbExperimental(msg) => write!(f, "{}", msg), + Unreachable => write!(f, "entering unreachable code"), + InvalidDiscriminant(val) => write!(f, "encountering invalid enum discriminant {}", val), + BoundsCheckFailed { ref len, ref index } => write!( + f, + "indexing out of bounds: the len is {:?} but the index is {:?}", + len, index + ), + DivisionByZero => write!(f, "dividing by zero"), + RemainderByZero => write!(f, "calculating the remainder with a divisor of zero"), + PointerArithOverflow => write!(f, "overflowing in-bounds pointer arithmetic"), } } } @@ -474,112 +438,133 @@ impl fmt::Debug for UnsupportedOpInfo<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use UnsupportedOpInfo::*; match self { - PointerOutOfBounds { ptr, msg, allocation_size } => { - write!(f, "{} failed: pointer must be in-bounds at offset {}, \ + PointerOutOfBounds { ptr, msg, allocation_size } => write!( + f, + "{} failed: pointer must be in-bounds at offset {}, \ but is outside bounds of allocation {} which has size {}", - msg, ptr.offset.bytes(), ptr.alloc_id, allocation_size.bytes()) - }, - ValidationFailure(ref err) => { - write!(f, "type validation failed: {}", err) - } + msg, + ptr.offset.bytes(), + ptr.alloc_id, + allocation_size.bytes() + ), + ValidationFailure(ref err) => write!(f, "type validation failed: {}", err), NoMirFor(ref func) => write!(f, "no MIR for `{}`", func), - FunctionAbiMismatch(caller_abi, callee_abi) => - write!(f, "tried to call a function with ABI {:?} using caller ABI {:?}", - callee_abi, caller_abi), - FunctionArgMismatch(caller_ty, callee_ty) => - write!(f, "tried to call a function with argument of type {:?} \ + FunctionAbiMismatch(caller_abi, callee_abi) => write!( + f, + "tried to call a function with ABI {:?} using caller ABI {:?}", + callee_abi, caller_abi + ), + FunctionArgMismatch(caller_ty, callee_ty) => write!( + f, + "tried to call a function with argument of type {:?} \ passing data of type {:?}", - callee_ty, caller_ty), - FunctionRetMismatch(caller_ty, callee_ty) => - write!(f, "tried to call a function with return type {:?} \ + callee_ty, caller_ty + ), + FunctionRetMismatch(caller_ty, callee_ty) => write!( + f, + "tried to call a function with return type {:?} \ passing return place of type {:?}", - callee_ty, caller_ty), - FunctionArgCountMismatch => - write!(f, "tried to call a function with incorrect number of arguments"), - ReallocatedWrongMemoryKind(ref old, ref new) => - write!(f, "tried to reallocate memory from `{}` to `{}`", old, new), - DeallocatedWrongMemoryKind(ref old, ref new) => - write!(f, "tried to deallocate `{}` memory but gave `{}` as the kind", old, new), - InvalidChar(c) => - write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c), - AlignmentCheckFailed { required, has } => - write!(f, "tried to access memory with alignment {}, but alignment {} is required", - has.bytes(), required.bytes()), - TypeNotPrimitive(ty) => - write!(f, "expected primitive type, got {}", ty), - PathNotFound(ref path) => - write!(f, "cannot find path {:?}", path), - IncorrectAllocationInformation(size, size2, align, align2) => - write!(f, "incorrect alloc info: expected size {} and align {}, \ + callee_ty, caller_ty + ), + FunctionArgCountMismatch => { + write!(f, "tried to call a function with incorrect number of arguments") + } + ReallocatedWrongMemoryKind(ref old, ref new) => { + write!(f, "tried to reallocate memory from `{}` to `{}`", old, new) + } + DeallocatedWrongMemoryKind(ref old, ref new) => { + write!(f, "tried to deallocate `{}` memory but gave `{}` as the kind", old, new) + } + InvalidChar(c) => { + write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c) + } + AlignmentCheckFailed { required, has } => write!( + f, + "tried to access memory with alignment {}, but alignment {} is required", + has.bytes(), + required.bytes() + ), + TypeNotPrimitive(ty) => write!(f, "expected primitive type, got {}", ty), + PathNotFound(ref path) => write!(f, "cannot find path {:?}", path), + IncorrectAllocationInformation(size, size2, align, align2) => write!( + f, + "incorrect alloc info: expected size {} and align {}, \ got size {} and align {}", - size.bytes(), align.bytes(), size2.bytes(), align2.bytes()), - InvalidMemoryAccess => - write!(f, "tried to access memory through an invalid pointer"), - DanglingPointerDeref => - write!(f, "dangling pointer was dereferenced"), - DoubleFree => - write!(f, "tried to deallocate dangling pointer"), - InvalidFunctionPointer => - write!(f, "tried to use a function pointer after offsetting it"), - InvalidBool => - write!(f, "invalid boolean value read"), - InvalidNullPointerUsage => - write!(f, "invalid use of NULL pointer"), - ReadPointerAsBytes => - write!(f, "a raw memory access tried to access part of a pointer value as raw \ - bytes"), - ReadBytesAsPointer => - write!(f, "a memory access tried to interpret some bytes as a pointer"), - ReadForeignStatic => - write!(f, "tried to read from foreign (extern) static"), - InvalidPointerMath => - write!(f, "attempted to do invalid arithmetic on pointers that would leak base \ - addresses, e.g., comparing pointers into different allocations"), - DeadLocal => - write!(f, "tried to access a dead local variable"), - DerefFunctionPointer => - write!(f, "tried to dereference a function pointer"), - ExecuteMemory => - write!(f, "tried to treat a memory pointer as a function pointer"), - OutOfTls => - write!(f, "reached the maximum number of representable TLS keys"), - TlsOutOfBounds => - write!(f, "accessed an invalid (unallocated) TLS key"), - CalledClosureAsFunction => - write!(f, "tried to call a closure through a function pointer"), - VtableForArgumentlessMethod => - write!(f, "tried to call a vtable function without arguments"), - ModifiedConstantMemory => - write!(f, "tried to modify constant memory"), - ModifiedStatic => - write!(f, "tried to modify a static's initial value from another static's \ - initializer"), - ReallocateNonBasePtr => - write!(f, "tried to reallocate with a pointer not to the beginning of an \ - existing object"), - DeallocateNonBasePtr => - write!(f, "tried to deallocate with a pointer not to the beginning of an \ - existing object"), - HeapAllocZeroBytes => - write!(f, "tried to re-, de- or allocate zero bytes on the heap"), - ReadFromReturnPointer => - write!(f, "tried to read from the return pointer"), - UnimplementedTraitSelection => - write!(f, "there were unresolved type arguments during trait selection"), - InvalidBoolOp(_) => - write!(f, "invalid boolean operation"), - UnterminatedCString(_) => - write!(f, "attempted to get length of a null-terminated string, but no null \ - found before end of allocation"), - ReadUndefBytes(_) => - write!(f, "attempted to read undefined bytes"), - HeapAllocNonPowerOfTwoAlignment(_) => - write!(f, "tried to re-, de-, or allocate heap memory with alignment that is \ - not a power of two"), - Unsupported(ref msg) => - write!(f, "{}", msg), - ConstPropUnsupported(ref msg) => - write!(f, "Constant propagation encountered an unsupported situation: {}", msg), + size.bytes(), + align.bytes(), + size2.bytes(), + align2.bytes() + ), + InvalidMemoryAccess => write!(f, "tried to access memory through an invalid pointer"), + DanglingPointerDeref => write!(f, "dangling pointer was dereferenced"), + DoubleFree => write!(f, "tried to deallocate dangling pointer"), + InvalidFunctionPointer => { + write!(f, "tried to use a function pointer after offsetting it") + } + InvalidBool => write!(f, "invalid boolean value read"), + InvalidNullPointerUsage => write!(f, "invalid use of NULL pointer"), + ReadPointerAsBytes => write!( + f, + "a raw memory access tried to access part of a pointer value as raw \ + bytes" + ), + ReadBytesAsPointer => { + write!(f, "a memory access tried to interpret some bytes as a pointer") + } + ReadForeignStatic => write!(f, "tried to read from foreign (extern) static"), + InvalidPointerMath => write!( + f, + "attempted to do invalid arithmetic on pointers that would leak base \ + addresses, e.g., comparing pointers into different allocations" + ), + DeadLocal => write!(f, "tried to access a dead local variable"), + DerefFunctionPointer => write!(f, "tried to dereference a function pointer"), + ExecuteMemory => write!(f, "tried to treat a memory pointer as a function pointer"), + OutOfTls => write!(f, "reached the maximum number of representable TLS keys"), + TlsOutOfBounds => write!(f, "accessed an invalid (unallocated) TLS key"), + CalledClosureAsFunction => { + write!(f, "tried to call a closure through a function pointer") + } + VtableForArgumentlessMethod => { + write!(f, "tried to call a vtable function without arguments") + } + ModifiedConstantMemory => write!(f, "tried to modify constant memory"), + ModifiedStatic => write!( + f, + "tried to modify a static's initial value from another static's \ + initializer" + ), + ReallocateNonBasePtr => write!( + f, + "tried to reallocate with a pointer not to the beginning of an \ + existing object" + ), + DeallocateNonBasePtr => write!( + f, + "tried to deallocate with a pointer not to the beginning of an \ + existing object" + ), + HeapAllocZeroBytes => write!(f, "tried to re-, de- or allocate zero bytes on the heap"), + ReadFromReturnPointer => write!(f, "tried to read from the return pointer"), + UnimplementedTraitSelection => { + write!(f, "there were unresolved type arguments during trait selection") + } + InvalidBoolOp(_) => write!(f, "invalid boolean operation"), + UnterminatedCString(_) => write!( + f, + "attempted to get length of a null-terminated string, but no null \ + found before end of allocation" + ), + ReadUndefBytes(_) => write!(f, "attempted to read undefined bytes"), + HeapAllocNonPowerOfTwoAlignment(_) => write!( + f, + "tried to re-, de-, or allocate heap memory with alignment that is \ + not a power of two" + ), + Unsupported(ref msg) => write!(f, "{}", msg), + ConstPropUnsupported(ref msg) => { + write!(f, "Constant propagation encountered an unsupported situation: {}", msg) + } } } } @@ -597,11 +582,14 @@ impl fmt::Debug for ResourceExhaustionInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use ResourceExhaustionInfo::*; match self { - StackFrameLimitReached => - write!(f, "reached the configured maximum number of stack frames"), - InfiniteLoop => - write!(f, "duplicate interpreter state observed here, const evaluation will never \ - terminate"), + StackFrameLimitReached => { + write!(f, "reached the configured maximum number of stack frames") + } + InfiniteLoop => write!( + f, + "duplicate interpreter state observed here, const evaluation will never \ + terminate" + ), } } } @@ -637,18 +625,12 @@ impl fmt::Debug for InterpError<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use InterpError::*; match *self { - Unsupported(ref msg) => - write!(f, "{:?}", msg), - InvalidProgram(ref msg) => - write!(f, "{:?}", msg), - UndefinedBehavior(ref msg) => - write!(f, "{:?}", msg), - ResourceExhaustion(ref msg) => - write!(f, "{:?}", msg), - Panic(ref msg) => - write!(f, "{:?}", msg), - MachineStop(_) => - write!(f, "machine caused execution to stop"), + Unsupported(ref msg) => write!(f, "{:?}", msg), + InvalidProgram(ref msg) => write!(f, "{:?}", msg), + UndefinedBehavior(ref msg) => write!(f, "{:?}", msg), + ResourceExhaustion(ref msg) => write!(f, "{:?}", msg), + Panic(ref msg) => write!(f, "{:?}", msg), + MachineStop(_) => write!(f, "machine caused execution to stop"), } } } diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 80bac92d00354..185fa4cf9416f 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -97,40 +97,40 @@ macro_rules! throw_machine_stop { }; } -mod error; -mod value; mod allocation; +mod error; mod pointer; mod queries; +mod value; pub use self::error::{ - InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error, - FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicInfo, UnsupportedOpInfo, - InvalidProgramInfo, ResourceExhaustionInfo, UndefinedBehaviorInfo, + struct_error, AssertMessage, ConstEvalErr, ConstEvalRawResult, ConstEvalResult, ErrorHandled, + FrameInfo, InterpError, InterpErrorInfo, InterpResult, InvalidProgramInfo, PanicInfo, + ResourceExhaustionInfo, UndefinedBehaviorInfo, UnsupportedOpInfo, }; -pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue, get_slice_bytes}; +pub use self::value::{get_slice_bytes, ConstValue, RawConst, Scalar, ScalarMaybeUndef}; pub use self::allocation::{Allocation, AllocationExtra, Relocations, UndefMask}; -pub use self::pointer::{Pointer, PointerArithmetic, CheckInAllocMsg}; +pub use self::pointer::{CheckInAllocMsg, Pointer, PointerArithmetic}; -use crate::mir; use crate::hir::def_id::DefId; -use crate::ty::{self, TyCtxt, Instance}; +use crate::mir; use crate::ty::codec::TyDecoder; use crate::ty::layout::{self, Size}; use crate::ty::subst::GenericArgKind; -use std::io; -use std::fmt; -use std::num::NonZeroU32; -use std::sync::atomic::{AtomicU32, Ordering}; -use rustc_serialize::{Encoder, Decodable, Encodable}; +use crate::ty::{self, Instance, TyCtxt}; +use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::{Lock, HashMapExt}; +use rustc_data_structures::sync::{HashMapExt, Lock}; use rustc_data_structures::tiny_list::TinyList; use rustc_macros::HashStable; -use byteorder::{WriteBytesExt, ReadBytesExt, LittleEndian, BigEndian}; +use rustc_serialize::{Decodable, Encodable, Encoder}; +use std::fmt; +use std::io; +use std::num::NonZeroU32; +use std::sync::atomic::{AtomicU32, Ordering}; /// Uniquely identifies one of the following: /// - A constant @@ -165,8 +165,8 @@ pub fn specialized_encode_alloc_id<'tcx, E: Encoder>( tcx: TyCtxt<'tcx>, alloc_id: AllocId, ) -> Result<(), E::Error> { - let alloc: GlobalAlloc<'tcx> = tcx.alloc_map.lock().get(alloc_id) - .expect("no value for given alloc ID"); + let alloc: GlobalAlloc<'tcx> = + tcx.alloc_map.lock().get(alloc_id).expect("no value for given alloc ID"); match alloc { GlobalAlloc::Memory(alloc) => { trace!("encoding {:?} with {:#?}", alloc_id, alloc); @@ -214,19 +214,13 @@ impl AllocDecodingState { // Make sure this is never zero. let session_id = DecodingSessionId::new((counter & 0x7FFFFFFF) + 1).unwrap(); - AllocDecodingSession { - state: self, - session_id, - } + AllocDecodingSession { state: self, session_id } } pub fn new(data_offsets: Vec) -> Self { let decoding_state = vec![Lock::new(State::Empty); data_offsets.len()]; - Self { - decoding_state, - data_offsets, - } + Self { decoding_state, data_offsets } } } @@ -269,16 +263,15 @@ impl<'s> AllocDecodingSession<'s> { // If this is an allocation, we need to reserve an // `AllocId` so we can decode cyclic graphs. let alloc_id = decoder.tcx().alloc_map.lock().reserve(); - *entry = State::InProgress( - TinyList::new_single(self.session_id), - alloc_id); + *entry = + State::InProgress(TinyList::new_single(self.session_id), alloc_id); Some(alloc_id) - }, + } AllocDiscriminant::Fn | AllocDiscriminant::Static => { // Fns and statics cannot be cyclic, and their `AllocId` // is determined later by interning. - *entry = State::InProgressNonAlloc( - TinyList::new_single(self.session_id)); + *entry = + State::InProgressNonAlloc(TinyList::new_single(self.session_id)); None } } @@ -295,7 +288,7 @@ impl<'s> AllocDecodingSession<'s> { State::InProgress(ref mut sessions, alloc_id) => { if sessions.contains(&self.session_id) { // Don't recurse. - return Ok(alloc_id) + return Ok(alloc_id); } else { // Start decoding concurrently. sessions.insert(self.session_id); @@ -315,7 +308,7 @@ impl<'s> AllocDecodingSession<'s> { trace!("decoded alloc {:?}: {:#?}", alloc_id, alloc); decoder.tcx().alloc_map.lock().set_alloc_id_same_memory(alloc_id, alloc); Ok(alloc_id) - }, + } AllocDiscriminant::Fn => { assert!(alloc_id.is_none()); trace!("creating fn alloc ID"); @@ -323,7 +316,7 @@ impl<'s> AllocDecodingSession<'s> { trace!("decoded fn alloc instance: {:?}", instance); let alloc_id = decoder.tcx().alloc_map.lock().create_fn_alloc(instance); Ok(alloc_id) - }, + } AllocDiscriminant::Static => { assert!(alloc_id.is_none()); trace!("creating extern static alloc ID"); @@ -379,11 +372,7 @@ pub struct AllocMap<'tcx> { impl<'tcx> AllocMap<'tcx> { pub fn new() -> Self { - AllocMap { - alloc_map: Default::default(), - dedup: Default::default(), - next_id: AllocId(0), - } + AllocMap { alloc_map: Default::default(), dedup: Default::default(), next_id: AllocId(0) } } /// Obtains a new allocation ID that can be referenced but does not @@ -391,15 +380,13 @@ impl<'tcx> AllocMap<'tcx> { /// /// Make sure to call `set_alloc_id_memory` or `set_alloc_id_same_memory` before returning such /// an `AllocId` from a query. - pub fn reserve( - &mut self, - ) -> AllocId { + pub fn reserve(&mut self) -> AllocId { let next = self.next_id; - self.next_id.0 = self.next_id.0 - .checked_add(1) - .expect("You overflowed a u64 by incrementing by 1... \ + self.next_id.0 = self.next_id.0.checked_add(1).expect( + "You overflowed a u64 by incrementing by 1... \ You've just earned yourself a free drink if we ever meet. \ - Seriously, how did you do that?!"); + Seriously, how did you do that?!", + ); next } @@ -408,7 +395,7 @@ impl<'tcx> AllocMap<'tcx> { /// to dedup IDs for "real" memory! fn reserve_and_set_dedup(&mut self, alloc: GlobalAlloc<'tcx>) -> AllocId { match alloc { - GlobalAlloc::Function(..) | GlobalAlloc::Static(..) => {}, + GlobalAlloc::Function(..) | GlobalAlloc::Static(..) => {} GlobalAlloc::Memory(..) => bug!("Trying to dedup-reserve memory with real data!"), } if let Some(&alloc_id) = self.dedup.get(&alloc) { @@ -437,11 +424,9 @@ impl<'tcx> AllocMap<'tcx> { // `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true. // However, formatting code relies on function identity (see #58320), so we only do // this for generic functions. Lifetime parameters are ignored. - let is_generic = instance.substs.into_iter().any(|kind| { - match kind.unpack() { - GenericArgKind::Lifetime(_) => false, - _ => true, - } + let is_generic = instance.substs.into_iter().any(|kind| match kind.unpack() { + GenericArgKind::Lifetime(_) => false, + _ => true, }); if is_generic { // Get a fresh ID. diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index 0b27f512e55b8..9b0399e22c59c 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -20,12 +20,16 @@ impl Display for CheckInAllocMsg { /// When this is printed as an error the context looks like this /// "{test name} failed: pointer must be in-bounds at offset..." fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", match *self { - CheckInAllocMsg::MemoryAccessTest => "Memory access", - CheckInAllocMsg::NullPointerTest => "Null pointer test", - CheckInAllocMsg::PointerArithmeticTest => "Pointer arithmetic", - CheckInAllocMsg::InboundsTest => "Inbounds test", - }) + write!( + f, + "{}", + match *self { + CheckInAllocMsg::MemoryAccessTest => "Memory access", + CheckInAllocMsg::NullPointerTest => "Null pointer test", + CheckInAllocMsg::PointerArithmeticTest => "Pointer arithmetic", + CheckInAllocMsg::InboundsTest => "Inbounds test", + } + ) } } @@ -44,13 +48,13 @@ pub trait PointerArithmetic: layout::HasDataLayout { #[inline] fn usize_max(&self) -> u64 { let max_usize_plus_1 = 1u128 << self.pointer_size().bits(); - u64::try_from(max_usize_plus_1-1).unwrap() + u64::try_from(max_usize_plus_1 - 1).unwrap() } #[inline] fn isize_max(&self) -> i64 { - let max_isize_plus_1 = 1u128 << (self.pointer_size().bits()-1); - i64::try_from(max_isize_plus_1-1).unwrap() + let max_isize_plus_1 = 1u128 << (self.pointer_size().bits() - 1); + i64::try_from(max_isize_plus_1 - 1).unwrap() } /// Helper function: truncate given value-"overflowed flag" pair to pointer size and @@ -107,8 +111,18 @@ impl PointerArithmetic for T {} /// /// `Pointer` is also generic over the `Tag` associated with each pointer, /// which is used to do provenance tracking during execution. -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, - RustcEncodable, RustcDecodable, Hash, HashStable)] +#[derive( + Copy, + Clone, + Eq, + PartialEq, + Ord, + PartialOrd, + RustcEncodable, + RustcDecodable, + Hash, + HashStable +)] pub struct Pointer { pub alloc_id: Id, pub offset: Size, @@ -144,8 +158,7 @@ impl Pointer<()> { } #[inline(always)] - pub fn with_tag(self, tag: Tag) -> Pointer - { + pub fn with_tag(self, tag: Tag) -> Pointer { Pointer::new_with_tag(self.alloc_id, self.offset, tag) } } @@ -161,7 +174,7 @@ impl<'tcx, Tag> Pointer { Ok(Pointer::new_with_tag( self.alloc_id, Size::from_bytes(cx.data_layout().offset(self.offset.bytes(), i.bytes())?), - self.tag + self.tag, )) } diff --git a/src/librustc/mir/interpret/queries.rs b/src/librustc/mir/interpret/queries.rs index 5fd49a056d22c..e6caa146a627f 100644 --- a/src/librustc/mir/interpret/queries.rs +++ b/src/librustc/mir/interpret/queries.rs @@ -1,14 +1,12 @@ use super::{ConstEvalResult, ErrorHandled, GlobalId}; -use crate::mir; use crate::hir::def_id::DefId; -use crate::ty::{self, TyCtxt}; +use crate::mir; use crate::ty::subst::{InternalSubsts, SubstsRef}; +use crate::ty::{self, TyCtxt}; use syntax_pos::Span; - impl<'tcx> TyCtxt<'tcx> { - /// Evaluates a constant without providing any substitutions. This is useful to evaluate consts /// that can't take any generic arguments like statics, const items or enum discriminants. If a /// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned. @@ -19,10 +17,7 @@ impl<'tcx> TyCtxt<'tcx> { // encountered. let substs = InternalSubsts::identity_for_item(self, def_id); let instance = ty::Instance::new(def_id, substs); - let cid = GlobalId { - instance, - promoted: None, - }; + let cid = GlobalId { instance, promoted: None }; let param_env = self.param_env(def_id); self.const_eval_validated(param_env.and(cid)) } @@ -41,14 +36,9 @@ impl<'tcx> TyCtxt<'tcx> { param_env: ty::ParamEnv<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>, - span: Option + span: Option, ) -> ConstEvalResult<'tcx> { - let instance = ty::Instance::resolve( - self, - param_env, - def_id, - substs, - ); + let instance = ty::Instance::resolve(self, param_env, def_id, substs); if let Some(instance) = instance { self.const_eval_instance(param_env, instance, span) } else { @@ -60,12 +50,9 @@ impl<'tcx> TyCtxt<'tcx> { self, param_env: ty::ParamEnv<'tcx>, instance: ty::Instance<'tcx>, - span: Option + span: Option, ) -> ConstEvalResult<'tcx> { - let cid = GlobalId { - instance, - promoted: None, - }; + let cid = GlobalId { instance, promoted: None }; if let Some(span) = span { self.at(span).const_eval_validated(param_env.and(cid)) } else { @@ -77,12 +64,9 @@ impl<'tcx> TyCtxt<'tcx> { pub fn const_eval_promoted( self, instance: ty::Instance<'tcx>, - promoted: mir::Promoted + promoted: mir::Promoted, ) -> ConstEvalResult<'tcx> { - let cid = GlobalId { - instance, - promoted: Some(promoted), - }; + let cid = GlobalId { instance, promoted: Some(promoted) }; let param_env = ty::ParamEnv::reveal_all(); self.const_eval_validated(param_env.and(cid)) } diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index f48d22291c6a4..49b542af0a034 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -1,10 +1,16 @@ -use std::fmt; +use rustc_apfloat::{ + ieee::{Double, Single}, + Float, +}; use rustc_macros::HashStable; -use rustc_apfloat::{Float, ieee::{Double, Single}}; +use std::fmt; -use crate::ty::{Ty, layout::{HasDataLayout, Size}}; +use crate::ty::{ + layout::{HasDataLayout, Size}, + Ty, +}; -use super::{InterpResult, Pointer, PointerArithmetic, Allocation, AllocId, sign_extend, truncate}; +use super::{sign_extend, truncate, AllocId, Allocation, InterpResult, Pointer, PointerArithmetic}; /// Represents the result of a raw const operation, pre-validation. #[derive(Clone, HashStable)] @@ -17,8 +23,19 @@ pub struct RawConst<'tcx> { /// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for /// array length computations, enum discriminants and the pattern matching logic. -#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, - RustcEncodable, RustcDecodable, Hash, HashStable)] +#[derive( + Copy, + Clone, + Debug, + Eq, + PartialEq, + PartialOrd, + Ord, + RustcEncodable, + RustcDecodable, + Hash, + HashStable +)] pub enum ConstValue<'tcx> { /// Used only for types with `layout::abi::Scalar` ABI and ZSTs. /// @@ -26,11 +43,7 @@ pub enum ConstValue<'tcx> { Scalar(Scalar), /// Used only for `&[u8]` and `&str` - Slice { - data: &'tcx Allocation, - start: usize, - end: usize, - }, + Slice { data: &'tcx Allocation, start: usize, end: usize }, /// A value not represented/representable by `Scalar` or `Slice` ByRef { @@ -49,8 +62,7 @@ impl<'tcx> ConstValue<'tcx> { #[inline] pub fn try_to_scalar(&self) -> Option { match *self { - ConstValue::ByRef { .. } | - ConstValue::Slice { .. } => None, + ConstValue::ByRef { .. } | ConstValue::Slice { .. } => None, ConstValue::Scalar(val) => Some(val), } } @@ -60,8 +72,18 @@ impl<'tcx> ConstValue<'tcx> { /// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in /// size. Like a range of bytes in an `Allocation`, a `Scalar` can either represent the raw bytes /// of a simple value or a pointer into another `Allocation` -#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, - RustcEncodable, RustcDecodable, Hash, HashStable)] +#[derive( + Clone, + Copy, + Eq, + PartialEq, + Ord, + PartialOrd, + RustcEncodable, + RustcDecodable, + Hash, + HashStable +)] pub enum Scalar { /// The raw bytes of a simple value. Raw { @@ -83,8 +105,7 @@ static_assert_size!(Scalar, 24); impl fmt::Debug for Scalar { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Scalar::Ptr(ptr) => - write!(f, "{:?}", ptr), + Scalar::Ptr(ptr) => write!(f, "{:?}", ptr), &Scalar::Raw { data, size } => { Scalar::check_data(data, size); if size == 0 { @@ -92,7 +113,7 @@ impl fmt::Debug for Scalar { } else { // Format as hex number wide enough to fit any value of the given `size`. // So data=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014". - write!(f, "0x{:>0width$x}", data, width=(size*2) as usize) + write!(f, "0x{:>0width$x}", data, width = (size * 2) as usize) } } } @@ -125,8 +146,13 @@ impl From for Scalar { impl Scalar<()> { #[inline(always)] fn check_data(data: u128, size: u8) { - debug_assert_eq!(truncate(data, Size::from_bytes(size as u64)), data, - "Scalar value {:#x} exceeds size of {} bytes", data, size); + debug_assert_eq!( + truncate(data, Size::from_bytes(size as u64)), + data, + "Scalar value {:#x} exceeds size of {} bytes", + data, + size + ); } /// Tag this scalar with `new_tag` if it is a pointer, leave it unchanged otherwise. @@ -155,10 +181,7 @@ impl<'tcx, Tag> Scalar { #[inline] pub fn ptr_null(cx: &impl HasDataLayout) -> Self { - Scalar::Raw { - data: 0, - size: cx.data_layout().pointer_size.bytes() as u8, - } + Scalar::Raw { data: 0, size: cx.data_layout().pointer_size.bytes() as u8 } } #[inline] @@ -172,10 +195,7 @@ impl<'tcx, Tag> Scalar { match self { Scalar::Raw { data, size } => { assert_eq!(size as u64, dl.pointer_size.bytes()); - Ok(Scalar::Raw { - data: dl.offset(data as u64, i.bytes())? as u128, - size, - }) + Ok(Scalar::Raw { data: dl.offset(data as u64, i.bytes())? as u128, size }) } Scalar::Ptr(ptr) => ptr.offset(i, dl).map(Scalar::Ptr), } @@ -187,10 +207,7 @@ impl<'tcx, Tag> Scalar { match self { Scalar::Raw { data, size } => { assert_eq!(size as u64, dl.pointer_size.bytes()); - Scalar::Raw { - data: dl.overflowing_offset(data as u64, i.bytes()).0 as u128, - size, - } + Scalar::Raw { data: dl.overflowing_offset(data as u64, i.bytes()).0 as u128, size } } Scalar::Ptr(ptr) => Scalar::Ptr(ptr.wrapping_offset(i, dl)), } @@ -202,10 +219,7 @@ impl<'tcx, Tag> Scalar { match self { Scalar::Raw { data, size } => { assert_eq!(size as u64, dl.pointer_size().bytes()); - Ok(Scalar::Raw { - data: dl.signed_offset(data as u64, i)? as u128, - size, - }) + Ok(Scalar::Raw { data: dl.signed_offset(data as u64, i)? as u128, size }) } Scalar::Ptr(ptr) => ptr.signed_offset(i, dl).map(Scalar::Ptr), } @@ -249,9 +263,8 @@ impl<'tcx, Tag> Scalar { #[inline] pub fn from_uint(i: impl Into, size: Size) -> Self { let i = i.into(); - Self::try_from_uint(i, size).unwrap_or_else(|| { - bug!("Unsigned value {:#x} does not fit in {} bits", i, size.bits()) - }) + Self::try_from_uint(i, size) + .unwrap_or_else(|| bug!("Unsigned value {:#x} does not fit in {} bits", i, size.bits())) } #[inline] @@ -289,9 +302,8 @@ impl<'tcx, Tag> Scalar { #[inline] pub fn from_int(i: impl Into, size: Size) -> Self { let i = i.into(); - Self::try_from_int(i, size).unwrap_or_else(|| { - bug!("Signed value {:#x} does not fit in {} bits", i, size.bits()) - }) + Self::try_from_int(i, size) + .unwrap_or_else(|| bug!("Signed value {:#x} does not fit in {} bits", i, size.bits())) } #[inline] @@ -517,8 +529,7 @@ impl<'tcx, Tag> ScalarMaybeUndef { /// /// Used by error reporting code to avoid having the error type depend on `Tag`. #[inline] - pub fn erase_tag(self) -> ScalarMaybeUndef - { + pub fn erase_tag(self) -> ScalarMaybeUndef { match self { ScalarMaybeUndef::Scalar(s) => ScalarMaybeUndef::Scalar(s.erase_tag()), ScalarMaybeUndef::Undef => ScalarMaybeUndef::Undef, @@ -615,7 +626,8 @@ pub fn get_slice_bytes<'tcx>(cx: &impl HasDataLayout, val: ConstValue<'tcx>) -> // invent a pointer, only the offset is relevant anyway Pointer::new(AllocId(0), Size::from_bytes(start as u64)), Size::from_bytes(len as u64), - ).unwrap_or_else(|err| bug!("const slice is invalid: {:?}", err)) + ) + .unwrap_or_else(|err| bug!("const slice is invalid: {:?}", err)) } else { bug!("expected const slice, but found another const value"); } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 0757e02da970d..dc74ff1e98d66 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -19,27 +19,27 @@ use crate::ty::{ }; use polonius_engine::Atom; -use rustc_index::bit_set::BitMatrix; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::graph::{self, GraphSuccessors}; -use rustc_index::vec::{Idx, IndexVec}; use rustc_data_structures::sync::Lrc; +use rustc_index::bit_set::BitMatrix; +use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; -use rustc_serialize::{Encodable, Decodable}; +use rustc_serialize::{Decodable, Encodable}; use smallvec::SmallVec; use std::borrow::Cow; use std::fmt::{self, Debug, Display, Formatter, Write}; use std::ops::Index; use std::slice; use std::{iter, mem, option, u32}; -use syntax::ast::Name; pub use syntax::ast::Mutability; +use syntax::ast::Name; use syntax::symbol::Symbol; use syntax_pos::{Span, DUMMY_SP}; -pub use crate::mir::interpret::AssertMessage; pub use crate::mir::cache::{BodyAndCache, ReadOnlyBodyAndCache}; +pub use crate::mir::interpret::AssertMessage; pub use crate::read_only; mod cache; @@ -71,8 +71,18 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> { /// The various "big phases" that MIR goes through. /// /// Warning: ordering of variants is significant. -#[derive(Copy, Clone, RustcEncodable, RustcDecodable, HashStable, - Debug, PartialEq, Eq, PartialOrd, Ord)] +#[derive( + Copy, + Clone, + RustcEncodable, + RustcDecodable, + HashStable, + Debug, + PartialEq, + Eq, + PartialOrd, + Ord +)] pub enum MirPhase { Build = 0, Const = 1, @@ -167,7 +177,7 @@ impl<'tcx> Body<'tcx> { var_debug_info: Vec>, span: Span, control_flow_destroyed: Vec<(Span, String)>, - generator_kind : Option, + generator_kind: Option, ) -> Self { // We need `arg_count` locals, and one for the return place. assert!( @@ -230,11 +240,7 @@ impl<'tcx> Body<'tcx> { pub fn temps_iter<'a>(&'a self) -> impl Iterator + 'a { (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| { let local = Local::new(index); - if self.local_decls[local].is_user_variable() { - None - } else { - Some(local) - } + if self.local_decls[local].is_user_variable() { None } else { Some(local) } }) } @@ -400,7 +406,16 @@ pub struct SourceInfo { // Borrow kinds #[derive( - Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, HashStable, + Copy, + Clone, + Debug, + PartialEq, + Eq, + PartialOrd, + Ord, + RustcEncodable, + RustcDecodable, + HashStable )] pub enum BorrowKind { /// Data must be immutable and is aliasable. @@ -760,9 +775,9 @@ impl<'tcx> LocalDecl<'tcx> { pat_span: _, }))) => true, - LocalInfo::User( - ClearCrossCrate::Set(BindingForm::ImplicitSelf(ImplicitSelfKind::Imm)), - ) => true, + LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf( + ImplicitSelfKind::Imm, + ))) => true, _ => false, } @@ -1327,11 +1342,7 @@ impl<'tcx> BasicBlockData<'tcx> { } pub fn visitable(&self, index: usize) -> &dyn MirVisitable<'tcx> { - if index < self.statements.len() { - &self.statements[index] - } else { - &self.terminator - } + if index < self.statements.len() { &self.statements[index] } else { &self.terminator } } } @@ -1418,13 +1429,9 @@ impl<'tcx> TerminatorKind<'tcx> { values .iter() .map(|&u| { - ty::Const::from_scalar( - tcx, - Scalar::from_uint(u, size).into(), - switch_ty, - ) - .to_string() - .into() + ty::Const::from_scalar(tcx, Scalar::from_uint(u, size).into(), switch_ty) + .to_string() + .into() }) .chain(iter::once("otherwise".into())) .collect() @@ -1600,7 +1607,7 @@ impl Debug for Statement<'_> { fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { use self::StatementKind::*; match self.kind { - Assign(box(ref place, ref rv)) => write!(fmt, "{:?} = {:?}", place, rv), + Assign(box (ref place, ref rv)) => write!(fmt, "{:?} = {:?}", place, rv), FakeRead(ref cause, ref place) => write!(fmt, "FakeRead({:?}, {:?})", cause, place), Retag(ref kind, ref place) => write!( fmt, @@ -1621,7 +1628,7 @@ impl Debug for Statement<'_> { InlineAsm(ref asm) => { write!(fmt, "asm!({:?} : {:?} : {:?})", asm.asm, asm.outputs, asm.inputs) } - AscribeUserType(box(ref place, ref c_ty), ref variance) => { + AscribeUserType(box (ref place, ref c_ty), ref variance) => { write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty) } Nop => write!(fmt, "nop"), @@ -1634,9 +1641,7 @@ impl Debug for Statement<'_> { /// A path to a value; something that can be evaluated without /// changing or disturbing program state. -#[derive( - Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, HashStable, -)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, HashStable)] pub struct Place<'tcx> { pub base: PlaceBase<'tcx>, @@ -1646,9 +1651,7 @@ pub struct Place<'tcx> { impl<'tcx> rustc_serialize::UseSpecializedDecodable for Place<'tcx> {} -#[derive( - Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable, -)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)] pub enum PlaceBase<'tcx> { /// local variable Local(Local), @@ -1658,8 +1661,18 @@ pub enum PlaceBase<'tcx> { } /// We store the normalized type to avoid requiring normalization when reading MIR -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, - RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Clone, + Debug, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + RustcEncodable, + RustcDecodable, + HashStable +)] pub struct Static<'tcx> { pub ty: Ty<'tcx>, pub kind: StaticKind<'tcx>, @@ -1671,7 +1684,16 @@ pub struct Static<'tcx> { } #[derive( - Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable, + Clone, + Debug, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + HashStable, + RustcEncodable, + RustcDecodable )] pub enum StaticKind<'tcx> { /// Promoted references consist of an id (`Promoted`) and the substs necessary to monomorphize @@ -1736,12 +1758,11 @@ impl ProjectionElem { match self { Self::Deref => true, - | Self::Field(_, _) + Self::Field(_, _) | Self::Index(_) | Self::ConstantIndex { .. } | Self::Subslice { .. } - | Self::Downcast(_, _) - => false + | Self::Downcast(_, _) => false, } } } @@ -1750,7 +1771,7 @@ impl ProjectionElem { /// and the index is a local. pub type PlaceElem<'tcx> = ProjectionElem>; -impl<'tcx> Copy for PlaceElem<'tcx> { } +impl<'tcx> Copy for PlaceElem<'tcx> {} // At least on 64 bit systems, `PlaceElem` should not be larger than two pointers. #[cfg(target_arch = "x86_64")] @@ -1776,10 +1797,7 @@ pub struct PlaceRef<'a, 'tcx> { impl<'tcx> Place<'tcx> { // FIXME change this to a const fn by also making List::empty a const fn. pub fn return_place() -> Place<'tcx> { - Place { - base: PlaceBase::Local(RETURN_PLACE), - projection: List::empty(), - } + Place { base: PlaceBase::Local(RETURN_PLACE), projection: List::empty() } } /// Returns `true` if this `Place` contains a `Deref` projection. @@ -1796,14 +1814,10 @@ impl<'tcx> Place<'tcx> { // FIXME: can we safely swap the semantics of `fn base_local` below in here instead? pub fn local_or_deref_local(&self) -> Option { match self.as_ref() { - PlaceRef { - base: &PlaceBase::Local(local), - projection: &[], - } | - PlaceRef { - base: &PlaceBase::Local(local), - projection: &[ProjectionElem::Deref], - } => Some(local), + PlaceRef { base: &PlaceBase::Local(local), projection: &[] } + | PlaceRef { base: &PlaceBase::Local(local), projection: &[ProjectionElem::Deref] } => { + Some(local) + } _ => None, } } @@ -1815,19 +1829,13 @@ impl<'tcx> Place<'tcx> { } pub fn as_ref(&self) -> PlaceRef<'_, 'tcx> { - PlaceRef { - base: &self.base, - projection: &self.projection, - } + PlaceRef { base: &self.base, projection: &self.projection } } } impl From for Place<'_> { fn from(local: Local) -> Self { - Place { - base: local.into(), - projection: List::empty(), - } + Place { base: local.into(), projection: List::empty() } } } @@ -1844,14 +1852,10 @@ impl<'a, 'tcx> PlaceRef<'a, 'tcx> { // FIXME: can we safely swap the semantics of `fn base_local` below in here instead? pub fn local_or_deref_local(&self) -> Option { match self { - PlaceRef { - base: PlaceBase::Local(local), - projection: [], - } | - PlaceRef { - base: PlaceBase::Local(local), - projection: [ProjectionElem::Deref], - } => Some(*local), + PlaceRef { base: PlaceBase::Local(local), projection: [] } + | PlaceRef { base: PlaceBase::Local(local), projection: [ProjectionElem::Deref] } => { + Some(*local) + } _ => None, } } @@ -1934,10 +1938,10 @@ impl Debug for PlaceBase<'_> { write!(fmt, "({}: {:?})", ty::tls::with(|tcx| tcx.def_path_str(def_id)), ty) } PlaceBase::Static(box self::Static { - ty, kind: StaticKind::Promoted(promoted, _), def_id: _ - }) => { - write!(fmt, "({:?}: {:?})", promoted, ty) - } + ty, + kind: StaticKind::Promoted(promoted, _), + def_id: _, + }) => write!(fmt, "({:?}: {:?})", promoted, ty), } } } @@ -2333,11 +2337,9 @@ impl Constant<'tcx> { Some(GlobalAlloc::Static(def_id)) => Some(def_id), Some(_) => None, None => { - tcx.sess.delay_span_bug( - DUMMY_SP, "MIR cannot contain dangling const pointers", - ); + tcx.sess.delay_span_bug(DUMMY_SP, "MIR cannot contain dangling const pointers"); None - }, + } }, _ => None, } @@ -2390,15 +2392,13 @@ impl<'tcx> UserTypeProjections { UserTypeProjections { contents: projs.collect() } } - pub fn projections_and_spans(&self) - -> impl Iterator + ExactSizeIterator - { + pub fn projections_and_spans( + &self, + ) -> impl Iterator + ExactSizeIterator { self.contents.iter() } - pub fn projections(&self) - -> impl Iterator + ExactSizeIterator - { + pub fn projections(&self) -> impl Iterator + ExactSizeIterator { self.contents.iter().map(|&(ref user_type, _span)| user_type) } @@ -2566,10 +2566,7 @@ impl<'tcx> graph::WithStartNode for Body<'tcx> { } impl<'tcx> graph::WithSuccessors for Body<'tcx> { - fn successors( - &self, - node: Self::Node, - ) -> >::Iter { + fn successors(&self, node: Self::Node) -> >::Iter { self.basic_blocks[node].terminator().successors().cloned() } } @@ -2611,7 +2608,7 @@ impl Location { pub fn is_predecessor_of<'tcx>( &self, other: Location, - body: ReadOnlyBodyAndCache<'_, 'tcx> + body: ReadOnlyBodyAndCache<'_, 'tcx>, ) -> bool { // If we are in the same block as the other location and are an earlier statement // then we are a predecessor of `other`. @@ -2812,7 +2809,7 @@ pub struct ClosureOutlivesRequirement<'tcx> { Hash, RustcEncodable, RustcDecodable, - HashStable, + HashStable )] pub enum ConstraintCategory { Return, @@ -2920,14 +2917,16 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { Assert { ref cond, expected, ref msg, target, cleanup } => { use PanicInfo::*; let msg = match msg { - BoundsCheck { ref len, ref index } => - BoundsCheck { - len: len.fold_with(folder), - index: index.fold_with(folder), - }, - Panic { .. } | Overflow(_) | OverflowNeg | DivisionByZero | RemainderByZero | - ResumedAfterReturn(_) | ResumedAfterPanic(_) => - msg.clone(), + BoundsCheck { ref len, ref index } => { + BoundsCheck { len: len.fold_with(folder), index: index.fold_with(folder) } + } + Panic { .. } + | Overflow(_) + | OverflowNeg + | DivisionByZero + | RemainderByZero + | ResumedAfterReturn(_) + | ResumedAfterPanic(_) => msg.clone(), }; Assert { cond: cond.fold_with(folder), expected, msg, target, cleanup } } @@ -2968,12 +2967,16 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { if cond.visit_with(visitor) { use PanicInfo::*; match msg { - BoundsCheck { ref len, ref index } => - len.visit_with(visitor) || index.visit_with(visitor), - Panic { .. } | Overflow(_) | OverflowNeg | - DivisionByZero | RemainderByZero | - ResumedAfterReturn(_) | ResumedAfterPanic(_) => - false + BoundsCheck { ref len, ref index } => { + len.visit_with(visitor) || index.visit_with(visitor) + } + Panic { .. } + | Overflow(_) + | OverflowNeg + | DivisionByZero + | RemainderByZero + | ResumedAfterReturn(_) + | ResumedAfterPanic(_) => false, } } else { false @@ -3003,10 +3006,7 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorKind { impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { - Place { - base: self.base.fold_with(folder), - projection: self.projection.fold_with(folder), - } + Place { base: self.base.fold_with(folder), projection: self.projection.fold_with(folder) } } fn super_visit_with>(&self, visitor: &mut V) -> bool { @@ -3060,17 +3060,19 @@ impl<'tcx> TypeFoldable<'tcx> for Static<'tcx> { impl<'tcx> TypeFoldable<'tcx> for StaticKind<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { match self { - StaticKind::Promoted(promoted, substs) => - StaticKind::Promoted(promoted.fold_with(folder), substs.fold_with(folder)), - StaticKind::Static => StaticKind::Static + StaticKind::Promoted(promoted, substs) => { + StaticKind::Promoted(promoted.fold_with(folder), substs.fold_with(folder)) + } + StaticKind::Static => StaticKind::Static, } } fn super_visit_with>(&self, visitor: &mut V) -> bool { match self { - StaticKind::Promoted(promoted, substs) => - promoted.visit_with(visitor) || substs.visit_with(visitor), - StaticKind::Static => { false } + StaticKind::Promoted(promoted, substs) => { + promoted.visit_with(visitor) || substs.visit_with(visitor) + } + StaticKind::Static => false, } } } @@ -3084,9 +3086,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { Ref(region, bk, ref place) => { Ref(region.fold_with(folder), bk, place.fold_with(folder)) } - AddressOf(mutability, ref place) => { - AddressOf(mutability, place.fold_with(folder)) - } + AddressOf(mutability, ref place) => AddressOf(mutability, place.fold_with(folder)), Len(ref place) => Len(place.fold_with(folder)), Cast(kind, ref op, ty) => Cast(kind, op.fold_with(folder), ty.fold_with(folder)), BinaryOp(op, ref rhs, ref lhs) => { diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 34daf185b2952..b13b4fd3b8d37 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -1,18 +1,18 @@ -use crate::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; +use crate::dep_graph::{DepConstructor, DepNode, WorkProduct, WorkProductId}; +use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use crate::hir::HirId; -use syntax::symbol::Symbol; -use syntax::attr::InlineAttr; -use syntax::source_map::Span; -use crate::ty::{Instance, InstanceDef, TyCtxt, SymbolName, subst::InternalSubsts}; -use crate::util::nodemap::FxHashMap; +use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext}; +use crate::session::config::OptLevel; use crate::ty::print::obsolete::DefPathBasedNames; -use crate::dep_graph::{WorkProductId, DepNode, WorkProduct, DepConstructor}; +use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt}; +use crate::util::nodemap::FxHashMap; use rustc_data_structures::base_n; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use crate::ich::{Fingerprint, StableHashingContext, NodeIdHashingMode}; -use crate::session::config::OptLevel; use std::fmt; use std::hash::Hash; +use syntax::attr::InlineAttr; +use syntax::source_map::Span; +use syntax::symbol::Symbol; /// Describes how a monomorphization will be instantiated in object files. #[derive(PartialEq)] @@ -53,62 +53,57 @@ impl<'tcx> MonoItem<'tcx> { // Estimate the size of a function based on how many statements // it contains. tcx.instance_def_size_estimate(instance.def) - }, + } // Conservatively estimate the size of a static declaration // or assembly to be 1. - MonoItem::Static(_) | - MonoItem::GlobalAsm(_) => 1, + MonoItem::Static(_) | MonoItem::GlobalAsm(_) => 1, } } pub fn is_generic_fn(&self) -> bool { match *self { - MonoItem::Fn(ref instance) => { - instance.substs.non_erasable_generics().next().is_some() - } - MonoItem::Static(..) | - MonoItem::GlobalAsm(..) => false, + MonoItem::Fn(ref instance) => instance.substs.non_erasable_generics().next().is_some(), + MonoItem::Static(..) | MonoItem::GlobalAsm(..) => false, } } pub fn symbol_name(&self, tcx: TyCtxt<'tcx>) -> SymbolName { match *self { MonoItem::Fn(instance) => tcx.symbol_name(instance), - MonoItem::Static(def_id) => { - tcx.symbol_name(Instance::mono(tcx, def_id)) - } + MonoItem::Static(def_id) => tcx.symbol_name(Instance::mono(tcx, def_id)), MonoItem::GlobalAsm(hir_id) => { let def_id = tcx.hir().local_def_id(hir_id); - SymbolName { - name: Symbol::intern(&format!("global_asm_{:?}", def_id)) - } + SymbolName { name: Symbol::intern(&format!("global_asm_{:?}", def_id)) } } } } pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode { - let inline_in_all_cgus = - tcx.sess.opts.debugging_opts.inline_in_all_cgus.unwrap_or_else(|| { - tcx.sess.opts.optimize != OptLevel::No - }) && !tcx.sess.opts.cg.link_dead_code; + let inline_in_all_cgus = tcx + .sess + .opts + .debugging_opts + .inline_in_all_cgus + .unwrap_or_else(|| tcx.sess.opts.optimize != OptLevel::No) + && !tcx.sess.opts.cg.link_dead_code; match *self { MonoItem::Fn(ref instance) => { let entry_def_id = tcx.entry_fn(LOCAL_CRATE).map(|(id, _)| id); // If this function isn't inlined or otherwise has explicit // linkage, then we'll be creating a globally shared version. - if self.explicit_linkage(tcx).is_some() || - !instance.def.requires_local(tcx) || - Some(instance.def_id()) == entry_def_id + if self.explicit_linkage(tcx).is_some() + || !instance.def.requires_local(tcx) + || Some(instance.def_id()) == entry_def_id { - return InstantiationMode::GloballyShared { may_conflict: false } + return InstantiationMode::GloballyShared { may_conflict: false }; } // At this point we don't have explicit linkage and we're an // inlined function. If we're inlining into all CGUs then we'll // be creating a local copy per CGU if inline_in_all_cgus { - return InstantiationMode::LocalCopy + return InstantiationMode::LocalCopy; } // Finally, if this is `#[inline(always)]` we're sure to respect @@ -118,13 +113,10 @@ impl<'tcx> MonoItem<'tcx> { // symbol. match tcx.codegen_fn_attrs(instance.def_id()).inline { InlineAttr::Always => InstantiationMode::LocalCopy, - _ => { - InstantiationMode::GloballyShared { may_conflict: true } - } + _ => InstantiationMode::GloballyShared { may_conflict: true }, } } - MonoItem::Static(..) | - MonoItem::GlobalAsm(..) => { + MonoItem::Static(..) | MonoItem::GlobalAsm(..) => { InstantiationMode::GloballyShared { may_conflict: false } } } @@ -172,7 +164,7 @@ impl<'tcx> MonoItem<'tcx> { MonoItem::Fn(ref instance) => (instance.def_id(), instance.substs), MonoItem::Static(def_id) => (def_id, InternalSubsts::empty()), // global asm never has predicates - MonoItem::GlobalAsm(..) => return true + MonoItem::GlobalAsm(..) => return true, }; tcx.substitute_normalize_and_test_predicates((def_id, &substs)) @@ -180,16 +172,12 @@ impl<'tcx> MonoItem<'tcx> { 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::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() } + MonoItem::GlobalAsm(..) => "global_asm".to_string(), }; fn to_string_internal<'tcx>( @@ -208,16 +196,11 @@ impl<'tcx> MonoItem<'tcx> { pub fn local_span(&self, tcx: TyCtxt<'tcx>) -> Option { match *self { - MonoItem::Fn(Instance { def, .. }) => { - tcx.hir().as_local_hir_id(def.def_id()) - } - MonoItem::Static(def_id) => { - tcx.hir().as_local_hir_id(def_id) - } - MonoItem::GlobalAsm(hir_id) => { - Some(hir_id) - } - }.map(|hir_id| tcx.hir().span(hir_id)) + MonoItem::Fn(Instance { def, .. }) => tcx.hir().as_local_hir_id(def.def_id()), + MonoItem::Static(def_id) => tcx.hir().as_local_hir_id(def_id), + MonoItem::GlobalAsm(hir_id) => Some(hir_id), + } + .map(|hir_id| tcx.hir().span(hir_id)) } } @@ -275,11 +258,7 @@ pub enum Visibility { impl<'tcx> CodegenUnit<'tcx> { pub fn new(name: Symbol) -> CodegenUnit<'tcx> { - CodegenUnit { - name: name, - items: Default::default(), - size_estimate: None, - } + CodegenUnit { name: name, items: Default::default(), size_estimate: None } } pub fn name(&self) -> Symbol { @@ -294,9 +273,7 @@ impl<'tcx> CodegenUnit<'tcx> { &self.items } - pub fn items_mut(&mut self) - -> &mut FxHashMap, (Linkage, Visibility)> - { + pub fn items_mut(&mut self) -> &mut FxHashMap, (Linkage, Visibility)> { &mut self.items } @@ -339,10 +316,8 @@ impl<'tcx> CodegenUnit<'tcx> { pub fn work_product(&self, tcx: TyCtxt<'_>) -> WorkProduct { let work_product_id = self.work_product_id(); tcx.dep_graph - .previous_work_product(&work_product_id) - .unwrap_or_else(|| { - panic!("Could not find work-product for CGU `{}`", self.name()) - }) + .previous_work_product(&work_product_id) + .unwrap_or_else(|| panic!("Could not find work-product for CGU `{}`", self.name())) } pub fn items_in_deterministic_order( @@ -355,35 +330,30 @@ impl<'tcx> CodegenUnit<'tcx> { pub struct ItemSortKey(Option, SymbolName); fn item_sort_key<'tcx>(tcx: TyCtxt<'tcx>, item: MonoItem<'tcx>) -> ItemSortKey { - ItemSortKey(match item { - MonoItem::Fn(ref instance) => { - match instance.def { - // We only want to take HirIds of user-defined - // instances into account. The others don't matter for - // the codegen tests and can even make item order - // unstable. - InstanceDef::Item(def_id) => { - tcx.hir().as_local_hir_id(def_id) - } - InstanceDef::VtableShim(..) | - InstanceDef::ReifyShim(..) | - InstanceDef::Intrinsic(..) | - InstanceDef::FnPtrShim(..) | - InstanceDef::Virtual(..) | - InstanceDef::ClosureOnceShim { .. } | - InstanceDef::DropGlue(..) | - InstanceDef::CloneShim(..) => { - None + ItemSortKey( + match item { + MonoItem::Fn(ref instance) => { + match instance.def { + // We only want to take HirIds of user-defined + // instances into account. The others don't matter for + // the codegen tests and can even make item order + // unstable. + InstanceDef::Item(def_id) => tcx.hir().as_local_hir_id(def_id), + InstanceDef::VtableShim(..) + | InstanceDef::ReifyShim(..) + | InstanceDef::Intrinsic(..) + | InstanceDef::FnPtrShim(..) + | InstanceDef::Virtual(..) + | InstanceDef::ClosureOnceShim { .. } + | InstanceDef::DropGlue(..) + | InstanceDef::CloneShim(..) => None, } } - } - MonoItem::Static(def_id) => { - tcx.hir().as_local_hir_id(def_id) - } - MonoItem::GlobalAsm(hir_id) => { - Some(hir_id) - } - }, item.symbol_name(tcx)) + MonoItem::Static(def_id) => tcx.hir().as_local_hir_id(def_id), + MonoItem::GlobalAsm(hir_id) => Some(hir_id), + }, + item.symbol_name(tcx), + ) } let mut items: Vec<_> = self.items().iter().map(|(&i, &l)| (i, l)).collect(); @@ -407,12 +377,15 @@ impl<'a, 'tcx> HashStable> for CodegenUnit<'tcx> { name.hash_stable(hcx, hasher); - let mut items: Vec<(Fingerprint, _)> = items.iter().map(|(mono_item, &attrs)| { - let mut hasher = StableHasher::new(); - mono_item.hash_stable(hcx, &mut hasher); - let mono_item_fingerprint = hasher.finish(); - (mono_item_fingerprint, attrs) - }).collect(); + let mut items: Vec<(Fingerprint, _)> = items + .iter() + .map(|(mono_item, &attrs)| { + let mut hasher = StableHasher::new(); + mono_item.hash_stable(hcx, &mut hasher); + let mono_item_fingerprint = hasher.finish(); + (mono_item_fingerprint, attrs) + }) + .collect(); items.sort_unstable_by_key(|i| i.0); items.hash_stable(hcx, hasher); @@ -426,10 +399,7 @@ pub struct CodegenUnitNameBuilder<'tcx> { impl CodegenUnitNameBuilder<'tcx> { pub fn new(tcx: TyCtxt<'tcx>) -> Self { - CodegenUnitNameBuilder { - tcx, - cache: Default::default(), - } + CodegenUnitNameBuilder { tcx, cache: Default::default() } } /// CGU names should fulfill the following requirements: @@ -450,18 +420,18 @@ impl CodegenUnitNameBuilder<'tcx> { /// The '.' before `` makes sure that names with a special /// suffix can never collide with a name built out of regular Rust /// identifiers (e.g., module paths). - pub fn build_cgu_name(&mut self, - cnum: CrateNum, - components: I, - special_suffix: Option) - -> Symbol - where I: IntoIterator, - C: fmt::Display, - S: fmt::Display, + pub fn build_cgu_name( + &mut self, + cnum: CrateNum, + components: I, + special_suffix: Option, + ) -> Symbol + where + I: IntoIterator, + C: fmt::Display, + S: fmt::Display, { - let cgu_name = self.build_cgu_name_no_mangle(cnum, - components, - special_suffix); + let cgu_name = self.build_cgu_name_no_mangle(cnum, components, special_suffix); if self.tcx.sess.opts.debugging_opts.human_readable_cgu_names { cgu_name @@ -473,14 +443,16 @@ impl CodegenUnitNameBuilder<'tcx> { /// Same as `CodegenUnit::build_cgu_name()` but will never mangle the /// resulting name. - pub fn build_cgu_name_no_mangle(&mut self, - cnum: CrateNum, - components: I, - special_suffix: Option) - -> Symbol - where I: IntoIterator, - C: fmt::Display, - S: fmt::Display, + pub fn build_cgu_name_no_mangle( + &mut self, + cnum: CrateNum, + components: I, + special_suffix: Option, + ) -> Symbol + where + I: IntoIterator, + C: fmt::Display, + S: fmt::Display, { use std::fmt::Write; @@ -493,21 +465,15 @@ impl CodegenUnitNameBuilder<'tcx> { // local crate's ID. Otherwise there can be collisions between CGUs // instantiating stuff for upstream crates. let local_crate_id = if cnum != LOCAL_CRATE { - let local_crate_disambiguator = - format!("{}", tcx.crate_disambiguator(LOCAL_CRATE)); - format!("-in-{}.{}", - tcx.crate_name(LOCAL_CRATE), - &local_crate_disambiguator[0 .. 8]) + let local_crate_disambiguator = format!("{}", tcx.crate_disambiguator(LOCAL_CRATE)); + format!("-in-{}.{}", tcx.crate_name(LOCAL_CRATE), &local_crate_disambiguator[0..8]) } else { String::new() }; let crate_disambiguator = tcx.crate_disambiguator(cnum).to_string(); // Using a shortened disambiguator of about 40 bits - format!("{}.{}{}", - tcx.crate_name(cnum), - &crate_disambiguator[0 .. 8], - local_crate_id) + format!("{}.{}{}", tcx.crate_name(cnum), &crate_disambiguator[0..8], local_crate_id) }); write!(cgu_name, "{}", crate_prefix).unwrap(); diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 841c0b458d157..234221130d832 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -3,12 +3,12 @@ * building is complete. */ +use crate::hir; use crate::mir::*; -use crate::ty::subst::Subst; -use crate::ty::{self, Ty, TyCtxt}; use crate::ty::layout::VariantIdx; -use crate::hir; +use crate::ty::subst::Subst; use crate::ty::util::IntTypeExt; +use crate::ty::{self, Ty, TyCtxt}; #[derive(Copy, Clone, Debug, TypeFoldable)] pub struct PlaceTy<'tcx> { @@ -78,36 +78,34 @@ impl<'tcx> PlaceTy<'tcx> { { let answer = match *elem { ProjectionElem::Deref => { - let ty = self.ty - .builtin_deref(true) - .unwrap_or_else(|| { - bug!("deref projection of non-dereferenceable ty {:?}", self) - }) - .ty; + let ty = self + .ty + .builtin_deref(true) + .unwrap_or_else(|| { + bug!("deref projection of non-dereferenceable ty {:?}", self) + }) + .ty; PlaceTy::from_ty(ty) } - ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } => - PlaceTy::from_ty(self.ty.builtin_index().unwrap()), + ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } => { + PlaceTy::from_ty(self.ty.builtin_index().unwrap()) + } ProjectionElem::Subslice { from, to, from_end } => { PlaceTy::from_ty(match self.ty.kind { ty::Slice(..) => self.ty, - ty::Array(inner, _) if !from_end => { - tcx.mk_array(inner, (to - from) as u64) - } + ty::Array(inner, _) if !from_end => tcx.mk_array(inner, (to - from) as u64), ty::Array(inner, size) if from_end => { let size = size.eval_usize(tcx, param_env); let len = size - (from as u64) - (to as u64); tcx.mk_array(inner, len) } - _ => { - bug!("cannot subslice non-array type: `{:?}`", self) - } + _ => bug!("cannot subslice non-array type: `{:?}`", self), }) } - ProjectionElem::Downcast(_name, index) => - PlaceTy { ty: self.ty, variant_index: Some(index) }, - ProjectionElem::Field(ref f, ref fty) => - PlaceTy::from_ty(handle_field(&self, f, fty)), + ProjectionElem::Downcast(_name, index) => { + PlaceTy { ty: self.ty, variant_index: Some(index) } + } + ProjectionElem::Field(ref f, ref fty) => PlaceTy::from_ty(handle_field(&self, f, fty)), }; debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer); answer @@ -119,14 +117,14 @@ impl<'tcx> Place<'tcx> { base: &PlaceBase<'tcx>, projection: &[PlaceElem<'tcx>], local_decls: &D, - tcx: TyCtxt<'tcx> + tcx: TyCtxt<'tcx>, ) -> PlaceTy<'tcx> - where D: HasLocalDecls<'tcx> + where + D: HasLocalDecls<'tcx>, { - projection.iter().fold( - base.ty(local_decls), - |place_ty, elem| place_ty.projection_ty(tcx, elem) - ) + projection + .iter() + .fold(base.ty(local_decls), |place_ty, elem| place_ty.projection_ty(tcx, elem)) } pub fn ty(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx> @@ -139,7 +137,8 @@ impl<'tcx> Place<'tcx> { impl<'tcx> PlaceBase<'tcx> { pub fn ty(&self, local_decls: &D) -> PlaceTy<'tcx> - where D: HasLocalDecls<'tcx> + where + D: HasLocalDecls<'tcx>, { match self { PlaceBase::Local(index) => PlaceTy::from_ty(local_decls.local_decls()[*index].ty), @@ -150,7 +149,7 @@ impl<'tcx> PlaceBase<'tcx> { pub enum RvalueInitializationState { Shallow, - Deep + Deep, } impl<'tcx> Rvalue<'tcx> { @@ -160,24 +159,14 @@ impl<'tcx> Rvalue<'tcx> { { match *self { Rvalue::Use(ref operand) => operand.ty(local_decls, tcx), - Rvalue::Repeat(ref operand, count) => { - tcx.mk_array(operand.ty(local_decls, tcx), count) - } + Rvalue::Repeat(ref operand, count) => tcx.mk_array(operand.ty(local_decls, tcx), count), Rvalue::Ref(reg, bk, ref place) => { let place_ty = place.ty(local_decls, tcx).ty; - tcx.mk_ref(reg, - ty::TypeAndMut { - ty: place_ty, - mutbl: bk.to_mutbl_lossy() - } - ) + tcx.mk_ref(reg, ty::TypeAndMut { ty: place_ty, mutbl: bk.to_mutbl_lossy() }) } Rvalue::AddressOf(mutability, ref place) => { let place_ty = place.ty(local_decls, tcx).ty; - tcx.mk_ptr(ty::TypeAndMut { - ty: place_ty, - mutbl: mutability.into(), - }) + tcx.mk_ptr(ty::TypeAndMut { ty: place_ty, mutbl: mutability.into() }) } Rvalue::Len(..) => tcx.types.usize, Rvalue::Cast(.., ty) => ty, @@ -192,8 +181,7 @@ impl<'tcx> Rvalue<'tcx> { let ty = op.ty(tcx, lhs_ty, rhs_ty); tcx.intern_tup(&[ty, tcx.types.bool]) } - Rvalue::UnaryOp(UnOp::Not, ref operand) | - Rvalue::UnaryOp(UnOp::Neg, ref operand) => { + Rvalue::UnaryOp(UnOp::Not, ref operand) | Rvalue::UnaryOp(UnOp::Neg, ref operand) => { operand.ty(local_decls, tcx) } Rvalue::Discriminant(ref place) => { @@ -209,25 +197,15 @@ impl<'tcx> Rvalue<'tcx> { } Rvalue::NullaryOp(NullOp::Box, t) => tcx.mk_box(t), Rvalue::NullaryOp(NullOp::SizeOf, _) => tcx.types.usize, - Rvalue::Aggregate(ref ak, ref ops) => { - match **ak { - AggregateKind::Array(ty) => { - tcx.mk_array(ty, ops.len() as u64) - } - AggregateKind::Tuple => { - tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx))) - } - AggregateKind::Adt(def, _, substs, _, _) => { - tcx.type_of(def.did).subst(tcx, substs) - } - AggregateKind::Closure(did, substs) => { - tcx.mk_closure(did, substs) - } - AggregateKind::Generator(did, substs, movability) => { - tcx.mk_generator(did, substs, movability) - } + Rvalue::Aggregate(ref ak, ref ops) => match **ak { + AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64), + AggregateKind::Tuple => tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx))), + AggregateKind::Adt(def, _, substs, _, _) => tcx.type_of(def.did).subst(tcx, substs), + AggregateKind::Closure(did, substs) => tcx.mk_closure(did, substs), + AggregateKind::Generator(did, substs, movability) => { + tcx.mk_generator(did, substs, movability) } - } + }, } } @@ -237,7 +215,7 @@ impl<'tcx> Rvalue<'tcx> { pub fn initialization_state(&self) -> RvalueInitializationState { match *self { Rvalue::NullaryOp(NullOp::Box, _) => RvalueInitializationState::Shallow, - _ => RvalueInitializationState::Deep + _ => RvalueInitializationState::Deep, } } } @@ -248,8 +226,7 @@ impl<'tcx> Operand<'tcx> { D: HasLocalDecls<'tcx>, { match self { - &Operand::Copy(ref l) | - &Operand::Move(ref l) => l.ty(local_decls, tcx).ty, + &Operand::Copy(ref l) | &Operand::Move(ref l) => l.ty(local_decls, tcx).ty, &Operand::Constant(ref c) => c.literal.ty, } } @@ -259,8 +236,14 @@ impl<'tcx> BinOp { pub fn ty(&self, tcx: TyCtxt<'tcx>, lhs_ty: Ty<'tcx>, rhs_ty: Ty<'tcx>) -> Ty<'tcx> { // FIXME: handle SIMD correctly match self { - &BinOp::Add | &BinOp::Sub | &BinOp::Mul | &BinOp::Div | &BinOp::Rem | - &BinOp::BitXor | &BinOp::BitAnd | &BinOp::BitOr => { + &BinOp::Add + | &BinOp::Sub + | &BinOp::Mul + | &BinOp::Div + | &BinOp::Rem + | &BinOp::BitXor + | &BinOp::BitAnd + | &BinOp::BitOr => { // these should be integers or floats of the same size. assert_eq!(lhs_ty, rhs_ty); lhs_ty @@ -268,8 +251,7 @@ impl<'tcx> BinOp { &BinOp::Shl | &BinOp::Shr | &BinOp::Offset => { lhs_ty // lhs_ty can be != rhs_ty } - &BinOp::Eq | &BinOp::Lt | &BinOp::Le | - &BinOp::Ne | &BinOp::Ge | &BinOp::Gt => { + &BinOp::Eq | &BinOp::Lt | &BinOp::Le | &BinOp::Ne | &BinOp::Ge | &BinOp::Gt => { tcx.types.bool } } @@ -313,7 +295,7 @@ impl BinOp { BinOp::Gt => hir::BinOpKind::Gt, BinOp::Le => hir::BinOpKind::Le, BinOp::Ge => hir::BinOpKind::Ge, - BinOp::Offset => unreachable!() + BinOp::Offset => unreachable!(), } } } diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs index f129dd3abeff7..a89811ed43bb8 100644 --- a/src/librustc/mir/traversal.rs +++ b/src/librustc/mir/traversal.rs @@ -114,7 +114,6 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> { root_is_start_block: root == START_BLOCK, }; - let data = &po.body[root]; if let Some(ref term) = data.terminator { @@ -254,20 +253,16 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { pub struct ReversePostorder<'a, 'tcx> { body: &'a Body<'tcx>, blocks: Vec, - idx: usize + idx: usize, } impl<'a, 'tcx> ReversePostorder<'a, 'tcx> { pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> ReversePostorder<'a, 'tcx> { - let blocks : Vec<_> = Postorder::new(body, root).map(|(bb, _)| bb).collect(); + let blocks: Vec<_> = Postorder::new(body, root).map(|(bb, _)| bb).collect(); let len = blocks.len(); - ReversePostorder { - body, - blocks, - idx: len - } + ReversePostorder { body, blocks, idx: len } } pub fn reset(&mut self) { @@ -275,7 +270,6 @@ impl<'a, 'tcx> ReversePostorder<'a, 'tcx> { } } - pub fn reverse_postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> ReversePostorder<'a, 'tcx> { ReversePostorder::new(body, START_BLOCK) } @@ -284,7 +278,9 @@ impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> { type Item = (BasicBlock, &'a BasicBlockData<'tcx>); fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> { - if self.idx == 0 { return None; } + if self.idx == 0 { + return None; + } self.idx -= 1; self.blocks.get(self.idx).map(|&bb| (bb, &self.body[bb])) diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index fa96b51347d35..50c5bd9299f36 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -1,6 +1,6 @@ +use crate::mir::*; use crate::ty::subst::SubstsRef; use crate::ty::{CanonicalUserTypeAnnotation, Ty}; -use crate::mir::*; use syntax_pos::Span; // # The MIR Visitor @@ -978,29 +978,26 @@ macro_rules! visit_place_fns { } make_mir_visitor!(Visitor,); -make_mir_visitor!(MutVisitor,mut); +make_mir_visitor!(MutVisitor, mut); pub trait MirVisitable<'tcx> { fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>); } impl<'tcx> MirVisitable<'tcx> for Statement<'tcx> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) - { + fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) { visitor.visit_statement(self, location) } } impl<'tcx> MirVisitable<'tcx> for Terminator<'tcx> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) - { + fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) { visitor.visit_terminator(self, location) } } impl<'tcx> MirVisitable<'tcx> for Option> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) - { + fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) { visitor.visit_terminator(self.as_ref().unwrap(), location) } } @@ -1112,10 +1109,10 @@ impl PlaceContext { /// Returns `true` if this place context represents a borrow. pub fn is_borrow(&self) -> bool { match *self { - PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) | - PlaceContext::MutatingUse(MutatingUseContext::Borrow) => true, + PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) + | PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) + | PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) + | PlaceContext::MutatingUse(MutatingUseContext::Borrow) => true, _ => false, } } @@ -1123,8 +1120,8 @@ impl PlaceContext { /// Returns `true` if this place context represents a storage live or storage dead marker. pub fn is_storage_marker(&self) -> bool { match *self { - PlaceContext::NonUse(NonUseContext::StorageLive) | - PlaceContext::NonUse(NonUseContext::StorageDead) => true, + PlaceContext::NonUse(NonUseContext::StorageLive) + | PlaceContext::NonUse(NonUseContext::StorageDead) => true, _ => false, } } @@ -1172,9 +1169,9 @@ impl PlaceContext { /// Returns `true` if this place context represents an assignment statement. pub fn is_place_assignment(&self) -> bool { match *self { - PlaceContext::MutatingUse(MutatingUseContext::Store) | - PlaceContext::MutatingUse(MutatingUseContext::Call) | - PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) => true, + PlaceContext::MutatingUse(MutatingUseContext::Store) + | PlaceContext::MutatingUse(MutatingUseContext::Call) + | PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) => true, _ => false, } } diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index a9dd856e75857..24841a1ccf456 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -1,18 +1,17 @@ -use crate::ty::query::QueryDescription; -use crate::ty::query::queries; -use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt}; -use crate::ty::subst::SubstsRef; -use crate::dep_graph::{RecoverKey,DepKind, DepNode, SerializedDepNodeIndex}; +use crate::dep_graph::{DepKind, DepNode, RecoverKey, SerializedDepNodeIndex}; use crate::hir::def_id::{CrateNum, DefId, DefIndex}; use crate::mir; use crate::mir::interpret::GlobalId; use crate::traits; use crate::traits::query::{ - CanonicalPredicateGoal, CanonicalProjectionGoal, - CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, - CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal, CanonicalTypeOpProvePredicateGoal, - CanonicalTypeOpNormalizeGoal, + CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, + CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal, + CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, }; +use crate::ty::query::queries; +use crate::ty::query::QueryDescription; +use crate::ty::subst::SubstsRef; +use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use std::borrow::Cow; use syntax_pos::symbol::Symbol; diff --git a/src/librustc/traits/auto_trait.rs b/src/librustc/traits/auto_trait.rs index a0d9f52d28ad5..89b28aeda1c5e 100644 --- a/src/librustc/traits/auto_trait.rs +++ b/src/librustc/traits/auto_trait.rs @@ -83,10 +83,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { ) -> AutoTraitResult { let tcx = self.tcx; - let trait_ref = ty::TraitRef { - def_id: trait_did, - substs: tcx.mk_substs_trait(ty, &[]), - }; + let trait_ref = ty::TraitRef { def_id: trait_did, substs: tcx.mk_substs_trait(ty, &[]) }; let trait_pred = ty::Binder::bind(trait_ref); @@ -107,7 +104,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { ); true } - _ => false + _ => false, } }); @@ -165,20 +162,19 @@ impl<'tcx> AutoTraitFinder<'tcx> { None => return AutoTraitResult::NegativeImpl, }; - let (full_env, full_user_env) = self.evaluate_predicates( - &mut infcx, - trait_did, - ty, - new_env, - user_env, - &mut fresh_preds, - true, - ).unwrap_or_else(|| { - panic!( - "Failed to fully process: {:?} {:?} {:?}", - ty, trait_did, orig_env + let (full_env, full_user_env) = self + .evaluate_predicates( + &mut infcx, + trait_did, + ty, + new_env, + user_env, + &mut fresh_preds, + true, ) - }); + .unwrap_or_else(|| { + panic!("Failed to fully process: {:?} {:?} {:?}", ty, trait_did, orig_env) + }); debug!( "find_auto_trait_generics({:?}): fulfilling \ @@ -199,33 +195,19 @@ impl<'tcx> AutoTraitFinder<'tcx> { ObligationCause::misc(DUMMY_SP, hir::DUMMY_HIR_ID), ); fulfill.select_all_or_error(&infcx).unwrap_or_else(|e| { - panic!( - "Unable to fulfill trait {:?} for '{:?}': {:?}", - trait_did, ty, e - ) + panic!("Unable to fulfill trait {:?} for '{:?}': {:?}", trait_did, ty, e) }); - let body_id_map: FxHashMap<_, _> = infcx - .region_obligations - .borrow() - .iter() - .map(|&(id, _)| (id, vec![])) - .collect(); + let body_id_map: FxHashMap<_, _> = + infcx.region_obligations.borrow().iter().map(|&(id, _)| (id, vec![])).collect(); infcx.process_registered_region_obligations(&body_id_map, None, full_env); - let region_data = infcx - .borrow_region_constraints() - .region_constraint_data() - .clone(); + let region_data = infcx.borrow_region_constraints().region_constraint_data().clone(); let vid_to_region = self.map_vid_to_region(®ion_data); - let info = AutoTraitInfo { - full_user_env, - region_data, - vid_to_region, - }; + let info = AutoTraitInfo { full_user_env, region_data, vid_to_region }; return AutoTraitResult::PositiveImpl(auto_trait_callback(&infcx, info)); }); @@ -311,9 +293,11 @@ impl AutoTraitFinder<'tcx> { // Call `infcx.resolve_vars_if_possible` to see if we can // get rid of any inference variables. - let obligation = infcx.resolve_vars_if_possible( - &Obligation::new(dummy_cause.clone(), new_env, pred) - ); + let obligation = infcx.resolve_vars_if_possible(&Obligation::new( + dummy_cause.clone(), + new_env, + pred, + )); let result = select.select(&obligation); match &result { @@ -323,13 +307,15 @@ impl AutoTraitFinder<'tcx> { match vtable { Vtable::VtableImpl(VtableImplData { impl_def_id, .. }) => { // Blame 'tidy' for the weird bracket placement. - if infcx.tcx.impl_polarity(*impl_def_id) == ty::ImplPolarity::Negative - { - debug!("evaluate_nested_obligations: found explicit negative impl\ - {:?}, bailing out", impl_def_id); + if infcx.tcx.impl_polarity(*impl_def_id) == ty::ImplPolarity::Negative { + debug!( + "evaluate_nested_obligations: found explicit negative impl\ + {:?}, bailing out", + impl_def_id + ); return None; } - }, + } _ => {} } @@ -351,10 +337,7 @@ impl AutoTraitFinder<'tcx> { &Err(SelectionError::Unimplemented) => { if self.is_param_no_infer(pred.skip_binder().trait_ref.substs) { already_visited.remove(&pred); - self.add_user_pred( - &mut user_computed_preds, - ty::Predicate::Trait(pred), - ); + self.add_user_pred(&mut user_computed_preds, ty::Predicate::Trait(pred)); predicates.push_back(pred); } else { debug!( @@ -373,17 +356,14 @@ impl AutoTraitFinder<'tcx> { computed_preds.extend(user_computed_preds.iter().cloned()); let normalized_preds = elaborate_predicates(tcx, computed_preds.iter().cloned().collect()); - new_env = ty::ParamEnv::new( - tcx.mk_predicates(normalized_preds), - param_env.reveal, - None - ); + new_env = + ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal, None); } let final_user_env = ty::ParamEnv::new( tcx.mk_predicates(user_computed_preds.into_iter()), user_env.reveal, - None + None, ); debug!( "evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \ @@ -447,8 +427,8 @@ impl AutoTraitFinder<'tcx> { ty::RegionKind::ReLateBound(_, _), ) => {} - (ty::RegionKind::ReLateBound(_, _), _) | - (_, ty::RegionKind::ReVar(_)) => { + (ty::RegionKind::ReLateBound(_, _), _) + | (_, ty::RegionKind::ReVar(_)) => { // One of these is true: // The new predicate has a HRTB in a spot where the old // predicate does not (if they both had a HRTB, the previous @@ -474,8 +454,8 @@ impl AutoTraitFinder<'tcx> { // `user_computed_preds`. return false; } - (_, ty::RegionKind::ReLateBound(_, _)) | - (ty::RegionKind::ReVar(_), _) => { + (_, ty::RegionKind::ReLateBound(_, _)) + | (ty::RegionKind::ReVar(_), _) => { // This is the opposite situation as the previous arm. // One of these is true: // @@ -491,7 +471,7 @@ impl AutoTraitFinder<'tcx> { // predicate in `user_computed_preds`, and skip adding // new_pred to `user_computed_params`. should_add_new = false - }, + } _ => {} } } @@ -598,8 +578,7 @@ impl AutoTraitFinder<'tcx> { } fn is_param_no_infer(&self, substs: SubstsRef<'_>) -> bool { - return self.is_of_param(substs.type_at(0)) && - !substs.types().any(|t| t.has_infer_types()); + return self.is_of_param(substs.type_at(0)) && !substs.types().any(|t| t.has_infer_types()); } pub fn is_of_param(&self, ty: Ty<'_>) -> bool { @@ -612,10 +591,8 @@ impl AutoTraitFinder<'tcx> { fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool { match p.ty().skip_binder().kind { - ty::Projection(proj) if proj == p.skip_binder().projection_ty => { - true - }, - _ => false + ty::Projection(proj) if proj == p.skip_binder().projection_ty => true, + _ => false, } } @@ -631,11 +608,8 @@ impl AutoTraitFinder<'tcx> { ) -> bool { let dummy_cause = ObligationCause::misc(DUMMY_SP, hir::DUMMY_HIR_ID); - for (obligation, mut predicate) in nested - .map(|o| (o.clone(), o.predicate)) - { - let is_new_pred = - fresh_preds.insert(self.clean_pred(select.infcx(), predicate)); + for (obligation, mut predicate) in nested.map(|o| (o.clone(), o.predicate)) { + let is_new_pred = fresh_preds.insert(self.clean_pred(select.infcx(), predicate)); // Resolve any inference variables that we can, to help selection succeed predicate = select.infcx().resolve_vars_if_possible(&predicate); @@ -656,15 +630,17 @@ impl AutoTraitFinder<'tcx> { &ty::Predicate::Trait(p) => { if self.is_param_no_infer(p.skip_binder().trait_ref.substs) && !only_projections - && is_new_pred { - + && is_new_pred + { self.add_user_pred(computed_preds, predicate); } predicates.push_back(p); } &ty::Predicate::Projection(p) => { - debug!("evaluate_nested_obligations: examining projection predicate {:?}", - predicate); + debug!( + "evaluate_nested_obligations: examining projection predicate {:?}", + predicate + ); // As described above, we only want to display // bounds which include a generic parameter but don't include @@ -673,27 +649,32 @@ impl AutoTraitFinder<'tcx> { // to avoid rendering duplicate bounds to the user. if self.is_param_no_infer(p.skip_binder().projection_ty.substs) && !p.ty().skip_binder().has_infer_types() - && is_new_pred { - debug!("evaluate_nested_obligations: adding projection predicate\ - to computed_preds: {:?}", predicate); - - // Under unusual circumstances, we can end up with a self-refeential - // projection predicate. For example: - // ::Value == ::Value - // Not only is displaying this to the user pointless, - // having it in the ParamEnv will cause an issue if we try to call - // poly_project_and_unify_type on the predicate, since this kind of - // predicate will normally never end up in a ParamEnv. - // - // For these reasons, we ignore these weird predicates, - // ensuring that we're able to properly synthesize an auto trait impl - if self.is_self_referential_projection(p) { - debug!("evaluate_nested_obligations: encountered a projection - predicate equating a type with itself! Skipping"); - - } else { - self.add_user_pred(computed_preds, predicate); - } + && is_new_pred + { + debug!( + "evaluate_nested_obligations: adding projection predicate\ + to computed_preds: {:?}", + predicate + ); + + // Under unusual circumstances, we can end up with a self-refeential + // projection predicate. For example: + // ::Value == ::Value + // Not only is displaying this to the user pointless, + // having it in the ParamEnv will cause an issue if we try to call + // poly_project_and_unify_type on the predicate, since this kind of + // predicate will normally never end up in a ParamEnv. + // + // For these reasons, we ignore these weird predicates, + // ensuring that we're able to properly synthesize an auto trait impl + if self.is_self_referential_projection(p) { + debug!( + "evaluate_nested_obligations: encountered a projection + predicate equating a type with itself! Skipping" + ); + } else { + self.add_user_pred(computed_preds, predicate); + } } // There are three possible cases when we project a predicate: @@ -736,8 +717,7 @@ impl AutoTraitFinder<'tcx> { // negative impl error. To properly handle this case, we need // to ensure that we catch any potential projection errors, // and turn them into an explicit negative impl for our type. - debug!("Projecting and unifying projection predicate {:?}", - predicate); + debug!("Projecting and unifying projection predicate {:?}", predicate); match poly_project_and_unify_type(select, &obligation.with(p)) { Err(e) => { @@ -782,11 +762,7 @@ impl AutoTraitFinder<'tcx> { } } &ty::Predicate::RegionOutlives(ref binder) => { - if select - .infcx() - .region_outlives_predicate(&dummy_cause, binder) - .is_err() - { + if select.infcx().region_outlives_predicate(&dummy_cause, binder).is_err() { return false; } } @@ -842,6 +818,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> { (match r { &ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned(), _ => None, - }).unwrap_or_else(|| r.super_fold_with(self)) + }) + .unwrap_or_else(|| r.super_fold_with(self)) } } diff --git a/src/librustc/traits/chalk_fulfill.rs b/src/librustc/traits/chalk_fulfill.rs index d9e83df7ddda6..a765e55d99fc2 100644 --- a/src/librustc/traits/chalk_fulfill.rs +++ b/src/librustc/traits/chalk_fulfill.rs @@ -1,16 +1,10 @@ +use crate::infer::canonical::{Canonical, OriginalQueryValues}; +use crate::infer::InferCtxt; +use crate::traits::query::NoSolution; use crate::traits::{ - Environment, - InEnvironment, - TraitEngine, - ObligationCause, - PredicateObligation, - FulfillmentError, - FulfillmentErrorCode, - SelectionError, + Environment, FulfillmentError, FulfillmentErrorCode, InEnvironment, ObligationCause, + PredicateObligation, SelectionError, TraitEngine, }; -use crate::traits::query::NoSolution; -use crate::infer::InferCtxt; -use crate::infer::canonical::{Canonical, OriginalQueryValues}; use crate::ty::{self, Ty}; use rustc_data_structures::fx::FxHashSet; @@ -22,9 +16,7 @@ pub struct FulfillmentContext<'tcx> { impl FulfillmentContext<'tcx> { crate fn new() -> Self { - FulfillmentContext { - obligations: FxHashSet::default(), - } + FulfillmentContext { obligations: FxHashSet::default() } } } @@ -37,16 +29,13 @@ fn in_environment( let environment = match obligation.param_env.def_id { Some(def_id) => infcx.tcx.environment(def_id), - None if obligation.param_env.caller_bounds.is_empty() => Environment { - clauses: ty::List::empty(), - }, + None if obligation.param_env.caller_bounds.is_empty() => { + Environment { clauses: ty::List::empty() } + } _ => bug!("non-empty `ParamEnv` with no def-id"), }; - InEnvironment { - environment, - goal: obligation, - } + InEnvironment { environment, goal: obligation } } impl TraitEngine<'tcx> for FulfillmentContext<'tcx> { @@ -77,7 +66,9 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> { if self.obligations.is_empty() { Ok(()) } else { - let errors = self.obligations.iter() + let errors = self + .obligations + .iter() .map(|obligation| FulfillmentError { obligation: obligation.goal.clone(), code: FulfillmentErrorCode::CodeAmbiguity, @@ -103,10 +94,13 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> { // to unambiguously prove at least one obligation. for obligation in self.obligations.drain() { let mut orig_values = OriginalQueryValues::default(); - let canonical_goal = infcx.canonicalize_query(&InEnvironment { - environment: obligation.environment, - goal: obligation.goal.predicate, - }, &mut orig_values); + let canonical_goal = infcx.canonicalize_query( + &InEnvironment { + environment: obligation.environment, + goal: obligation.goal.predicate, + }, + &mut orig_values, + ); match infcx.tcx.evaluate_goal(canonical_goal) { Ok(response) => { @@ -117,18 +111,19 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> { &obligation.goal.cause, obligation.goal.param_env, &orig_values, - &response + &response, ) { Ok(infer_ok) => next_round.extend( - infer_ok.obligations + infer_ok + .obligations .into_iter() - .map(|obligation| in_environment(infcx, obligation)) + .map(|obligation| in_environment(infcx, obligation)), ), Err(_err) => errors.push(FulfillmentError { obligation: obligation.goal, code: FulfillmentErrorCode::CodeSelectionError( - SelectionError::Unimplemented + SelectionError::Unimplemented, ), points_at_arg_span: false, }), @@ -142,10 +137,10 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> { Err(NoSolution) => errors.push(FulfillmentError { obligation: obligation.goal, code: FulfillmentErrorCode::CodeSelectionError( - SelectionError::Unimplemented + SelectionError::Unimplemented, ), points_at_arg_span: false, - }) + }), } } next_round = std::mem::replace(&mut self.obligations, next_round); @@ -155,11 +150,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> { } } - if errors.is_empty() { - Ok(()) - } else { - Err(errors) - } + if errors.is_empty() { Ok(()) } else { Err(errors) } } fn pending_obligations(&self) -> Vec> { diff --git a/src/librustc/traits/codegen/mod.rs b/src/librustc/traits/codegen/mod.rs index 9dff699deb8af..8bd3f3141d53d 100644 --- a/src/librustc/traits/codegen/mod.rs +++ b/src/librustc/traits/codegen/mod.rs @@ -4,11 +4,12 @@ // general routines. use crate::infer::InferCtxt; -use crate::traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext, - TraitEngine, Vtable}; -use crate::ty::{self, TyCtxt}; -use crate::ty::subst::{Subst, SubstsRef}; +use crate::traits::{ + FulfillmentContext, Obligation, ObligationCause, SelectionContext, TraitEngine, Vtable, +}; use crate::ty::fold::TypeFoldable; +use crate::ty::subst::{Subst, SubstsRef}; +use crate::ty::{self, TyCtxt}; /// Attempts to resolve an obligation to a vtable. The result is /// a shallow vtable resolution, meaning that we do not @@ -23,8 +24,11 @@ pub fn codegen_fulfill_obligation<'tcx>( // Remove any references to regions; this helps improve caching. let trait_ref = ty.erase_regions(&trait_ref); - debug!("codegen_fulfill_obligation(trait_ref={:?}, def_id={:?})", - (param_env, trait_ref), trait_ref.def_id()); + debug!( + "codegen_fulfill_obligation(trait_ref={:?}, def_id={:?})", + (param_env, trait_ref), + trait_ref.def_id() + ); // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. @@ -32,9 +36,8 @@ pub fn codegen_fulfill_obligation<'tcx>( let mut selcx = SelectionContext::new(&infcx); let obligation_cause = ObligationCause::dummy(); - let obligation = Obligation::new(obligation_cause, - param_env, - trait_ref.to_poly_trait_predicate()); + let obligation = + Obligation::new(obligation_cause, param_env, trait_ref.to_poly_trait_predicate()); let selection = match selcx.select(&obligation) { Ok(Some(selection)) => selection, @@ -45,9 +48,11 @@ pub fn codegen_fulfill_obligation<'tcx>( // leading to an ambiguous result. So report this as an // overflow bug, since I believe this is the only case // where ambiguity can result. - bug!("Encountered ambiguity selecting `{:?}` during codegen, \ + bug!( + "Encountered ambiguity selecting `{:?}` during codegen, \ presuming due to overflow", - trait_ref) + trait_ref + ) } Err(e) => { bug!("Encountered error `{:?}` selecting `{:?}` during codegen", e, trait_ref) @@ -79,7 +84,7 @@ impl<'tcx> TyCtxt<'tcx> { self, param_substs: SubstsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, - value: &T + value: &T, ) -> T where T: TypeFoldable<'tcx>, @@ -89,9 +94,7 @@ impl<'tcx> TyCtxt<'tcx> { param_substs={:?}, \ value={:?}, \ param_env={:?})", - param_substs, - value, - param_env, + param_substs, value, param_env, ); let substituted = value.subst(self, param_substs); self.normalize_erasing_regions(param_env, substituted) diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 933bc06c21efe..3eaa9db0b1522 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -4,14 +4,14 @@ //! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html //! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html -use crate::infer::{CombinedSnapshot, InferOk}; use crate::hir::def_id::{DefId, LOCAL_CRATE}; -use crate::traits::{self, Normalized, SelectionContext, Obligation, ObligationCause}; -use crate::traits::IntercrateMode; +use crate::infer::{CombinedSnapshot, InferOk}; use crate::traits::select::IntercrateAmbiguityCause; -use crate::ty::{self, Ty, TyCtxt}; +use crate::traits::IntercrateMode; +use crate::traits::{self, Normalized, Obligation, ObligationCause, SelectionContext}; use crate::ty::fold::TypeFoldable; use crate::ty::subst::Subst; +use crate::ty::{self, Ty, TyCtxt}; use syntax::symbol::sym; use syntax_pos::DUMMY_SP; @@ -20,13 +20,13 @@ use syntax_pos::DUMMY_SP; #[derive(Copy, Clone, Debug)] enum InCrate { Local, - Remote + Remote, } #[derive(Debug, Copy, Clone)] pub enum Conflict { Upstream, - Downstream { used_to_be_broken: bool } + Downstream { used_to_be_broken: bool }, } pub struct OverlapResult<'tcx> { @@ -60,13 +60,13 @@ where F1: FnOnce(OverlapResult<'_>) -> R, F2: FnOnce() -> R, { - debug!("overlapping_impls(\ + debug!( + "overlapping_impls(\ impl1_def_id={:?}, \ impl2_def_id={:?}, intercrate_mode={:?})", - impl1_def_id, - impl2_def_id, - intercrate_mode); + impl1_def_id, impl2_def_id, intercrate_mode + ); let overlaps = tcx.infer_ctxt().enter(|infcx| { let selcx = &mut SelectionContext::intercrate(&infcx, intercrate_mode); @@ -140,35 +140,39 @@ fn overlap_within_probe( debug!("overlap: b_impl_header={:?}", b_impl_header); // Do `a` and `b` unify? If not, no overlap. - let obligations = match selcx.infcx().at(&ObligationCause::dummy(), param_env) - .eq_impl_headers(&a_impl_header, &b_impl_header) + let obligations = match selcx + .infcx() + .at(&ObligationCause::dummy(), param_env) + .eq_impl_headers(&a_impl_header, &b_impl_header) { Ok(InferOk { obligations, value: () }) => obligations, - Err(_) => return None + Err(_) => return None, }; debug!("overlap: unification check succeeded"); // Are any of the obligations unsatisfiable? If so, no overlap. let infcx = selcx.infcx(); - let opt_failing_obligation = - a_impl_header.predicates - .iter() - .chain(&b_impl_header.predicates) - .map(|p| infcx.resolve_vars_if_possible(p)) - .map(|p| Obligation { cause: ObligationCause::dummy(), - param_env, - recursion_depth: 0, - predicate: p }) - .chain(obligations) - .find(|o| !selcx.predicate_may_hold_fatal(o)); + let opt_failing_obligation = a_impl_header + .predicates + .iter() + .chain(&b_impl_header.predicates) + .map(|p| infcx.resolve_vars_if_possible(p)) + .map(|p| Obligation { + cause: ObligationCause::dummy(), + param_env, + recursion_depth: 0, + predicate: p, + }) + .chain(obligations) + .find(|o| !selcx.predicate_may_hold_fatal(o)); // FIXME: the call to `selcx.predicate_may_hold_fatal` above should be ported // to the canonical trait query form, `infcx.predicate_may_hold`, once // the new system supports intercrate mode (which coherence needs). if let Some(failing_obligation) = opt_failing_obligation { debug!("overlap: obligation unsatisfiable {:?}", failing_obligation); - return None + return None; } let impl_header = selcx.infcx().resolve_vars_if_possible(&a_impl_header); @@ -195,8 +199,7 @@ pub fn trait_ref_is_knowable<'tcx>( // A trait can be implementable for a trait ref by both the current // crate and crates downstream of it. Older versions of rustc // were not aware of this, causing incoherence (issue #43355). - let used_to_be_broken = - orphan_check_trait_ref(tcx, trait_ref, InCrate::Local).is_ok(); + let used_to_be_broken = orphan_check_trait_ref(tcx, trait_ref, InCrate::Local).is_ok(); if used_to_be_broken { debug!("trait_ref_is_knowable({:?}) - USED TO BE BROKEN", trait_ref); } @@ -247,10 +250,7 @@ pub enum OrphanCheckErr<'tcx> { /// /// 1. All type parameters in `Self` must be "covered" by some local type constructor. /// 2. Some local type must appear in `Self`. -pub fn orphan_check( - tcx: TyCtxt<'_>, - impl_def_id: DefId, -) -> Result<(), OrphanCheckErr<'_>> { +pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanCheckErr<'_>> { debug!("orphan_check({:?})", impl_def_id); // We only except this routine to be invoked on implementations @@ -260,8 +260,7 @@ pub fn orphan_check( // If the *trait* is local to the crate, ok. if trait_ref.def_id.is_local() { - debug!("trait {:?} is local to current crate", - trait_ref.def_id); + debug!("trait {:?} is local to current crate", trait_ref.def_id); return Ok(()); } @@ -359,12 +358,13 @@ fn orphan_check_trait_ref<'tcx>( trait_ref: ty::TraitRef<'tcx>, in_crate: InCrate, ) -> Result<(), OrphanCheckErr<'tcx>> { - debug!("orphan_check_trait_ref(trait_ref={:?}, in_crate={:?})", - trait_ref, in_crate); + debug!("orphan_check_trait_ref(trait_ref={:?}, in_crate={:?})", trait_ref, in_crate); if trait_ref.needs_infer() && trait_ref.needs_subst() { - bug!("can't orphan check a trait ref with both params and inference variables {:?}", - trait_ref); + bug!( + "can't orphan check a trait ref with both params and inference variables {:?}", + trait_ref + ); } // Given impl Trait for T0, an impl is valid only @@ -390,10 +390,8 @@ fn orphan_check_trait_ref<'tcx>( } let mut non_local_spans = vec![]; - for (i, input_ty) in trait_ref - .input_types() - .flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate)) - .enumerate() + for (i, input_ty) in + trait_ref.input_types().flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate)).enumerate() { debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty); let non_local_tys = ty_is_non_local(input_ty, in_crate); @@ -410,7 +408,7 @@ fn orphan_check_trait_ref<'tcx>( debug!("orphan_check_trait_ref: uncovered ty local_type: `{:?}`", local_type); - return Err(OrphanCheckErr::UncoveredTy(input_ty, local_type)) + return Err(OrphanCheckErr::UncoveredTy(input_ty, local_type)); } if let Some(non_local_tys) = non_local_tys { for input_ty in non_local_tys { @@ -425,19 +423,18 @@ fn orphan_check_trait_ref<'tcx>( fn ty_is_non_local<'t>(ty: Ty<'t>, in_crate: InCrate) -> Option>> { match ty_is_non_local_constructor(ty, in_crate) { - Some(ty) => if !fundamental_ty(ty) { - Some(vec![ty]) - } else { - let tys: Vec<_> = ty.walk_shallow() - .filter_map(|t| ty_is_non_local(t, in_crate)) - .flat_map(|i| i) - .collect(); - if tys.is_empty() { - None + Some(ty) => { + if !fundamental_ty(ty) { + Some(vec![ty]) } else { - Some(tys) + let tys: Vec<_> = ty + .walk_shallow() + .filter_map(|t| ty_is_non_local(t, in_crate)) + .flat_map(|i| i) + .collect(); + if tys.is_empty() { None } else { Some(tys) } } - }, + } None => None, } } @@ -446,7 +443,7 @@ fn fundamental_ty(ty: Ty<'_>) -> bool { match ty.kind { ty::Ref(..) => true, ty::Adt(def, _) => def.is_fundamental(), - _ => false + _ => false, } } @@ -455,35 +452,30 @@ fn def_id_is_local(def_id: DefId, in_crate: InCrate) -> bool { // The type is local to *this* crate - it will not be // local in any other crate. InCrate::Remote => false, - InCrate::Local => def_id.is_local() + InCrate::Local => def_id.is_local(), } } -fn ty_is_non_local_constructor<'tcx>( - ty: Ty<'tcx>, - in_crate: InCrate, -) -> Option> { +fn ty_is_non_local_constructor<'tcx>(ty: Ty<'tcx>, in_crate: InCrate) -> Option> { debug!("ty_is_non_local_constructor({:?})", ty); match ty.kind { - ty::Bool | - ty::Char | - ty::Int(..) | - ty::Uint(..) | - ty::Float(..) | - ty::Str | - ty::FnDef(..) | - ty::FnPtr(_) | - ty::Array(..) | - ty::Slice(..) | - ty::RawPtr(..) | - ty::Ref(..) | - ty::Never | - ty::Tuple(..) | - ty::Param(..) | - ty::Projection(..) => { - Some(ty) - } + ty::Bool + | ty::Char + | ty::Int(..) + | ty::Uint(..) + | ty::Float(..) + | ty::Str + | ty::FnDef(..) + | ty::FnPtr(_) + | ty::Array(..) + | ty::Slice(..) + | ty::RawPtr(..) + | ty::Ref(..) + | ty::Never + | ty::Tuple(..) + | ty::Param(..) + | ty::Projection(..) => Some(ty), ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => match in_crate { InCrate::Local => Some(ty), @@ -492,16 +484,20 @@ fn ty_is_non_local_constructor<'tcx>( InCrate::Remote => None, }, - ty::Adt(def, _) => if def_id_is_local(def.did, in_crate) { - None - } else { - Some(ty) - }, - ty::Foreign(did) => if def_id_is_local(did, in_crate) { - None - } else { - Some(ty) - }, + ty::Adt(def, _) => { + if def_id_is_local(def.did, in_crate) { + None + } else { + Some(ty) + } + } + ty::Foreign(did) => { + if def_id_is_local(did, in_crate) { + None + } else { + Some(ty) + } + } ty::Opaque(..) => { // This merits some explanation. // Normally, opaque types are not involed when performing @@ -533,11 +529,7 @@ fn ty_is_non_local_constructor<'tcx>( ty::Dynamic(ref tt, ..) => { if let Some(principal) = tt.principal() { - if def_id_is_local(principal.def_id(), in_crate) { - None - } else { - Some(ty) - } + if def_id_is_local(principal.def_id(), in_crate) { None } else { Some(ty) } } else { Some(ty) } @@ -545,11 +537,9 @@ fn ty_is_non_local_constructor<'tcx>( ty::Error => None, - ty::UnnormalizedProjection(..) | - ty::Closure(..) | - ty::Generator(..) | - ty::GeneratorWitness(..) => { - bug!("ty_is_local invoked on unexpected type: {:?}", ty) - } + ty::UnnormalizedProjection(..) + | ty::Closure(..) + | ty::Generator(..) + | ty::GeneratorWitness(..) => bug!("ty_is_local invoked on unexpected type: {:?}", ty), } } diff --git a/src/librustc/traits/engine.rs b/src/librustc/traits/engine.rs index b96126c7b6735..b664540402605 100644 --- a/src/librustc/traits/engine.rs +++ b/src/librustc/traits/engine.rs @@ -1,7 +1,7 @@ +use crate::hir::def_id::DefId; use crate::infer::InferCtxt; -use crate::ty::{self, Ty, TyCtxt, ToPredicate}; use crate::traits::Obligation; -use crate::hir::def_id::DefId; +use crate::ty::{self, ToPredicate, Ty, TyCtxt}; use super::{ChalkFulfillmentContext, FulfillmentContext, FulfillmentError}; use super::{ObligationCause, PredicateObligation}; @@ -26,16 +26,16 @@ pub trait TraitEngine<'tcx>: 'tcx { def_id: DefId, cause: ObligationCause<'tcx>, ) { - let trait_ref = ty::TraitRef { - def_id, - substs: infcx.tcx.mk_substs_trait(ty, &[]), - }; - self.register_predicate_obligation(infcx, Obligation { - cause, - recursion_depth: 0, - param_env, - predicate: trait_ref.to_predicate() - }); + let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) }; + self.register_predicate_obligation( + infcx, + Obligation { + cause, + recursion_depth: 0, + param_env, + predicate: trait_ref.to_predicate(), + }, + ); } fn register_predicate_obligation( diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index b299fd6117e41..2ac2d789b2d34 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1,47 +1,35 @@ use super::{ - ConstEvalFailure, - EvaluationResult, - FulfillmentError, - FulfillmentErrorCode, - MismatchedProjectionTypes, - ObjectSafetyViolation, - Obligation, - ObligationCause, - ObligationCauseCode, - OnUnimplementedDirective, - OnUnimplementedNote, - OutputTypeParameterMismatch, - Overflow, - PredicateObligation, - SelectionContext, - SelectionError, + ConstEvalFailure, EvaluationResult, FulfillmentError, FulfillmentErrorCode, + MismatchedProjectionTypes, ObjectSafetyViolation, Obligation, ObligationCause, + ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote, + OutputTypeParameterMismatch, Overflow, PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe, }; use crate::hir; -use crate::hir::Node; use crate::hir::def_id::DefId; -use crate::infer::{self, InferCtxt}; +use crate::hir::Node; use crate::infer::error_reporting::TypeAnnotationNeeded as ErrorCode; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::{self, InferCtxt}; use crate::session::DiagnosticMessageId; -use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable}; -use crate::ty::TypeckTables; -use crate::ty::GenericParamDefKind; use crate::ty::error::ExpectedFound; use crate::ty::fast_reject; use crate::ty::fold::TypeFolder; use crate::ty::subst::Subst; +use crate::ty::GenericParamDefKind; use crate::ty::SubtypePredicate; +use crate::ty::TypeckTables; +use crate::ty::{self, AdtKind, DefIdTree, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; use crate::util::nodemap::{FxHashMap, FxHashSet}; -use errors::{Applicability, DiagnosticBuilder, pluralize, Style}; +use errors::{pluralize, Applicability, DiagnosticBuilder, Style}; +use rustc::hir::def_id::LOCAL_CRATE; use std::fmt; use syntax::ast; -use syntax::symbol::{sym, kw}; -use syntax_pos::{DUMMY_SP, Span, ExpnKind, MultiSpan}; -use rustc::hir::def_id::LOCAL_CRATE; +use syntax::symbol::{kw, sym}; use syntax_pos::source_map::SourceMap; +use syntax_pos::{ExpnKind, MultiSpan, Span, DUMMY_SP}; use rustc_error_codes::*; @@ -58,13 +46,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { index: Option, // None if this is an old error } - let mut error_map: FxHashMap<_, Vec<_>> = - self.reported_trait_errors.borrow().iter().map(|(&span, predicates)| { - (span, predicates.iter().map(|predicate| ErrorDescriptor { - predicate: predicate.clone(), - index: None - }).collect()) - }).collect(); + let mut error_map: FxHashMap<_, Vec<_>> = self + .reported_trait_errors + .borrow() + .iter() + .map(|(&span, predicates)| { + ( + span, + predicates + .iter() + .map(|predicate| ErrorDescriptor { + predicate: predicate.clone(), + index: None, + }) + .collect(), + ) + }) + .collect(); for (index, error) in errors.iter().enumerate() { // We want to ignore desugarings here: spans are equivalent even @@ -75,15 +73,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { span = expn_data.call_site; } - error_map.entry(span).or_default().push( - ErrorDescriptor { - predicate: error.obligation.predicate.clone(), - index: Some(index) - } - ); + error_map.entry(span).or_default().push(ErrorDescriptor { + predicate: error.obligation.predicate.clone(), + index: Some(index), + }); - self.reported_trait_errors.borrow_mut() - .entry(span).or_default() + self.reported_trait_errors + .borrow_mut() + .entry(span) + .or_default() .push(error.obligation.predicate.clone()); } @@ -102,16 +100,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Avoid errors being suppressed by already-suppressed // errors, to prevent all errors from being suppressed // at once. - continue + continue; } - if self.error_implies(&error2.predicate, &error.predicate) && - !(error2.index >= error.index && - self.error_implies(&error.predicate, &error2.predicate)) + if self.error_implies(&error2.predicate, &error.predicate) + && !(error2.index >= error.index + && self.error_implies(&error.predicate, &error2.predicate)) { info!("skipping {:?} (implied by {:?})", error, error2); is_suppressed[index] = true; - break + break; } } } @@ -127,21 +125,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // returns if `cond` not occurring implies that `error` does not occur - i.e., that // `error` occurring implies that `cond` occurs. - fn error_implies( - &self, - cond: &ty::Predicate<'tcx>, - error: &ty::Predicate<'tcx>, - ) -> bool { + fn error_implies(&self, cond: &ty::Predicate<'tcx>, error: &ty::Predicate<'tcx>) -> bool { if cond == error { - return true + return true; } let (cond, error) = match (cond, error) { - (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error)) - => (cond, error), + (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error)) => (cond, error), _ => { // FIXME: make this work in other cases too. - return false + return false; } }; @@ -155,7 +148,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let param_env = ty::ParamEnv::empty(); if self.can_sub(param_env, error, implication).is_ok() { debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication); - return true + return true; } } } @@ -191,7 +184,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { expected_found.expected, expected_found.found, err.clone(), - ).emit(); + ) + .emit(); } } } @@ -204,7 +198,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let predicate = self.resolve_vars_if_possible(&obligation.predicate); if predicate.references_error() { - return + return; } self.probe(|_| { @@ -221,7 +215,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let (data, _) = self.replace_bound_vars_with_fresh_vars( obligation.cause.span, infer::LateBoundRegionConversionTime::HigherRankedType, - data + data, ); let mut obligations = vec![]; let normalized_ty = super::normalize_projection_type( @@ -230,27 +224,36 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { data.projection_ty, obligation.cause.clone(), 0, - &mut obligations + &mut obligations, ); - debug!("report_projection_error obligation.cause={:?} obligation.param_env={:?}", - obligation.cause, obligation.param_env); + debug!( + "report_projection_error obligation.cause={:?} obligation.param_env={:?}", + obligation.cause, obligation.param_env + ); - debug!("report_projection_error normalized_ty={:?} data.ty={:?}", - normalized_ty, data.ty); + debug!( + "report_projection_error normalized_ty={:?} data.ty={:?}", + normalized_ty, data.ty + ); let is_normalized_ty_expected = match &obligation.cause.code { - ObligationCauseCode::ItemObligation(_) | - ObligationCauseCode::BindingObligation(_, _) | - ObligationCauseCode::ObjectCastObligation(_) => false, + ObligationCauseCode::ItemObligation(_) + | ObligationCauseCode::BindingObligation(_, _) + | ObligationCauseCode::ObjectCastObligation(_) => false, _ => true, }; - if let Err(error) = self.at(&obligation.cause, obligation.param_env) - .eq_exp(is_normalized_ty_expected, normalized_ty, data.ty) - { - values = Some(infer::ValuePairs::Types( - ExpectedFound::new(is_normalized_ty_expected, normalized_ty, data.ty))); + if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp( + is_normalized_ty_expected, + normalized_ty, + data.ty, + ) { + values = Some(infer::ValuePairs::Types(ExpectedFound::new( + is_normalized_ty_expected, + normalized_ty, + data.ty, + ))); err_buf = error; err = &err_buf; @@ -258,11 +261,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } let msg = format!("type mismatch resolving `{}`", predicate); - let error_id = ( - DiagnosticMessageId::ErrorId(271), - Some(obligation.cause.span), - msg, - ); + let error_id = (DiagnosticMessageId::ErrorId(271), Some(obligation.cause.span), msg); let fresh = self.tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id); if fresh { let mut diag = struct_span_err!( @@ -315,18 +314,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { match (type_category(a), type_category(b)) { (Some(cat_a), Some(cat_b)) => match (&a.kind, &b.kind) { (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => def_a == def_b, - _ => cat_a == cat_b + _ => cat_a == cat_b, }, // infer and error can be equated to all types - _ => true + _ => true, } } - fn impl_similar_to(&self, - trait_ref: ty::PolyTraitRef<'tcx>, - obligation: &PredicateObligation<'tcx>) - -> Option - { + fn impl_similar_to( + &self, + trait_ref: ty::PolyTraitRef<'tcx>, + obligation: &PredicateObligation<'tcx>, + ) -> Option { let tcx = self.tcx; let param_env = obligation.param_env; let trait_ref = tcx.erase_late_bound_regions(&trait_ref); @@ -335,47 +334,44 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let mut self_match_impls = vec![]; let mut fuzzy_match_impls = vec![]; - self.tcx.for_each_relevant_impl( - trait_ref.def_id, trait_self_ty, |def_id| { - let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id); - let impl_trait_ref = tcx - .impl_trait_ref(def_id) - .unwrap() - .subst(tcx, impl_substs); + self.tcx.for_each_relevant_impl(trait_ref.def_id, trait_self_ty, |def_id| { + let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id); + let impl_trait_ref = tcx.impl_trait_ref(def_id).unwrap().subst(tcx, impl_substs); - let impl_self_ty = impl_trait_ref.self_ty(); + let impl_self_ty = impl_trait_ref.self_ty(); - if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) { - self_match_impls.push(def_id); + if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) { + self_match_impls.push(def_id); - if trait_ref.substs.types().skip(1) - .zip(impl_trait_ref.substs.types().skip(1)) - .all(|(u,v)| self.fuzzy_match_tys(u, v)) - { - fuzzy_match_impls.push(def_id); - } + if trait_ref + .substs + .types() + .skip(1) + .zip(impl_trait_ref.substs.types().skip(1)) + .all(|(u, v)| self.fuzzy_match_tys(u, v)) + { + fuzzy_match_impls.push(def_id); } - }); + } + }); let impl_def_id = if self_match_impls.len() == 1 { self_match_impls[0] } else if fuzzy_match_impls.len() == 1 { fuzzy_match_impls[0] } else { - return None + return None; }; tcx.has_attr(impl_def_id, sym::rustc_on_unimplemented).then_some(impl_def_id) } fn describe_generator(&self, body_id: hir::BodyId) -> Option<&'static str> { - self.tcx.hir().body(body_id).generator_kind.map(|gen_kind| { - match gen_kind { - hir::GeneratorKind::Gen => "a generator", - hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "an async block", - hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "an async function", - hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "an async closure", - } + self.tcx.hir().body(body_id).generator_kind.map(|gen_kind| match gen_kind { + hir::GeneratorKind::Gen => "a generator", + hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "an async block", + hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "an async function", + hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "an async closure", }) } @@ -384,24 +380,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { fn describe_enclosure(&self, hir_id: hir::HirId) -> Option<&'static str> { let hir = &self.tcx.hir(); let node = hir.find(hir_id)?; - if let hir::Node::Item( - hir::Item{kind: hir::ItemKind::Fn(sig, _, body_id), .. }) = &node { - self.describe_generator(*body_id).or_else(|| - Some(if let hir::FnHeader{ asyncness: hir::IsAsync::Async, .. } = sig.header { + if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) = &node { + self.describe_generator(*body_id).or_else(|| { + Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { "an async function" } else { "a function" }) - ) + }) } else if let hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability), .. }) = &node { - self.describe_generator(*body_id).or_else(|| - Some(if gen_movability.is_some() { - "an async closure" - } else { - "a closure" - }) - ) + kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability), + .. + }) = &node + { + self.describe_generator(*body_id).or_else(|| { + Some(if gen_movability.is_some() { "an async closure" } else { "a closure" }) + }) } else if let hir::Node::Expr(hir::Expr { .. }) = &node { let parent_hid = hir.get_parent_node(hir_id); if parent_hid != hir_id { @@ -419,17 +413,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { trait_ref: ty::PolyTraitRef<'tcx>, obligation: &PredicateObligation<'tcx>, ) -> OnUnimplementedNote { - let def_id = self.impl_similar_to(trait_ref, obligation) - .unwrap_or_else(|| trait_ref.def_id()); + let def_id = + self.impl_similar_to(trait_ref, obligation).unwrap_or_else(|| trait_ref.def_id()); let trait_ref = *trait_ref.skip_binder(); let mut flags = vec![]; - flags.push((sym::item_context, - self.describe_enclosure(obligation.cause.body_id).map(|s|s.to_owned()))); + flags.push(( + sym::item_context, + self.describe_enclosure(obligation.cause.body_id).map(|s| s.to_owned()), + )); match obligation.cause.code { - ObligationCauseCode::BuiltinDerivedObligation(..) | - ObligationCauseCode::ImplDerivedObligation(..) => {} + ObligationCauseCode::BuiltinDerivedObligation(..) + | ObligationCauseCode::ImplDerivedObligation(..) => {} _ => { // this is a "direct", user-specified, rather than derived, // obligation. @@ -470,10 +466,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { for param in generics.params.iter() { let value = match param.kind { - GenericParamDefKind::Type { .. } | - GenericParamDefKind::Const => { + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => { trait_ref.substs[param.index as usize].to_string() - }, + } GenericParamDefKind::Lifetime => continue, }; let name = param.name; @@ -514,9 +509,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - if let Ok(Some(command)) = OnUnimplementedDirective::of_item( - self.tcx, trait_ref.def_id, def_id - ) { + if let Ok(Some(command)) = + OnUnimplementedDirective::of_item(self.tcx, trait_ref.def_id, def_id) + { command.evaluate(self.tcx, trait_ref, &flags[..]) } else { OnUnimplementedNote::default() @@ -531,20 +526,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let all_impls = self.tcx.all_impls(trait_ref.def_id()); match simp { - Some(simp) => all_impls.iter().filter_map(|&def_id| { - let imp = self.tcx.impl_trait_ref(def_id).unwrap(); - let imp_simp = fast_reject::simplify_type(self.tcx, imp.self_ty(), true); - if let Some(imp_simp) = imp_simp { - if simp != imp_simp { - return None + Some(simp) => all_impls + .iter() + .filter_map(|&def_id| { + let imp = self.tcx.impl_trait_ref(def_id).unwrap(); + let imp_simp = fast_reject::simplify_type(self.tcx, imp.self_ty(), true); + if let Some(imp_simp) = imp_simp { + if simp != imp_simp { + return None; + } } - } - Some(imp) - }).collect(), - None => all_impls.iter().map(|&def_id| - self.tcx.impl_trait_ref(def_id).unwrap() - ).collect() + Some(imp) + }) + .collect(), + None => { + all_impls.iter().map(|&def_id| self.tcx.impl_trait_ref(def_id).unwrap()).collect() + } } } @@ -558,42 +556,35 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } let len = impl_candidates.len(); - let end = if impl_candidates.len() <= 5 { - impl_candidates.len() - } else { - 4 + let end = if impl_candidates.len() <= 5 { impl_candidates.len() } else { 4 }; + + let normalize = |candidate| { + self.tcx.infer_ctxt().enter(|ref infcx| { + let normalized = infcx + .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) + .normalize(candidate) + .ok(); + match normalized { + Some(normalized) => format!("\n {:?}", normalized.value), + None => format!("\n {:?}", candidate), + } + }) }; - let normalize = |candidate| self.tcx.infer_ctxt().enter(|ref infcx| { - let normalized = infcx - .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) - .normalize(candidate) - .ok(); - match normalized { - Some(normalized) => format!("\n {:?}", normalized.value), - None => format!("\n {:?}", candidate), - } - }); - // Sort impl candidates so that ordering is consistent for UI tests. - let mut normalized_impl_candidates = impl_candidates - .iter() - .map(normalize) - .collect::>(); + let mut normalized_impl_candidates = + impl_candidates.iter().map(normalize).collect::>(); // Sort before taking the `..end` range, // because the ordering of `impl_candidates` may not be deterministic: // https://github.com/rust-lang/rust/pull/57475#issuecomment-455519507 normalized_impl_candidates.sort(); - err.help(&format!("the following implementations were found:{}{}", - normalized_impl_candidates[..end].join(""), - if len > 5 { - format!("\nand {} others", len - 4) - } else { - String::new() - } - )); + err.help(&format!( + "the following implementations were found:{}{}", + normalized_impl_candidates[..end].join(""), + if len > 5 { format!("\nand {} others", len - 4) } else { String::new() } + )); } /// Reports that an overflow has occurred and halts compilation. We @@ -607,10 +598,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { obligation: &Obligation<'tcx, T>, suggest_increasing_limit: bool, ) -> ! - where T: fmt::Display + TypeFoldable<'tcx> + where + T: fmt::Display + TypeFoldable<'tcx>, { - let predicate = - self.resolve_vars_if_possible(&obligation.predicate); + let predicate = self.resolve_vars_if_possible(&obligation.predicate); let mut err = struct_span_err!( self.tcx.sess, obligation.cause.span, @@ -649,14 +640,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.report_overflow_error(&cycle[0], false); } - pub fn report_extra_impl_obligation(&self, - error_span: Span, - item_name: ast::Name, - _impl_item_def_id: DefId, - trait_item_def_id: DefId, - requirement: &dyn fmt::Display) - -> DiagnosticBuilder<'tcx> - { + pub fn report_extra_impl_obligation( + &self, + error_span: Span, + item_name: ast::Name, + _impl_item_def_id: DefId, + trait_item_def_id: DefId, + requirement: &dyn fmt::Display, + ) -> DiagnosticBuilder<'tcx> { let msg = "impl has stricter requirements than trait"; let sp = self.tcx.sess.source_map().def_span(error_span); @@ -672,13 +663,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err } - /// Gets the parent trait chain start fn get_parent_trait_ref(&self, code: &ObligationCauseCode<'tcx>) -> Option { match code { &ObligationCauseCode::BuiltinDerivedObligation(ref data) => { - let parent_trait_ref = self.resolve_vars_if_possible( - &data.parent_trait_ref); + let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref); match self.get_parent_trait_ref(&data.parent_code) { Some(t) => Some(t), None => Some(parent_trait_ref.skip_binder().self_ty().to_string()), @@ -701,17 +690,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let mut err = match *error { SelectionError::Unimplemented => { if let ObligationCauseCode::CompareImplMethodObligation { - item_name, impl_item_def_id, trait_item_def_id, - } | ObligationCauseCode::CompareImplTypeObligation { - item_name, impl_item_def_id, trait_item_def_id, - } = obligation.cause.code { + item_name, + impl_item_def_id, + trait_item_def_id, + } + | ObligationCauseCode::CompareImplTypeObligation { + item_name, + impl_item_def_id, + trait_item_def_id, + } = obligation.cause.code + { self.report_extra_impl_obligation( span, item_name, impl_item_def_id, trait_item_def_id, - &format!("`{}`", obligation.predicate)) - .emit(); + &format!("`{}`", obligation.predicate), + ) + .emit(); return; } match obligation.predicate { @@ -722,34 +718,35 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { return; } let trait_ref = trait_predicate.to_poly_trait_ref(); - let ( - post_message, - pre_message, - ) = self.get_parent_trait_ref(&obligation.cause.code) + let (post_message, pre_message) = self + .get_parent_trait_ref(&obligation.cause.code) .map(|t| (format!(" in `{}`", t), format!("within `{}`, ", t))) .unwrap_or_default(); - let OnUnimplementedNote { - message, - label, - note, - enclosing_scope, - } = self.on_unimplemented_note(trait_ref, obligation); + let OnUnimplementedNote { message, label, note, enclosing_scope } = + self.on_unimplemented_note(trait_ref, obligation); let have_alt_message = message.is_some() || label.is_some(); - let is_try = self.tcx.sess.source_map().span_to_snippet(span) + let is_try = self + .tcx + .sess + .source_map() + .span_to_snippet(span) .map(|s| &s == "?") .unwrap_or(false); - let is_from = - format!("{}", trait_ref.print_only_trait_path()) + let is_from = format!("{}", trait_ref.print_only_trait_path()) .starts_with("std::convert::From<"); let (message, note) = if is_try && is_from { - (Some(format!( - "`?` couldn't convert the error to `{}`", - trait_ref.self_ty(), - )), Some( - "the question mark operation (`?`) implicitly performs a \ - conversion on the error value using the `From` trait".to_owned() - )) + ( + Some(format!( + "`?` couldn't convert the error to `{}`", + trait_ref.self_ty(), + )), + Some( + "the question mark operation (`?`) implicitly performs a \ + conversion on the error value using the `From` trait" + .to_owned(), + ), + ) } else { (message, note) }; @@ -763,7 +760,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "the trait bound `{}` is not satisfied{}", trait_ref.to_predicate(), post_message, - ))); + )) + ); let explanation = if obligation.cause.code == ObligationCauseCode::MainFunctionType { @@ -821,8 +819,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.note_version_mismatch(&mut err, &trait_ref); // Try to report a help message - if !trait_ref.has_infer_types() && - self.predicate_can_apply(obligation.param_env, trait_ref) { + if !trait_ref.has_infer_types() + && self.predicate_can_apply(obligation.param_env, trait_ref) + { // If a where-clause may be useful, remind the // user that they can add it. // @@ -865,15 +864,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }); let unit_obligation = Obligation { predicate: ty::Predicate::Trait(predicate), - .. obligation.clone() + ..obligation.clone() }; if self.predicate_may_hold(&unit_obligation) { - err.note("the trait is implemented for `()`. \ + err.note( + "the trait is implemented for `()`. \ Possibly this error has been caused by changes to \ Rust's type-inference algorithm \ (see: https://github.com/rust-lang/rust/issues/48950 \ for more info). Consider whether you meant to use the \ - type `()` here instead."); + type `()` here instead.", + ); } } @@ -889,50 +890,62 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ty::Predicate::RegionOutlives(ref predicate) => { let predicate = self.resolve_vars_if_possible(predicate); - let err = self.region_outlives_predicate(&obligation.cause, - &predicate).err().unwrap(); + let err = self + .region_outlives_predicate(&obligation.cause, &predicate) + .err() + .unwrap(); struct_span_err!( - self.tcx.sess, span, E0279, + self.tcx.sess, + span, + E0279, "the requirement `{}` is not satisfied (`{}`)", - predicate, err, + predicate, + err, ) } ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => { - let predicate = - self.resolve_vars_if_possible(&obligation.predicate); - struct_span_err!(self.tcx.sess, span, E0280, + let predicate = self.resolve_vars_if_possible(&obligation.predicate); + struct_span_err!( + self.tcx.sess, + span, + E0280, "the requirement `{}` is not satisfied", - predicate) + predicate + ) } ty::Predicate::ObjectSafe(trait_def_id) => { let violations = self.tcx.object_safety_violations(trait_def_id); - self.tcx.report_object_safety_error( - span, - trait_def_id, - violations, - ) + self.tcx.report_object_safety_error(span, trait_def_id, violations) } ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { let found_kind = self.closure_kind(closure_def_id, closure_substs).unwrap(); - let closure_span = self.tcx.sess.source_map() + let closure_span = self + .tcx + .sess + .source_map() .def_span(self.tcx.hir().span_if_local(closure_def_id).unwrap()); let hir_id = self.tcx.hir().as_local_hir_id(closure_def_id).unwrap(); let mut err = struct_span_err!( - self.tcx.sess, closure_span, E0525, + self.tcx.sess, + closure_span, + E0525, "expected a closure that implements the `{}` trait, \ but this closure only implements `{}`", kind, - found_kind); + found_kind + ); err.span_label( closure_span, - format!("this closure implements `{}`, not `{}`", found_kind, kind)); + format!("this closure implements `{}`, not `{}`", found_kind, kind), + ); err.span_label( obligation.cause.span, - format!("the requirement to implement `{}` derives from here", kind)); + format!("the requirement to implement `{}` derives from here", kind), + ); // Additional context information explaining why the closure only implements // a particular trait. @@ -940,15 +953,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let tables = tables.borrow(); match (found_kind, tables.closure_kind_origins().get(hir_id)) { (ty::ClosureKind::FnOnce, Some((span, name))) => { - err.span_label(*span, format!( - "closure is `FnOnce` because it moves the \ - variable `{}` out of its environment", name)); - }, + err.span_label( + *span, + format!( + "closure is `FnOnce` because it moves the \ + variable `{}` out of its environment", + name + ), + ); + } (ty::ClosureKind::FnMut, Some((span, name))) => { - err.span_label(*span, format!( - "closure is `FnMut` because it mutates the \ - variable `{}` here", name)); - }, + err.span_label( + *span, + format!( + "closure is `FnMut` because it mutates the \ + variable `{}` here", + name + ), + ); + } _ => {} } } @@ -970,7 +993,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // which bounds actually failed to hold. self.tcx.sess.struct_span_err( span, - &format!("the type `{}` is not well-formed (chalk)", ty) + &format!("the type `{}` is not well-formed (chalk)", ty), ) } } @@ -979,8 +1002,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Errors for `ConstEvaluatable` predicates show up as // `SelectionError::ConstEvalFailure`, // not `Unimplemented`. - span_bug!(span, - "const-evaluatable requirement gave wrong error: `{:?}`", obligation) + span_bug!( + span, + "const-evaluatable requirement gave wrong error: `{:?}`", + obligation + ) } } } @@ -1001,9 +1027,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => None, }; - let found_span = found_did.and_then(|did| - self.tcx.hir().span_if_local(did) - ).map(|sp| self.tcx.sess.source_map().def_span(sp)); // the sp could be an fn def + let found_span = found_did + .and_then(|did| self.tcx.hir().span_if_local(did)) + .map(|sp| self.tcx.sess.source_map().def_span(sp)); // the sp could be an fn def if self.reported_closure_mismatch.borrow().contains(&(span, found_span)) { // We check closures twice, with obligations flowing in different directions, @@ -1020,29 +1046,36 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1); let expected = match expected_ty.kind { - ty::Tuple(ref tys) => tys.iter() - .map(|t| ArgKind::from_expected_ty(t.expect_ty(), Some(span))).collect(), + ty::Tuple(ref tys) => tys + .iter() + .map(|t| ArgKind::from_expected_ty(t.expect_ty(), Some(span))) + .collect(), _ => vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())], }; if found.len() == expected.len() { - self.report_closure_arg_mismatch(span, - found_span, - found_trait_ref, - expected_trait_ref) + self.report_closure_arg_mismatch( + span, + found_span, + found_trait_ref, + expected_trait_ref, + ) } else { let (closure_span, found) = found_did .and_then(|did| self.tcx.hir().get_if_local(did)) .map(|node| { let (found_span, found) = self.get_fn_like_arguments(node); (Some(found_span), found) - }).unwrap_or((found_span, found)); + }) + .unwrap_or((found_span, found)); - self.report_arg_count_mismatch(span, - closure_span, - expected, - found, - found_trait_ty.is_closure()) + self.report_arg_count_mismatch( + span, + closure_span, + expected, + found, + found_trait_ty.is_closure(), + ) } } @@ -1120,29 +1153,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => return, }; - let suggest_restriction = | - generics: &hir::Generics, - msg, - err: &mut DiagnosticBuilder<'_>, - | { - let span = generics.where_clause.span_for_predicates_or_empty_place(); - if !span.from_expansion() && span.desugaring_kind().is_none() { - err.span_suggestion( - generics.where_clause.span_for_predicates_or_empty_place().shrink_to_hi(), - &format!("consider further restricting {}", msg), - format!( - "{} {} ", - if !generics.where_clause.predicates.is_empty() { - "," - } else { - " where" - }, - trait_ref.to_predicate(), - ), - Applicability::MachineApplicable, - ); - } - }; + let suggest_restriction = + |generics: &hir::Generics, msg, err: &mut DiagnosticBuilder<'_>| { + let span = generics.where_clause.span_for_predicates_or_empty_place(); + if !span.from_expansion() && span.desugaring_kind().is_none() { + err.span_suggestion( + generics.where_clause.span_for_predicates_or_empty_place().shrink_to_hi(), + &format!("consider further restricting {}", msg), + format!( + "{} {} ", + if !generics.where_clause.predicates.is_empty() { + "," + } else { + " where" + }, + trait_ref.to_predicate(), + ), + Applicability::MachineApplicable, + ); + } + }; // FIXME: Add check for trait bound that is already present, particularly `?Sized` so we // don't suggest `T: Sized + ?Sized`. @@ -1151,59 +1181,85 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { match node { hir::Node::TraitItem(hir::TraitItem { generics, - kind: hir::TraitItemKind::Method(..), .. + kind: hir::TraitItemKind::Method(..), + .. }) if param_ty && self_ty == self.tcx.types.self_param => { // Restricting `Self` for a single method. suggest_restriction(&generics, "`Self`", err); return; } - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Fn(_, generics, _), .. - }) | - hir::Node::TraitItem(hir::TraitItem { + hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }) + | hir::Node::TraitItem(hir::TraitItem { generics, - kind: hir::TraitItemKind::Method(..), .. - }) | - hir::Node::ImplItem(hir::ImplItem { + kind: hir::TraitItemKind::Method(..), + .. + }) + | hir::Node::ImplItem(hir::ImplItem { generics, - kind: hir::ImplItemKind::Method(..), .. - }) | - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Trait(_, _, generics, _, _), .. - }) | - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(_, _, _, generics, ..), .. + kind: hir::ImplItemKind::Method(..), + .. + }) + | hir::Node::Item(hir::Item { + kind: hir::ItemKind::Trait(_, _, generics, _, _), + .. + }) + | hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(_, _, _, generics, ..), + .. }) if projection.is_some() => { // Missing associated type bound. suggest_restriction(&generics, "the associated type", err); return; } - hir::Node::Item(hir::Item { kind: hir::ItemKind::Struct(_, generics), span, .. }) | - hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(_, generics), span, .. }) | - hir::Node::Item(hir::Item { kind: hir::ItemKind::Union(_, generics), span, .. }) | - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Trait(_, _, generics, ..), span, .. - }) | hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(_, _, _, generics, ..), span, .. - }) | - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Fn(_, generics, _), span, .. - }) | - hir::Node::Item(hir::Item { - kind: hir::ItemKind::TyAlias(_, generics), span, .. - }) | - hir::Node::Item(hir::Item { - kind: hir::ItemKind::TraitAlias(generics, _), span, .. - }) | - hir::Node::Item(hir::Item { - kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }), span, .. - }) | - hir::Node::TraitItem(hir::TraitItem { generics, span, .. }) | - hir::Node::ImplItem(hir::ImplItem { generics, span, .. }) - if param_ty => { + kind: hir::ItemKind::Struct(_, generics), + span, + .. + }) + | hir::Node::Item(hir::Item { + kind: hir::ItemKind::Enum(_, generics), span, .. + }) + | hir::Node::Item(hir::Item { + kind: hir::ItemKind::Union(_, generics), + span, + .. + }) + | hir::Node::Item(hir::Item { + kind: hir::ItemKind::Trait(_, _, generics, ..), + span, + .. + }) + | hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(_, _, _, generics, ..), + span, + .. + }) + | hir::Node::Item(hir::Item { + kind: hir::ItemKind::Fn(_, generics, _), + span, + .. + }) + | hir::Node::Item(hir::Item { + kind: hir::ItemKind::TyAlias(_, generics), + span, + .. + }) + | hir::Node::Item(hir::Item { + kind: hir::ItemKind::TraitAlias(generics, _), + span, + .. + }) + | hir::Node::Item(hir::Item { + kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }), + span, + .. + }) + | hir::Node::TraitItem(hir::TraitItem { generics, span, .. }) + | hir::Node::ImplItem(hir::ImplItem { generics, span, .. }) + if param_ty => + { // Missing generic type parameter bound. let param_name = self_ty.to_string(); let constraint = trait_ref.print_only_trait_path().to_string(); @@ -1245,7 +1301,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { expr.span, "consider borrowing here", format!("&{}", snippet), - Applicability::MachineApplicable + Applicability::MachineApplicable, ); } } @@ -1261,10 +1317,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> PredicateObligation<'tcx> { - let new_trait_ref = ty::TraitRef { - def_id, - substs: self.tcx.mk_substs_trait(output_ty, &[]), - }; + let new_trait_ref = + ty::TraitRef { def_id, substs: self.tcx.mk_substs_trait(output_ty, &[]) }; Obligation::new(cause, param_env, new_trait_ref.to_predicate()) } @@ -1295,9 +1349,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let hir_id = hir.as_local_hir_id(def_id)?; let parent_node = hir.get_parent_node(hir_id); match hir.find(parent_node) { - Some(hir::Node::Stmt(hir::Stmt { - kind: hir::StmtKind::Local(local), .. - })) => get_name(err, &local.pat.kind), + Some(hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(local), .. })) => { + get_name(err, &local.pat.kind) + } // Different to previous arm because one is `&hir::Local` and the other // is `P`. Some(hir::Node::Local(local)) => get_name(err, &local.pat.kind), @@ -1320,9 +1374,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ty::Closure(def_id, substs) => { (def_id, self.closure_sig(def_id, substs).output(), "closure") } - ty::FnDef(def_id, _) => { - (def_id, self_ty.fn_sig(self.tcx).output(), "function") - } + ty::FnDef(def_id, _) => (def_id, self_ty.fn_sig(self.tcx).output(), "function"), _ => return, }; let msg = format!("use parentheses to call the {}", callable); @@ -1335,9 +1387,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); match self.evaluate_obligation(&obligation) { - Ok(EvaluationResult::EvaluatedToOk) | - Ok(EvaluationResult::EvaluatedToOkModuloRegions) | - Ok(EvaluationResult::EvaluatedToAmbig) => {} + Ok(EvaluationResult::EvaluatedToOk) + | Ok(EvaluationResult::EvaluatedToOkModuloRegions) + | Ok(EvaluationResult::EvaluatedToAmbig) => {} _ => return, } let hir = self.tcx.hir(); @@ -1352,10 +1404,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { Some(name) => name, None => return, }; - let args = decl.inputs.iter() - .map(|_| "_") - .collect::>() - .join(", "); + let args = decl.inputs.iter().map(|_| "_").collect::>().join(", "); format!("{}({})", name, args) } Some(hir::Node::Item(hir::Item { @@ -1365,7 +1414,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { })) => { err.span_label(ident.span, "consider calling this function"); let body = hir.body(*body_id); - let args = body.params.iter() + let args = body + .params + .iter() .map(|arg| match &arg.pat.kind { hir::PatKind::Binding(_, _, ident, None) // FIXME: provide a better suggestion when encountering `SelfLower`, it @@ -1418,11 +1469,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let new_self_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, self_ty); let substs = self.tcx.mk_substs_trait(new_self_ty, &[]); let new_trait_ref = ty::TraitRef::new(obligation.parent_trait_ref.def_id(), substs); - let new_obligation = Obligation::new( - ObligationCause::dummy(), - param_env, - new_trait_ref.to_predicate(), - ); + let new_obligation = + Obligation::new(ObligationCause::dummy(), param_env, new_trait_ref.to_predicate()); if self.predicate_must_hold_modulo_regions(&new_obligation) { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { // We have a very specific type of error, where just borrowing this argument @@ -1445,10 +1493,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // somewhere else in the obligation chain. Do not suggest non-sense. return false; } - err.span_label(span, &format!( - "expected an implementor of trait `{}`", - obligation.parent_trait_ref.skip_binder().print_only_trait_path(), - )); + err.span_label( + span, + &format!( + "expected an implementor of trait `{}`", + obligation.parent_trait_ref.skip_binder().print_only_trait_path(), + ), + ); err.span_suggestion( span, "consider borrowing here", @@ -1474,15 +1525,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let span = obligation.cause.span; if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - let refs_number = snippet.chars() - .filter(|c| !c.is_whitespace()) - .take_while(|c| *c == '&') - .count(); - if let Some('\'') = snippet.chars() - .filter(|c| !c.is_whitespace()) - .skip(refs_number) - .next() - { // Do not suggest removal of borrow from type arguments. + let refs_number = + snippet.chars().filter(|c| !c.is_whitespace()).take_while(|c| *c == '&').count(); + if let Some('\'') = + snippet.chars().filter(|c| !c.is_whitespace()).skip(refs_number).next() + { + // Do not suggest removal of borrow from type arguments. return; } @@ -1500,15 +1548,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); if self.predicate_may_hold(&new_obligation) { - let sp = self.tcx.sess.source_map() + let sp = self + .tcx + .sess + .source_map() .span_take_while(span, |c| c.is_whitespace() || *c == '&'); let remove_refs = refs_remaining + 1; - let format_str = format!("consider removing {} leading `&`-references", - remove_refs); + let format_str = + format!("consider removing {} leading `&`-references", remove_refs); err.span_suggestion_short( - sp, &format_str, String::new(), Applicability::MachineApplicable + sp, + &format_str, + String::new(), + Applicability::MachineApplicable, ); break; } @@ -1530,15 +1584,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) { let span = obligation.cause.span; if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - let refs_number = snippet.chars() - .filter(|c| !c.is_whitespace()) - .take_while(|c| *c == '&') - .count(); - if let Some('\'') = snippet.chars() - .filter(|c| !c.is_whitespace()) - .skip(refs_number) - .next() - { // Do not suggest removal of borrow from type arguments. + let refs_number = + snippet.chars().filter(|c| !c.is_whitespace()).take_while(|c| *c == '&').count(); + if let Some('\'') = + snippet.chars().filter(|c| !c.is_whitespace()).skip(refs_number).next() + { + // Do not suggest removal of borrow from type arguments. return; } let trait_ref = self.resolve_vars_if_possible(trait_ref); @@ -1561,15 +1612,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { obligation.param_env, ); - if self.evaluate_obligation_no_overflow( - &new_obligation, - ).must_apply_modulo_regions() { - let sp = self.tcx.sess.source_map() + if self.evaluate_obligation_no_overflow(&new_obligation).must_apply_modulo_regions() + { + let sp = self + .tcx + .sess + .source_map() .span_take_while(span, |c| c.is_whitespace() || *c == '&'); - if points_at_arg && - mutability == hir::Mutability::Not && - refs_number > 0 - { + if points_at_arg && mutability == hir::Mutability::Not && refs_number > 0 { err.span_suggestion( sp, "consider changing this borrow's mutability", @@ -1600,13 +1650,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let parent_node = hir.get_parent_node(obligation.cause.body_id); let node = hir.find(parent_node); if let Some(hir::Node::Item(hir::Item { - kind: hir::ItemKind::Fn(sig, _, body_id), - .. - })) = node { + kind: hir::ItemKind::Fn(sig, _, body_id), .. + })) = node + { let body = hir.body(*body_id); if let hir::ExprKind::Block(blk, _) = &body.value.kind { - if sig.decl.output.span().overlaps(span) && blk.expr.is_none() && - "()" == &trait_ref.self_ty().to_string() + if sig.decl.output.span().overlaps(span) + && blk.expr.is_none() + && "()" == &trait_ref.self_ty().to_string() { // FIXME(estebank): When encountering a method with a trait // bound not satisfied in the return type with a body that has @@ -1630,57 +1681,66 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(_, ref _decl, id, span, _), .. - }) => { - (self.tcx.sess.source_map().def_span(span), - self.tcx.hir().body(id).params.iter() + }) => ( + self.tcx.sess.source_map().def_span(span), + self.tcx + .hir() + .body(id) + .params + .iter() .map(|arg| { - if let hir::Pat { - kind: hir::PatKind::Tuple(ref args, _), - span, - .. - } = *arg.pat { + if let hir::Pat { kind: hir::PatKind::Tuple(ref args, _), span, .. } = + *arg.pat + { ArgKind::Tuple( Some(span), - args.iter().map(|pat| { - let snippet = self.tcx.sess.source_map() - .span_to_snippet(pat.span).unwrap(); - (snippet, "_".to_owned()) - }).collect::>(), + args.iter() + .map(|pat| { + let snippet = self + .tcx + .sess + .source_map() + .span_to_snippet(pat.span) + .unwrap(); + (snippet, "_".to_owned()) + }) + .collect::>(), ) } else { - let name = self.tcx.sess.source_map() - .span_to_snippet(arg.pat.span).unwrap(); + let name = + self.tcx.sess.source_map().span_to_snippet(arg.pat.span).unwrap(); ArgKind::Arg(name, "_".to_owned()) } }) - .collect::>()) - } - Node::Item(&hir::Item { - span, - kind: hir::ItemKind::Fn(ref sig, ..), - .. - }) | - Node::ImplItem(&hir::ImplItem { + .collect::>(), + ), + Node::Item(&hir::Item { span, kind: hir::ItemKind::Fn(ref sig, ..), .. }) + | Node::ImplItem(&hir::ImplItem { span, kind: hir::ImplItemKind::Method(ref sig, _), .. - }) | - Node::TraitItem(&hir::TraitItem { + }) + | Node::TraitItem(&hir::TraitItem { span, kind: hir::TraitItemKind::Method(ref sig, _), .. - }) => { - (self.tcx.sess.source_map().def_span(span), sig.decl.inputs.iter() - .map(|arg| match arg.clone().kind { - hir::TyKind::Tup(ref tys) => ArgKind::Tuple( - Some(arg.span), - vec![("_".to_owned(), "_".to_owned()); tys.len()] - ), - _ => ArgKind::empty() - }).collect::>()) - } + }) => ( + self.tcx.sess.source_map().def_span(span), + sig.decl + .inputs + .iter() + .map(|arg| match arg.clone().kind { + hir::TyKind::Tup(ref tys) => ArgKind::Tuple( + Some(arg.span), + vec![("_".to_owned(), "_".to_owned()); tys.len()], + ), + _ => ArgKind::empty(), + }) + .collect::>(), + ), Node::Ctor(ref variant_data) => { - let span = variant_data.ctor_hir_id() + let span = variant_data + .ctor_hir_id() .map(|hir_id| self.tcx.hir().span(hir_id)) .unwrap_or(DUMMY_SP); let span = self.tcx.sess.source_map().def_span(span); @@ -1714,10 +1774,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { (1, Some(&ArgKind::Tuple(_, ref fields))) => { format!("a single {}-tuple as argument", fields.len()) } - _ => format!("{} {}argument{}", - arg_length, - if distinct && arg_length > 1 { "distinct " } else { "" }, - pluralize!(arg_length)) + _ => format!( + "{} {}argument{}", + arg_length, + if distinct && arg_length > 1 { "distinct " } else { "" }, + pluralize!(arg_length) + ), } }; @@ -1747,11 +1809,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let prefix_span = self.tcx.sess.source_map().span_until_non_whitespace(found_span); // move |_| { ... } // ^^^-- pipe_span - let pipe_span = if let Some(span) = found_span.trim_start(prefix_span) { - span - } else { - found_span - }; + let pipe_span = + if let Some(span) = found_span.trim_start(prefix_span) { span } else { found_span }; // Suggest to take and ignore the arguments with expected_args_length `_`s if // found arguments is empty (assume the user just wants to ignore args in this case). @@ -1762,11 +1821,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pipe_span, &format!( "consider changing the closure to take and ignore the expected argument{}", - if expected_args.len() < 2 { - "" - } else { - "s" - } + if expected_args.len() < 2 { "" } else { "s" } ), format!("|{}|", underscores), Applicability::MachineApplicable, @@ -1775,7 +1830,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] { if fields.len() == expected_args.len() { - let sugg = fields.iter() + let sugg = fields + .iter() .map(|(name, _)| name.to_owned()) .collect::>() .join(", "); @@ -1791,7 +1847,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if fields.len() == found_args.len() && is_closure { let sugg = format!( "|({}){}|", - found_args.iter() + found_args + .iter() .map(|arg| match arg { ArgKind::Arg(name, _) => name.to_owned(), _ => "_".to_owned(), @@ -1803,11 +1860,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ArgKind::Arg(_, ty) => ty != "_", _ => false, }) { - format!(": ({})", - fields.iter() - .map(|(_, ty)| ty.to_owned()) - .collect::>() - .join(", ")) + format!( + ": ({})", + fields + .iter() + .map(|(_, ty)| ty.to_owned()) + .collect::>() + .join(", ") + ) } else { String::new() }, @@ -1840,7 +1900,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { tcx.mk_ty_infer(ty::TyVar(ty::TyVid { index: 0 })), false, hir::Unsafety::Normal, - ::rustc_target::spec::abi::Abi::Rust + ::rustc_target::spec::abi::Abi::Rust, ) } else { tcx.mk_fn_sig( @@ -1848,16 +1908,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { tcx.mk_ty_infer(ty::TyVar(ty::TyVid { index: 0 })), false, hir::Unsafety::Normal, - ::rustc_target::spec::abi::Abi::Rust + ::rustc_target::spec::abi::Abi::Rust, ) }; ty::Binder::bind(sig).to_string() } let argument_is_closure = expected_ref.skip_binder().substs.type_at(0).is_closure(); - let mut err = struct_span_err!(self.tcx.sess, span, E0631, - "type mismatch in {} arguments", - if argument_is_closure { "closure" } else { "function" }); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0631, + "type mismatch in {} arguments", + if argument_is_closure { "closure" } else { "function" } + ); let found_str = format!( "expected signature of `{}`", @@ -1877,20 +1941,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } impl<'tcx> TyCtxt<'tcx> { - pub fn recursive_type_with_infinite_size_error(self, - type_def_id: DefId) - -> DiagnosticBuilder<'tcx> - { + pub fn recursive_type_with_infinite_size_error( + self, + type_def_id: DefId, + ) -> DiagnosticBuilder<'tcx> { assert!(type_def_id.is_local()); let span = self.hir().span_if_local(type_def_id).unwrap(); let span = self.sess.source_map().def_span(span); - let mut err = struct_span_err!(self.sess, span, E0072, - "recursive type `{}` has infinite size", - self.def_path_str(type_def_id)); + let mut err = struct_span_err!( + self.sess, + span, + E0072, + "recursive type `{}` has infinite size", + self.def_path_str(type_def_id) + ); err.span_label(span, "recursive type has infinite size"); - err.help(&format!("insert indirection (e.g., a `Box`, `Rc`, or `&`) \ + err.help(&format!( + "insert indirection (e.g., a `Box`, `Rc`, or `&`) \ at some point to make `{}` representable", - self.def_path_str(type_def_id))); + self.def_path_str(type_def_id) + )); err } @@ -1903,9 +1973,12 @@ impl<'tcx> TyCtxt<'tcx> { let trait_str = self.def_path_str(trait_def_id); let span = self.sess.source_map().def_span(span); let mut err = struct_span_err!( - self.sess, span, E0038, + self.sess, + span, + E0038, "the trait `{}` cannot be made into an object", - trait_str); + trait_str + ); err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str)); let mut reported_violations = FxHashSet::default(); @@ -1943,10 +2016,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { debug!( "maybe_report_ambiguity(predicate={:?}, obligation={:?} body_id={:?}, code={:?})", - predicate, - obligation, - body_id, - obligation.cause.code, + predicate, obligation, body_id, obligation.cause.code, ); // Ambiguity errors are often caused as fallout from earlier @@ -1989,7 +2059,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // avoid inundating the user with unnecessary errors, but we now // check upstream for type errors and dont add the obligations to // begin with in those cases. - if self.tcx.lang_items().sized_trait() + if self + .tcx + .lang_items() + .sized_trait() .map_or(false, |sized_id| sized_id == trait_ref.def_id()) { self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0282).emit(); @@ -1997,12 +2070,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283); err.note(&format!("cannot resolve `{}`", predicate)); - if let (Ok(ref snippet), ObligationCauseCode::BindingObligation(ref def_id, _)) = ( - self.tcx.sess.source_map().span_to_snippet(span), - &obligation.cause.code, - ) { + if let (Ok(ref snippet), ObligationCauseCode::BindingObligation(ref def_id, _)) = + (self.tcx.sess.source_map().span_to_snippet(span), &obligation.cause.code) + { let generics = self.tcx.generics_of(*def_id); - if !generics.params.is_empty() && !snippet.ends_with('>'){ + if !generics.params.is_empty() && !snippet.ends_with('>') { // FIXME: To avoid spurious suggestions in functions where type arguments // where already supplied, we check the snippet to make sure it doesn't // end with a turbofish. Ideally we would have access to a `PathSegment` @@ -2028,16 +2100,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { span, &format!( "consider specifying the type argument{} in the function call", - if generics.params.len() > 1 { - "s" - } else { - "" - }, + if generics.params.len() > 1 { "s" } else { "" }, + ), + format!( + "{}::<{}>", + snippet, + generics + .params + .iter() + .map(|p| p.name.to_string()) + .collect::>() + .join(", ") ), - format!("{}::<{}>", snippet, generics.params.iter() - .map(|p| p.name.to_string()) - .collect::>() - .join(", ")), Applicability::HasPlaceholders, ); } @@ -2057,7 +2131,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ty::Predicate::Subtype(ref data) => { if data.references_error() || self.tcx.sess.has_errors() { // no need to overload user in such cases - return + return; } let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder(); // both must be type variables, or the other would've been instantiated @@ -2107,19 +2181,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } impl<'a, 'tcx> TypeFolder<'tcx> for ParamToVarFolder<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.infcx.tcx } + fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + self.infcx.tcx + } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if let ty::Param(ty::ParamTy {name, .. }) = ty.kind { + if let ty::Param(ty::ParamTy { name, .. }) = ty.kind { let infcx = self.infcx; - self.var_map.entry(ty).or_insert_with(|| - infcx.next_ty_var( - TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeParameterDefinition(name, None), - span: DUMMY_SP, - } - ) - ) + self.var_map.entry(ty).or_insert_with(|| { + infcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeParameterDefinition(name, None), + span: DUMMY_SP, + }) + }) } else { ty.super_fold_with(self) } @@ -2129,23 +2203,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.probe(|_| { let mut selcx = SelectionContext::new(self); - let cleaned_pred = pred.fold_with(&mut ParamToVarFolder { - infcx: self, - var_map: Default::default() - }); + let cleaned_pred = + pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() }); let cleaned_pred = super::project::normalize( &mut selcx, param_env, ObligationCause::dummy(), - &cleaned_pred - ).value; + &cleaned_pred, + ) + .value; - let obligation = Obligation::new( - ObligationCause::dummy(), - param_env, - cleaned_pred.to_predicate() - ); + let obligation = + Obligation::new(ObligationCause::dummy(), param_env, cleaned_pred.to_predicate()); self.predicate_may_hold(&obligation) }) @@ -2159,8 +2229,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // First, attempt to add note to this error with an async-await-specific // message, and fall back to regular note otherwise. if !self.maybe_note_obligation_cause_for_async_await(err, obligation) { - self.note_obligation_cause_code(err, &obligation.predicate, &obligation.cause.code, - &mut vec![]); + self.note_obligation_cause_code( + err, + &obligation.predicate, + &obligation.cause.code, + &mut vec![], + ); } } @@ -2211,8 +2285,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err: &mut DiagnosticBuilder<'_>, obligation: &PredicateObligation<'tcx>, ) -> bool { - debug!("maybe_note_obligation_cause_for_async_await: obligation.predicate={:?} \ - obligation.cause.span={:?}", obligation.predicate, obligation.cause.span); + debug!( + "maybe_note_obligation_cause_for_async_await: obligation.predicate={:?} \ + obligation.cause.span={:?}", + obligation.predicate, obligation.cause.span + ); let source_map = self.tcx.sess.source_map(); // Attempt to detect an async-await error by looking at the obligation causes, looking @@ -2241,8 +2318,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // the type. The last generator has information about where the bound was introduced. At // least one generator should be present for this diagnostic to be modified. let (mut trait_ref, mut target_ty) = match obligation.predicate { - ty::Predicate::Trait(p) => - (Some(p.skip_binder().trait_ref), Some(p.skip_binder().self_ty())), + ty::Predicate::Trait(p) => { + (Some(p.skip_binder().trait_ref), Some(p.skip_binder().self_ty())) + } _ => (None, None), }; let mut generator = None; @@ -2251,38 +2329,44 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { while let Some(code) = next_code { debug!("maybe_note_obligation_cause_for_async_await: code={:?}", code); match code { - ObligationCauseCode::BuiltinDerivedObligation(derived_obligation) | - ObligationCauseCode::ImplDerivedObligation(derived_obligation) => { + ObligationCauseCode::BuiltinDerivedObligation(derived_obligation) + | ObligationCauseCode::ImplDerivedObligation(derived_obligation) => { let ty = derived_obligation.parent_trait_ref.self_ty(); - debug!("maybe_note_obligation_cause_for_async_await: \ + debug!( + "maybe_note_obligation_cause_for_async_await: \ parent_trait_ref={:?} self_ty.kind={:?}", - derived_obligation.parent_trait_ref, ty.kind); + derived_obligation.parent_trait_ref, ty.kind + ); match ty.kind { ty::Generator(did, ..) => { generator = generator.or(Some(did)); last_generator = Some(did); - }, - ty::GeneratorWitness(..) => {}, + } + ty::GeneratorWitness(..) => {} _ if generator.is_none() => { trait_ref = Some(*derived_obligation.parent_trait_ref.skip_binder()); target_ty = Some(ty); - }, - _ => {}, + } + _ => {} } next_code = Some(derived_obligation.parent_code.as_ref()); - }, + } _ => break, } } // Only continue if a generator was found. - debug!("maybe_note_obligation_cause_for_async_await: generator={:?} trait_ref={:?} \ - target_ty={:?}", generator, trait_ref, target_ty); + debug!( + "maybe_note_obligation_cause_for_async_await: generator={:?} trait_ref={:?} \ + target_ty={:?}", + generator, trait_ref, target_ty + ); let (generator_did, trait_ref, target_ty) = match (generator, trait_ref, target_ty) { - (Some(generator_did), Some(trait_ref), Some(target_ty)) => - (generator_did, trait_ref, target_ty), + (Some(generator_did), Some(trait_ref), Some(target_ty)) => { + (generator_did, trait_ref, target_ty) + } _ => return false, }; @@ -2298,10 +2382,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // This is needed to avoid cycles. let in_progress_tables = self.in_progress_tables.map(|t| t.borrow()); let generator_did_root = self.tcx.closure_base_def_id(generator_did); - debug!("maybe_note_obligation_cause_for_async_await: generator_did={:?} \ + debug!( + "maybe_note_obligation_cause_for_async_await: generator_did={:?} \ generator_did_root={:?} in_progress_tables.local_id_root={:?} span={:?}", - generator_did, generator_did_root, - in_progress_tables.as_ref().map(|t| t.local_id_root), span); + generator_did, + generator_did_root, + in_progress_tables.as_ref().map(|t| t.local_id_root), + span + ); let query_tables; let tables: &TypeckTables<'tcx> = match &in_progress_tables { Some(t) if t.local_id_root == Some(generator_did_root) => t, @@ -2314,7 +2402,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Look for a type inside the generator interior that matches the target type to get // a span. let target_ty_erased = self.tcx.erase_regions(&target_ty); - let target_span = tables.generator_interior_types.iter() + let target_span = tables + .generator_interior_types + .iter() .find(|ty::GeneratorInteriorTypeCause { ty, .. }| { // Careful: the regions for types that appear in the // generator interior are not generally known, so we @@ -2331,19 +2421,34 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let ty_erased = self.tcx.erase_late_bound_regions(&ty::Binder::bind(*ty)); let ty_erased = self.tcx.erase_regions(&ty_erased); let eq = ty::TyS::same_type(ty_erased, target_ty_erased); - debug!("maybe_note_obligation_cause_for_async_await: ty_erased={:?} \ - target_ty_erased={:?} eq={:?}", ty_erased, target_ty_erased, eq); + debug!( + "maybe_note_obligation_cause_for_async_await: ty_erased={:?} \ + target_ty_erased={:?} eq={:?}", + ty_erased, target_ty_erased, eq + ); eq }) - .map(|ty::GeneratorInteriorTypeCause { span, scope_span, .. }| - (span, source_map.span_to_snippet(*span), scope_span)); - debug!("maybe_note_obligation_cause_for_async_await: target_ty={:?} \ + .map(|ty::GeneratorInteriorTypeCause { span, scope_span, .. }| { + (span, source_map.span_to_snippet(*span), scope_span) + }); + debug!( + "maybe_note_obligation_cause_for_async_await: target_ty={:?} \ generator_interior_types={:?} target_span={:?}", - target_ty, tables.generator_interior_types, target_span); + target_ty, tables.generator_interior_types, target_span + ); if let Some((target_span, Ok(snippet), scope_span)) = target_span { self.note_obligation_cause_for_async_await( - err, *target_span, scope_span, snippet, generator_did, last_generator, - trait_ref, target_ty, tables, obligation, next_code, + err, + *target_span, + scope_span, + snippet, + generator_did, + last_generator, + trait_ref, + target_ty, + tables, + obligation, + next_code, ); true } else { @@ -2369,11 +2474,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) { let source_map = self.tcx.sess.source_map(); - let is_async_fn = self.tcx.parent(first_generator) + let is_async_fn = self + .tcx + .parent(first_generator) .map(|parent_did| self.tcx.asyncness(parent_did)) .map(|parent_asyncness| parent_asyncness == hir::IsAsync::Async) .unwrap_or(false); - let is_async_move = self.tcx.hir().as_local_hir_id(first_generator) + let is_async_move = self + .tcx + .hir() + .as_local_hir_id(first_generator) .and_then(|hir_id| self.tcx.hir().maybe_body_owned_by(hir_id)) .map(|body_id| self.tcx.hir().body(body_id)) .and_then(|body| body.generator_kind()) @@ -2389,16 +2499,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let is_send = self.tcx.is_diagnostic_item(sym::send_trait, trait_ref.def_id); let is_sync = self.tcx.is_diagnostic_item(sym::sync_trait, trait_ref.def_id); let trait_explanation = if is_send || is_sync { - let (trait_name, trait_verb) = if is_send { - ("`Send`", "sent") - } else { - ("`Sync`", "shared") - }; + let (trait_name, trait_verb) = + if is_send { ("`Send`", "sent") } else { ("`Sync`", "shared") }; err.clear_code(); - err.set_primary_message( - format!("future cannot be {} between threads safely", trait_verb) - ); + err.set_primary_message(format!( + "future cannot be {} between threads safely", + trait_verb + )); let original_span = err.span.primary_span().unwrap(); let mut span = MultiSpan::from_span(original_span); @@ -2426,7 +2534,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let mut span = MultiSpan::from_span(await_span); span.push_span_label( await_span, - format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet)); + format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet), + ); span.push_span_label(target_span, format!("has type `{}`", target_ty)); @@ -2438,11 +2547,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); } - err.span_note(span, &format!( - "future {} as this value is used across an {}", - trait_explanation, - await_or_yield, - )); + err.span_note( + span, + &format!( + "future {} as this value is used across an {}", + trait_explanation, await_or_yield, + ), + ); // Add a note for the item obligation that remains - normally a note pointing to the // bound that introduced the obligation (e.g. `T: Send`). @@ -2455,26 +2566,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); } - fn note_obligation_cause_code(&self, - err: &mut DiagnosticBuilder<'_>, - predicate: &T, - cause_code: &ObligationCauseCode<'tcx>, - obligated_types: &mut Vec<&ty::TyS<'tcx>>) - where T: fmt::Display + fn note_obligation_cause_code( + &self, + err: &mut DiagnosticBuilder<'_>, + predicate: &T, + cause_code: &ObligationCauseCode<'tcx>, + obligated_types: &mut Vec<&ty::TyS<'tcx>>, + ) where + T: fmt::Display, { let tcx = self.tcx; match *cause_code { - ObligationCauseCode::ExprAssignable | - ObligationCauseCode::MatchExpressionArm { .. } | - ObligationCauseCode::MatchExpressionArmPattern { .. } | - ObligationCauseCode::IfExpression { .. } | - ObligationCauseCode::IfExpressionWithNoElse | - ObligationCauseCode::MainFunctionType | - ObligationCauseCode::StartFunctionType | - ObligationCauseCode::IntrinsicType | - ObligationCauseCode::MethodReceiver | - ObligationCauseCode::ReturnNoExpression | - ObligationCauseCode::MiscObligation => {} + ObligationCauseCode::ExprAssignable + | ObligationCauseCode::MatchExpressionArm { .. } + | ObligationCauseCode::MatchExpressionArmPattern { .. } + | ObligationCauseCode::IfExpression { .. } + | ObligationCauseCode::IfExpressionWithNoElse + | ObligationCauseCode::MainFunctionType + | ObligationCauseCode::StartFunctionType + | ObligationCauseCode::IntrinsicType + | ObligationCauseCode::MethodReceiver + | ObligationCauseCode::ReturnNoExpression + | ObligationCauseCode::MiscObligation => {} ObligationCauseCode::SliceOrArrayElem => { err.note("slice and array elements must have `Sized` type"); } @@ -2482,10 +2595,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.note("only the last element of a tuple may have a dynamically sized type"); } ObligationCauseCode::ProjectionWf(data) => { - err.note(&format!( - "required so that the projection `{}` is well-formed", - data, - )); + err.note(&format!("required so that the projection `{}` is well-formed", data,)); } ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => { err.note(&format!( @@ -2496,8 +2606,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ObligationCauseCode::ObjectTypeBound(object_ty, region) => { err.note(&format!( "required so that the lifetime bound of `{}` for `{}` is satisfied", - region, - object_ty, + region, object_ty, )); } ObligationCauseCode::ItemObligation(item_def_id) => { @@ -2524,23 +2633,30 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } ObligationCauseCode::ObjectCastObligation(object_ty) => { - err.note(&format!("required for the cast to the object type `{}`", - self.ty_to_string(object_ty))); + err.note(&format!( + "required for the cast to the object type `{}`", + self.ty_to_string(object_ty) + )); } ObligationCauseCode::Coercion { source: _, target } => { - err.note(&format!("required by cast to type `{}`", - self.ty_to_string(target))); + err.note(&format!("required by cast to type `{}`", self.ty_to_string(target))); } ObligationCauseCode::RepeatVec(suggest_const_in_array_repeat_expressions) => { - err.note("the `Copy` trait is required because the \ - repeated element will be copied"); + err.note( + "the `Copy` trait is required because the \ + repeated element will be copied", + ); if suggest_const_in_array_repeat_expressions { - err.note("this array initializer can be evaluated at compile-time, for more \ + err.note( + "this array initializer can be evaluated at compile-time, for more \ information, see issue \ - https://github.com/rust-lang/rust/issues/49147"); + https://github.com/rust-lang/rust/issues/49147", + ); if tcx.sess.opts.unstable_features.is_nightly_build() { - err.help("add `#![feature(const_in_array_repeat_expressions)]` to the \ - crate attributes to enable"); + err.help( + "add `#![feature(const_in_array_repeat_expressions)]` to the \ + crate attributes to enable", + ); } } } @@ -2557,12 +2673,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } ObligationCauseCode::SizedReturnType => { - err.note("the return type of a function must have a \ - statically known size"); + err.note( + "the return type of a function must have a \ + statically known size", + ); } ObligationCauseCode::SizedYieldType => { - err.note("the yield type of a generator must have a \ - statically known size"); + err.note( + "the yield type of a generator must have a \ + statically known size", + ); } ObligationCauseCode::AssignmentLhsSized => { err.note("the left-hand-side of an assignment must have a statically known size"); @@ -2573,25 +2693,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ObligationCauseCode::StructInitializerSized => { err.note("structs must have a statically known size to be initialized"); } - ObligationCauseCode::FieldSized { adt_kind: ref item, last } => { - match *item { - AdtKind::Struct => { - if last { - err.note("the last field of a packed struct may only have a \ - dynamically sized type if it does not need drop to be run"); - } else { - err.note("only the last field of a struct may have a dynamically \ - sized type"); - } - } - AdtKind::Union => { - err.note("no field of a union may have a dynamically sized type"); - } - AdtKind::Enum => { - err.note("no field of an enum variant may have a dynamically sized type"); + ObligationCauseCode::FieldSized { adt_kind: ref item, last } => match *item { + AdtKind::Struct => { + if last { + err.note( + "the last field of a packed struct may only have a \ + dynamically sized type if it does not need drop to be run", + ); + } else { + err.note( + "only the last field of a struct may have a dynamically \ + sized type", + ); } } - } + AdtKind::Union => { + err.note("no field of a union may have a dynamically sized type"); + } + AdtKind::Enum => { + err.note("no field of an enum variant may have a dynamically sized type"); + } + }, ObligationCauseCode::ConstSized => { err.note("constant expressions must have a statically known size"); } @@ -2609,43 +2731,51 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let parent_predicate = parent_trait_ref.to_predicate(); if !self.is_recursive_obligation(obligated_types, &data.parent_code) { - self.note_obligation_cause_code(err, - &parent_predicate, - &data.parent_code, - obligated_types); + self.note_obligation_cause_code( + err, + &parent_predicate, + &data.parent_code, + obligated_types, + ); } } ObligationCauseCode::ImplDerivedObligation(ref data) => { let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref); - err.note( - &format!("required because of the requirements on the impl of `{}` for `{}`", - parent_trait_ref.print_only_trait_path(), - parent_trait_ref.skip_binder().self_ty())); + err.note(&format!( + "required because of the requirements on the impl of `{}` for `{}`", + parent_trait_ref.print_only_trait_path(), + parent_trait_ref.skip_binder().self_ty() + )); let parent_predicate = parent_trait_ref.to_predicate(); - self.note_obligation_cause_code(err, - &parent_predicate, - &data.parent_code, - obligated_types); + self.note_obligation_cause_code( + err, + &parent_predicate, + &data.parent_code, + obligated_types, + ); } ObligationCauseCode::CompareImplMethodObligation { .. } => { - err.note( - &format!("the requirement `{}` appears on the impl method \ + err.note(&format!( + "the requirement `{}` appears on the impl method \ but not on the corresponding trait method", - predicate)); + predicate + )); } ObligationCauseCode::CompareImplTypeObligation { .. } => { err.note(&format!( "the requirement `{}` appears on the associated impl type\ but not on the corresponding associated trait type", - predicate)); + predicate + )); } - ObligationCauseCode::ReturnType | - ObligationCauseCode::ReturnValue(_) | - ObligationCauseCode::BlockTailExpression(_) => (), + ObligationCauseCode::ReturnType + | ObligationCauseCode::ReturnValue(_) + | ObligationCauseCode::BlockTailExpression(_) => (), ObligationCauseCode::TrivialBound => { err.help("see issue #48214"); if tcx.sess.opts.unstable_features.is_nightly_build() { - err.help("add `#![feature(trivial_bounds)]` to the \ + err.help( + "add `#![feature(trivial_bounds)]` to the \ crate attributes to enable", ); } @@ -2665,13 +2795,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>) { let current_limit = self.tcx.sess.recursion_limit.get(); let suggested_limit = current_limit * 2; - err.help(&format!("consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate", - suggested_limit)); + err.help(&format!( + "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate", + suggested_limit + )); } - fn is_recursive_obligation(&self, - obligated_types: &mut Vec<&ty::TyS<'tcx>>, - cause_code: &ObligationCauseCode<'tcx>) -> bool { + fn is_recursive_obligation( + &self, + obligated_types: &mut Vec<&ty::TyS<'tcx>>, + cause_code: &ObligationCauseCode<'tcx>, + ) -> bool { if let ObligationCauseCode::BuiltinDerivedObligation(ref data) = cause_code { let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref); @@ -2707,9 +2841,7 @@ impl ArgKind { match t.kind { ty::Tuple(ref tys) => ArgKind::Tuple( span, - tys.iter() - .map(|ty| ("_".to_owned(), ty.to_string())) - .collect::>() + tys.iter().map(|ty| ("_".to_owned(), ty.to_string())).collect::>(), ), _ => ArgKind::Arg("_".to_owned(), t.to_string()), } @@ -2726,9 +2858,9 @@ pub fn suggest_constraining_type_param( span: Span, ) -> bool { let restrict_msg = "consider further restricting this bound"; - if let Some(param) = generics.params.iter().filter(|p| { - p.name.ident().as_str() == param_name - }).next() { + if let Some(param) = + generics.params.iter().filter(|p| p.name.ident().as_str() == param_name).next() + { if param_name.starts_with("impl ") { // `impl Trait` in argument: // `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}` @@ -2739,9 +2871,7 @@ pub fn suggest_constraining_type_param( format!("{} + {}", param_name, constraint), Applicability::MachineApplicable, ); - } else if generics.where_clause.predicates.is_empty() && - param.bounds.is_empty() - { + } else if generics.where_clause.predicates.is_empty() && param.bounds.is_empty() { // If there are no bounds whatsoever, suggest adding a constraint // to the type parameter: // `fn foo(t: T) {}` → `fn foo(t: T) {}` diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 3fd2415c83c0c..614375287ba6e 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -1,25 +1,27 @@ use crate::infer::{InferCtxt, ShallowResolver}; -use crate::ty::{self, Ty, TypeFoldable, ToPolyTraitRef}; use crate::ty::error::ExpectedFound; +use crate::ty::{self, ToPolyTraitRef, Ty, TypeFoldable}; +use rustc_data_structures::obligation_forest::ProcessResult; use rustc_data_structures::obligation_forest::{DoCompleted, Error, ForestObligation}; use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor}; -use rustc_data_structures::obligation_forest::{ProcessResult}; use std::marker::PhantomData; +use super::engine::{TraitEngine, TraitEngineExt}; +use super::project; +use super::select::SelectionContext; use super::CodeAmbiguity; use super::CodeProjectionError; use super::CodeSelectionError; -use super::engine::{TraitEngine, TraitEngineExt}; +use super::{ConstEvalFailure, Unimplemented}; use super::{FulfillmentError, FulfillmentErrorCode}; use super::{ObligationCause, PredicateObligation}; -use super::project; -use super::select::SelectionContext; -use super::{Unimplemented, ConstEvalFailure}; impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> { type Predicate = ty::Predicate<'tcx>; - fn as_predicate(&self) -> &Self::Predicate { &self.obligation.predicate } + fn as_predicate(&self) -> &Self::Predicate { + &self.obligation.predicate + } } /// The fulfillment context is used to drive trait resolution. It @@ -58,7 +60,7 @@ pub struct FulfillmentContext<'tcx> { // other fulfillment contexts sometimes do live inside of // a snapshot (they don't *straddle* a snapshot, so there // is no trouble there). - usable_in_snapshot: bool + usable_in_snapshot: bool, } #[derive(Clone, Debug)] @@ -93,7 +95,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { FulfillmentContext { predicates: ObligationForest::new(), register_region_obligations: false, - usable_in_snapshot: false + usable_in_snapshot: false, } } @@ -110,18 +112,19 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { debug!("select: starting another iteration"); // Process pending obligations. - let outcome = self.predicates.process_obligations(&mut FulfillProcessor { - selcx, - register_region_obligations: self.register_region_obligations - }, DoCompleted::No); + let outcome = self.predicates.process_obligations( + &mut FulfillProcessor { + selcx, + register_region_obligations: self.register_region_obligations, + }, + DoCompleted::No, + ); debug!("select: outcome={:#?}", outcome); // FIXME: if we kept the original cache key, we could mark projection // obligations as complete for the projection cache here. - errors.extend( - outcome.errors.into_iter() - .map(|e| to_fulfillment_error(e))); + errors.extend(outcome.errors.into_iter().map(|e| to_fulfillment_error(e))); // If nothing new was added, no need to keep looping. if outcome.stalled { @@ -129,14 +132,13 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { } } - debug!("select({} predicates remaining, {} errors) done", - self.predicates.len(), errors.len()); + debug!( + "select({} predicates remaining, {} errors) done", + self.predicates.len(), + errors.len() + ); - if errors.is_empty() { - Ok(()) - } else { - Err(errors) - } + if errors.is_empty() { Ok(()) } else { Err(errors) } } } @@ -155,8 +157,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { projection_ty: ty::ProjectionTy<'tcx>, cause: ObligationCause<'tcx>, ) -> Ty<'tcx> { - debug!("normalize_projection_type(projection_ty={:?})", - projection_ty); + debug!("normalize_projection_type(projection_ty={:?})", projection_ty); debug_assert!(!projection_ty.has_escaping_bound_vars()); @@ -164,12 +165,14 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { let mut selcx = SelectionContext::new(infcx); let mut obligations = vec![]; - let normalized_ty = project::normalize_projection_type(&mut selcx, - param_env, - projection_ty, - cause, - 0, - &mut obligations); + let normalized_ty = project::normalize_projection_type( + &mut selcx, + param_env, + projection_ty, + cause, + 0, + &mut obligations, + ); self.register_predicate_obligations(infcx, obligations); debug!("normalize_projection_type: result={:?}", normalized_ty); @@ -190,10 +193,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { assert!(!infcx.is_in_snapshot() || self.usable_in_snapshot); - self.predicates.register_obligation(PendingPredicateObligation { - obligation, - stalled_on: vec![] - }); + self.predicates + .register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] }); } fn select_all_or_error( @@ -202,16 +203,13 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { ) -> Result<(), Vec>> { self.select_where_possible(infcx)?; - let errors: Vec<_> = - self.predicates.to_errors(CodeAmbiguity) - .into_iter() - .map(|e| to_fulfillment_error(e)) - .collect(); - if errors.is_empty() { - Ok(()) - } else { - Err(errors) - } + let errors: Vec<_> = self + .predicates + .to_errors(CodeAmbiguity) + .into_iter() + .map(|e| to_fulfillment_error(e)) + .collect(); + if errors.is_empty() { Ok(()) } else { Err(errors) } } fn select_where_possible( @@ -233,10 +231,9 @@ struct FulfillProcessor<'a, 'b, 'tcx> { } fn mk_pending(os: Vec>) -> Vec> { - os.into_iter().map(|o| PendingPredicateObligation { - obligation: o, - stalled_on: vec![] - }).collect() + os.into_iter() + .map(|o| PendingPredicateObligation { obligation: o, stalled_on: vec![] }) + .collect() } impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { @@ -284,10 +281,11 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { }; if !change { - debug!("process_predicate: pending obligation {:?} still stalled on {:?}", - self.selcx.infcx() - .resolve_vars_if_possible(&pending_obligation.obligation), - pending_obligation.stalled_on); + debug!( + "process_predicate: pending obligation {:?} still stalled on {:?}", + self.selcx.infcx().resolve_vars_if_possible(&pending_obligation.obligation), + pending_obligation.stalled_on + ); return ProcessResult::Unchanged; } @@ -319,21 +317,27 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. if self.selcx.infcx().predicate_must_hold_considering_regions(&obligation) { - debug!("selecting trait `{:?}` at depth {} evaluated to holds", - data, obligation.recursion_depth); - return ProcessResult::Changed(vec![]) + debug!( + "selecting trait `{:?}` at depth {} evaluated to holds", + data, obligation.recursion_depth + ); + return ProcessResult::Changed(vec![]); } } match self.selcx.select(&trait_obligation) { Ok(Some(vtable)) => { - debug!("selecting trait `{:?}` at depth {} yielded Ok(Some)", - data, obligation.recursion_depth); + debug!( + "selecting trait `{:?}` at depth {} yielded Ok(Some)", + data, obligation.recursion_depth + ); ProcessResult::Changed(mk_pending(vtable.nested_obligations())) } Ok(None) => { - debug!("selecting trait `{:?}` at depth {} yielded Ok(None)", - data, obligation.recursion_depth); + debug!( + "selecting trait `{:?}` at depth {} yielded Ok(None)", + data, obligation.recursion_depth + ); // This is a bit subtle: for the most part, the // only reason we can fail to make progress on @@ -351,15 +355,19 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { pending_obligation.stalled_on = trait_ref_type_vars(self.selcx, data.to_poly_trait_ref()); - debug!("process_predicate: pending obligation {:?} now stalled on {:?}", - self.selcx.infcx().resolve_vars_if_possible(obligation), - pending_obligation.stalled_on); + debug!( + "process_predicate: pending obligation {:?} now stalled on {:?}", + self.selcx.infcx().resolve_vars_if_possible(obligation), + pending_obligation.stalled_on + ); ProcessResult::Unchanged } Err(selection_err) => { - info!("selecting trait `{:?}` at depth {} yielded Err", - data, obligation.recursion_depth); + info!( + "selecting trait `{:?}` at depth {} yielded Err", + data, obligation.recursion_depth + ); ProcessResult::Error(CodeSelectionError(selection_err)) } @@ -386,9 +394,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { // If so, this obligation is an error (for now). Eventually we should be // able to support additional cases here, like `for<'a> &'a str: 'a`. // NOTE: this is duplicate-implemented between here and fulfillment. - None => { - ProcessResult::Error(CodeSelectionError(Unimplemented)) - } + None => ProcessResult::Error(CodeSelectionError(Unimplemented)), // Otherwise, we have something of the form // `for<'a> T: 'a where 'a not in T`, which we can treat as // `T: 'static`. @@ -429,7 +435,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { ProcessResult::Unchanged } Ok(Some(os)) => ProcessResult::Changed(mk_pending(os)), - Err(e) => ProcessResult::Error(CodeProjectionError(e)) + Err(e) => ProcessResult::Error(CodeProjectionError(e)), } } @@ -450,9 +456,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { ProcessResult::Error(CodeSelectionError(Unimplemented)) } } - None => { - ProcessResult::Unchanged - } + None => ProcessResult::Unchanged, } } @@ -468,45 +472,54 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { pending_obligation.stalled_on = vec![infer_ty(ty)]; ProcessResult::Unchanged } - Some(os) => ProcessResult::Changed(mk_pending(os)) + Some(os) => ProcessResult::Changed(mk_pending(os)), } } ty::Predicate::Subtype(ref subtype) => { - match self.selcx.infcx().subtype_predicate(&obligation.cause, - obligation.param_env, - subtype) { + match self.selcx.infcx().subtype_predicate( + &obligation.cause, + obligation.param_env, + subtype, + ) { None => { // None means that both are unresolved. - pending_obligation.stalled_on = vec![infer_ty(subtype.skip_binder().a), - infer_ty(subtype.skip_binder().b)]; + pending_obligation.stalled_on = vec![ + infer_ty(subtype.skip_binder().a), + infer_ty(subtype.skip_binder().b), + ]; ProcessResult::Unchanged } - Some(Ok(ok)) => { - ProcessResult::Changed(mk_pending(ok.obligations)) - } + Some(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)), Some(Err(err)) => { - let expected_found = ExpectedFound::new(subtype.skip_binder().a_is_expected, - subtype.skip_binder().a, - subtype.skip_binder().b); - ProcessResult::Error( - FulfillmentErrorCode::CodeSubtypeError(expected_found, err)) + let expected_found = ExpectedFound::new( + subtype.skip_binder().a_is_expected, + subtype.skip_binder().a, + subtype.skip_binder().b, + ); + ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError( + expected_found, + err, + )) } } } ty::Predicate::ConstEvaluatable(def_id, substs) => { if obligation.param_env.has_local_value() { - ProcessResult::Unchanged + ProcessResult::Unchanged } else { if !substs.has_local_value() { - match self.selcx.tcx().const_eval_resolve(obligation.param_env, - def_id, - substs, - Some(obligation.cause.span)) { + match self.selcx.tcx().const_eval_resolve( + obligation.param_env, + def_id, + substs, + Some(obligation.cause.span), + ) { Ok(_) => ProcessResult::Changed(vec![]), - Err(err) => ProcessResult::Error( - CodeSelectionError(ConstEvalFailure(err))) + Err(err) => { + ProcessResult::Error(CodeSelectionError(ConstEvalFailure(err))) + } } } else { pending_obligation.stalled_on = @@ -518,9 +531,12 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { } } - fn process_backedge<'c, I>(&mut self, cycle: I, - _marker: PhantomData<&'c PendingPredicateObligation<'tcx>>) - where I: Clone + Iterator>, + fn process_backedge<'c, I>( + &mut self, + cycle: I, + _marker: PhantomData<&'c PendingPredicateObligation<'tcx>>, + ) where + I: Clone + Iterator>, { if self.selcx.coinductive_match(cycle.clone().map(|s| s.obligation.predicate)) { debug!("process_child_obligations: coinductive match"); @@ -537,18 +553,20 @@ fn trait_ref_type_vars<'a, 'tcx>( t: ty::PolyTraitRef<'tcx>, ) -> Vec { t.skip_binder() // ok b/c this check doesn't care about regions - .input_types() - .map(|t| selcx.infcx().resolve_vars_if_possible(&t)) - .filter(|t| t.has_infer_types()) - .flat_map(|t| t.walk()) - .filter_map(|t| match t.kind { ty::Infer(infer) => Some(infer), _ => None }) - .collect() + .input_types() + .map(|t| selcx.infcx().resolve_vars_if_possible(&t)) + .filter(|t| t.has_infer_types()) + .flat_map(|t| t.walk()) + .filter_map(|t| match t.kind { + ty::Infer(infer) => Some(infer), + _ => None, + }) + .collect() } fn to_fulfillment_error<'tcx>( - error: Error, FulfillmentErrorCode<'tcx>>) - -> FulfillmentError<'tcx> -{ + error: Error, FulfillmentErrorCode<'tcx>>, +) -> FulfillmentError<'tcx> { let obligation = error.backtrace.into_iter().next().unwrap().obligation; FulfillmentError::new(obligation, error.error) } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 8ded1417ee570..ac49f522f431f 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -14,8 +14,8 @@ use crate::hir; use crate::hir::def_id::DefId; use crate::lint; use crate::traits::{self, Obligation, ObligationCause}; -use crate::ty::{self, Ty, TyCtxt, TypeFoldable, Predicate, ToPredicate}; -use crate::ty::subst::{Subst, InternalSubsts}; +use crate::ty::subst::{InternalSubsts, Subst}; +use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable}; use std::borrow::Cow; use std::iter::{self}; use syntax::ast::{self}; @@ -41,28 +41,36 @@ pub enum ObjectSafetyViolation { impl ObjectSafetyViolation { pub fn error_msg(&self) -> Cow<'static, str> { match *self { - ObjectSafetyViolation::SizedSelf => - "the trait cannot require that `Self : Sized`".into(), - ObjectSafetyViolation::SupertraitSelf => + ObjectSafetyViolation::SizedSelf => { + "the trait cannot require that `Self : Sized`".into() + } + ObjectSafetyViolation::SupertraitSelf => { "the trait cannot use `Self` as a type parameter \ - in the supertraits or where-clauses".into(), - ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) => - format!("associated function `{}` has no `self` parameter", name).into(), + in the supertraits or where-clauses" + .into() + } + ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) => { + format!("associated function `{}` has no `self` parameter", name).into() + } ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf, _) => format!( "method `{}` references the `Self` type in its parameters or return type", name, - ).into(), + ) + .into(), ObjectSafetyViolation::Method( name, MethodViolationCode::WhereClauseReferencesSelf, _, ) => format!("method `{}` references the `Self` type in where clauses", name).into(), - ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) => - format!("method `{}` has generic type parameters", name).into(), - ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => - format!("method `{}`'s `self` parameter cannot be dispatched on", name).into(), - ObjectSafetyViolation::AssocConst(name, _) => - format!("the trait cannot contain associated consts like `{}`", name).into(), + ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) => { + format!("method `{}` has generic type parameters", name).into() + } + ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => { + format!("method `{}`'s `self` parameter cannot be dispatched on", name).into() + } + ObjectSafetyViolation::AssocConst(name, _) => { + format!("the trait cannot contain associated consts like `{}`", name).into() + } } } @@ -70,8 +78,12 @@ impl ObjectSafetyViolation { // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so // diagnostics use a `note` instead of a `span_label`. match *self { - ObjectSafetyViolation::AssocConst(_, span) | - ObjectSafetyViolation::Method(_, _, span) if span != DUMMY_SP => Some(span), + ObjectSafetyViolation::AssocConst(_, span) + | ObjectSafetyViolation::Method(_, _, span) + if span != DUMMY_SP => + { + Some(span) + } _ => None, } } @@ -111,16 +123,15 @@ impl<'tcx> TyCtxt<'tcx> { .map(|_| ObjectSafetyViolation::SupertraitSelf) .collect(); - debug!("astconv_object_safety_violations(trait_def_id={:?}) = {:?}", - trait_def_id, - violations); + debug!( + "astconv_object_safety_violations(trait_def_id={:?}) = {:?}", + trait_def_id, violations + ); violations } - pub fn object_safety_violations(self, trait_def_id: DefId) - -> Vec - { + pub fn object_safety_violations(self, trait_def_id: DefId) -> Vec { debug_assert!(self.generics_of(trait_def_id).has_self); debug!("object_safety_violations: {:?}", trait_def_id); @@ -149,32 +160,39 @@ impl<'tcx> TyCtxt<'tcx> { fn object_safety_violations_for_trait(self, trait_def_id: DefId) -> Vec { // Check methods for violations. - let mut violations: Vec<_> = self.associated_items(trait_def_id) + let mut violations: Vec<_> = self + .associated_items(trait_def_id) .filter(|item| item.kind == ty::AssocKind::Method) - .filter_map(|item| + .filter_map(|item| { self.object_safety_violation_for_method(trait_def_id, &item).map(|code| { ObjectSafetyViolation::Method(item.ident.name, code, item.ident.span) }) - ).filter(|violation| { + }) + .filter(|violation| { if let ObjectSafetyViolation::Method( _, MethodViolationCode::WhereClauseReferencesSelf, span, - ) = violation { + ) = violation + { // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. // It's also hard to get a use site span, so we use the method definition span. self.lint_node_note( lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, *span, - &format!("the trait `{}` cannot be made into an object", - self.def_path_str(trait_def_id)), - &violation.error_msg()); + &format!( + "the trait `{}` cannot be made into an object", + self.def_path_str(trait_def_id) + ), + &violation.error_msg(), + ); false } else { true } - }).collect(); + }) + .collect(); // Check the trait itself. if self.trait_has_sized_self(trait_def_id) { @@ -184,22 +202,21 @@ impl<'tcx> TyCtxt<'tcx> { violations.push(ObjectSafetyViolation::SupertraitSelf); } - violations.extend(self.associated_items(trait_def_id) - .filter(|item| item.kind == ty::AssocKind::Const) - .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name, item.ident.span))); + violations.extend( + self.associated_items(trait_def_id) + .filter(|item| item.kind == ty::AssocKind::Const) + .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name, item.ident.span)), + ); - debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}", - trait_def_id, - violations); + debug!( + "object_safety_violations_for_trait(trait_def_id={:?}) = {:?}", + trait_def_id, violations + ); violations } - fn predicates_reference_self( - self, - trait_def_id: DefId, - supertraits_only: bool, - ) -> bool { + fn predicates_reference_self(self, trait_def_id: DefId, supertraits_only: bool) -> bool { let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(self, trait_def_id)); let predicates = if supertraits_only { self.super_predicates_of(trait_def_id) @@ -238,15 +255,13 @@ impl<'tcx> TyCtxt<'tcx> { .skip(1) .any(has_self_ty) } - ty::Predicate::WellFormed(..) | - ty::Predicate::ObjectSafe(..) | - ty::Predicate::TypeOutlives(..) | - ty::Predicate::RegionOutlives(..) | - ty::Predicate::ClosureKind(..) | - ty::Predicate::Subtype(..) | - ty::Predicate::ConstEvaluatable(..) => { - false - } + ty::Predicate::WellFormed(..) + | ty::Predicate::ObjectSafe(..) + | ty::Predicate::TypeOutlives(..) + | ty::Predicate::RegionOutlives(..) + | ty::Predicate::ClosureKind(..) + | ty::Predicate::Subtype(..) + | ty::Predicate::ConstEvaluatable(..) => false, } }) } @@ -258,30 +273,28 @@ impl<'tcx> TyCtxt<'tcx> { fn generics_require_sized_self(self, def_id: DefId) -> bool { let sized_def_id = match self.lang_items().sized_trait() { Some(def_id) => def_id, - None => { return false; /* No Sized trait, can't require it! */ } + None => { + return false; /* No Sized trait, can't require it! */ + } }; // Search for a predicate like `Self : Sized` amongst the trait bounds. let predicates = self.predicates_of(def_id); let predicates = predicates.instantiate_identity(self).predicates; - elaborate_predicates(self, predicates) - .any(|predicate| match predicate { - ty::Predicate::Trait(ref trait_pred) => { - trait_pred.def_id() == sized_def_id - && trait_pred.skip_binder().self_ty().is_param(0) - } - ty::Predicate::Projection(..) | - ty::Predicate::Subtype(..) | - ty::Predicate::RegionOutlives(..) | - ty::Predicate::WellFormed(..) | - ty::Predicate::ObjectSafe(..) | - ty::Predicate::ClosureKind(..) | - ty::Predicate::TypeOutlives(..) | - ty::Predicate::ConstEvaluatable(..) => { - false - } + elaborate_predicates(self, predicates).any(|predicate| match predicate { + ty::Predicate::Trait(ref trait_pred) => { + trait_pred.def_id() == sized_def_id + && trait_pred.skip_binder().self_ty().is_param(0) } - ) + ty::Predicate::Projection(..) + | ty::Predicate::Subtype(..) + | ty::Predicate::RegionOutlives(..) + | ty::Predicate::WellFormed(..) + | ty::Predicate::ObjectSafe(..) + | ty::Predicate::ClosureKind(..) + | ty::Predicate::TypeOutlives(..) + | ty::Predicate::ConstEvaluatable(..) => false, + }) } /// Returns `Some(_)` if this method makes the containing trait not object safe. @@ -331,24 +344,24 @@ impl<'tcx> TyCtxt<'tcx> { return Some(MethodViolationCode::Generic); } - if self.predicates_of(method.def_id).predicates.iter() - // A trait object can't claim to live more than the concrete type, - // so outlives predicates will always hold. - .cloned() - .filter(|(p, _)| p.to_opt_type_outlives().is_none()) - .collect::>() - // Do a shallow visit so that `contains_illegal_self_type_reference` - // may apply it's custom visiting. - .visit_tys_shallow(|t| { - self.contains_illegal_self_type_reference(trait_def_id, t) - }) { + if self + .predicates_of(method.def_id) + .predicates + .iter() + // A trait object can't claim to live more than the concrete type, + // so outlives predicates will always hold. + .cloned() + .filter(|(p, _)| p.to_opt_type_outlives().is_none()) + .collect::>() + // Do a shallow visit so that `contains_illegal_self_type_reference` + // may apply it's custom visiting. + .visit_tys_shallow(|t| self.contains_illegal_self_type_reference(trait_def_id, t)) + { return Some(MethodViolationCode::WhereClauseReferencesSelf); } - let receiver_ty = self.liberate_late_bound_regions( - method.def_id, - &sig.map_bound(|sig| sig.inputs()[0]), - ); + let receiver_ty = + self.liberate_late_bound_regions(method.def_id, &sig.map_bound(|sig| sig.inputs()[0])); // Until `unsized_locals` is fully implemented, `self: Self` can't be dispatched on. // However, this is already considered object-safe. We allow it as a special case here. @@ -367,16 +380,15 @@ impl<'tcx> TyCtxt<'tcx> { let abi_of_ty = |ty: Ty<'tcx>| -> &Abi { match self.layout_of(param_env.and(ty)) { Ok(layout) => &layout.abi, - Err(err) => bug!( - "error: {}\n while computing layout for type {:?}", err, ty - ) + Err(err) => { + bug!("error: {}\n while computing layout for type {:?}", err, ty) + } } }; // e.g., `Rc<()>` - let unit_receiver_ty = self.receiver_for_self_ty( - receiver_ty, self.mk_unit(), method.def_id - ); + let unit_receiver_ty = + self.receiver_for_self_ty(receiver_ty, self.mk_unit(), method.def_id); match abi_of_ty(unit_receiver_ty) { &Abi::Scalar(..) => (), @@ -391,14 +403,12 @@ impl<'tcx> TyCtxt<'tcx> { } } - let trait_object_ty = self.object_ty_for_trait( - trait_def_id, self.mk_region(ty::ReStatic) - ); + let trait_object_ty = + self.object_ty_for_trait(trait_def_id, self.mk_region(ty::ReStatic)); // e.g., `Rc` - let trait_object_receiver = self.receiver_for_self_ty( - receiver_ty, trait_object_ty, method.def_id - ); + let trait_object_receiver = + self.receiver_for_self_ty(receiver_ty, trait_object_ty, method.def_id); match abi_of_ty(trait_object_receiver) { &Abi::ScalarPair(..) => (), @@ -429,16 +439,14 @@ impl<'tcx> TyCtxt<'tcx> { ) -> Ty<'tcx> { debug!("receiver_for_self_ty({:?}, {:?}, {:?})", receiver_ty, self_ty, method_def_id); let substs = InternalSubsts::for_item(self, method_def_id, |param, _| { - if param.index == 0 { - self_ty.into() - } else { - self.mk_param_from_def(param) - } + if param.index == 0 { self_ty.into() } else { self.mk_param_from_def(param) } }); let result = receiver_ty.subst(self, substs); - debug!("receiver_for_self_ty({:?}, {:?}, {:?}) = {:?}", - receiver_ty, self_ty, method_def_id, result); + debug!( + "receiver_for_self_ty({:?}, {:?}, {:?}) = {:?}", + receiver_ty, self_ty, method_def_id, result + ); result } @@ -451,7 +459,7 @@ impl<'tcx> TyCtxt<'tcx> { let trait_ref = ty::TraitRef::identity(self, trait_def_id); let trait_predicate = ty::ExistentialPredicate::Trait( - ty::ExistentialTraitRef::erase_self_ty(self, trait_ref) + ty::ExistentialTraitRef::erase_self_ty(self, trait_ref), ); let mut associated_types = traits::supertraits(self, ty::Binder::dummy(trait_ref)) @@ -478,9 +486,8 @@ impl<'tcx> TyCtxt<'tcx> { }) }); - let existential_predicates = self.mk_existential_predicates( - iter::once(trait_predicate).chain(projection_predicates) - ); + let existential_predicates = self + .mk_existential_predicates(iter::once(trait_predicate).chain(projection_predicates)); let object_ty = self.mk_dynamic( // (*) ... binder re-introduced here @@ -540,15 +547,11 @@ impl<'tcx> TyCtxt<'tcx> { // fallback query: `Receiver: Unsize U]>` to support receivers like // `self: Wrapper`. #[allow(dead_code)] - fn receiver_is_dispatchable( - self, - method: &ty::AssocItem, - receiver_ty: Ty<'tcx>, - ) -> bool { + fn receiver_is_dispatchable(self, method: &ty::AssocItem, receiver_ty: Ty<'tcx>) -> bool { debug!("receiver_is_dispatchable: method = {:?}, receiver_ty = {:?}", method, receiver_ty); - let traits = (self.lang_items().unsize_trait(), - self.lang_items().dispatch_from_dyn_trait()); + let traits = + (self.lang_items().unsize_trait(), self.lang_items().dispatch_from_dyn_trait()); let (unsize_did, dispatch_from_dyn_did) = if let (Some(u), Some(cu)) = traits { (u, cu) } else { @@ -560,15 +563,12 @@ impl<'tcx> TyCtxt<'tcx> { // use a bogus type parameter to mimick a forall(U) query using u32::MAX for now. // FIXME(mikeyhew) this is a total hack. Once object_safe_for_dispatch is stabilized, we can // replace this with `dyn Trait` - let unsized_self_ty: Ty<'tcx> = self.mk_ty_param( - ::std::u32::MAX, - Symbol::intern("RustaceansAreAwesome"), - ); + let unsized_self_ty: Ty<'tcx> = + self.mk_ty_param(::std::u32::MAX, Symbol::intern("RustaceansAreAwesome")); // `Receiver[Self => U]` - let unsized_receiver_ty = self.receiver_for_self_ty( - receiver_ty, unsized_self_ty, method.def_id - ); + let unsized_receiver_ty = + self.receiver_for_self_ty(receiver_ty, unsized_self_ty, method.def_id); // create a modified param env, with `Self: Unsize` and `U: Trait` added to caller bounds // `U: ?Sized` is already implied here @@ -579,29 +579,27 @@ impl<'tcx> TyCtxt<'tcx> { let unsize_predicate = ty::TraitRef { def_id: unsize_did, substs: self.mk_substs_trait(self.types.self_param, &[unsized_self_ty.into()]), - }.to_predicate(); + } + .to_predicate(); // U: Trait let trait_predicate = { - let substs = InternalSubsts::for_item( - self, - method.container.assert_trait(), - |param, _| { + let substs = + InternalSubsts::for_item(self, method.container.assert_trait(), |param, _| { if param.index == 0 { unsized_self_ty.into() } else { self.mk_param_from_def(param) } - }, - ); + }); - ty::TraitRef { - def_id: unsize_did, - substs, - }.to_predicate() + ty::TraitRef { def_id: unsize_did, substs }.to_predicate() }; - let caller_bounds: Vec> = param_env.caller_bounds.iter().cloned() + let caller_bounds: Vec> = param_env + .caller_bounds + .iter() + .cloned() .chain(iter::once(unsize_predicate)) .chain(iter::once(trait_predicate)) .collect(); @@ -616,13 +614,10 @@ impl<'tcx> TyCtxt<'tcx> { let predicate = ty::TraitRef { def_id: dispatch_from_dyn_did, substs: self.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]), - }.to_predicate(); + } + .to_predicate(); - Obligation::new( - ObligationCause::dummy(), - param_env, - predicate, - ) + Obligation::new(ObligationCause::dummy(), param_env, predicate) }; self.infer_ctxt().enter(|ref infcx| { @@ -631,11 +626,7 @@ impl<'tcx> TyCtxt<'tcx> { }) } - fn contains_illegal_self_type_reference( - self, - trait_def_id: DefId, - ty: Ty<'tcx>, - ) -> bool { + fn contains_illegal_self_type_reference(self, trait_def_id: DefId, ty: Ty<'tcx>) -> bool { // This is somewhat subtle. In general, we want to forbid // references to `Self` in the argument and return types, // since the value of `Self` is erased. However, there is one @@ -693,9 +684,8 @@ impl<'tcx> TyCtxt<'tcx> { // Compute supertraits of current trait lazily. if supertraits.is_none() { - let trait_ref = ty::Binder::bind( - ty::TraitRef::identity(self, trait_def_id), - ); + let trait_ref = + ty::Binder::bind(ty::TraitRef::identity(self, trait_def_id)); supertraits = Some(traits::supertraits(self, trait_ref).collect()); } diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 604f39dcf293b..ff4d8980054cf 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -1,13 +1,13 @@ use fmt_macros::{Parser, Piece, Position}; use crate::hir::def_id::DefId; -use crate::ty::{self, TyCtxt, GenericParamDefKind}; +use crate::ty::{self, GenericParamDefKind, TyCtxt}; use crate::util::common::ErrorReported; use crate::util::nodemap::FxHashMap; use syntax::ast::{MetaItem, NestedMetaItem}; use syntax::attr; -use syntax::symbol::{Symbol, kw, sym}; +use syntax::symbol::{kw, sym, Symbol}; use syntax_pos::Span; use rustc_error_codes::*; @@ -40,8 +40,7 @@ fn parse_error( label: &str, note: Option<&str>, ) -> ErrorReported { - let mut diag = struct_span_err!( - tcx.sess, span, E0232, "{}", message); + let mut diag = struct_span_err!(tcx.sess, span, E0232, "{}", message); diag.span_label(span, label); if let Some(note) = note { diag.note(note); @@ -64,17 +63,27 @@ impl<'tcx> OnUnimplementedDirective { let condition = if is_root { None } else { - let cond = item_iter.next().ok_or_else(|| - parse_error(tcx, span, - "empty `on`-clause in `#[rustc_on_unimplemented]`", - "empty on-clause here", - None) - )?.meta_item().ok_or_else(|| - parse_error(tcx, span, - "invalid `on`-clause in `#[rustc_on_unimplemented]`", - "invalid on-clause here", - None) - )?; + let cond = item_iter + .next() + .ok_or_else(|| { + parse_error( + tcx, + span, + "empty `on`-clause in `#[rustc_on_unimplemented]`", + "empty on-clause here", + None, + ) + })? + .meta_item() + .ok_or_else(|| { + parse_error( + tcx, + span, + "invalid `on`-clause in `#[rustc_on_unimplemented]`", + "invalid on-clause here", + None, + ) + })?; attr::eval_condition(cond, &tcx.sess.parse_sess, &mut |_| true); Some(cond.clone()) }; @@ -86,9 +95,8 @@ impl<'tcx> OnUnimplementedDirective { let mut subcommands = vec![]; let parse_value = |value_str| { - OnUnimplementedFormatString::try_parse(tcx, trait_def_id, value_str, span) - .map(Some) - }; + OnUnimplementedFormatString::try_parse(tcx, trait_def_id, value_str, span).map(Some) + }; for item in item_iter { if item.check_name(sym::message) && message.is_none() { @@ -111,8 +119,11 @@ impl<'tcx> OnUnimplementedDirective { enclosing_scope = parse_value(enclosing_scope_)?; continue; } - } else if item.check_name(sym::on) && is_root && - message.is_none() && label.is_none() && note.is_none() + } else if item.check_name(sym::on) + && is_root + && message.is_none() + && label.is_none() + && note.is_none() { if let Some(items) = item.meta_item_list() { if let Ok(subcommand) = @@ -122,15 +133,18 @@ impl<'tcx> OnUnimplementedDirective { } else { errored = true; } - continue + continue; } } // nothing found - parse_error(tcx, item.span(), - "this attribute must have a valid value", - "expected value here", - Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#)); + parse_error( + tcx, + item.span(), + "this attribute must have a valid value", + "expected value here", + Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#), + ); } if errored { @@ -142,7 +156,7 @@ impl<'tcx> OnUnimplementedDirective { message, label, note, - enclosing_scope + enclosing_scope, }) } } @@ -168,7 +182,11 @@ impl<'tcx> OnUnimplementedDirective { message: None, subcommands: vec![], label: Some(OnUnimplementedFormatString::try_parse( - tcx, trait_def_id, value, attr.span)?), + tcx, + trait_def_id, + value, + attr.span, + )?), note: None, enclosing_scope: None, })) @@ -195,14 +213,11 @@ impl<'tcx> OnUnimplementedDirective { if let Some(ref condition) = command.condition { if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| { c.ident().map_or(false, |ident| { - options.contains(&( - ident.name, - c.value_str().map(|s| s.to_string()) - )) + options.contains(&(ident.name, c.value_str().map(|s| s.to_string()))) }) }) { debug!("evaluate: skipping {:?} due to condition", command); - continue + continue; } } debug!("evaluate: {:?} succeeded", command); @@ -223,7 +238,8 @@ impl<'tcx> OnUnimplementedDirective { } } - let options: FxHashMap = options.into_iter() + let options: FxHashMap = options + .into_iter() .filter_map(|(k, v)| v.as_ref().map(|v| (*k, v.to_owned()))) .collect(); OnUnimplementedNote { @@ -273,23 +289,33 @@ impl<'tcx> OnUnimplementedFormatString { // `{ItemContext}` is allowed Position::ArgumentNamed(s) if s == sym::item_context => (), // So is `{A}` if A is a type parameter - Position::ArgumentNamed(s) => match generics.params.iter().find(|param| { - param.name == s - }) { - Some(_) => (), - None => { - span_err!(tcx.sess, span, E0230, - "there is no parameter `{}` on trait `{}`", s, name); - result = Err(ErrorReported); + Position::ArgumentNamed(s) => { + match generics.params.iter().find(|param| param.name == s) { + Some(_) => (), + None => { + span_err!( + tcx.sess, + span, + E0230, + "there is no parameter `{}` on trait `{}`", + s, + name + ); + result = Err(ErrorReported); + } } - }, + } // `{:1}` and `{}` are not to be used Position::ArgumentIs(_) | Position::ArgumentImplicitlyIs(_) => { - span_err!(tcx.sess, span, E0231, - "only named substitution parameters are allowed"); + span_err!( + tcx.sess, + span, + E0231, + "only named substitution parameters are allowed" + ); result = Err(ErrorReported); } - } + }, } } @@ -305,31 +331,32 @@ impl<'tcx> OnUnimplementedFormatString { let name = tcx.item_name(trait_ref.def_id); let trait_str = tcx.def_path_str(trait_ref.def_id); let generics = tcx.generics_of(trait_ref.def_id); - let generic_map = generics.params.iter().filter_map(|param| { - let value = match param.kind { - GenericParamDefKind::Type { .. } | - GenericParamDefKind::Const => { - trait_ref.substs[param.index as usize].to_string() - }, - GenericParamDefKind::Lifetime => return None - }; - let name = param.name; - Some((name, value)) - }).collect::>(); + let generic_map = generics + .params + .iter() + .filter_map(|param| { + let value = match param.kind { + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => { + trait_ref.substs[param.index as usize].to_string() + } + GenericParamDefKind::Lifetime => return None, + }; + let name = param.name; + Some((name, value)) + }) + .collect::>(); let empty_string = String::new(); let s = self.0.as_str(); let parser = Parser::new(&s, None, vec![], false); let item_context = (options.get(&sym::item_context)).unwrap_or(&empty_string); - parser.map(|p| - match p { + parser + .map(|p| match p { Piece::String(s) => s, Piece::NextArgument(a) => match a.position { Position::ArgumentNamed(s) => match generic_map.get(&s) { Some(val) => val, - None if s == name => { - &trait_str - } + None if s == name => &trait_str, None => { if let Some(val) = options.get(&s) { val @@ -339,15 +366,19 @@ impl<'tcx> OnUnimplementedFormatString { } else if s == sym::item_context { &item_context } else { - bug!("broken on_unimplemented {:?} for {:?}: \ + bug!( + "broken on_unimplemented {:?} for {:?}: \ no argument matching {:?}", - self.0, trait_ref, s) + self.0, + trait_ref, + s + ) } } }, - _ => bug!("broken on_unimplemented {:?} - bad format arg", self.0) - } - } - ).collect() + _ => bug!("broken on_unimplemented {:?} - bad format arg", self.0), + }, + }) + .collect() } } diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 408743d5788d1..90381895f0a33 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -3,26 +3,26 @@ use super::elaborate_predicates; use super::specialization_graph; use super::translate_substs; +use super::util; use super::Obligation; use super::ObligationCause; use super::PredicateObligation; use super::Selection; use super::SelectionContext; use super::SelectionError; -use super::{VtableImplData, VtableClosureData, VtableGeneratorData, VtableFnPointerData}; -use super::util; +use super::{VtableClosureData, VtableFnPointerData, VtableGeneratorData, VtableImplData}; use crate::hir::def_id::DefId; -use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; +use crate::ty::fold::{TypeFoldable, TypeFolder}; +use crate::ty::subst::{InternalSubsts, Subst}; +use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt}; +use crate::util::common::FN_OUTPUT_NAME; use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap}; use rustc_macros::HashStable; use syntax::ast::Ident; use syntax::symbol::sym; -use crate::ty::subst::{Subst, InternalSubsts}; -use crate::ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt}; -use crate::ty::fold::{TypeFoldable, TypeFolder}; -use crate::util::common::FN_OUTPUT_NAME; use syntax_pos::DUMMY_SP; /// Depending on the stage of compilation, we want projection to be @@ -67,14 +67,11 @@ pub enum Reveal { All, } -pub type PolyProjectionObligation<'tcx> = - Obligation<'tcx, ty::PolyProjectionPredicate<'tcx>>; +pub type PolyProjectionObligation<'tcx> = Obligation<'tcx, ty::PolyProjectionPredicate<'tcx>>; -pub type ProjectionObligation<'tcx> = - Obligation<'tcx, ty::ProjectionPredicate<'tcx>>; +pub type ProjectionObligation<'tcx> = Obligation<'tcx, ty::ProjectionPredicate<'tcx>>; -pub type ProjectionTyObligation<'tcx> = - Obligation<'tcx, ty::ProjectionTy<'tcx>>; +pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::ProjectionTy<'tcx>>; /// When attempting to resolve `::Name` ... #[derive(Debug)] @@ -88,7 +85,7 @@ pub enum ProjectionTyError<'tcx> { #[derive(Clone)] pub struct MismatchedProjectionTypes<'tcx> { - pub err: ty::error::TypeError<'tcx> + pub err: ty::error::TypeError<'tcx>, } #[derive(PartialEq, Eq, Debug)] @@ -123,8 +120,8 @@ impl<'tcx> ProjectionTyCandidateSet<'tcx> { // was discarded -- this could be because of ambiguity, or because // a higher-priority candidate is already there. fn push_candidate(&mut self, candidate: ProjectionTyCandidate<'tcx>) -> bool { - use self::ProjectionTyCandidateSet::*; use self::ProjectionTyCandidate::*; + use self::ProjectionTyCandidateSet::*; // This wacky variable is just used to try and // make code readable and avoid confusing paths. @@ -187,8 +184,7 @@ pub fn poly_project_and_unify_type<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &PolyProjectionObligation<'tcx>, ) -> Result>>, MismatchedProjectionTypes<'tcx>> { - debug!("poly_project_and_unify_type(obligation={:?})", - obligation); + debug!("poly_project_and_unify_type(obligation={:?})", obligation); let infcx = selcx.infcx(); infcx.commit_if_ok(|snapshot| { @@ -197,7 +193,8 @@ pub fn poly_project_and_unify_type<'cx, 'tcx>( let placeholder_obligation = obligation.with(placeholder_predicate); let result = project_and_unify_type(selcx, &placeholder_obligation)?; - infcx.leak_check(false, &placeholder_map, snapshot) + infcx + .leak_check(false, &placeholder_map, snapshot) .map_err(|err| MismatchedProjectionTypes { err })?; Ok(result) }) @@ -212,32 +209,35 @@ fn project_and_unify_type<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionObligation<'tcx>, ) -> Result>>, MismatchedProjectionTypes<'tcx>> { - debug!("project_and_unify_type(obligation={:?})", - obligation); + debug!("project_and_unify_type(obligation={:?})", obligation); let mut obligations = vec![]; - let normalized_ty = - match opt_normalize_projection_type(selcx, - obligation.param_env, - obligation.predicate.projection_ty, - obligation.cause.clone(), - obligation.recursion_depth, - &mut obligations) { - Some(n) => n, - None => return Ok(None), - }; + let normalized_ty = match opt_normalize_projection_type( + selcx, + obligation.param_env, + obligation.predicate.projection_ty, + obligation.cause.clone(), + obligation.recursion_depth, + &mut obligations, + ) { + Some(n) => n, + None => return Ok(None), + }; - debug!("project_and_unify_type: normalized_ty={:?} obligations={:?}", - normalized_ty, - obligations); + debug!( + "project_and_unify_type: normalized_ty={:?} obligations={:?}", + normalized_ty, obligations + ); let infcx = selcx.infcx(); - match infcx.at(&obligation.cause, obligation.param_env) - .eq(normalized_ty, obligation.predicate.ty) { + match infcx + .at(&obligation.cause, obligation.param_env) + .eq(normalized_ty, obligation.predicate.ty) + { Ok(InferOk { obligations: inferred_obligations, value: () }) => { obligations.extend(inferred_obligations); Ok(Some(obligations)) - }, + } Err(err) => { debug!("project_and_unify_type: equating types encountered error {:?}", err); Err(MismatchedProjectionTypes { err }) @@ -275,14 +275,14 @@ where debug!("normalize_with_depth(depth={}, value={:?})", depth, value); let mut normalizer = AssocTypeNormalizer::new(selcx, param_env, cause, depth); let result = normalizer.fold(value); - debug!("normalize_with_depth: depth={} result={:?} with {} obligations", - depth, result, normalizer.obligations.len()); - debug!("normalize_with_depth: depth={} obligations={:?}", - depth, normalizer.obligations); - Normalized { - value: result, - obligations: normalizer.obligations, - } + debug!( + "normalize_with_depth: depth={} result={:?} with {} obligations", + depth, + result, + normalizer.obligations.len() + ); + debug!("normalize_with_depth: depth={} obligations={:?}", depth, normalizer.obligations); + Normalized { value: result, obligations: normalizer.obligations } } struct AssocTypeNormalizer<'a, 'b, 'tcx> { @@ -300,23 +300,13 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { cause: ObligationCause<'tcx>, depth: usize, ) -> AssocTypeNormalizer<'a, 'b, 'tcx> { - AssocTypeNormalizer { - selcx, - param_env, - cause, - obligations: vec![], - depth, - } + AssocTypeNormalizer { selcx, param_env, cause, obligations: vec![], depth } } - fn fold>(&mut self, value: &T) -> T { + fn fold>(&mut self, value: &T) -> T { let value = self.selcx.infcx().resolve_vars_if_possible(value); - if !value.has_projections() { - value - } else { - value.fold_with(self) - } + if !value.has_projections() { value } else { value.fold_with(self) } } } @@ -339,7 +329,8 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { let ty = ty.super_fold_with(self); match ty.kind { - ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { // (*) + ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { + // (*) // Only normalize `impl Trait` after type-checking, usually in codegen. match self.param_env.reveal { Reveal::UserFacing => ty, @@ -366,7 +357,8 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { } } - ty::Projection(ref data) if !data.has_escaping_bound_vars() => { // (*) + ty::Projection(ref data) if !data.has_escaping_bound_vars() => { + // (*) // (*) This is kind of hacky -- we need to be able to // handle normalization within binders because @@ -380,19 +372,26 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { // binder). It would be better to normalize in a // binding-aware fashion. - let normalized_ty = normalize_projection_type(self.selcx, - self.param_env, - data.clone(), - self.cause.clone(), - self.depth, - &mut self.obligations); - debug!("AssocTypeNormalizer: depth={} normalized {:?} to {:?}, \ + let normalized_ty = normalize_projection_type( + self.selcx, + self.param_env, + data.clone(), + self.cause.clone(), + self.depth, + &mut self.obligations, + ); + debug!( + "AssocTypeNormalizer: depth={} normalized {:?} to {:?}, \ now with {} obligations", - self.depth, ty, normalized_ty, self.obligations.len()); + self.depth, + ty, + normalized_ty, + self.obligations.len() + ); normalized_ty } - _ => ty + _ => ty, } } @@ -402,15 +401,15 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { } #[derive(Clone, TypeFoldable)] -pub struct Normalized<'tcx,T> { +pub struct Normalized<'tcx, T> { pub value: T, pub obligations: Vec>, } pub type NormalizedTy<'tcx> = Normalized<'tcx, Ty<'tcx>>; -impl<'tcx,T> Normalized<'tcx,T> { - pub fn with(self, value: U) -> Normalized<'tcx,U> { +impl<'tcx, T> Normalized<'tcx, T> { + pub fn with(self, value: U) -> Normalized<'tcx, U> { Normalized { value: value, obligations: self.obligations } } } @@ -429,30 +428,31 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>( depth: usize, obligations: &mut Vec>, ) -> Ty<'tcx> { - opt_normalize_projection_type(selcx, param_env, projection_ty.clone(), cause.clone(), depth, - obligations) - .unwrap_or_else(move || { - // if we bottom out in ambiguity, create a type variable - // and a deferred predicate to resolve this when more type - // information is available. - - let tcx = selcx.infcx().tcx; - let def_id = projection_ty.item_def_id; - let ty_var = selcx.infcx().next_ty_var( - TypeVariableOrigin { - kind: TypeVariableOriginKind::NormalizeProjectionType, - span: tcx.def_span(def_id), - }, - ); - let projection = ty::Binder::dummy(ty::ProjectionPredicate { - projection_ty, - ty: ty_var - }); - let obligation = Obligation::with_depth( - cause, depth + 1, param_env, projection.to_predicate()); - obligations.push(obligation); - ty_var - }) + opt_normalize_projection_type( + selcx, + param_env, + projection_ty.clone(), + cause.clone(), + depth, + obligations, + ) + .unwrap_or_else(move || { + // if we bottom out in ambiguity, create a type variable + // and a deferred predicate to resolve this when more type + // information is available. + + let tcx = selcx.infcx().tcx; + let def_id = projection_ty.item_def_id; + let ty_var = selcx.infcx().next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::NormalizeProjectionType, + span: tcx.def_span(def_id), + }); + let projection = ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, ty: ty_var }); + let obligation = + Obligation::with_depth(cause, depth + 1, param_env, projection.to_predicate()); + obligations.push(obligation); + ty_var + }) } /// The guts of `normalize`: normalize a specific projection like `( let projection_ty = infcx.resolve_vars_if_possible(&projection_ty); let cache_key = ProjectionCacheKey { ty: projection_ty }; - debug!("opt_normalize_projection_type(\ + debug!( + "opt_normalize_projection_type(\ projection_ty={:?}, \ depth={})", - projection_ty, - depth); + projection_ty, depth + ); // FIXME(#20304) For now, I am caching here, which is good, but it // means we don't capture the type variables that are created in @@ -494,7 +495,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( let cache_result = infcx.projection_cache.borrow_mut().try_start(cache_key); match cache_result { - Ok(()) => { } + Ok(()) => {} Err(ProjectionCacheEntry::Ambiguous) => { // If we found ambiguity the last time, that generally // means we will continue to do so until some type in the @@ -505,8 +506,10 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( // // FIXME(#32286) refactor this so that closure type // changes - debug!("opt_normalize_projection_type: \ - found cache entry: ambiguous"); + debug!( + "opt_normalize_projection_type: \ + found cache entry: ambiguous" + ); if !projection_ty.has_closure_types() { return None; } @@ -532,15 +535,15 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( // return Some(NormalizedTy { value: v, obligations: vec![] }); // ``` - debug!("opt_normalize_projection_type: \ - found cache entry: in-progress"); + debug!( + "opt_normalize_projection_type: \ + found cache entry: in-progress" + ); // But for now, let's classify this as an overflow: let recursion_limit = *selcx.tcx().sess.recursion_limit.get(); - let obligation = Obligation::with_depth(cause, - recursion_limit, - param_env, - projection_ty); + let obligation = + Obligation::with_depth(cause, recursion_limit, param_env, projection_ty); selcx.infcx().report_overflow_error(&obligation, false); } Err(ProjectionCacheEntry::NormalizedTy(ty)) => { @@ -555,74 +558,74 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( // discarded as duplicated). But when doing trait // evaluation this is not the case, and dropping the trait // evaluations can causes ICEs (e.g., #43132). - debug!("opt_normalize_projection_type: \ + debug!( + "opt_normalize_projection_type: \ found normalized ty `{:?}`", - ty); + ty + ); // Once we have inferred everything we need to know, we // can ignore the `obligations` from that point on. if infcx.unresolved_type_vars(&ty.value).is_none() { infcx.projection_cache.borrow_mut().complete_normalized(cache_key, &ty); - // No need to extend `obligations`. + // No need to extend `obligations`. } else { obligations.extend(ty.obligations); } - obligations.push(get_paranoid_cache_value_obligation(infcx, - param_env, - projection_ty, - cause, - depth)); + obligations.push(get_paranoid_cache_value_obligation( + infcx, + param_env, + projection_ty, + cause, + depth, + )); return Some(ty.value); } Err(ProjectionCacheEntry::Error) => { - debug!("opt_normalize_projection_type: \ - found error"); + debug!( + "opt_normalize_projection_type: \ + found error" + ); let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth); obligations.extend(result.obligations); - return Some(result.value) + return Some(result.value); } } let obligation = Obligation::with_depth(cause.clone(), depth, param_env, projection_ty); match project_type(selcx, &obligation) { - Ok(ProjectedTy::Progress(Progress { ty: projected_ty, - obligations: mut projected_obligations })) => { + Ok(ProjectedTy::Progress(Progress { + ty: projected_ty, + obligations: mut projected_obligations, + })) => { // if projection succeeded, then what we get out of this // is also non-normalized (consider: it was derived from // an impl, where-clause etc) and hence we must // re-normalize it - debug!("opt_normalize_projection_type: \ + debug!( + "opt_normalize_projection_type: \ projected_ty={:?} \ depth={} \ projected_obligations={:?}", - projected_ty, - depth, - projected_obligations); + projected_ty, depth, projected_obligations + ); let result = if projected_ty.has_projections() { - let mut normalizer = AssocTypeNormalizer::new(selcx, - param_env, - cause, - depth+1); + let mut normalizer = AssocTypeNormalizer::new(selcx, param_env, cause, depth + 1); let normalized_ty = normalizer.fold(&projected_ty); - debug!("opt_normalize_projection_type: \ + debug!( + "opt_normalize_projection_type: \ normalized_ty={:?} depth={}", - normalized_ty, - depth); + normalized_ty, depth + ); projected_obligations.extend(normalizer.obligations); - Normalized { - value: normalized_ty, - obligations: projected_obligations, - } + Normalized { value: normalized_ty, obligations: projected_obligations } } else { - Normalized { - value: projected_ty, - obligations: projected_obligations, - } + Normalized { value: projected_ty, obligations: projected_obligations } }; let cache_value = prune_cache_value_obligations(infcx, &result); @@ -631,22 +634,22 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( Some(result.value) } Ok(ProjectedTy::NoProgress(projected_ty)) => { - debug!("opt_normalize_projection_type: \ + debug!( + "opt_normalize_projection_type: \ projected_ty={:?} no progress", - projected_ty); - let result = Normalized { - value: projected_ty, - obligations: vec![] - }; + projected_ty + ); + let result = Normalized { value: projected_ty, obligations: vec![] }; infcx.projection_cache.borrow_mut().insert_ty(cache_key, result.clone()); // No need to extend `obligations`. Some(result.value) } Err(ProjectionTyError::TooManyCandidates) => { - debug!("opt_normalize_projection_type: \ - too many candidates"); - infcx.projection_cache.borrow_mut() - .ambiguous(cache_key); + debug!( + "opt_normalize_projection_type: \ + too many candidates" + ); + infcx.projection_cache.borrow_mut().ambiguous(cache_key); None } Err(ProjectionTyError::TraitSelectionError(_)) => { @@ -656,8 +659,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( // Trait`, which when processed will cause the error to be // reported later - infcx.projection_cache.borrow_mut() - .error(cache_key); + infcx.projection_cache.borrow_mut().error(cache_key); let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth); obligations.extend(result.obligations); Some(result.value) @@ -676,28 +678,27 @@ fn prune_cache_value_obligations<'a, 'tcx>( return NormalizedTy { value: result.value, obligations: vec![] }; } - let mut obligations: Vec<_> = - result.obligations - .iter() - .filter(|obligation| match obligation.predicate { - // We found a `T: Foo` predicate, let's check - // if `U` references any unresolved type - // variables. In principle, we only care if this - // projection can help resolve any of the type - // variables found in `result.value` -- but we just - // check for any type variables here, for fear of - // indirect obligations (e.g., we project to `?0`, - // but we have `T: Foo` and `?1: Bar`). - ty::Predicate::Projection(ref data) => - infcx.unresolved_type_vars(&data.ty()).is_some(), - - // We are only interested in `T: Foo` predicates, whre - // `U` references one of `unresolved_type_vars`. =) - _ => false, - }) - .cloned() - .collect(); + let mut obligations: Vec<_> = result + .obligations + .iter() + .filter(|obligation| match obligation.predicate { + // We found a `T: Foo` predicate, let's check + // if `U` references any unresolved type + // variables. In principle, we only care if this + // projection can help resolve any of the type + // variables found in `result.value` -- but we just + // check for any type variables here, for fear of + // indirect obligations (e.g., we project to `?0`, + // but we have `T: Foo` and `?1: Bar`). + ty::Predicate::Projection(ref data) => infcx.unresolved_type_vars(&data.ty()).is_some(), + + // We are only interested in `T: Foo` predicates, whre + // `U` references one of `unresolved_type_vars`. =) + _ => false, + }) + .cloned() + .collect(); obligations.shrink_to_fit(); @@ -735,12 +736,7 @@ fn get_paranoid_cache_value_obligation<'a, 'tcx>( depth: usize, ) -> PredicateObligation<'tcx> { let trait_ref = projection_ty.trait_ref(infcx.tcx).to_poly_trait_ref(); - Obligation { - cause, - recursion_depth: depth, - param_env, - predicate: trait_ref.to_predicate(), - } + Obligation { cause, recursion_depth: depth, param_env, predicate: trait_ref.to_predicate() } } /// If we are projecting `::Item`, but `T: Trait` does not @@ -770,22 +766,19 @@ fn normalize_to_error<'a, 'tcx>( depth: usize, ) -> NormalizedTy<'tcx> { let trait_ref = projection_ty.trait_ref(selcx.tcx()).to_poly_trait_ref(); - let trait_obligation = Obligation { cause, - recursion_depth: depth, - param_env, - predicate: trait_ref.to_predicate() }; + let trait_obligation = Obligation { + cause, + recursion_depth: depth, + param_env, + predicate: trait_ref.to_predicate(), + }; let tcx = selcx.infcx().tcx; let def_id = projection_ty.item_def_id; - let new_value = selcx.infcx().next_ty_var( - TypeVariableOrigin { - kind: TypeVariableOriginKind::NormalizeProjectionType, - span: tcx.def_span(def_id), - }, - ); - Normalized { - value: new_value, - obligations: vec![trait_obligation] - } + let new_value = selcx.infcx().next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::NormalizeProjectionType, + span: tcx.def_span(def_id), + }); + Normalized { value: new_value, obligations: vec![trait_obligation] } } enum ProjectedTy<'tcx> { @@ -800,20 +793,20 @@ struct Progress<'tcx> { impl<'tcx> Progress<'tcx> { fn error(tcx: TyCtxt<'tcx>) -> Self { - Progress { - ty: tcx.types.err, - obligations: vec![], - } + Progress { ty: tcx.types.err, obligations: vec![] } } - fn with_addl_obligations(mut self, - mut obligations: Vec>) - -> Self { - debug!("with_addl_obligations: self.obligations.len={} obligations.len={}", - self.obligations.len(), obligations.len()); + fn with_addl_obligations(mut self, mut obligations: Vec>) -> Self { + debug!( + "with_addl_obligations: self.obligations.len={} obligations.len={}", + self.obligations.len(), + obligations.len() + ); - debug!("with_addl_obligations: self.obligations={:?} obligations={:?}", - self.obligations, obligations); + debug!( + "with_addl_obligations: self.obligations={:?} obligations={:?}", + self.obligations, obligations + ); self.obligations.append(&mut obligations); self @@ -828,8 +821,7 @@ fn project_type<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, ) -> Result, ProjectionTyError<'tcx>> { - debug!("project(obligation={:?})", - obligation); + debug!("project(obligation={:?})", obligation); let recursion_limit = *selcx.tcx().sess.recursion_limit.get(); if obligation.recursion_depth >= recursion_limit { @@ -850,37 +842,26 @@ fn project_type<'cx, 'tcx>( // Make sure that the following procedures are kept in order. ParamEnv // needs to be first because it has highest priority, and Select checks // the return value of push_candidate which assumes it's ran at last. - assemble_candidates_from_param_env(selcx, - obligation, - &obligation_trait_ref, - &mut candidates); + assemble_candidates_from_param_env(selcx, obligation, &obligation_trait_ref, &mut candidates); - assemble_candidates_from_trait_def(selcx, - obligation, - &obligation_trait_ref, - &mut candidates); + assemble_candidates_from_trait_def(selcx, obligation, &obligation_trait_ref, &mut candidates); - assemble_candidates_from_impls(selcx, - obligation, - &obligation_trait_ref, - &mut candidates); + assemble_candidates_from_impls(selcx, obligation, &obligation_trait_ref, &mut candidates); match candidates { ProjectionTyCandidateSet::Single(candidate) => Ok(ProjectedTy::Progress( - confirm_candidate(selcx, - obligation, - &obligation_trait_ref, - candidate))), + confirm_candidate(selcx, obligation, &obligation_trait_ref, candidate), + )), ProjectionTyCandidateSet::None => Ok(ProjectedTy::NoProgress( - selcx.tcx().mk_projection( - obligation.predicate.item_def_id, - obligation.predicate.substs))), + selcx + .tcx() + .mk_projection(obligation.predicate.item_def_id, obligation.predicate.substs), + )), // Error occurred while trying to processing impls. ProjectionTyCandidateSet::Error(e) => Err(ProjectionTyError::TraitSelectionError(e)), // Inherent ambiguity that prevents us from even enumerating the // candidates. ProjectionTyCandidateSet::Ambiguous => Err(ProjectionTyError::TooManyCandidates), - } } @@ -894,12 +875,14 @@ fn assemble_candidates_from_param_env<'cx, 'tcx>( candidate_set: &mut ProjectionTyCandidateSet<'tcx>, ) { debug!("assemble_candidates_from_param_env(..)"); - assemble_candidates_from_predicates(selcx, - obligation, - obligation_trait_ref, - candidate_set, - ProjectionTyCandidate::ParamEnv, - obligation.param_env.caller_bounds.iter().cloned()); + assemble_candidates_from_predicates( + selcx, + obligation, + obligation_trait_ref, + candidate_set, + ProjectionTyCandidate::ParamEnv, + obligation.param_env.caller_bounds.iter().cloned(), + ); } /// In the case of a nested projection like <::FooT as Bar>::BarT, we may find @@ -923,9 +906,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>( let tcx = selcx.tcx(); // Check whether the self-type is itself a projection. let (def_id, substs) = match obligation_trait_ref.self_ty().kind { - ty::Projection(ref data) => { - (data.trait_ref(tcx).def_id, data.substs) - } + ty::Projection(ref data) => (data.trait_ref(tcx).def_id, data.substs), ty::Opaque(def_id, substs) => (def_id, substs), ty::Infer(ty::TyVar(_)) => { // If the self-type is an inference variable, then it MAY wind up @@ -933,19 +914,21 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>( candidate_set.mark_ambiguous(); return; } - _ => return + _ => return, }; // If so, extract what we know from the trait and try to come up with a good answer. let trait_predicates = tcx.predicates_of(def_id); let bounds = trait_predicates.instantiate(tcx, substs); let bounds = elaborate_predicates(tcx, bounds.predicates); - assemble_candidates_from_predicates(selcx, - obligation, - obligation_trait_ref, - candidate_set, - ProjectionTyCandidate::TraitDef, - bounds) + assemble_candidates_from_predicates( + selcx, + obligation, + obligation_trait_ref, + candidate_set, + ProjectionTyCandidate::TraitDef, + bounds, + ) } fn assemble_candidates_from_predicates<'cx, 'tcx, I>( @@ -958,32 +941,32 @@ fn assemble_candidates_from_predicates<'cx, 'tcx, I>( ) where I: IntoIterator>, { - debug!("assemble_candidates_from_predicates(obligation={:?})", - obligation); + debug!("assemble_candidates_from_predicates(obligation={:?})", obligation); let infcx = selcx.infcx(); for predicate in env_predicates { - debug!("assemble_candidates_from_predicates: predicate={:?}", - predicate); + debug!("assemble_candidates_from_predicates: predicate={:?}", predicate); if let ty::Predicate::Projection(data) = predicate { let same_def_id = data.projection_def_id() == obligation.predicate.item_def_id; - let is_match = same_def_id && infcx.probe(|_| { - let data_poly_trait_ref = - data.to_poly_trait_ref(infcx.tcx); - let obligation_poly_trait_ref = - obligation_trait_ref.to_poly_trait_ref(); - infcx.at(&obligation.cause, obligation.param_env) - .sup(obligation_poly_trait_ref, data_poly_trait_ref) - .map(|InferOk { obligations: _, value: () }| { - // FIXME(#32730) -- do we need to take obligations - // into account in any way? At the moment, no. - }) - .is_ok() - }); - - debug!("assemble_candidates_from_predicates: candidate={:?} \ + let is_match = same_def_id + && infcx.probe(|_| { + let data_poly_trait_ref = data.to_poly_trait_ref(infcx.tcx); + let obligation_poly_trait_ref = obligation_trait_ref.to_poly_trait_ref(); + infcx + .at(&obligation.cause, obligation.param_env) + .sup(obligation_poly_trait_ref, data_poly_trait_ref) + .map(|InferOk { obligations: _, value: () }| { + // FIXME(#32730) -- do we need to take obligations + // into account in any way? At the moment, no. + }) + .is_ok() + }); + + debug!( + "assemble_candidates_from_predicates: candidate={:?} \ is_match={} same_def_id={}", - data, is_match, same_def_id); + data, is_match, same_def_id + ); if is_match { candidate_set.push_candidate(ctor(data)); @@ -1017,13 +1000,12 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( }; let eligible = match &vtable { - super::VtableClosure(_) | - super::VtableGenerator(_) | - super::VtableFnPointer(_) | - super::VtableObject(_) | - super::VtableTraitAlias(_) => { - debug!("assemble_candidates_from_impls: vtable={:?}", - vtable); + super::VtableClosure(_) + | super::VtableGenerator(_) + | super::VtableFnPointer(_) + | super::VtableObject(_) + | super::VtableTraitAlias(_) => { + debug!("assemble_candidates_from_impls: vtable={:?}", vtable); true } super::VtableImpl(impl_data) => { @@ -1046,9 +1028,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // In either case, we handle this by not adding a // candidate for an impl if it contains a `default` // type. - let node_item = assoc_ty_def(selcx, - impl_data.impl_def_id, - obligation.predicate.item_def_id); + let node_item = + assoc_ty_def(selcx, impl_data.impl_def_id, obligation.predicate.item_def_id); let is_default = if node_item.node.is_from_trait() { // If true, the impl inherited a `type Foo = Bar` @@ -1069,8 +1050,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // being invoked). node_item.item.defaultness.has_value() } else { - node_item.item.defaultness.is_default() || - selcx.tcx().impl_is_default(node_item.node.def_id()) + node_item.item.defaultness.is_default() + || selcx.tcx().impl_is_default(node_item.node.def_id()) }; // Only reveal a specializable default if we're past type-checking @@ -1116,13 +1097,13 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // in `assemble_candidates_from_param_env`. false } - super::VtableAutoImpl(..) | - super::VtableBuiltin(..) => { + super::VtableAutoImpl(..) | super::VtableBuiltin(..) => { // These traits have no associated types. span_bug!( obligation.cause.span, "Cannot project an associated type from `{:?}`", - vtable); + vtable + ); } }; @@ -1144,13 +1125,11 @@ fn confirm_candidate<'cx, 'tcx>( obligation_trait_ref: &ty::TraitRef<'tcx>, candidate: ProjectionTyCandidate<'tcx>, ) -> Progress<'tcx> { - debug!("confirm_candidate(candidate={:?}, obligation={:?})", - candidate, - obligation); + debug!("confirm_candidate(candidate={:?}, obligation={:?})", candidate, obligation); match candidate { - ProjectionTyCandidate::ParamEnv(poly_projection) | - ProjectionTyCandidate::TraitDef(poly_projection) => { + ProjectionTyCandidate::ParamEnv(poly_projection) + | ProjectionTyCandidate::TraitDef(poly_projection) => { confirm_param_env_candidate(selcx, obligation, poly_projection) } @@ -1167,25 +1146,23 @@ fn confirm_select_candidate<'cx, 'tcx>( vtable: Selection<'tcx>, ) -> Progress<'tcx> { match vtable { - super::VtableImpl(data) => - confirm_impl_candidate(selcx, obligation, data), - super::VtableGenerator(data) => - confirm_generator_candidate(selcx, obligation, data), - super::VtableClosure(data) => - confirm_closure_candidate(selcx, obligation, data), - super::VtableFnPointer(data) => - confirm_fn_pointer_candidate(selcx, obligation, data), - super::VtableObject(_) => - confirm_object_candidate(selcx, obligation, obligation_trait_ref), - super::VtableAutoImpl(..) | - super::VtableParam(..) | - super::VtableBuiltin(..) | - super::VtableTraitAlias(..) => - // we don't create Select candidates with this kind of resolution + super::VtableImpl(data) => confirm_impl_candidate(selcx, obligation, data), + super::VtableGenerator(data) => confirm_generator_candidate(selcx, obligation, data), + super::VtableClosure(data) => confirm_closure_candidate(selcx, obligation, data), + super::VtableFnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data), + super::VtableObject(_) => confirm_object_candidate(selcx, obligation, obligation_trait_ref), + super::VtableAutoImpl(..) + | super::VtableParam(..) + | super::VtableBuiltin(..) + | super::VtableTraitAlias(..) => + // we don't create Select candidates with this kind of resolution + { span_bug!( obligation.cause.span, "Cannot project an associated type from `{:?}`", - vtable), + vtable + ) + } } } @@ -1196,44 +1173,46 @@ fn confirm_object_candidate<'cx, 'tcx>( ) -> Progress<'tcx> { let self_ty = obligation_trait_ref.self_ty(); let object_ty = selcx.infcx().shallow_resolve(self_ty); - debug!("confirm_object_candidate(object_ty={:?})", - object_ty); + debug!("confirm_object_candidate(object_ty={:?})", object_ty); let data = match object_ty.kind { ty::Dynamic(ref data, ..) => data, - _ => { - span_bug!( - obligation.cause.span, - "confirm_object_candidate called with non-object: {:?}", - object_ty) - } + _ => span_bug!( + obligation.cause.span, + "confirm_object_candidate called with non-object: {:?}", + object_ty + ), }; - let env_predicates = data.projection_bounds().map(|p| { - p.with_self_ty(selcx.tcx(), object_ty).to_predicate() - }).collect(); + let env_predicates = data + .projection_bounds() + .map(|p| p.with_self_ty(selcx.tcx(), object_ty).to_predicate()) + .collect(); let env_predicate = { let env_predicates = elaborate_predicates(selcx.tcx(), env_predicates); // select only those projections that are actually projecting an // item with the correct name let env_predicates = env_predicates.filter_map(|p| match p { - ty::Predicate::Projection(data) => + ty::Predicate::Projection(data) => { if data.projection_def_id() == obligation.predicate.item_def_id { Some(data) } else { None - }, - _ => None + } + } + _ => None, }); // select those with a relevant trait-ref let mut env_predicates = env_predicates.filter(|data| { let data_poly_trait_ref = data.to_poly_trait_ref(selcx.tcx()); let obligation_poly_trait_ref = obligation_trait_ref.to_poly_trait_ref(); - selcx.infcx().probe(|_| - selcx.infcx().at(&obligation.cause, obligation.param_env) - .sup(obligation_poly_trait_ref, data_poly_trait_ref) - .is_ok() - ) + selcx.infcx().probe(|_| { + selcx + .infcx() + .at(&obligation.cause, obligation.param_env) + .sup(obligation_poly_trait_ref, data_poly_trait_ref) + .is_ok() + }) }); // select the first matching one; there really ought to be one or @@ -1242,9 +1221,11 @@ fn confirm_object_candidate<'cx, 'tcx>( match env_predicates.next() { Some(env_predicate) => env_predicate, None => { - debug!("confirm_object_candidate: no env-predicate \ + debug!( + "confirm_object_candidate: no env-predicate \ found in object type `{:?}`; ill-formed", - object_ty); + object_ty + ); return Progress::error(selcx.tcx()); } } @@ -1259,28 +1240,25 @@ fn confirm_generator_candidate<'cx, 'tcx>( vtable: VtableGeneratorData<'tcx, PredicateObligation<'tcx>>, ) -> Progress<'tcx> { let gen_sig = vtable.substs.as_generator().poly_sig(vtable.generator_def_id, selcx.tcx()); - let Normalized { - value: gen_sig, - obligations - } = normalize_with_depth(selcx, - obligation.param_env, - obligation.cause.clone(), - obligation.recursion_depth+1, - &gen_sig); - - debug!("confirm_generator_candidate: obligation={:?},gen_sig={:?},obligations={:?}", - obligation, - gen_sig, - obligations); + let Normalized { value: gen_sig, obligations } = normalize_with_depth( + selcx, + obligation.param_env, + obligation.cause.clone(), + obligation.recursion_depth + 1, + &gen_sig, + ); + + debug!( + "confirm_generator_candidate: obligation={:?},gen_sig={:?},obligations={:?}", + obligation, gen_sig, obligations + ); let tcx = selcx.tcx(); let gen_def_id = tcx.lang_items().gen_trait().unwrap(); - let predicate = - tcx.generator_trait_ref_and_outputs(gen_def_id, - obligation.predicate.self_ty(), - gen_sig) + let predicate = tcx + .generator_trait_ref_and_outputs(gen_def_id, obligation.predicate.self_ty(), gen_sig) .map_bound(|(trait_ref, yield_ty, return_ty)| { let name = tcx.associated_item(obligation.predicate.item_def_id).ident.name; let ty = if name == sym::Return { @@ -1296,7 +1274,7 @@ fn confirm_generator_candidate<'cx, 'tcx>( substs: trait_ref.substs, item_def_id: obligation.predicate.item_def_id, }, - ty: ty + ty: ty, } }); @@ -1312,14 +1290,13 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>( ) -> Progress<'tcx> { let fn_type = selcx.infcx().shallow_resolve(fn_pointer_vtable.fn_ty); let sig = fn_type.fn_sig(selcx.tcx()); - let Normalized { - value: sig, - obligations - } = normalize_with_depth(selcx, - obligation.param_env, - obligation.cause.clone(), - obligation.recursion_depth+1, - &sig); + let Normalized { value: sig, obligations } = normalize_with_depth( + selcx, + obligation.param_env, + obligation.cause.clone(), + obligation.recursion_depth + 1, + &sig, + ); confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes) .with_addl_obligations(fn_pointer_vtable.nested) @@ -1333,27 +1310,22 @@ fn confirm_closure_candidate<'cx, 'tcx>( ) -> Progress<'tcx> { let tcx = selcx.tcx(); let infcx = selcx.infcx(); - let closure_sig_ty = vtable.substs - .as_closure().sig_ty(vtable.closure_def_id, tcx); + let closure_sig_ty = vtable.substs.as_closure().sig_ty(vtable.closure_def_id, tcx); let closure_sig = infcx.shallow_resolve(closure_sig_ty).fn_sig(tcx); - let Normalized { - value: closure_sig, - obligations - } = normalize_with_depth(selcx, - obligation.param_env, - obligation.cause.clone(), - obligation.recursion_depth+1, - &closure_sig); - - debug!("confirm_closure_candidate: obligation={:?},closure_sig={:?},obligations={:?}", - obligation, - closure_sig, - obligations); - - confirm_callable_candidate(selcx, - obligation, - closure_sig, - util::TupleArgumentsFlag::No) + let Normalized { value: closure_sig, obligations } = normalize_with_depth( + selcx, + obligation.param_env, + obligation.cause.clone(), + obligation.recursion_depth + 1, + &closure_sig, + ); + + debug!( + "confirm_closure_candidate: obligation={:?},closure_sig={:?},obligations={:?}", + obligation, closure_sig, obligations + ); + + confirm_callable_candidate(selcx, obligation, closure_sig, util::TupleArgumentsFlag::No) .with_addl_obligations(vtable.nested) .with_addl_obligations(obligations) } @@ -1366,28 +1338,26 @@ fn confirm_callable_candidate<'cx, 'tcx>( ) -> Progress<'tcx> { let tcx = selcx.tcx(); - debug!("confirm_callable_candidate({:?},{:?})", - obligation, - fn_sig); + debug!("confirm_callable_candidate({:?},{:?})", obligation, fn_sig); // the `Output` associated type is declared on `FnOnce` let fn_once_def_id = tcx.lang_items().fn_once_trait().unwrap(); - let predicate = - tcx.closure_trait_ref_and_return_type(fn_once_def_id, - obligation.predicate.self_ty(), - fn_sig, - flag) - .map_bound(|(trait_ref, ret_type)| - ty::ProjectionPredicate { - projection_ty: ty::ProjectionTy::from_ref_and_name( - tcx, - trait_ref, - Ident::with_dummy_span(FN_OUTPUT_NAME), - ), - ty: ret_type - } - ); + let predicate = tcx + .closure_trait_ref_and_return_type( + fn_once_def_id, + obligation.predicate.self_ty(), + fn_sig, + flag, + ) + .map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate { + projection_ty: ty::ProjectionTy::from_ref_and_name( + tcx, + trait_ref, + Ident::with_dummy_span(FN_OUTPUT_NAME), + ), + ty: ret_type, + }); confirm_param_env_candidate(selcx, obligation, predicate) } @@ -1401,34 +1371,24 @@ fn confirm_param_env_candidate<'cx, 'tcx>( let cause = &obligation.cause; let param_env = obligation.param_env; - let (cache_entry, _) = - infcx.replace_bound_vars_with_fresh_vars( - cause.span, - LateBoundRegionConversionTime::HigherRankedType, - &poly_cache_entry); + let (cache_entry, _) = infcx.replace_bound_vars_with_fresh_vars( + cause.span, + LateBoundRegionConversionTime::HigherRankedType, + &poly_cache_entry, + ); let cache_trait_ref = cache_entry.projection_ty.trait_ref(infcx.tcx); let obligation_trait_ref = obligation.predicate.trait_ref(infcx.tcx); match infcx.at(cause, param_env).eq(cache_trait_ref, obligation_trait_ref) { - Ok(InferOk { value: _, obligations }) => { - Progress { - ty: cache_entry.ty, - obligations, - } - } + Ok(InferOk { value: _, obligations }) => Progress { ty: cache_entry.ty, obligations }, Err(e) => { let msg = format!( "Failed to unify obligation `{:?}` with poly_projection `{:?}`: {:?}", - obligation, - poly_cache_entry, - e, + obligation, poly_cache_entry, e, ); debug!("confirm_param_env_candidate: {}", msg); infcx.tcx.sess.delay_span_bug(obligation.cause.span, &msg); - Progress { - ty: infcx.tcx.types.err, - obligations: vec![], - } + Progress { ty: infcx.tcx.types.err, obligations: vec![] } } } } @@ -1452,13 +1412,11 @@ fn confirm_impl_candidate<'cx, 'tcx>( // associated type. This error will be reported by the type // checker method `check_impl_items_against_trait`, so here we // just return Error. - debug!("confirm_impl_candidate: no associated type {:?} for {:?}", - assoc_ty.item.ident, - obligation.predicate); - return Progress { - ty: tcx.types.err, - obligations: nested, - }; + debug!( + "confirm_impl_candidate: no associated type {:?} for {:?}", + assoc_ty.item.ident, obligation.predicate + ); + return Progress { ty: tcx.types.err, obligations: nested }; } let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs); let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node); @@ -1469,19 +1427,11 @@ fn confirm_impl_candidate<'cx, 'tcx>( tcx.type_of(assoc_ty.item.def_id) }; if substs.len() != tcx.generics_of(assoc_ty.item.def_id).count() { - tcx.sess.delay_span_bug( - DUMMY_SP, - "impl item and trait item have different parameter counts", - ); - Progress { - ty: tcx.types.err, - obligations: nested, - } + tcx.sess + .delay_span_bug(DUMMY_SP, "impl item and trait item have different parameter counts"); + Progress { ty: tcx.types.err, obligations: nested } } else { - Progress { - ty: ty.subst(tcx, substs), - obligations: nested, - } + Progress { ty: ty.subst(tcx, substs), obligations: nested } } } @@ -1508,8 +1458,9 @@ fn assoc_ty_def( // cycle error if the specialization graph is currently being built. let impl_node = specialization_graph::Node::Impl(impl_def_id); for item in impl_node.items(tcx) { - if item.kind == ty::AssocKind::Type && - tcx.hygienic_eq(item.ident, assoc_ty_name, trait_def_id) { + if item.kind == ty::AssocKind::Type + && tcx.hygienic_eq(item.ident, assoc_ty_name, trait_def_id) + { return specialization_graph::NodeItem { node: specialization_graph::Node::Impl(impl_def_id), item, @@ -1517,10 +1468,9 @@ fn assoc_ty_def( } } - if let Some(assoc_item) = trait_def - .ancestors(tcx, impl_def_id) - .leaf_def(tcx, assoc_ty_name, ty::AssocKind::Type) { - + if let Some(assoc_item) = + trait_def.ancestors(tcx, impl_def_id).leaf_def(tcx, assoc_ty_name, ty::AssocKind::Type) + { assoc_item } else { // This is saying that neither the trait nor @@ -1529,9 +1479,7 @@ fn assoc_ty_def( // could only arise through a compiler bug -- // if the user wrote a bad item name, it // should have failed in astconv. - bug!("No associated type `{}` for {}", - assoc_ty_name, - tcx.def_path_str(impl_def_id)) + bug!("No associated type `{}` for {}", assoc_ty_name, tcx.def_path_str(impl_def_id)) } } @@ -1573,7 +1521,7 @@ pub struct ProjectionCache<'tcx> { #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct ProjectionCacheKey<'tcx> { - ty: ty::ProjectionTy<'tcx> + ty: ty::ProjectionTy<'tcx>, } impl<'cx, 'tcx> ProjectionCacheKey<'tcx> { @@ -1584,14 +1532,13 @@ impl<'cx, 'tcx> ProjectionCacheKey<'tcx> { let infcx = selcx.infcx(); // We don't do cross-snapshot caching of obligations with escaping regions, // so there's no cache key to use - predicate.no_bound_vars() - .map(|predicate| ProjectionCacheKey { - // We don't attempt to match up with a specific type-variable state - // from a specific call to `opt_normalize_projection_type` - if - // there's no precise match, the original cache entry is "stranded" - // anyway. - ty: infcx.resolve_vars_if_possible(&predicate.projection_ty) - }) + predicate.no_bound_vars().map(|predicate| ProjectionCacheKey { + // We don't attempt to match up with a specific type-variable state + // from a specific call to `opt_normalize_projection_type` - if + // there's no precise match, the original cache entry is "stranded" + // anyway. + ty: infcx.resolve_vars_if_possible(&predicate.projection_ty), + }) } } @@ -1632,8 +1579,10 @@ impl<'tcx> ProjectionCache<'tcx> { /// Try to start normalize `key`; returns an error if /// normalization already occurred (this error corresponds to a /// cache hit, so it's actually a good thing). - fn try_start(&mut self, key: ProjectionCacheKey<'tcx>) - -> Result<(), ProjectionCacheEntry<'tcx>> { + fn try_start( + &mut self, + key: ProjectionCacheKey<'tcx>, + ) -> Result<(), ProjectionCacheEntry<'tcx>> { if let Some(entry) = self.map.get(&key) { return Err(entry.clone()); } @@ -1644,8 +1593,10 @@ impl<'tcx> ProjectionCache<'tcx> { /// Indicates that `key` was normalized to `value`. fn insert_ty(&mut self, key: ProjectionCacheKey<'tcx>, value: NormalizedTy<'tcx>) { - debug!("ProjectionCacheEntry::insert_ty: adding cache entry: key={:?}, value={:?}", - key, value); + debug!( + "ProjectionCacheEntry::insert_ty: adding cache entry: key={:?}, value={:?}", + key, value + ); let fresh_key = self.map.insert(key, ProjectionCacheEntry::NormalizedTy(value)); assert!(!fresh_key, "never started projecting `{:?}`", key); } @@ -1657,23 +1608,21 @@ impl<'tcx> ProjectionCache<'tcx> { pub fn complete(&mut self, key: ProjectionCacheKey<'tcx>) { let ty = match self.map.get(&key) { Some(&ProjectionCacheEntry::NormalizedTy(ref ty)) => { - debug!("ProjectionCacheEntry::complete({:?}) - completing {:?}", - key, ty); + debug!("ProjectionCacheEntry::complete({:?}) - completing {:?}", key, ty); ty.value } ref value => { // Type inference could "strand behind" old cache entries. Leave // them alone for now. - debug!("ProjectionCacheEntry::complete({:?}) - ignoring {:?}", - key, value); - return + debug!("ProjectionCacheEntry::complete({:?}) - ignoring {:?}", key, value); + return; } }; - self.map.insert(key, ProjectionCacheEntry::NormalizedTy(Normalized { - value: ty, - obligations: vec![] - })); + self.map.insert( + key, + ProjectionCacheEntry::NormalizedTy(Normalized { value: ty, obligations: vec![] }), + ); } /// A specialized version of `complete` for when the key's value is known @@ -1682,10 +1631,13 @@ impl<'tcx> ProjectionCache<'tcx> { // We want to insert `ty` with no obligations. If the existing value // already has no obligations (as is common) we don't insert anything. if !ty.obligations.is_empty() { - self.map.insert(key, ProjectionCacheEntry::NormalizedTy(Normalized { - value: ty.value, - obligations: vec![] - })); + self.map.insert( + key, + ProjectionCacheEntry::NormalizedTy(Normalized { + value: ty.value, + obligations: vec![], + }), + ); } } diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 785b4122d0873..80a82021c9a34 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -1,10 +1,10 @@ use crate::infer::at::At; -use crate::infer::InferOk; use crate::infer::canonical::OriginalQueryValues; -use std::iter::FromIterator; -use syntax::source_map::Span; +use crate::infer::InferOk; use crate::ty::subst::GenericArg; use crate::ty::{self, Ty, TyCtxt}; +use std::iter::FromIterator; +use syntax::source_map::Span; use rustc_error_codes::*; @@ -27,19 +27,13 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { /// [#1238]: https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md /// [#1327]: https://github.com/rust-lang/rfcs/blob/master/text/1327-dropck-param-eyepatch.md pub fn dropck_outlives(&self, ty: Ty<'tcx>) -> InferOk<'tcx, Vec>> { - debug!( - "dropck_outlives(ty={:?}, param_env={:?})", - ty, self.param_env, - ); + debug!("dropck_outlives(ty={:?}, param_env={:?})", ty, self.param_env,); // Quick check: there are a number of cases that we know do not require // any destructor. let tcx = self.infcx.tcx; if trivial_dropck_outlives(tcx, ty) { - return InferOk { - value: vec![], - obligations: vec![], - }; + return InferOk { value: vec![], obligations: vec![] }; } let mut orig_values = OriginalQueryValues::default(); @@ -50,17 +44,15 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { if result.is_proven() { if let Ok(InferOk { value, obligations }) = self.infcx.instantiate_query_response_and_region_obligations( - self.cause, - self.param_env, - &orig_values, - result) + self.cause, + self.param_env, + &orig_values, + result, + ) { let ty = self.infcx.resolve_vars_if_possible(&ty); let kinds = value.into_kinds_reporting_overflows(tcx, span, ty); - return InferOk { - value: kinds, - obligations, - }; + return InferOk { value: kinds, obligations }; } } } @@ -69,13 +61,9 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { // - unresolved inference variables at the end of typeck // - non well-formed types where projections cannot be resolved // Either of these should have created an error before. - tcx.sess - .delay_span_bug(span, "dtorck encountered internal error"); + tcx.sess.delay_span_bug(span, "dtorck encountered internal error"); - InferOk { - value: vec![], - obligations: vec![], - } + InferOk { value: vec![], obligations: vec![] } } } @@ -131,11 +119,7 @@ pub struct DtorckConstraint<'tcx> { impl<'tcx> DtorckConstraint<'tcx> { pub fn empty() -> DtorckConstraint<'tcx> { - DtorckConstraint { - outlives: vec![], - dtorck_types: vec![], - overflows: vec![], - } + DtorckConstraint { outlives: vec![], dtorck_types: vec![], overflows: vec![] } } } @@ -192,10 +176,9 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { // (T1..Tn) and closures have same properties as T1..Tn -- // check if *any* of those are trivial. ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t.expect_ty())), - ty::Closure(def_id, ref substs) => substs - .as_closure() - .upvar_tys(def_id, tcx) - .all(|t| trivial_dropck_outlives(tcx, t)), + ty::Closure(def_id, ref substs) => { + substs.as_closure().upvar_tys(def_id, tcx).all(|t| trivial_dropck_outlives(tcx, t)) + } ty::Adt(def, _) => { if Some(def.did) == tcx.lang_items().manually_drop() { diff --git a/src/librustc/traits/query/evaluate_obligation.rs b/src/librustc/traits/query/evaluate_obligation.rs index 0d426cab9b751..b9ce3ccff2748 100644 --- a/src/librustc/traits/query/evaluate_obligation.rs +++ b/src/librustc/traits/query/evaluate_obligation.rs @@ -1,16 +1,13 @@ -use crate::infer::InferCtxt; use crate::infer::canonical::OriginalQueryValues; +use crate::infer::InferCtxt; use crate::traits::{ - EvaluationResult, PredicateObligation, SelectionContext, TraitQueryMode, OverflowError, + EvaluationResult, OverflowError, PredicateObligation, SelectionContext, TraitQueryMode, }; impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// Evaluates whether the predicate can be satisfied (by any means) /// in the given `ParamEnv`. - pub fn predicate_may_hold( - &self, - obligation: &PredicateObligation<'tcx>, - ) -> bool { + pub fn predicate_may_hold(&self, obligation: &PredicateObligation<'tcx>) -> bool { self.evaluate_obligation_no_overflow(obligation).may_apply() } @@ -45,8 +42,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { obligation: &PredicateObligation<'tcx>, ) -> Result { let mut _orig_values = OriginalQueryValues::default(); - let c_pred = self.canonicalize_query(&obligation.param_env.and(obligation.predicate), - &mut _orig_values); + let c_pred = self + .canonicalize_query(&obligation.param_env.and(obligation.predicate), &mut _orig_values); // Run canonical query. If overflow occurs, rerun from scratch but this time // in standard trait query mode so that overflow is handled appropriately // within `SelectionContext`. @@ -63,17 +60,15 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { match self.evaluate_obligation(obligation) { Ok(result) => result, Err(OverflowError) => { - let mut selcx = - SelectionContext::with_query_mode(&self, TraitQueryMode::Standard); - selcx.evaluate_root_obligation(obligation) - .unwrap_or_else(|r| { - span_bug!( - obligation.cause.span, - "Overflow should be caught earlier in standard query mode: {:?}, {:?}", - obligation, - r, - ) - }) + let mut selcx = SelectionContext::with_query_mode(&self, TraitQueryMode::Standard); + selcx.evaluate_root_obligation(obligation).unwrap_or_else(|r| { + span_bug!( + obligation.cause.span, + "Overflow should be caught earlier in standard query mode: {:?}, {:?}", + obligation, + r, + ) + }) } } } diff --git a/src/librustc/traits/query/method_autoderef.rs b/src/librustc/traits/query/method_autoderef.rs index be846287e290c..4ef775750ec37 100644 --- a/src/librustc/traits/query/method_autoderef.rs +++ b/src/librustc/traits/query/method_autoderef.rs @@ -1,6 +1,6 @@ -use rustc_data_structures::sync::Lrc; use crate::infer::canonical::{Canonical, QueryResponse}; use crate::ty::Ty; +use rustc_data_structures::sync::Lrc; #[derive(Debug, HashStable)] pub struct CandidateStep<'tcx> { diff --git a/src/librustc/traits/query/mod.rs b/src/librustc/traits/query/mod.rs index 66683cab95960..fb9f46011b99b 100644 --- a/src/librustc/traits/query/mod.rs +++ b/src/librustc/traits/query/mod.rs @@ -22,8 +22,7 @@ pub type CanonicalProjectionGoal<'tcx> = pub type CanonicalTyGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>; -pub type CanonicalPredicateGoal<'tcx> = - Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>; +pub type CanonicalPredicateGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>; pub type CanonicalTypeOpAscribeUserTypeGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ascribe_user_type::AscribeUserType<'tcx>>>; diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 09c7f45c22b0a..8f23f98a2a423 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -38,10 +38,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { self.param_env, ); if !value.has_projections() { - return Ok(Normalized { - value: value.clone(), - obligations: vec![], - }); + return Ok(Normalized { value: value.clone(), obligations: vec![] }); } let mut normalizer = QueryNormalizer { @@ -57,10 +54,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { if normalizer.error { Err(NoSolution) } else { - Ok(Normalized { - value: value1, - obligations: normalizer.obligations, - }) + Ok(Normalized { value: value1, obligations: normalizer.obligations }) } } } @@ -146,8 +140,9 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { let mut orig_values = OriginalQueryValues::default(); // HACK(matthewjasper) `'static` is special-cased in selection, // so we cannot canonicalize it. - let c_data = self.infcx.canonicalize_hr_query_hack( - &self.param_env.and(*data), &mut orig_values); + let c_data = self + .infcx + .canonicalize_hr_query_hack(&self.param_env.and(*data), &mut orig_values); debug!("QueryNormalizer: c_data = {:#?}", c_data); debug!("QueryNormalizer: orig_values = {:#?}", orig_values); match tcx.normalize_projection_ty(c_data) { @@ -162,8 +157,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { self.cause, self.param_env, &orig_values, - &result) - { + &result, + ) { Ok(InferOk { value: result, obligations }) => { debug!("QueryNormalizer: result = {:#?}", result); debug!("QueryNormalizer: obligations = {:#?}", obligations); diff --git a/src/librustc/traits/query/normalize_erasing_regions.rs b/src/librustc/traits/query/normalize_erasing_regions.rs index d09288461d444..2fa52e8810bd9 100644 --- a/src/librustc/traits/query/normalize_erasing_regions.rs +++ b/src/librustc/traits/query/normalize_erasing_regions.rs @@ -7,8 +7,8 @@ //! `normalize_ty_after_erasing_regions` query for each type found //! within. (This underlying query is what is cached.) -use crate::ty::{self, Ty, TyCtxt}; use crate::ty::fold::{TypeFoldable, TypeFolder}; +use crate::ty::{self, Ty, TyCtxt}; impl<'tcx> TyCtxt<'tcx> { /// Erase the regions in `value` and then fully normalize all the diff --git a/src/librustc/traits/query/outlives_bounds.rs b/src/librustc/traits/query/outlives_bounds.rs index d6cd2cce425cb..722bd0bca6a5b 100644 --- a/src/librustc/traits/query/outlives_bounds.rs +++ b/src/librustc/traits/query/outlives_bounds.rs @@ -1,10 +1,10 @@ -use crate::infer::InferCtxt; -use crate::infer::canonical::OriginalQueryValues; use crate::hir; -use syntax::source_map::Span; -use crate::traits::{FulfillmentContext, ObligationCause, TraitEngine, TraitEngineExt}; +use crate::infer::canonical::OriginalQueryValues; +use crate::infer::InferCtxt; use crate::traits::query::NoSolution; +use crate::traits::{FulfillmentContext, ObligationCause, TraitEngine, TraitEngineExt}; use crate::ty::{self, Ty}; +use syntax::source_map::Span; use crate::ich::StableHashingContext; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -82,7 +82,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { Err(NoSolution) => { self.tcx.sess.delay_span_bug( span, - "implied_outlives_bounds failed to solve all obligations" + "implied_outlives_bounds failed to solve all obligations", ); return vec![]; } @@ -90,15 +90,16 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { assert!(result.value.is_proven()); let result = self.instantiate_query_response_and_region_obligations( - &ObligationCause::misc(span, body_id), param_env, &orig_values, &result); + &ObligationCause::misc(span, body_id), + param_env, + &orig_values, + &result, + ); debug!("implied_outlives_bounds for {:?}: {:#?}", ty, result); let result = match result { Ok(v) => v, Err(_) => { - self.tcx.sess.delay_span_bug( - span, - "implied_outlives_bounds failed to instantiate" - ); + self.tcx.sess.delay_span_bug(span, "implied_outlives_bounds failed to instantiate"); return vec![]; } }; @@ -110,7 +111,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { if fulfill_cx.select_all_or_error(self).is_err() { self.tcx.sess.delay_span_bug( span, - "implied_outlives_bounds failed to solve obligations from instantiation" + "implied_outlives_bounds failed to solve obligations from instantiation", ); } @@ -122,20 +123,17 @@ pub fn explicit_outlives_bounds<'tcx>( param_env: ty::ParamEnv<'tcx>, ) -> impl Iterator> + 'tcx { debug!("explicit_outlives_bounds()"); - param_env - .caller_bounds - .into_iter() - .filter_map(move |predicate| match predicate { - ty::Predicate::Projection(..) | - ty::Predicate::Trait(..) | - ty::Predicate::Subtype(..) | - ty::Predicate::WellFormed(..) | - ty::Predicate::ObjectSafe(..) | - ty::Predicate::ClosureKind(..) | - ty::Predicate::TypeOutlives(..) | - ty::Predicate::ConstEvaluatable(..) => None, - ty::Predicate::RegionOutlives(ref data) => data.no_bound_vars().map( - |ty::OutlivesPredicate(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a), - ), - }) + param_env.caller_bounds.into_iter().filter_map(move |predicate| match predicate { + ty::Predicate::Projection(..) + | ty::Predicate::Trait(..) + | ty::Predicate::Subtype(..) + | ty::Predicate::WellFormed(..) + | ty::Predicate::ObjectSafe(..) + | ty::Predicate::ClosureKind(..) + | ty::Predicate::TypeOutlives(..) + | ty::Predicate::ConstEvaluatable(..) => None, + ty::Predicate::RegionOutlives(ref data) => data + .no_bound_vars() + .map(|ty::OutlivesPredicate(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a)), + }) } diff --git a/src/librustc/traits/query/type_op/ascribe_user_type.rs b/src/librustc/traits/query/type_op/ascribe_user_type.rs index ee8b73f86a61a..e183a5a54702d 100644 --- a/src/librustc/traits/query/type_op/ascribe_user_type.rs +++ b/src/librustc/traits/query/type_op/ascribe_user_type.rs @@ -1,8 +1,8 @@ +use crate::hir::def_id::DefId; use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; use crate::traits::query::Fallible; -use crate::hir::def_id::DefId; -use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; use crate::ty::subst::UserSubsts; +use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] pub struct AscribeUserType<'tcx> { @@ -12,12 +12,8 @@ pub struct AscribeUserType<'tcx> { } impl<'tcx> AscribeUserType<'tcx> { - pub fn new( - mir_ty: Ty<'tcx>, - def_id: DefId, - user_substs: UserSubsts<'tcx>, - ) -> Self { - Self { mir_ty, def_id, user_substs } + pub fn new(mir_ty: Ty<'tcx>, def_id: DefId, user_substs: UserSubsts<'tcx>) -> Self { + Self { mir_ty, def_id, user_substs } } } diff --git a/src/librustc/traits/query/type_op/custom.rs b/src/librustc/traits/query/type_op/custom.rs index a2a5f3f950c7a..3ca6636c1dea6 100644 --- a/src/librustc/traits/query/type_op/custom.rs +++ b/src/librustc/traits/query/type_op/custom.rs @@ -1,12 +1,12 @@ use crate::infer::{InferCtxt, InferOk}; -use std::fmt; use crate::traits::query::Fallible; +use std::fmt; use crate::infer::canonical::query_response; use crate::infer::canonical::QueryRegionConstraints; +use crate::traits::{ObligationCause, TraitEngine, TraitEngineExt}; use std::rc::Rc; use syntax::source_map::DUMMY_SP; -use crate::traits::{ObligationCause, TraitEngine, TraitEngineExt}; pub struct CustomTypeOp { closure: F, @@ -19,10 +19,7 @@ impl CustomTypeOp { F: FnOnce(&InferCtxt<'_, 'tcx>) -> Fallible>, G: Fn() -> String, { - CustomTypeOp { - closure, - description, - } + CustomTypeOp { closure, description } } } diff --git a/src/librustc/traits/query/type_op/eq.rs b/src/librustc/traits/query/type_op/eq.rs index 8ea800cced213..267722362c5c7 100644 --- a/src/librustc/traits/query/type_op/eq.rs +++ b/src/librustc/traits/query/type_op/eq.rs @@ -21,11 +21,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> { _tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Eq<'tcx>>, ) -> Option { - if key.value.a == key.value.b { - Some(()) - } else { - None - } + if key.value.a == key.value.b { Some(()) } else { None } } fn perform_query( diff --git a/src/librustc/traits/query/type_op/mod.rs b/src/librustc/traits/query/type_op/mod.rs index 98e535234b630..adf63e4d60c99 100644 --- a/src/librustc/traits/query/type_op/mod.rs +++ b/src/librustc/traits/query/type_op/mod.rs @@ -1,14 +1,13 @@ use crate::infer::canonical::{ - Canonicalized, CanonicalizedQueryResponse, OriginalQueryValues, - QueryRegionConstraints, + Canonicalized, CanonicalizedQueryResponse, OriginalQueryValues, QueryRegionConstraints, }; use crate::infer::{InferCtxt, InferOk}; -use std::fmt; -use std::rc::Rc; use crate::traits::query::Fallible; use crate::traits::ObligationCause; use crate::ty::fold::TypeFoldable; use crate::ty::{ParamEnvAnd, TyCtxt}; +use std::fmt; +use std::rc::Rc; pub mod ascribe_user_type; pub mod custom; @@ -102,9 +101,7 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Sized + TypeFoldable<'tcx> + 'tcx { // fulfill them. We do this via a (recursive) query. for obligation in obligations { let () = ProvePredicate::fully_perform_into( - obligation - .param_env - .and(ProvePredicate::new(obligation.predicate)), + obligation.param_env.and(ProvePredicate::new(obligation.predicate)), infcx, output_query_region_constraints, )?; @@ -129,11 +126,8 @@ where // Promote the final query-region-constraints into a // (optional) ref-counted vector: - let opt_qrc = if region_constraints.is_empty() { - None - } else { - Some(Rc::new(region_constraints)) - }; + let opt_qrc = + if region_constraints.is_empty() { None } else { Some(Rc::new(region_constraints)) }; Ok((r, opt_qrc)) } diff --git a/src/librustc/traits/query/type_op/normalize.rs b/src/librustc/traits/query/type_op/normalize.rs index f905d5a019ec8..8a028eecd5b62 100644 --- a/src/librustc/traits/query/type_op/normalize.rs +++ b/src/librustc/traits/query/type_op/normalize.rs @@ -1,8 +1,8 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; -use std::fmt; use crate::traits::query::Fallible; use crate::ty::fold::TypeFoldable; use crate::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt}; +use std::fmt; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, TypeFoldable, Lift)] pub struct Normalize { @@ -25,11 +25,7 @@ where type QueryResponse = T; fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option { - if !key.value.value.has_projections() { - Some(key.value.value) - } else { - None - } + if !key.value.value.has_projections() { Some(key.value.value) } else { None } } fn perform_query( diff --git a/src/librustc/traits/query/type_op/outlives.rs b/src/librustc/traits/query/type_op/outlives.rs index 83d51b6d3ebf7..35afa63796883 100644 --- a/src/librustc/traits/query/type_op/outlives.rs +++ b/src/librustc/traits/query/type_op/outlives.rs @@ -1,5 +1,5 @@ use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse}; -use crate::traits::query::dropck_outlives::{DropckOutlivesResult, trivial_dropck_outlives}; +use crate::traits::query::dropck_outlives::{trivial_dropck_outlives, DropckOutlivesResult}; use crate::traits::query::Fallible; use crate::ty::{ParamEnvAnd, Ty, TyCtxt}; diff --git a/src/librustc/traits/query/type_op/subtype.rs b/src/librustc/traits/query/type_op/subtype.rs index 76292f9dea085..c70508a20a182 100644 --- a/src/librustc/traits/query/type_op/subtype.rs +++ b/src/librustc/traits/query/type_op/subtype.rs @@ -10,10 +10,7 @@ pub struct Subtype<'tcx> { impl<'tcx> Subtype<'tcx> { pub fn new(sub: Ty<'tcx>, sup: Ty<'tcx>) -> Self { - Self { - sub, - sup, - } + Self { sub, sup } } } @@ -21,11 +18,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> { type QueryResponse = (); fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<()> { - if key.value.sub == key.value.sup { - Some(()) - } else { - None - } + if key.value.sub == key.value.sup { Some(()) } else { None } } fn perform_query( diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index afc8a4d9e1415..f11fcc4ebae4e 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -39,17 +39,17 @@ use crate::ty::subst::{Subst, SubstsRef}; use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; use crate::hir; -use rustc_index::bit_set::GrowableBitSet; +use crate::util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lock; +use rustc_index::bit_set::GrowableBitSet; use rustc_target::spec::abi::Abi; -use syntax::attr; -use syntax::symbol::sym; use std::cell::{Cell, RefCell}; use std::cmp; use std::fmt::{self, Display}; use std::iter; use std::rc::Rc; -use crate::util::nodemap::{FxHashMap, FxHashSet}; +use syntax::attr; +use syntax::symbol::sym; pub struct SelectionContext<'cx, 'tcx> { infcx: &'cx InferCtxt<'cx, 'tcx>, @@ -92,17 +92,9 @@ pub struct SelectionContext<'cx, 'tcx> { #[derive(Clone, Debug)] pub enum IntercrateAmbiguityCause { - DownstreamCrate { - trait_desc: String, - self_desc: Option, - }, - UpstreamCrateUpdate { - trait_desc: String, - self_desc: Option, - }, - ReservationImpl { - message: String - }, + DownstreamCrate { trait_desc: String, self_desc: Option }, + UpstreamCrateUpdate { trait_desc: String, self_desc: Option }, + ReservationImpl { message: String }, } impl IntercrateAmbiguityCause { @@ -114,24 +106,15 @@ impl IntercrateAmbiguityCause { pub fn intercrate_ambiguity_hint(&self) -> String { match self { - &IntercrateAmbiguityCause::DownstreamCrate { - ref trait_desc, - ref self_desc, - } => { + &IntercrateAmbiguityCause::DownstreamCrate { ref trait_desc, ref self_desc } => { let self_desc = if let &Some(ref ty) = self_desc { format!(" for type `{}`", ty) } else { String::new() }; - format!( - "downstream crates may implement trait `{}`{}", - trait_desc, self_desc - ) + format!("downstream crates may implement trait `{}`{}", trait_desc, self_desc) } - &IntercrateAmbiguityCause::UpstreamCrateUpdate { - ref trait_desc, - ref self_desc, - } => { + &IntercrateAmbiguityCause::UpstreamCrateUpdate { ref trait_desc, ref self_desc } => { let self_desc = if let &Some(ref ty) = self_desc { format!(" for type `{}`", ty) } else { @@ -143,11 +126,7 @@ impl IntercrateAmbiguityCause { trait_desc, self_desc ) } - &IntercrateAmbiguityCause::ReservationImpl { - ref message - } => { - message.clone() - } + &IntercrateAmbiguityCause::ReservationImpl { ref message } => message.clone(), } } } @@ -704,10 +683,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut result = EvaluatedToOk; for obligation in predicates { let eval = self.evaluate_predicate_recursively(stack, obligation.clone())?; - debug!( - "evaluate_predicate_recursively({:?}) = {:?}", - obligation, eval - ); + debug!("evaluate_predicate_recursively({:?}) = {:?}", obligation, eval); if let EvaluatedToErr = eval { // fast-path - EvaluatedToErr is the top of the lattice, // so we don't need to look on the other predicates. @@ -724,8 +700,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { previous_stack: TraitObligationStackList<'o, 'tcx>, obligation: PredicateObligation<'tcx>, ) -> Result { - debug!("evaluate_predicate_recursively(previous_stack={:?}, obligation={:?})", - previous_stack.head(), obligation); + debug!( + "evaluate_predicate_recursively(previous_stack={:?}, obligation={:?})", + previous_stack.head(), + obligation + ); // `previous_stack` stores a `TraitObligatiom`, while `obligation` is // a `PredicateObligation`. These are distinct types, so we can't @@ -733,7 +712,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // the same. match previous_stack.head() { Some(h) => self.check_recursion_limit(&obligation, h.obligation)?, - None => self.check_recursion_limit(&obligation, &obligation)? + None => self.check_recursion_limit(&obligation, &obligation)?, } match obligation.predicate { @@ -745,12 +724,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::Predicate::Subtype(ref p) => { // Does this code ever run? - match self.infcx - .subtype_predicate(&obligation.cause, obligation.param_env, p) - { + match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) { Some(Ok(InferOk { mut obligations, .. })) => { self.add_depth(obligations.iter_mut(), obligation.recursion_depth); - self.evaluate_predicates_recursively(previous_stack,obligations.into_iter()) + self.evaluate_predicates_recursively( + previous_stack, + obligations.into_iter(), + ) } Some(Err(_)) => Ok(EvaluatedToErr), None => Ok(EvaluatedToAmbig), @@ -820,10 +800,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::Predicate::ConstEvaluatable(def_id, substs) => { if !(obligation.param_env, substs).has_local_value() { - match self.tcx().const_eval_resolve(obligation.param_env, - def_id, - substs, - None) { + match self.tcx().const_eval_resolve(obligation.param_env, def_id, substs, None) + { Ok(_) => Ok(EvaluatedToOk), Err(_) => Ok(EvaluatedToErr), } @@ -842,20 +820,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result { debug!("evaluate_trait_predicate_recursively({:?})", obligation); - if self.intercrate.is_none() && obligation.is_global() - && obligation - .param_env - .caller_bounds - .iter() - .all(|bound| bound.needs_subst()) + if self.intercrate.is_none() + && obligation.is_global() + && obligation.param_env.caller_bounds.iter().all(|bound| bound.needs_subst()) { // If a param env has no global bounds, global obligations do not // depend on its particular value in order to work, so we can clear // out the param env and get better caching. - debug!( - "evaluate_trait_predicate_recursively({:?}) - in global", - obligation - ); + debug!("evaluate_trait_predicate_recursively({:?}) - in global", obligation); obligation.param_env = obligation.param_env.without_caller_bounds(); } @@ -906,20 +878,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!( "evaluate_trait_predicate_recursively: caching provisionally because {:?} \ is a cycle participant (at depth {}, reached depth {})", - fresh_trait_ref, - stack.depth, - reached_depth, + fresh_trait_ref, stack.depth, reached_depth, ); - stack.cache().insert_provisional( - stack.dfn, - reached_depth, - fresh_trait_ref, - result, - ); + stack.cache().insert_provisional(stack.dfn, reached_depth, fresh_trait_ref, result); } - Ok(result) } @@ -946,16 +910,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, stack: &TraitObligationStack<'_, 'tcx>, ) -> Option { - if let Some(cycle_depth) = stack.iter() + if let Some(cycle_depth) = stack + .iter() .skip(1) // Skip top-most frame. - .find(|prev| stack.obligation.param_env == prev.obligation.param_env && - stack.fresh_trait_ref == prev.fresh_trait_ref) + .find(|prev| { + stack.obligation.param_env == prev.obligation.param_env + && stack.fresh_trait_ref == prev.fresh_trait_ref + }) .map(|stack| stack.depth) { debug!( "evaluate_stack({:?}) --> recursive at depth {}", - stack.fresh_trait_ref, - cycle_depth, + stack.fresh_trait_ref, cycle_depth, ); // If we have a stack like `A B C D E A`, where the top of @@ -974,16 +940,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let cycle = stack.iter().skip(1).take_while(|s| s.depth >= cycle_depth); let cycle = cycle.map(|stack| ty::Predicate::Trait(stack.obligation.predicate)); if self.coinductive_match(cycle) { - debug!( - "evaluate_stack({:?}) --> recursive, coinductive", - stack.fresh_trait_ref - ); + debug!("evaluate_stack({:?}) --> recursive, coinductive", stack.fresh_trait_ref); Some(EvaluatedToOk) } else { - debug!( - "evaluate_stack({:?}) --> recursive, inductive", - stack.fresh_trait_ref - ); + debug!("evaluate_stack({:?}) --> recursive, inductive", stack.fresh_trait_ref); Some(EvaluatedToRecur) } } else { @@ -1019,11 +979,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // This suffices to allow chains like `FnMut` implemented in // terms of `Fn` etc, but we could probably make this more // precise still. - let unbound_input_types = stack - .fresh_trait_ref - .skip_binder() - .input_types() - .any(|ty| ty.is_fresh()); + let unbound_input_types = + stack.fresh_trait_ref.skip_binder().input_types().any(|ty| ty.is_fresh()); // This check was an imperfect workaround for a bug in the old // intercrate mode; it should be removed when that goes away. if unbound_input_types && self.intercrate == Some(IntercrateMode::Issue43355) { @@ -1047,20 +1004,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }, }; debug!("evaluate_stack: pushing cause = {:?}", cause); - self.intercrate_ambiguity_causes - .as_mut() - .unwrap() - .push(cause); + self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause); } } } return Ok(EvaluatedToAmbig); } - if unbound_input_types && stack.iter().skip(1).any(|prev| { - stack.obligation.param_env == prev.obligation.param_env - && self.match_fresh_trait_refs( - &stack.fresh_trait_ref, &prev.fresh_trait_ref, prev.obligation.param_env) - }) { + if unbound_input_types + && stack.iter().skip(1).any(|prev| { + stack.obligation.param_env == prev.obligation.param_env + && self.match_fresh_trait_refs( + &stack.fresh_trait_ref, + &prev.fresh_trait_ref, + prev.obligation.param_env, + ) + }) + { debug!( "evaluate_stack({:?}) --> unbound argument, recursive --> giving up", stack.fresh_trait_ref @@ -1118,7 +1077,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match this.confirm_candidate(stack.obligation, candidate) { Ok(selection) => this.evaluate_predicates_recursively( stack.list(), - selection.nested_obligations().into_iter() + selection.nested_obligations().into_iter(), ), Err(..) => Ok(EvaluatedToErr), } @@ -1182,10 +1141,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - debug!( - "insert_evaluation_cache(trait_ref={:?}, candidate={:?})", - trait_ref, result, - ); + debug!("insert_evaluation_cache(trait_ref={:?}, candidate={:?})", trait_ref, result,); self.infcx .evaluation_cache .hashmap @@ -1204,8 +1160,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// /// To ensure that obligation_depth never decreasees, we force all subobligations /// to have at least the depth of the original obligation. - fn add_depth>>(&self, it: I, - min_depth: usize) { + fn add_depth>>( + &self, + it: I, + min_depth: usize, + ) { it.for_each(|o| o.recursion_depth = cmp::max(min_depth, o.recursion_depth) + 1); } @@ -1216,8 +1175,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn check_recursion_limit, V: Display + TypeFoldable<'tcx>>( &self, obligation: &Obligation<'tcx, T>, - error_obligation: &Obligation<'tcx, V> - ) -> Result<(), OverflowError> { + error_obligation: &Obligation<'tcx, V>, + ) -> Result<(), OverflowError> { let recursion_limit = *self.infcx.tcx.sess.recursion_limit.get(); if obligation.recursion_depth >= recursion_limit { match self.query_mode { @@ -1277,10 +1236,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let (candidate, dep_node) = self.in_task(|this| this.candidate_from_obligation_no_cache(stack)); - debug!( - "CACHE MISS: SELECT({:?})={:?}", - cache_fresh_trait_pred, candidate - ); + debug!("CACHE MISS: SELECT({:?})={:?}", cache_fresh_trait_pred, candidate); self.insert_candidate_cache( stack.obligation.param_env, cache_fresh_trait_pred, @@ -1294,9 +1250,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { where OP: FnOnce(&mut Self) -> R, { - let (result, dep_node) = self.tcx() - .dep_graph - .with_anon_task(DepKind::TraitSelect, || op(self)); + let (result, dep_node) = + self.tcx().dep_graph.with_anon_task(DepKind::TraitSelect, || op(self)); self.tcx().dep_graph.read_index(dep_node); (result, dep_node) } @@ -1313,19 +1268,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return Err(Unimplemented); } ty::ImplPolarity::Reservation => { - if let Some(intercrate_ambiguity_clauses) - = &mut self.intercrate_ambiguity_causes + if let Some(intercrate_ambiguity_clauses) = + &mut self.intercrate_ambiguity_causes { let attrs = tcx.get_attrs(def_id); let attr = attr::find_by_name(&attrs, sym::rustc_reservation_impl); let value = attr.and_then(|a| a.value_str()); if let Some(value) = value { - debug!("filter_negative_and_reservation_impls: \ - reservation impl ambiguity on {:?}", def_id); + debug!( + "filter_negative_and_reservation_impls: \ + reservation impl ambiguity on {:?}", + def_id + ); intercrate_ambiguity_clauses.push( IntercrateAmbiguityCause::ReservationImpl { - message: value.to_string() - } + message: value.to_string(), + }, ); } } @@ -1360,10 +1318,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if let Ok(candidate_set) = self.assemble_candidates(stack) { let mut no_candidates_apply = true; { - let evaluated_candidates = candidate_set - .vec - .iter() - .map(|c| self.evaluate_candidate(stack, &c)); + let evaluated_candidates = + candidate_set.vec.iter().map(|c| self.evaluate_candidate(stack, &c)); for ec in evaluated_candidates { match ec { @@ -1388,21 +1344,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { None }; let cause = if let Conflict::Upstream = conflict { - IntercrateAmbiguityCause::UpstreamCrateUpdate { - trait_desc, - self_desc, - } + IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc } } else { - IntercrateAmbiguityCause::DownstreamCrate { - trait_desc, - self_desc, - } + IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc } }; debug!("evaluate_stack: pushing cause = {:?}", cause); - self.intercrate_ambiguity_causes - .as_mut() - .unwrap() - .push(cause); + self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause); } } } @@ -1418,12 +1365,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut candidates = candidate_set.vec; - debug!( - "assembled {} candidates for {:?}: {:?}", - candidates.len(), - stack, - candidates - ); + debug!("assembled {} candidates for {:?}: {:?}", candidates.len(), stack, candidates); // At this point, we know that each of the entries in the // candidate set is *individually* applicable. Now we have to @@ -1457,22 +1399,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut candidates = candidates .into_iter() .map(|c| match self.evaluate_candidate(stack, &c) { - Ok(eval) if eval.may_apply() => Ok(Some(EvaluatedCandidate { - candidate: c, - evaluation: eval, - })), + Ok(eval) if eval.may_apply() => { + Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval })) + } Ok(_) => Ok(None), Err(OverflowError) => Err(Overflow), }) .flat_map(Result::transpose) .collect::, _>>()?; - debug!( - "winnowed to {} candidates for {:?}: {:?}", - candidates.len(), - stack, - candidates - ); + debug!("winnowed to {} candidates for {:?}: {:?}", candidates.len(), stack, candidates); // If there are STILL multiple candidates, we can further // reduce the list by dropping duplicates -- including @@ -1484,20 +1420,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.candidate_should_be_dropped_in_favor_of(&candidates[i], &candidates[j]) }); if is_dup { - debug!( - "Dropping candidate #{}/{}: {:?}", - i, - candidates.len(), - candidates[i] - ); + debug!("Dropping candidate #{}/{}: {:?}", i, candidates.len(), candidates[i]); candidates.swap_remove(i); } else { - debug!( - "Retaining candidate #{}/{}: {:?}", - i, - candidates.len(), - candidates[i] - ); + debug!("Retaining candidate #{}/{}: {:?}", i, candidates.len(), candidates[i]); i += 1; // If there are *STILL* multiple candidates, give up @@ -1535,8 +1461,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } let obligation = &stack.obligation; - let predicate = self.infcx() - .resolve_vars_if_possible(&obligation.predicate); + let predicate = self.infcx().resolve_vars_if_possible(&obligation.predicate); // Okay to skip binder because of the nature of the // trait-ref-is-knowable check, which does not care about @@ -1545,9 +1470,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let result = coherence::trait_ref_is_knowable(self.tcx(), trait_ref); if let ( - Some(Conflict::Downstream { - used_to_be_broken: true, - }), + Some(Conflict::Downstream { used_to_be_broken: true }), Some(IntercrateMode::Issue43355), ) = (result, self.intercrate) { @@ -1621,14 +1544,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Because of this, we always want to re-run the full selection /// process for our obligation the next time we see it, since /// we might end up picking a different `SelectionCandidate` (or none at all). - fn can_cache_candidate(&self, - result: &SelectionResult<'tcx, SelectionCandidate<'tcx>> - ) -> bool { + fn can_cache_candidate( + &self, + result: &SelectionResult<'tcx, SelectionCandidate<'tcx>>, + ) -> bool { match result { Ok(Some(SelectionCandidate::ParamCandidate(trait_ref))) => { !trait_ref.skip_binder().input_types().any(|t| t.walk().any(|t_| t_.is_ty_infer())) - }, - _ => true + } + _ => true, } } @@ -1643,10 +1567,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let trait_ref = cache_fresh_trait_pred.skip_binder().trait_ref; if !self.can_cache_candidate(&candidate) { - debug!("insert_candidate_cache(trait_ref={:?}, candidate={:?} -\ - candidate is not cacheable", trait_ref, candidate); + debug!( + "insert_candidate_cache(trait_ref={:?}, candidate={:?} -\ + candidate is not cacheable", + trait_ref, candidate + ); return; - } if self.can_use_global_caches(param_env) { @@ -1688,8 +1614,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { param_env: obligation.param_env, cause: obligation.cause.clone(), recursion_depth: obligation.recursion_depth, - predicate: self.infcx() - .resolve_vars_if_possible(&obligation.predicate), + predicate: self.infcx().resolve_vars_if_possible(&obligation.predicate), }; if obligation.predicate.skip_binder().self_ty().is_ty_var() { @@ -1702,16 +1627,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Take the fast path out - this also improves // performance by preventing assemble_candidates_from_impls from // matching every impl for this trait. - return Ok(SelectionCandidateSet { - vec: vec![], - ambiguous: true, - }); + return Ok(SelectionCandidateSet { vec: vec![], ambiguous: true }); } - let mut candidates = SelectionCandidateSet { - vec: Vec::new(), - ambiguous: false, - }; + let mut candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false }; self.assemble_candidates_for_trait_alias(obligation, &mut candidates)?; @@ -1721,10 +1640,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let lang_items = self.tcx().lang_items(); if lang_items.copy_trait() == Some(def_id) { - debug!( - "obligation self ty is {:?}", - obligation.predicate.skip_binder().self_ty() - ); + debug!("obligation self ty is {:?}", obligation.predicate.skip_binder().self_ty()); // User-defined copy impls are permitted, but only for // structs and enums. @@ -1788,10 +1704,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } let result = self.infcx.probe(|snapshot| { - self.match_projection_obligation_against_definition_bounds( - obligation, - snapshot, - ) + self.match_projection_obligation_against_definition_bounds(obligation, snapshot) }); if result { @@ -1804,10 +1717,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, snapshot: &CombinedSnapshot<'_, 'tcx>, ) -> bool { - let poly_trait_predicate = self.infcx() - .resolve_vars_if_possible(&obligation.predicate); - let (placeholder_trait_predicate, placeholder_map) = self.infcx() - .replace_bound_vars_with_placeholders(&poly_trait_predicate); + let poly_trait_predicate = self.infcx().resolve_vars_if_possible(&obligation.predicate); + let (placeholder_trait_predicate, placeholder_map) = + self.infcx().replace_bound_vars_with_placeholders(&poly_trait_predicate); debug!( "match_projection_obligation_against_definition_bounds: \ placeholder_trait_predicate={:?}", @@ -1841,19 +1753,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); let elaborated_predicates = util::elaborate_predicates(self.tcx(), bounds.predicates); - let matching_bound = elaborated_predicates - .filter_to_traits() - .find(|bound| { - self.infcx.probe(|_| { - self.match_projection( - obligation, - bound.clone(), - placeholder_trait_predicate.trait_ref.clone(), - &placeholder_map, - snapshot, - ) - }) - }); + let matching_bound = elaborated_predicates.filter_to_traits().find(|bound| { + self.infcx.probe(|_| { + self.match_projection( + obligation, + bound.clone(), + placeholder_trait_predicate.trait_ref.clone(), + &placeholder_map, + snapshot, + ) + }) + }); debug!( "match_projection_obligation_against_definition_bounds: \ @@ -1891,8 +1801,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .at(&obligation.cause, obligation.param_env) .sup(ty::Binder::dummy(placeholder_trait_ref), trait_bound) .is_ok() - && - self.infcx.leak_check(false, placeholder_map, snapshot).is_ok() + && self.infcx.leak_check(false, placeholder_map, snapshot).is_ok() } /// Given an obligation like ``, searches the obligations that the caller @@ -1904,10 +1813,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { stack: &TraitObligationStack<'o, 'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) -> Result<(), SelectionError<'tcx>> { - debug!( - "assemble_candidates_from_caller_bounds({:?})", - stack.obligation - ); + debug!("assemble_candidates_from_caller_bounds({:?})", stack.obligation); let all_bounds = stack .obligation @@ -1992,10 +1898,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) -> Result<(), SelectionError<'tcx>> { - let kind = match self.tcx() - .lang_items() - .fn_trait_kind(obligation.predicate.def_id()) - { + let kind = match self.tcx().lang_items().fn_trait_kind(obligation.predicate.def_id()) { Some(k) => k, None => { return Ok(()); @@ -2007,19 +1910,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // type/region parameters match obligation.self_ty().skip_binder().kind { ty::Closure(closure_def_id, closure_substs) => { - debug!( - "assemble_unboxed_candidates: kind={:?} obligation={:?}", - kind, obligation - ); - match self.infcx.closure_kind( - closure_def_id, - closure_substs - ) { + debug!("assemble_unboxed_candidates: kind={:?} obligation={:?}", kind, obligation); + match self.infcx.closure_kind(closure_def_id, closure_substs) { Some(closure_kind) => { - debug!( - "assemble_unboxed_candidates: closure_kind = {:?}", - closure_kind - ); + debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind); if closure_kind.extends(kind) { candidates.vec.push(ClosureCandidate); } @@ -2047,11 +1941,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates: &mut SelectionCandidateSet<'tcx>, ) -> Result<(), SelectionError<'tcx>> { // We provide impl of all fn traits for fn pointers. - if self.tcx() - .lang_items() - .fn_trait_kind(obligation.predicate.def_id()) - .is_none() - { + if self.tcx().lang_items().fn_trait_kind(obligation.predicate.def_id()).is_none() { return Ok(()); } @@ -2086,18 +1976,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) -> Result<(), SelectionError<'tcx>> { - debug!( - "assemble_candidates_from_impls(obligation={:?})", - obligation - ); + debug!("assemble_candidates_from_impls(obligation={:?})", obligation); self.tcx().for_each_relevant_impl( obligation.predicate.def_id(), obligation.predicate.skip_binder().trait_ref.self_ty(), |impl_def_id| { self.infcx.probe(|snapshot| { - if let Ok(_substs) = self.match_impl(impl_def_id, obligation, snapshot) - { + if let Ok(_substs) = self.match_impl(impl_def_id, obligation, snapshot) { candidates.vec.push(ImplCandidate(impl_def_id)); } }); @@ -2162,9 +2048,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { hir::Movability::Movable => { // Movable generators are always `Unpin`, so add an // unconditional builtin candidate. - candidates.vec.push(BuiltinCandidate { - has_nested: false, - }); + candidates.vec.push(BuiltinCandidate { has_nested: false }); } } } @@ -2194,9 +2078,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let self_ty = self.tcx().erase_late_bound_regions(&obligation.self_ty()); let poly_trait_ref = match self_ty.kind { ty::Dynamic(ref data, ..) => { - if data.auto_traits() - .any(|did| did == obligation.predicate.def_id()) - { + if data.auto_traits().any(|did| did == obligation.predicate.def_id()) { debug!( "assemble_candidates_from_object_ty: matched builtin bound, \ pushing candidate" @@ -2226,10 +2108,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { _ => return, }; - debug!( - "assemble_candidates_from_object_ty: poly_trait_ref={:?}", - poly_trait_ref - ); + debug!("assemble_candidates_from_object_ty: poly_trait_ref={:?}", poly_trait_ref); // Count only those upcast versions that match the trait-ref // we are looking for. Specifically, do not only check for the @@ -2240,8 +2119,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .filter(|upcast_trait_ref| { self.infcx.probe(|_| { let upcast_trait_ref = upcast_trait_ref.clone(); - self.match_poly_trait_ref(obligation, upcast_trait_ref) - .is_ok() + self.match_poly_trait_ref(obligation, upcast_trait_ref).is_ok() }) }) .count(); @@ -2282,17 +2160,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return; } }; - let target = obligation - .predicate - .skip_binder() - .trait_ref - .substs - .type_at(1); + let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1); - debug!( - "assemble_candidates_for_unsizing(source={:?}, target={:?})", - source, target - ); + debug!("assemble_candidates_for_unsizing(source={:?}, target={:?})", source, target); let may_apply = match (&source.kind, &target.kind) { // Trait+Kx+'a -> Trait+Ky+'b (upcasts). @@ -2309,9 +2179,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // We always upcast when we can because of reason // #2 (region bounds). data_a.principal_def_id() == data_b.principal_def_id() - && data_b.auto_traits() - // All of a's auto traits need to be in b's auto traits. - .all(|b| data_a.auto_traits().any(|a| a == b)) + && data_b + .auto_traits() + // All of a's auto traits need to be in b's auto traits. + .all(|b| data_a.auto_traits().any(|a| a == b)) } // `T` -> `Trait` @@ -2462,8 +2333,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplCandidate(victim_def) => { let tcx = self.tcx(); return tcx.specializes((other_def, victim_def)) - || tcx.impls_are_allowed_to_overlap( - other_def, victim_def).is_some(); + || tcx + .impls_are_allowed_to_overlap(other_def, victim_def) + .is_some(); } ParamCandidate(ref cand) => { // Prefer the impl to a global where clause candidate. @@ -2508,9 +2380,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match conditions { BuiltinImplConditions::Where(nested) => { debug!("builtin_bound: nested={:?}", nested); - candidates.vec.push(BuiltinCandidate { - has_nested: nested.skip_binder().len() > 0, - }); + candidates + .vec + .push(BuiltinCandidate { has_nested: nested.skip_binder().len() > 0 }); } BuiltinImplConditions::None => {} BuiltinImplConditions::Ambiguous => { @@ -2529,8 +2401,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { use self::BuiltinImplConditions::{Ambiguous, None, Where}; // NOTE: binder moved to (*) - let self_ty = self.infcx - .shallow_resolve(obligation.predicate.skip_binder().self_ty()); + let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty()); match self_ty.kind { ty::Infer(ty::IntVar(_)) @@ -2564,10 +2435,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let sized_crit = def.sized_constraint(self.tcx()); // (*) binder moved here Where(ty::Binder::bind( - sized_crit - .iter() - .map(|ty| ty.subst(self.tcx(), substs)) - .collect(), + sized_crit.iter().map(|ty| ty.subst(self.tcx(), substs)).collect(), )) } @@ -2580,10 +2448,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshFloatTy(_)) => { - bug!( - "asked to assemble builtin bounds of unexpected type: {:?}", - self_ty - ); + bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); } } } @@ -2593,8 +2458,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, ) -> BuiltinImplConditions<'tcx> { // NOTE: binder moved to (*) - let self_ty = self.infcx - .shallow_resolve(obligation.predicate.skip_binder().self_ty()); + let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty()); use self::BuiltinImplConditions::{Ambiguous, None, Where}; @@ -2637,9 +2501,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::Closure(def_id, substs) => { // (*) binder moved here - Where(ty::Binder::bind( - substs.as_closure().upvar_tys(def_id, self.tcx()).collect(), - )) + Where(ty::Binder::bind(substs.as_closure().upvar_tys(def_id, self.tcx()).collect())) } ty::Adt(..) | ty::Projection(..) | ty::Param(..) | ty::Opaque(..) => { @@ -2660,10 +2522,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshFloatTy(_)) => { - bug!( - "asked to assemble builtin bounds of unexpected type: {:?}", - self_ty - ); + bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); } } } @@ -2705,10 +2564,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Infer(ty::FreshTy(_)) | ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshFloatTy(_)) => { - bug!( - "asked to assemble constituent types of unexpected type: {:?}", - t - ); + bug!("asked to assemble constituent types of unexpected type: {:?}", t); } ty::RawPtr(ty::TypeAndMut { ty: element_ty, .. }) | ty::Ref(_, element_ty, _) => { @@ -2722,9 +2578,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { tys.iter().map(|k| k.expect_ty()).collect() } - ty::Closure(def_id, ref substs) => substs.as_closure() - .upvar_tys(def_id, self.tcx()) - .collect(), + ty::Closure(def_id, ref substs) => { + substs.as_closure().upvar_tys(def_id, self.tcx()).collect() + } ty::Generator(def_id, ref substs, _) => { let witness = substs.as_generator().witness(def_id, self.tcx()); @@ -2786,18 +2642,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let ty: ty::Binder> = ty::Binder::bind(ty); // <----/ self.infcx.commit_unconditionally(|_| { - let (skol_ty, _) = self.infcx - .replace_bound_vars_with_placeholders(&ty); - let Normalized { - value: normalized_ty, - mut obligations, - } = project::normalize_with_depth( - self, - param_env, - cause.clone(), - recursion_depth, - &skol_ty, - ); + let (skol_ty, _) = self.infcx.replace_bound_vars_with_placeholders(&ty); + let Normalized { value: normalized_ty, mut obligations } = + project::normalize_with_depth( + self, + param_env, + cause.clone(), + recursion_depth, + &skol_ty, + ); let skol_obligation = self.tcx().predicate_for_trait_def( param_env, cause.clone(), @@ -2841,10 +2694,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Ok(VtableParam(obligations)) } - ImplCandidate(impl_def_id) => Ok(VtableImpl(self.confirm_impl_candidate( - obligation, - impl_def_id, - ))), + ImplCandidate(impl_def_id) => { + Ok(VtableImpl(self.confirm_impl_candidate(obligation, impl_def_id))) + } AutoImplCandidate(trait_def_id) => { let data = self.confirm_auto_impl_candidate(obligation, trait_def_id); @@ -2898,10 +2750,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_projection_candidate(&mut self, obligation: &TraitObligation<'tcx>) { self.infcx.commit_unconditionally(|snapshot| { let result = - self.match_projection_obligation_against_definition_bounds( - obligation, - snapshot, - ); + self.match_projection_obligation_against_definition_bounds(obligation, snapshot); assert!(result); }) } @@ -2934,10 +2783,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, has_nested: bool, ) -> VtableBuiltinData> { - debug!( - "confirm_builtin_candidate({:?}, {:?})", - obligation, has_nested - ); + debug!("confirm_builtin_candidate({:?}, {:?})", obligation, has_nested); let lang_items = self.tcx().lang_items(); let obligations = if has_nested { @@ -2953,10 +2799,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }; let nested = match conditions { BuiltinImplConditions::Where(nested) => nested, - _ => bug!( - "obligation {:?} had matched a builtin impl but now doesn't", - obligation - ), + _ => bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation), }; let cause = obligation.derived_cause(BuiltinDerivedObligation); @@ -2973,9 +2816,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!("confirm_builtin_candidate: obligations={:?}", obligations); - VtableBuiltinData { - nested: obligations, - } + VtableBuiltinData { nested: obligations } } /// This handles the case where a `auto trait Foo` impl is being used. @@ -2988,10 +2829,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, trait_def_id: DefId, ) -> VtableAutoImplData> { - debug!( - "confirm_auto_impl_candidate({:?}, {:?})", - obligation, trait_def_id - ); + debug!("confirm_auto_impl_candidate({:?}, {:?})", obligation, trait_def_id); let types = obligation.predicate.map_bound(|inner| { let self_ty = self.infcx.shallow_resolve(inner.self_ty()); @@ -3021,8 +2859,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let trait_obligations: Vec> = self.infcx.commit_unconditionally(|_| { let poly_trait_ref = obligation.predicate.to_poly_trait_ref(); - let (trait_ref, _) = self.infcx - .replace_bound_vars_with_placeholders(&poly_trait_ref); + let (trait_ref, _) = + self.infcx.replace_bound_vars_with_placeholders(&poly_trait_ref); let cause = obligation.derived_cause(ImplDerivedObligation); self.impl_or_trait_obligations( cause, @@ -3039,10 +2877,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!("vtable_auto_impl: obligations={:?}", obligations); - VtableAutoImplData { - trait_def_id, - nested: obligations, - } + VtableAutoImplData { trait_def_id, nested: obligations } } fn confirm_impl_candidate( @@ -3101,11 +2936,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // e.g., `impl> Foo<::T> for V` impl_obligations.append(&mut substs.obligations); - VtableImplData { - impl_def_id, - substs: substs.value, - nested: impl_obligations, - } + VtableImplData { impl_def_id, substs: substs.value, nested: impl_obligations } } fn confirm_object_candidate( @@ -3118,13 +2949,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // probably flatten the binder from the obligation and the binder // from the object. Have to try to make a broken test case that // results. - let self_ty = self.infcx - .shallow_resolve(*obligation.self_ty().skip_binder()); + let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder()); let poly_trait_ref = match self_ty.kind { - ty::Dynamic(ref data, ..) => - data.principal().unwrap_or_else(|| { + ty::Dynamic(ref data, ..) => data + .principal() + .unwrap_or_else(|| { span_bug!(obligation.cause.span, "object candidate with no principal") - }).with_self_ty(self.tcx(), self_ty), + }) + .with_self_ty(self.tcx(), self_ty), _ => span_bug!(obligation.cause.span, "object candidate with non-object"), }; @@ -3141,16 +2973,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // where we can unify, because otherwise select would have // reported an ambiguity. (When we do find a match, also // record it for later.) - let nonmatching = util::supertraits(tcx, poly_trait_ref).take_while( - |&t| match self.infcx.commit_if_ok(|_| self.match_poly_trait_ref(obligation, t)) { + let nonmatching = util::supertraits(tcx, poly_trait_ref).take_while(|&t| { + match self.infcx.commit_if_ok(|_| self.match_poly_trait_ref(obligation, t)) { Ok(obligations) => { upcast_trait_ref = Some(t); nested.extend(obligations); false } Err(_) => true, - }, - ); + } + }); // Additionally, for each of the non-matching predicates that // we pass over, we sum up the set of number of vtable @@ -3159,11 +2991,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { vtable_base = nonmatching.map(|t| tcx.count_own_vtable_entries(t)).sum(); } - VtableObjectData { - upcast_trait_ref: upcast_trait_ref.unwrap(), - vtable_base, - nested, - } + VtableObjectData { upcast_trait_ref: upcast_trait_ref.unwrap(), vtable_base, nested } } fn confirm_fn_pointer_candidate( @@ -3173,10 +3001,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!("confirm_fn_pointer_candidate({:?})", obligation); // Okay to skip binder; it is reintroduced below. - let self_ty = self.infcx - .shallow_resolve(*obligation.self_ty().skip_binder()); + let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder()); let sig = self_ty.fn_sig(self.tcx()); - let trait_ref = self.tcx() + let trait_ref = self + .tcx() .closure_trait_ref_and_return_type( obligation.predicate.def_id(), self_ty, @@ -3185,10 +3013,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) .map_bound(|(trait_ref, _)| trait_ref); - let Normalized { - value: trait_ref, - obligations, - } = project::normalize_with_depth( + let Normalized { value: trait_ref, obligations } = project::normalize_with_depth( self, obligation.param_env, obligation.cause.clone(), @@ -3202,10 +3027,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.predicate.to_poly_trait_ref(), trait_ref, )?; - Ok(VtableFnPointerData { - fn_ty: self_ty, - nested: obligations, - }) + Ok(VtableFnPointerData { fn_ty: self_ty, nested: obligations }) } fn confirm_trait_alias_candidate( @@ -3213,14 +3035,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, alias_def_id: DefId, ) -> VtableTraitAliasData<'tcx, PredicateObligation<'tcx>> { - debug!( - "confirm_trait_alias_candidate({:?}, {:?})", - obligation, alias_def_id - ); + debug!("confirm_trait_alias_candidate({:?}, {:?})", obligation, alias_def_id); self.infcx.commit_unconditionally(|_| { - let (predicate, _) = self.infcx() - .replace_bound_vars_with_placeholders(&obligation.predicate); + let (predicate, _) = + self.infcx().replace_bound_vars_with_placeholders(&obligation.predicate); let trait_ref = predicate.trait_ref; let trait_def_id = trait_ref.def_id; let substs = trait_ref.substs; @@ -3238,11 +3057,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { trait_def_id, trait_obligations ); - VtableTraitAliasData { - alias_def_id, - substs: substs, - nested: trait_obligations, - } + VtableTraitAliasData { alias_def_id, substs: substs, nested: trait_obligations } }) } @@ -3259,16 +3074,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { _ => bug!("closure candidate for non-closure {:?}", obligation), }; - debug!( - "confirm_generator_candidate({:?},{:?},{:?})", - obligation, generator_def_id, substs - ); + debug!("confirm_generator_candidate({:?},{:?},{:?})", obligation, generator_def_id, substs); let trait_ref = self.generator_trait_ref_unnormalized(obligation, generator_def_id, substs); - let Normalized { - value: trait_ref, - mut obligations, - } = normalize_with_depth( + let Normalized { value: trait_ref, mut obligations } = normalize_with_depth( self, obligation.param_env, obligation.cause.clone(), @@ -3289,11 +3098,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { trait_ref, )?); - Ok(VtableGeneratorData { - generator_def_id, - substs, - nested: obligations, - }) + Ok(VtableGeneratorData { generator_def_id, substs, nested: obligations }) } fn confirm_closure_candidate( @@ -3302,7 +3107,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result>, SelectionError<'tcx>> { debug!("confirm_closure_candidate({:?})", obligation); - let kind = self.tcx() + let kind = self + .tcx() .lang_items() .fn_trait_kind(obligation.predicate.def_id()) .unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}", obligation)); @@ -3317,10 +3123,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }; let trait_ref = self.closure_trait_ref_unnormalized(obligation, closure_def_id, substs); - let Normalized { - value: trait_ref, - mut obligations, - } = normalize_with_depth( + let Normalized { value: trait_ref, mut obligations } = normalize_with_depth( self, obligation.param_env, obligation.cause.clone(), @@ -3346,19 +3149,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligations.push(Obligation::new( obligation.cause.clone(), obligation.param_env, - ty::Predicate::ClosureKind( - closure_def_id, - substs, - kind - ), + ty::Predicate::ClosureKind(closure_def_id, substs, kind), )); } - Ok(VtableClosureData { - closure_def_id, - substs: substs, - nested: obligations, - }) + Ok(VtableClosureData { closure_def_id, substs: substs, nested: obligations }) } /// In the case of closure types and fn pointers, @@ -3409,20 +3204,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // `assemble_candidates_for_unsizing` should ensure there are no late-bound // regions here. See the comment there for more details. - let source = self.infcx - .shallow_resolve(obligation.self_ty().no_bound_vars().unwrap()); - let target = obligation - .predicate - .skip_binder() - .trait_ref - .substs - .type_at(1); + let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap()); + let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1); let target = self.infcx.shallow_resolve(target); - debug!( - "confirm_builtin_unsize_candidate(source={:?}, target={:?})", - source, target - ); + debug!("confirm_builtin_unsize_candidate(source={:?}, target={:?})", source, target); let mut nested = vec![]; match (&source.kind, &target.kind) { @@ -3430,18 +3216,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => { // See `assemble_candidates_for_unsizing` for more info. let existential_predicates = data_a.map_bound(|data_a| { - let iter = - data_a.principal().map(|x| ty::ExistentialPredicate::Trait(x)) - .into_iter().chain( - data_a - .projection_bounds() - .map(|x| ty::ExistentialPredicate::Projection(x)), - ) - .chain( - data_b - .auto_traits() - .map(ty::ExistentialPredicate::AutoTrait), - ); + let iter = data_a + .principal() + .map(|x| ty::ExistentialPredicate::Trait(x)) + .into_iter() + .chain( + data_a + .projection_bounds() + .map(|x| ty::ExistentialPredicate::Projection(x)), + ) + .chain(data_b.auto_traits().map(ty::ExistentialPredicate::AutoTrait)); tcx.mk_existential_predicates(iter) }); let source_trait = tcx.mk_dynamic(existential_predicates, r_b); @@ -3462,7 +3246,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // because I want to continue rejecting that test (as we have // done for quite some time) before we are firmly comfortable // with what our behavior should be there. -nikomatsakis - let InferOk { obligations, .. } = self.infcx + let InferOk { obligations, .. } = self + .infcx .at(&obligation.cause, obligation.param_env) .eq(target, source_trait) // FIXME -- see below .map_err(|_| Unimplemented)?; @@ -3485,8 +3270,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // `T` -> `Trait` (_, &ty::Dynamic(ref data, r)) => { - let mut object_dids = data.auto_traits() - .chain(data.principal_def_id()); + let mut object_dids = data.auto_traits().chain(data.principal_def_id()); if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) { return Err(TraitNotObjectSafe(did)); } @@ -3513,10 +3297,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // the `Send` check.) // - Projection predicates nested.extend( - data.iter() - .map(|predicate| - predicate_to_obligation(predicate.with_self_ty(tcx, source)) - ), + data.iter().map(|predicate| { + predicate_to_obligation(predicate.with_self_ty(tcx, source)) + }), ); // We can only make objects from sized types. @@ -3529,14 +3312,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // If the type is `Foo + 'a`, ensure that the type // being cast to `Foo + 'a` outlives `'a`: let outlives = ty::OutlivesPredicate(source, r); - nested.push(predicate_to_obligation( - ty::Binder::dummy(outlives).to_predicate(), - )); + nested.push(predicate_to_obligation(ty::Binder::dummy(outlives).to_predicate())); } // `[T; n]` -> `[T]` (&ty::Array(a, _), &ty::Slice(b)) => { - let InferOk { obligations, .. } = self.infcx + let InferOk { obligations, .. } = self + .infcx .at(&obligation.cause, obligation.param_env) .eq(b, a) .map_err(|_| Unimplemented)?; @@ -3545,9 +3327,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // `Struct` -> `Struct` (&ty::Adt(def, substs_a), &ty::Adt(_, substs_b)) => { - let fields = def.all_fields() - .map(|field| tcx.type_of(field.did)) - .collect::>(); + let fields = + def.all_fields().map(|field| tcx.type_of(field.did)).collect::>(); // The last field of the structure has to exist and contain type parameters. let field = if let Some(&field) = fields.last() { @@ -3571,13 +3352,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Error and ensure they do not affect any other fields. // This could be checked after type collection for any struct // with a potentially unsized trailing field. - let params = substs_a.iter().enumerate().map(|(i, &k)| { - if ty_params.contains(i) { - tcx.types.err.into() - } else { - k - } - }); + let params = substs_a + .iter() + .enumerate() + .map(|(i, &k)| if ty_params.contains(i) { tcx.types.err.into() } else { k }); let substs = tcx.mk_substs(params); for &ty in fields.split_last().unwrap().1 { if ty.subst(tcx, substs).references_error() { @@ -3592,14 +3370,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Check that the source struct with the target's // unsized parameters is equal to the target. let params = substs_a.iter().enumerate().map(|(i, &k)| { - if ty_params.contains(i) { - substs_b.type_at(i).into() - } else { - k - } + if ty_params.contains(i) { substs_b.type_at(i).into() } else { k } }); let new_struct = tcx.mk_adt(def, tcx.mk_substs(params)); - let InferOk { obligations, .. } = self.infcx + let InferOk { obligations, .. } = self + .infcx .at(&obligation.cause, obligation.param_env) .eq(target, new_struct) .map_err(|_| Unimplemented)?; @@ -3633,7 +3408,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let new_tuple = tcx.mk_tup( a_mid.iter().map(|k| k.expect_ty()).chain(iter::once(b_last.expect_ty())), ); - let InferOk { obligations, .. } = self.infcx + let InferOk { obligations, .. } = self + .infcx .at(&obligation.cause, obligation.param_env) .eq(target, new_tuple) .map_err(|_| Unimplemented)?; @@ -3699,25 +3475,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return Err(()); } - let (skol_obligation, placeholder_map) = self.infcx() - .replace_bound_vars_with_placeholders(&obligation.predicate); + let (skol_obligation, placeholder_map) = + self.infcx().replace_bound_vars_with_placeholders(&obligation.predicate); let skol_obligation_trait_ref = skol_obligation.trait_ref; - let impl_substs = self.infcx - .fresh_substs_for_item(obligation.cause.span, impl_def_id); + let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id); let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs); - let Normalized { - value: impl_trait_ref, - obligations: mut nested_obligations, - } = project::normalize_with_depth( - self, - obligation.param_env, - obligation.cause.clone(), - obligation.recursion_depth + 1, - &impl_trait_ref, - ); + let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } = + project::normalize_with_depth( + self, + obligation.param_env, + obligation.cause.clone(), + obligation.recursion_depth + 1, + &impl_trait_ref, + ); debug!( "match_impl(impl_def_id={:?}, obligation={:?}, \ @@ -3725,7 +3498,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { impl_def_id, obligation, impl_trait_ref, skol_obligation_trait_ref ); - let InferOk { obligations, .. } = self.infcx + let InferOk { obligations, .. } = self + .infcx .at(&obligation.cause, obligation.param_env) .eq(skol_obligation_trait_ref, impl_trait_ref) .map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{}`", e))?; @@ -3744,10 +3518,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } debug!("match_impl: success impl_substs={:?}", impl_substs); - Ok(Normalized { - value: impl_substs, - obligations: nested_obligations, - }) + Ok(Normalized { value: impl_substs, obligations: nested_obligations }) } fn fast_reject_trait_refs( @@ -3759,12 +3530,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // substitution if we find that any of the input types, when // simplified, do not match. - obligation - .predicate - .skip_binder() - .input_types() - .zip(impl_trait_ref.input_types()) - .any(|(obligation_ty, impl_ty)| { + obligation.predicate.skip_binder().input_types().zip(impl_trait_ref.input_types()).any( + |(obligation_ty, impl_ty)| { let simplified_obligation_ty = fast_reject::simplify_type(self.tcx(), obligation_ty, true); let simplified_impl_ty = fast_reject::simplify_type(self.tcx(), impl_ty, false); @@ -3772,7 +3539,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { simplified_obligation_ty.is_some() && simplified_impl_ty.is_some() && simplified_obligation_ty != simplified_impl_ty - }) + }, + ) } /// Normalize `where_clause_trait_ref` and try to match it against @@ -3825,10 +3593,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { previous_stack: TraitObligationStackList<'o, 'tcx>, obligation: &'o TraitObligation<'tcx>, ) -> TraitObligationStack<'o, 'tcx> { - let fresh_trait_ref = obligation - .predicate - .to_poly_trait_ref() - .fold_with(&mut self.freshener); + let fresh_trait_ref = + obligation.predicate.to_poly_trait_ref().fold_with(&mut self.freshener); let dfn = previous_stack.cache.next_dfn(); let depth = previous_stack.depth() + 1; @@ -3854,10 +3620,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); let closure_type = self.infcx.closure_sig(closure_def_id, substs); - debug!( - "closure_trait_ref_unnormalized: closure_type = {:?}", - closure_type - ); + debug!("closure_trait_ref_unnormalized: closure_type = {:?}", closure_type); // (1) Feels icky to skip the binder here, but OTOH we know // that the self-type is an unboxed closure type and hence is @@ -3906,8 +3669,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause: ObligationCause<'tcx>, recursion_depth: usize, param_env: ty::ParamEnv<'tcx>, - def_id: DefId, // of impl or trait - substs: SubstsRef<'tcx>, // for impl or trait + def_id: DefId, // of impl or trait + substs: SubstsRef<'tcx>, // for impl or trait ) -> Vec> { debug!("impl_or_trait_obligations(def_id={:?})", def_id); let tcx = self.tcx(); @@ -4001,11 +3764,7 @@ impl<'tcx> TraitObligation<'tcx> { parent_code: Rc::new(obligation.cause.code.clone()), }; let derived_code = variant(derived_cause); - ObligationCause::new( - obligation.cause.span, - obligation.cause.body_id, - derived_code, - ) + ObligationCause::new(obligation.cause.span, obligation.cause.body_id, derived_code) } else { obligation.cause.clone() } @@ -4211,10 +3970,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> { ) { debug!( "insert_provisional(from_dfn={}, reached_depth={}, fresh_trait_ref={:?}, result={:?})", - from_dfn, - reached_depth, - fresh_trait_ref, - result, + from_dfn, reached_depth, fresh_trait_ref, result, ); let r_d = self.reached_depth.get(); self.reached_depth.set(r_d.min(reached_depth)); @@ -4233,10 +3989,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> { /// these provisional entries must either depend on it or some /// ancestor of it. fn on_failure(&self, dfn: usize) { - debug!( - "on_failure(dfn={:?})", - dfn, - ); + debug!("on_failure(dfn={:?})", dfn,); self.map.borrow_mut().retain(|key, eval| { if !eval.from_dfn >= dfn { debug!("on_failure: removing {:?}", key); @@ -4257,11 +4010,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> { depth: usize, mut op: impl FnMut(ty::PolyTraitRef<'tcx>, EvaluationResult), ) { - debug!( - "on_completion(depth={}, reached_depth={})", - depth, - self.reached_depth.get(), - ); + debug!("on_completion(depth={}, reached_depth={})", depth, self.reached_depth.get(),); if self.reached_depth.get() < depth { debug!("on_completion: did not yet reach depth to complete"); @@ -4269,11 +4018,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> { } for (fresh_trait_ref, eval) in self.map.borrow_mut().drain() { - debug!( - "on_completion: fresh_trait_ref={:?} eval={:?}", - fresh_trait_ref, - eval, - ); + debug!("on_completion: fresh_trait_ref={:?} eval={:?}", fresh_trait_ref, eval,); op(fresh_trait_ref, eval.result); } @@ -4302,11 +4047,7 @@ impl<'o, 'tcx> TraitObligationStackList<'o, 'tcx> { } fn depth(&self) -> usize { - if let Some(head) = self.head { - head.depth - } else { - 0 - } + if let Some(head) = self.head { head.depth } else { 0 } } } @@ -4338,10 +4079,7 @@ pub struct WithDepNode { impl WithDepNode { pub fn new(dep_node: DepNodeIndex, cached_value: T) -> Self { - WithDepNode { - dep_node, - cached_value, - } + WithDepNode { dep_node, cached_value } } pub fn get(&self, tcx: TyCtxt<'_>) -> T { diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 88a2db3dc6223..d527aa310ad28 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -14,15 +14,15 @@ pub mod specialization_graph; use crate::hir::def_id::DefId; use crate::infer::{InferCtxt, InferOk}; use crate::lint; +use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine}; +use crate::ty::subst::{InternalSubsts, Subst, SubstsRef}; +use crate::ty::{self, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::FxHashSet; use syntax_pos::DUMMY_SP; -use crate::traits::select::IntercrateAmbiguityCause; -use crate::ty::{self, TyCtxt, TypeFoldable}; -use crate::ty::subst::{Subst, InternalSubsts, SubstsRef}; -use super::{SelectionContext, FulfillmentContext}; use super::util::impl_trait_ref_and_oblig; +use super::{FulfillmentContext, SelectionContext}; use rustc_error_codes::*; @@ -78,12 +78,12 @@ pub fn translate_substs<'a, 'tcx>( source_substs: SubstsRef<'tcx>, target_node: specialization_graph::Node, ) -> SubstsRef<'tcx> { - debug!("translate_substs({:?}, {:?}, {:?}, {:?})", - param_env, source_impl, source_substs, target_node); - let source_trait_ref = infcx.tcx - .impl_trait_ref(source_impl) - .unwrap() - .subst(infcx.tcx, &source_substs); + debug!( + "translate_substs({:?}, {:?}, {:?}, {:?})", + param_env, source_impl, source_substs, target_node + ); + let source_trait_ref = + infcx.tcx.impl_trait_ref(source_impl).unwrap().subst(infcx.tcx, &source_substs); // translate the Self and Param parts of the substitution, since those // vary across impls @@ -94,11 +94,14 @@ pub fn translate_substs<'a, 'tcx>( return source_substs; } - fulfill_implication(infcx, param_env, source_trait_ref, target_impl) - .unwrap_or_else(|_| - bug!("When translating substitutions for specialization, the expected \ - specialization failed to hold") - ) + fulfill_implication(infcx, param_env, source_trait_ref, target_impl).unwrap_or_else( + |_| { + bug!( + "When translating substitutions for specialization, the expected \ + specialization failed to hold" + ) + }, + ) } specialization_graph::Node::Trait(..) => source_trait_ref.substs, }; @@ -119,8 +122,7 @@ pub fn find_associated_item<'tcx>( substs: SubstsRef<'tcx>, impl_data: &super::VtableImplData<'tcx, ()>, ) -> (DefId, SubstsRef<'tcx>) { - debug!("find_associated_item({:?}, {:?}, {:?}, {:?})", - param_env, item, substs, impl_data); + debug!("find_associated_item({:?}, {:?}, {:?}, {:?})", param_env, item, substs, impl_data); assert!(!substs.needs_infer()); let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap(); @@ -132,13 +134,18 @@ pub fn find_associated_item<'tcx>( let substs = tcx.infer_ctxt().enter(|infcx| { let param_env = param_env.with_reveal_all(); let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs); - let substs = translate_substs(&infcx, param_env, impl_data.impl_def_id, - substs, node_item.node); + let substs = translate_substs( + &infcx, + param_env, + impl_data.impl_def_id, + substs, + node_item.node, + ); infcx.tcx.erase_regions(&substs) }); (node_item.item.def_id, substs) } - None => bug!("{:?} not found in {:?}", item, impl_data.impl_def_id) + None => bug!("{:?} not found in {:?}", item, impl_data.impl_def_id), } } @@ -147,16 +154,12 @@ pub fn find_associated_item<'tcx>( /// Specialization is determined by the sets of types to which the impls apply; /// `impl1` specializes `impl2` if it applies to a subset of the types `impl2` applies /// to. -pub(super) fn specializes( - tcx: TyCtxt<'_>, - (impl1_def_id, impl2_def_id): (DefId, DefId), -) -> bool { +pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, DefId)) -> bool { debug!("specializes({:?}, {:?})", impl1_def_id, impl2_def_id); // The feature gate should prevent introducing new specializations, but not // taking advantage of upstream ones. - if !tcx.features().specialization && - (impl1_def_id.is_local() || impl2_def_id.is_local()) { + if !tcx.features().specialization && (impl1_def_id.is_local() || impl2_def_id.is_local()) { return false; } @@ -185,17 +188,18 @@ pub(super) fn specializes( tcx.infer_ctxt().enter(|infcx| { // Normalize the trait reference. The WF rules ought to ensure // that this always succeeds. - let impl1_trait_ref = - match traits::fully_normalize(&infcx, - FulfillmentContext::new(), - ObligationCause::dummy(), - penv, - &impl1_trait_ref) { - Ok(impl1_trait_ref) => impl1_trait_ref, - Err(err) => { - bug!("failed to fully normalize {:?}: {:?}", impl1_trait_ref, err); - } - }; + let impl1_trait_ref = match traits::fully_normalize( + &infcx, + FulfillmentContext::new(), + ObligationCause::dummy(), + penv, + &impl1_trait_ref, + ) { + Ok(impl1_trait_ref) => impl1_trait_ref, + Err(err) => { + bug!("failed to fully normalize {:?}: {:?}", impl1_trait_ref, err); + } + }; // Attempt to prove that impl2 applies, given all of the above. fulfill_implication(&infcx, penv, impl1_trait_ref, impl2_def_id).is_ok() @@ -213,28 +217,30 @@ fn fulfill_implication<'a, 'tcx>( source_trait_ref: ty::TraitRef<'tcx>, target_impl: DefId, ) -> Result, ()> { - debug!("fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)", - param_env, source_trait_ref, target_impl); + debug!( + "fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)", + param_env, source_trait_ref, target_impl + ); let selcx = &mut SelectionContext::new(&infcx); let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl); - let (target_trait_ref, mut obligations) = impl_trait_ref_and_oblig(selcx, - param_env, - target_impl, - target_substs); - debug!("fulfill_implication: target_trait_ref={:?}, obligations={:?}", - target_trait_ref, obligations); + let (target_trait_ref, mut obligations) = + impl_trait_ref_and_oblig(selcx, param_env, target_impl, target_substs); + debug!( + "fulfill_implication: target_trait_ref={:?}, obligations={:?}", + target_trait_ref, obligations + ); // do the impls unify? If not, no specialization. - match infcx.at(&ObligationCause::dummy(), param_env) - .eq(source_trait_ref, target_trait_ref) { + match infcx.at(&ObligationCause::dummy(), param_env).eq(source_trait_ref, target_trait_ref) { Ok(InferOk { obligations: o, .. }) => { obligations.extend(o); } Err(_) => { - debug!("fulfill_implication: {:?} does not unify with {:?}", - source_trait_ref, - target_trait_ref); + debug!( + "fulfill_implication: {:?} does not unify with {:?}", + source_trait_ref, target_trait_ref + ); return Err(()); } } @@ -261,19 +267,19 @@ fn fulfill_implication<'a, 'tcx>( match fulfill_cx.select_all_or_error(infcx) { Err(errors) => { // no dice! - debug!("fulfill_implication: for impls on {:?} and {:?}, \ + debug!( + "fulfill_implication: for impls on {:?} and {:?}, \ could not fulfill: {:?} given {:?}", - source_trait_ref, - target_trait_ref, - errors, - param_env.caller_bounds); + source_trait_ref, target_trait_ref, errors, param_env.caller_bounds + ); Err(()) } Ok(()) => { - debug!("fulfill_implication: an impl for {:?} specializes {:?}", - source_trait_ref, - target_trait_ref); + debug!( + "fulfill_implication: an impl for {:?} specializes {:?}", + source_trait_ref, target_trait_ref + ); // Now resolve the *substitution* we built for the target earlier, replacing // the inference variables inside with whatever we got from fulfillment. @@ -296,9 +302,8 @@ pub(super) fn specialization_graph_provider( // iterated over (roughly) in definition order, so we are sorting by // negated `CrateNum` (so remote definitions are visited first) and then // by a flattened version of the `DefIndex`. - trait_impls.sort_unstable_by_key(|def_id| { - (-(def_id.krate.as_u32() as i64), def_id.index.index()) - }); + trait_impls + .sort_unstable_by_key(|def_id| (-(def_id.krate.as_u32() as i64), def_id.index.index())); for impl_def_id in trait_impls { if impl_def_id.is_local() { @@ -308,60 +313,67 @@ pub(super) fn specialization_graph_provider( let (overlap, used_to_be_allowed) = match insert_result { Err(overlap) => (Some(overlap), None), Ok(Some(overlap)) => (Some(overlap.error), Some(overlap.kind)), - Ok(None) => (None, None) + Ok(None) => (None, None), }; if let Some(overlap) = overlap { - let msg = format!("conflicting implementations of trait `{}`{}:{}", + let msg = format!( + "conflicting implementations of trait `{}`{}:{}", overlap.trait_desc, - overlap.self_desc.clone().map_or( - String::new(), |ty| { - format!(" for type `{}`", ty) - }), + overlap + .self_desc + .clone() + .map_or(String::new(), |ty| { format!(" for type `{}`", ty) }), match used_to_be_allowed { Some(FutureCompatOverlapErrorKind::Issue33140) => " (E0119)", _ => "", } ); - let impl_span = tcx.sess.source_map().def_span( - tcx.span_of_impl(impl_def_id).unwrap() - ); + let impl_span = + tcx.sess.source_map().def_span(tcx.span_of_impl(impl_def_id).unwrap()); let mut err = match used_to_be_allowed { - Some(FutureCompatOverlapErrorKind::Issue43355) | None => - struct_span_err!(tcx.sess, - impl_span, - E0119, - "{}", - msg), + Some(FutureCompatOverlapErrorKind::Issue43355) | None => { + struct_span_err!(tcx.sess, impl_span, E0119, "{}", msg) + } Some(kind) => { let lint = match kind { - FutureCompatOverlapErrorKind::Issue43355 => - unreachable!("converted to hard error above"), - FutureCompatOverlapErrorKind::Issue33140 => - lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS, + FutureCompatOverlapErrorKind::Issue43355 => { + unreachable!("converted to hard error above") + } + FutureCompatOverlapErrorKind::Issue33140 => { + lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS + } }; tcx.struct_span_lint_hir( lint, tcx.hir().as_local_hir_id(impl_def_id).unwrap(), impl_span, - &msg) + &msg, + ) } }; match tcx.span_of_impl(overlap.with_impl) { Ok(span) => { - err.span_label(tcx.sess.source_map().def_span(span), - "first implementation here".to_string()); - err.span_label(impl_span, - format!("conflicting implementation{}", - overlap.self_desc - .map_or(String::new(), - |ty| format!(" for `{}`", ty)))); + err.span_label( + tcx.sess.source_map().def_span(span), + "first implementation here".to_string(), + ); + err.span_label( + impl_span, + format!( + "conflicting implementation{}", + overlap + .self_desc + .map_or(String::new(), |ty| format!(" for `{}`", ty)) + ), + ); } Err(cname) => { let msg = match to_pretty_impl_header(tcx, overlap.with_impl) { - Some(s) => format!( - "conflicting implementation in crate `{}`:\n- {}", cname, s), + Some(s) => { + format!("conflicting implementation in crate `{}`:\n- {}", cname, s) + } None => format!("conflicting implementation in crate `{}`", cname), }; err.note(&msg); @@ -410,10 +422,14 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option if !substs.is_noop() { types_without_default_bounds.extend(substs.types()); w.push('<'); - w.push_str(&substs.iter() - .map(|k| k.to_string()) - .filter(|k| k != "'_") - .collect::>().join(", ")); + w.push_str( + &substs + .iter() + .map(|k| k.to_string()) + .filter(|k| k != "'_") + .collect::>() + .join(", "), + ); w.push('>'); } @@ -422,8 +438,8 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option // The predicates will contain default bounds like `T: Sized`. We need to // remove these bounds, and add `T: ?Sized` to any untouched type parameters. let predicates = tcx.predicates_of(impl_def_id).predicates; - let mut pretty_predicates = Vec::with_capacity( - predicates.len() + types_without_default_bounds.len()); + let mut pretty_predicates = + Vec::with_capacity(predicates.len() + types_without_default_bounds.len()); for (p, _) in predicates { if let Some(poly_trait_ref) = p.to_opt_poly_trait_ref() { @@ -435,9 +451,8 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option pretty_predicates.push(p.to_string()); } - pretty_predicates.extend( - types_without_default_bounds.iter().map(|ty| format!("{}: ?Sized", ty)) - ); + pretty_predicates + .extend(types_without_default_bounds.iter().map(|ty| format!("{}: ?Sized", ty))); if !pretty_predicates.is_empty() { write!(w, "\n where {}", pretty_predicates.join(", ")).unwrap(); diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index b8ddf6078bda6..8d2dcee22f544 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -2,12 +2,12 @@ use super::OverlapError; use crate::hir::def_id::DefId; use crate::ich::{self, StableHashingContext}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use crate::traits; -use crate::ty::{self, TyCtxt, TypeFoldable}; use crate::ty::fast_reject::{self, SimplifiedType}; -use syntax::ast::Ident; +use crate::ty::{self, TyCtxt, TypeFoldable}; use crate::util::nodemap::{DefIdMap, FxHashMap}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use syntax::ast::Ident; /// A per-trait graph of impls in specialization order. At the moment, this /// graph forms a tree rooted with the trait itself, with all other nodes @@ -47,7 +47,6 @@ struct Children { // A similar division is used within `TraitDef`, but the lists there collect // together *all* the impls for a trait, and are populated prior to building // the specialization graph. - /// Impls of the trait. nonblanket_impls: FxHashMap>, @@ -64,7 +63,7 @@ pub enum FutureCompatOverlapErrorKind { #[derive(Debug)] pub struct FutureCompatOverlapError { pub error: OverlapError, - pub kind: FutureCompatOverlapErrorKind + pub kind: FutureCompatOverlapErrorKind, } /// The result of attempting to insert an impl into a group of children. @@ -121,11 +120,7 @@ impl<'tcx> Children { let mut last_lint = None; let mut replace_children = Vec::new(); - debug!( - "insert(impl_def_id={:?}, simplified_self={:?})", - impl_def_id, - simplified_self, - ); + debug!("insert(impl_def_id={:?}, simplified_self={:?})", impl_def_id, simplified_self,); let possible_siblings = match simplified_self { Some(st) => PotentialSiblings::Filtered(self.filtered(st)), @@ -135,9 +130,7 @@ impl<'tcx> Children { for possible_sibling in possible_siblings { debug!( "insert: impl_def_id={:?}, simplified_self={:?}, possible_sibling={:?}", - impl_def_id, - simplified_self, - possible_sibling, + impl_def_id, simplified_self, possible_sibling, ); let overlap_error = |overlap: traits::coherence::OverlapResult<'_>| { @@ -174,7 +167,7 @@ impl<'tcx> Children { ty::ImplOverlapKind::Issue33140 => { last_lint = Some(FutureCompatOverlapError { error: overlap_error(overlap), - kind: FutureCompatOverlapErrorKind::Issue33140 + kind: FutureCompatOverlapErrorKind::Issue33140, }); } } @@ -185,30 +178,28 @@ impl<'tcx> Children { let le = tcx.specializes((impl_def_id, possible_sibling)); let ge = tcx.specializes((possible_sibling, impl_def_id)); - if le == ge { - Err(overlap_error(overlap)) - } else { - Ok((le, ge)) - } + if le == ge { Err(overlap_error(overlap)) } else { Ok((le, ge)) } }, || Ok((false, false)), )?; if le && !ge { - debug!("descending as child of TraitRef {:?}", - tcx.impl_trait_ref(possible_sibling).unwrap()); + debug!( + "descending as child of TraitRef {:?}", + tcx.impl_trait_ref(possible_sibling).unwrap() + ); // The impl specializes `possible_sibling`. return Ok(Inserted::ShouldRecurseOn(possible_sibling)); } else if ge && !le { - debug!("placing as parent of TraitRef {:?}", - tcx.impl_trait_ref(possible_sibling).unwrap()); + debug!( + "placing as parent of TraitRef {:?}", + tcx.impl_trait_ref(possible_sibling).unwrap() + ); replace_children.push(possible_sibling); } else { - if let None = tcx.impls_are_allowed_to_overlap( - impl_def_id, possible_sibling) - { + if let None = tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) { // do future-compat checks for overlap. Have issue #33140 // errors overwrite issue #43355 errors when both are present. @@ -220,7 +211,7 @@ impl<'tcx> Children { |overlap| { last_lint = Some(FutureCompatOverlapError { error: overlap_error(overlap), - kind: FutureCompatOverlapErrorKind::Issue43355 + kind: FutureCompatOverlapErrorKind::Issue43355, }); }, || (), @@ -254,33 +245,32 @@ impl<'tcx> Children { // A custom iterator used by Children::insert enum PotentialSiblings - where I: Iterator, - J: Iterator +where + I: Iterator, + J: Iterator, { Unfiltered(I), - Filtered(J) + Filtered(J), } impl Iterator for PotentialSiblings - where I: Iterator, - J: Iterator +where + I: Iterator, + J: Iterator, { type Item = DefId; fn next(&mut self) -> Option { match *self { PotentialSiblings::Unfiltered(ref mut iter) => iter.next(), - PotentialSiblings::Filtered(ref mut iter) => iter.next() + PotentialSiblings::Filtered(ref mut iter) => iter.next(), } } } impl<'tcx> Graph { pub fn new() -> Graph { - Graph { - parent: Default::default(), - children: Default::default(), - } + Graph { parent: Default::default(), children: Default::default() } } /// Insert a local impl into the specialization graph. If an existing impl @@ -296,21 +286,24 @@ impl<'tcx> Graph { let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); let trait_def_id = trait_ref.def_id; - debug!("insert({:?}): inserting TraitRef {:?} into specialization graph", - impl_def_id, trait_ref); + debug!( + "insert({:?}): inserting TraitRef {:?} into specialization graph", + impl_def_id, trait_ref + ); // If the reference itself contains an earlier error (e.g., due to a // resolution failure), then we just insert the impl at the top level of // the graph and claim that there's no overlap (in order to suppress // bogus errors). if trait_ref.references_error() { - debug!("insert: inserting dummy node for erroneous TraitRef {:?}, \ + debug!( + "insert: inserting dummy node for erroneous TraitRef {:?}, \ impl_def_id={:?}, trait_def_id={:?}", - trait_ref, impl_def_id, trait_def_id); + trait_ref, impl_def_id, trait_def_id + ); self.parent.insert(impl_def_id, trait_def_id); - self.children.entry(trait_def_id).or_default() - .insert_blindly(tcx, impl_def_id); + self.children.entry(trait_def_id).or_default().insert_blindly(tcx, impl_def_id); return Ok(None); } @@ -322,8 +315,8 @@ impl<'tcx> Graph { loop { use self::Inserted::*; - let insert_result = self.children.entry(parent).or_default() - .insert(tcx, impl_def_id, simplified)?; + let insert_result = + self.children.entry(parent).or_default().insert(tcx, impl_def_id, simplified)?; match insert_result { BecameNewSibling(opt_lint) => { @@ -347,9 +340,7 @@ impl<'tcx> Graph { // Adjust P's list of children: remove G and then add N. { - let siblings = self.children - .get_mut(&parent) - .unwrap(); + let siblings = self.children.get_mut(&parent).unwrap(); for &grand_child_to_be in &grand_children_to_be { siblings.remove_existing(tcx, grand_child_to_be); } @@ -364,7 +355,9 @@ impl<'tcx> Graph { // Add G as N's child. for &grand_child_to_be in &grand_children_to_be { - self.children.entry(impl_def_id).or_default() + self.children + .entry(impl_def_id) + .or_default() .insert_blindly(tcx, grand_child_to_be); } break; @@ -382,8 +375,10 @@ impl<'tcx> Graph { /// Insert cached metadata mapping from a child impl back to its parent. pub fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'tcx>, parent: DefId, child: DefId) { if self.parent.insert(child, parent).is_some() { - bug!("When recording an impl from the crate store, information about its parent \ - was already present."); + bug!( + "When recording an impl from the crate store, information about its parent \ + was already present." + ); } self.children.entry(parent).or_default().insert_blindly(tcx, child); @@ -431,8 +426,8 @@ impl<'tcx> Node { ) -> Option { use crate::ty::AssocKind::*; - tcx.associated_items(self.def_id()) - .find(move |impl_item| match (trait_item_kind, impl_item.kind) { + tcx.associated_items(self.def_id()).find(move |impl_item| { + match (trait_item_kind, impl_item.kind) { | (Const, Const) | (Method, Method) | (Type, Type) @@ -444,7 +439,8 @@ impl<'tcx> Node { | (Type, _) | (OpaqueTy, _) => false, - }) + } + }) } pub fn def_id(&self) -> DefId { @@ -486,10 +482,7 @@ pub struct NodeItem { impl NodeItem { pub fn map U>(self, f: F) -> NodeItem { - NodeItem { - node: self.node, - item: f(self.item), - } + NodeItem { node: self.node, item: f(self.item) } } } @@ -527,10 +520,7 @@ pub fn ancestors( impl<'a> HashStable> for Children { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let Children { - ref nonblanket_impls, - ref blanket_impls, - } = *self; + let Children { ref nonblanket_impls, ref blanket_impls } = *self; ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, nonblanket_impls); } diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 1e78b79ebb619..ed0842d80988f 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -1,14 +1,14 @@ -use chalk_engine; -use smallvec::SmallVec; use crate::traits; use crate::traits::project::Normalized; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::{self, Lift, Ty, TyCtxt}; +use chalk_engine; +use smallvec::SmallVec; use syntax::symbol::Symbol; +use std::collections::{BTreeMap, BTreeSet}; use std::fmt; use std::rc::Rc; -use std::collections::{BTreeSet, BTreeMap}; // Structural impls for the structs in `traits`. @@ -27,11 +27,7 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for traits::Obligation<'tcx, O> { self.predicate, self.cause, self.param_env, self.recursion_depth ) } else { - write!( - f, - "Obligation(predicate={:?}, depth={})", - self.predicate, self.recursion_depth - ) + write!(f, "Obligation(predicate={:?}, depth={})", self.predicate, self.recursion_depth) } } } @@ -118,11 +114,7 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableObjectData<'tcx, N> { impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableFnPointerData<'tcx, N> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "VtableFnPointerData(fn_ty={:?}, nested={:?})", - self.fn_ty, self.nested - ) + write!(f, "VtableFnPointerData(fn_ty={:?}, nested={:?})", self.fn_ty, self.nested) } } @@ -169,7 +161,7 @@ impl<'tcx> fmt::Display for traits::WhereClause<'tcx> { // FIXME(eddyb) implement a custom `PrettyPrinter`, or move this to `ty::print`. fn write_region_name<'tcx>( r: ty::Region<'tcx>, - fmt: &mut fmt::Formatter<'_> + fmt: &mut fmt::Formatter<'_>, ) -> fmt::Result { match r { ty::ReLateBound(index, br) => match br { @@ -182,7 +174,7 @@ impl<'tcx> fmt::Display for traits::WhereClause<'tcx> { } } _ => write!(fmt, "'_"), - } + }, _ => write!(fmt, "{}", r), } @@ -235,12 +227,9 @@ impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> { Holds(wc) => write!(fmt, "{}", wc), WellFormed(wf) => write!(fmt, "{}", wf), FromEnv(from_env) => write!(fmt, "{}", from_env), - Normalize(projection) => write!( - fmt, - "Normalize({} -> {})", - projection.projection_ty, - projection.ty - ), + Normalize(projection) => { + write!(fmt, "Normalize({} -> {})", projection.projection_ty, projection.ty) + } } } } @@ -318,10 +307,10 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector { bound_ty.var.as_u32(), match bound_ty.kind { ty::BoundTyKind::Param(name) => name, - ty::BoundTyKind::Anon => - Symbol::intern(&format!("^{}", bound_ty.var.as_u32()), - ), - } + ty::BoundTyKind::Anon => { + Symbol::intern(&format!("^{}", bound_ty.var.as_u32())) + } + }, ); } @@ -333,19 +322,17 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector { fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { match r { - ty::ReLateBound(index, br) if *index == self.binder_index => { - match br { - ty::BoundRegion::BrNamed(_, name) => { - self.regions.insert(*name); - } - - ty::BoundRegion::BrAnon(var) => { - self.regions.insert(Symbol::intern(&format!("'^{}", var))); - } + ty::ReLateBound(index, br) if *index == self.binder_index => match br { + ty::BoundRegion::BrNamed(_, name) => { + self.regions.insert(*name); + } - _ => (), + ty::BoundRegion::BrAnon(var) => { + self.regions.insert(Symbol::intern(&format!("'^{}", var))); } - } + + _ => (), + }, _ => (), }; @@ -450,10 +437,9 @@ impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> { match *self { super::Unimplemented => Some(super::Unimplemented), super::OutputTypeParameterMismatch(a, b, ref err) => { - tcx.lift(&(a, b)).and_then(|(a, b)| - tcx.lift(err) - .map(|err| super::OutputTypeParameterMismatch(a, b, err)) - ) + tcx.lift(&(a, b)).and_then(|(a, b)| { + tcx.lift(err).map(|err| super::OutputTypeParameterMismatch(a, b, err)) + }) } super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)), super::ConstEvalFailure(err) => Some(super::ConstEvalFailure(err)), @@ -476,15 +462,13 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { super::ReferenceOutlivesReferent(ty) => { tcx.lift(&ty).map(super::ReferenceOutlivesReferent) } - super::ObjectTypeBound(ty, r) => tcx.lift(&ty).and_then(|ty| - tcx.lift(&r) - .and_then(|r| Some(super::ObjectTypeBound(ty, r))) - ), + super::ObjectTypeBound(ty, r) => tcx + .lift(&ty) + .and_then(|ty| tcx.lift(&r).and_then(|r| Some(super::ObjectTypeBound(ty, r)))), super::ObjectCastObligation(ty) => tcx.lift(&ty).map(super::ObjectCastObligation), - super::Coercion { source, target } => Some(super::Coercion { - source: tcx.lift(&source)?, - target: tcx.lift(&target)?, - }), + super::Coercion { source, target } => { + Some(super::Coercion { source: tcx.lift(&source)?, target: tcx.lift(&target)? }) + } super::AssignmentLhsSized => Some(super::AssignmentLhsSized), super::TupleInitializerSized => Some(super::TupleInitializerSized), super::StructInitializerSized => Some(super::StructInitializerSized), @@ -514,15 +498,13 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { impl_item_def_id, trait_item_def_id, }), - super::CompareImplTypeObligation { - item_name, - impl_item_def_id, - trait_item_def_id, - } => Some(super::CompareImplTypeObligation { - item_name, - impl_item_def_id, - trait_item_def_id, - }), + super::CompareImplTypeObligation { item_name, impl_item_def_id, trait_item_def_id } => { + Some(super::CompareImplTypeObligation { + item_name, + impl_item_def_id, + trait_item_def_id, + }) + } super::ExprAssignable => Some(super::ExprAssignable), super::MatchExpressionArm(box super::MatchExpressionArmCause { arm_span, @@ -530,26 +512,20 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { ref prior_arms, last_ty, discrim_hir_id, - }) => { - tcx.lift(&last_ty).map(|last_ty| { - super::MatchExpressionArm(box super::MatchExpressionArmCause { - arm_span, - source, - prior_arms: prior_arms.clone(), - last_ty, - discrim_hir_id, - }) + }) => tcx.lift(&last_ty).map(|last_ty| { + super::MatchExpressionArm(box super::MatchExpressionArmCause { + arm_span, + source, + prior_arms: prior_arms.clone(), + last_ty, + discrim_hir_id, }) - } + }), super::MatchExpressionArmPattern { span, ty } => { tcx.lift(&ty).map(|ty| super::MatchExpressionArmPattern { span, ty }) } super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }) => { - Some(super::IfExpression(box super::IfExpressionCause { - then, - outer, - semicolon, - })) + Some(super::IfExpression(box super::IfExpressionCause { then, outer, semicolon })) } super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse), super::MainFunctionType => Some(super::MainFunctionType), @@ -566,13 +542,12 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> { type Lifted = traits::DerivedObligationCause<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| - tcx.lift(&*self.parent_code) - .map(|code| traits::DerivedObligationCause { - parent_trait_ref: trait_ref, - parent_code: Rc::new(code), - }) - ) + tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| { + tcx.lift(&*self.parent_code).map(|code| traits::DerivedObligationCause { + parent_trait_ref: trait_ref, + parent_code: Rc::new(code), + }) + }) } } @@ -592,44 +567,36 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> { type Lifted = traits::Vtable<'tcx, ()>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { match self.clone() { - traits::VtableImpl(traits::VtableImplData { - impl_def_id, - substs, - nested, - }) => tcx.lift(&substs).map(|substs| - traits::VtableImpl(traits::VtableImplData { - impl_def_id, - substs, - nested, + traits::VtableImpl(traits::VtableImplData { impl_def_id, substs, nested }) => { + tcx.lift(&substs).map(|substs| { + traits::VtableImpl(traits::VtableImplData { impl_def_id, substs, nested }) }) - ), + } traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)), traits::VtableGenerator(traits::VtableGeneratorData { generator_def_id, substs, nested, - }) => tcx.lift(&substs).map(|substs| + }) => tcx.lift(&substs).map(|substs| { traits::VtableGenerator(traits::VtableGeneratorData { generator_def_id: generator_def_id, substs: substs, nested: nested, }) - ), - traits::VtableClosure(traits::VtableClosureData { - closure_def_id, - substs, - nested, - }) => tcx.lift(&substs).map(|substs| - traits::VtableClosure(traits::VtableClosureData { - closure_def_id, - substs, - nested, + }), + traits::VtableClosure(traits::VtableClosureData { closure_def_id, substs, nested }) => { + tcx.lift(&substs).map(|substs| { + traits::VtableClosure(traits::VtableClosureData { + closure_def_id, + substs, + nested, + }) }) - ), + } traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => { - tcx.lift(&fn_ty).map(|fn_ty| + tcx.lift(&fn_ty).map(|fn_ty| { traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) - ) + }) } traits::VtableParam(n) => Some(traits::VtableParam(n)), traits::VtableBuiltin(n) => Some(traits::VtableBuiltin(n)), @@ -637,24 +604,24 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> { upcast_trait_ref, vtable_base, nested, - }) => tcx.lift(&upcast_trait_ref).map(|trait_ref| + }) => tcx.lift(&upcast_trait_ref).map(|trait_ref| { traits::VtableObject(traits::VtableObjectData { upcast_trait_ref: trait_ref, vtable_base, nested, }) - ), + }), traits::VtableTraitAlias(traits::VtableTraitAliasData { alias_def_id, substs, nested, - }) => tcx.lift(&substs).map(|substs| + }) => tcx.lift(&substs).map(|substs| { traits::VtableTraitAlias(traits::VtableTraitAliasData { alias_def_id, substs, nested, }) - ), + }), } } } @@ -662,11 +629,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> { impl<'a, 'tcx> Lift<'tcx> for traits::Environment<'a> { type Lifted = traits::Environment<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.clauses).map(|clauses| { - traits::Environment { - clauses, - } - }) + tcx.lift(&self.clauses).map(|clauses| traits::Environment { clauses }) } } @@ -674,12 +637,7 @@ impl<'a, 'tcx, G: Lift<'tcx>> Lift<'tcx> for traits::InEnvironment<'a, G> { type Lifted = traits::InEnvironment<'tcx, G::Lifted>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { tcx.lift(&self.environment).and_then(|environment| { - tcx.lift(&self.goal).map(|goal| { - traits::InEnvironment { - environment, - goal, - } - }) + tcx.lift(&self.goal).map(|goal| traits::InEnvironment { environment, goal }) }) } } @@ -744,9 +702,7 @@ CloneTypeFoldableAndLiftImpls! { impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { fn super_fold_with>(&self, folder: &mut F) -> Self { - let v = self.iter() - .map(|t| t.fold_with(folder)) - .collect::>(); + let v = self.iter().map(|t| t.fold_with(folder)).collect::>(); folder.tcx().intern_goals(&v) } @@ -772,9 +728,7 @@ CloneTypeFoldableAndLiftImpls! { impl<'tcx> TypeFoldable<'tcx> for traits::Clauses<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { - let v = self.iter() - .map(|t| t.fold_with(folder)) - .collect::>(); + let v = self.iter().map(|t| t.fold_with(folder)).collect::>(); folder.tcx().intern_clauses(&v) } @@ -790,17 +744,11 @@ where C::RegionConstraint: Clone, { fn super_fold_with>(&self, folder: &mut F) -> Self { - ::fold_ex_clause_with( - self, - folder, - ) + ::fold_ex_clause_with(self, folder) } fn super_visit_with>(&self, visitor: &mut V) -> bool { - ::visit_ex_clause_with( - self, - visitor, - ) + ::visit_ex_clause_with(self, visitor) } } diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index c15915a9d561f..d36ff8c236f8f 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -4,41 +4,46 @@ use syntax_pos::Span; use crate::hir; use crate::hir::def_id::DefId; -use crate::ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef}; use crate::ty::outlives::Component; use crate::ty::subst::{GenericArg, Subst, SubstsRef}; +use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt}; use crate::util::nodemap::FxHashSet; -use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext, Normalized}; +use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext}; fn anonymize_predicate<'tcx>(tcx: TyCtxt<'tcx>, pred: &ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { match *pred { - ty::Predicate::Trait(ref data) => - ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data)), + ty::Predicate::Trait(ref data) => { + ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data)) + } - ty::Predicate::RegionOutlives(ref data) => - ty::Predicate::RegionOutlives(tcx.anonymize_late_bound_regions(data)), + ty::Predicate::RegionOutlives(ref data) => { + ty::Predicate::RegionOutlives(tcx.anonymize_late_bound_regions(data)) + } - ty::Predicate::TypeOutlives(ref data) => - ty::Predicate::TypeOutlives(tcx.anonymize_late_bound_regions(data)), + ty::Predicate::TypeOutlives(ref data) => { + ty::Predicate::TypeOutlives(tcx.anonymize_late_bound_regions(data)) + } - ty::Predicate::Projection(ref data) => - ty::Predicate::Projection(tcx.anonymize_late_bound_regions(data)), + ty::Predicate::Projection(ref data) => { + ty::Predicate::Projection(tcx.anonymize_late_bound_regions(data)) + } - ty::Predicate::WellFormed(data) => - ty::Predicate::WellFormed(data), + ty::Predicate::WellFormed(data) => ty::Predicate::WellFormed(data), - ty::Predicate::ObjectSafe(data) => - ty::Predicate::ObjectSafe(data), + ty::Predicate::ObjectSafe(data) => ty::Predicate::ObjectSafe(data), - ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => - ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind), + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) + } - ty::Predicate::Subtype(ref data) => - ty::Predicate::Subtype(tcx.anonymize_late_bound_regions(data)), + ty::Predicate::Subtype(ref data) => { + ty::Predicate::Subtype(tcx.anonymize_late_bound_regions(data)) + } - ty::Predicate::ConstEvaluatable(def_id, substs) => - ty::Predicate::ConstEvaluatable(def_id, substs), + ty::Predicate::ConstEvaluatable(def_id, substs) => { + ty::Predicate::ConstEvaluatable(def_id, substs) + } } } @@ -126,11 +131,11 @@ impl Elaborator<'tcx> { // Get predicates declared on the trait. let predicates = tcx.super_predicates_of(data.def_id()); - let predicates = predicates.predicates + let predicates = predicates + .predicates .iter() .map(|(pred, _)| pred.subst_supertrait(tcx, &data.to_poly_trait_ref())); - debug!("super_predicates: data={:?} predicates={:?}", - data, predicates.clone()); + debug!("super_predicates: data={:?} predicates={:?}", data, predicates.clone()); // Only keep those bounds that we haven't already seen. // This is necessary to prevent infinite recursion in some @@ -194,32 +199,33 @@ impl Elaborator<'tcx> { components .into_iter() .filter_map(|component| match component { - Component::Region(r) => if r.is_late_bound() { - None - } else { - Some(ty::Predicate::RegionOutlives( - ty::Binder::dummy(ty::OutlivesPredicate(r, r_min)))) + Component::Region(r) => { + if r.is_late_bound() { + None + } else { + Some(ty::Predicate::RegionOutlives(ty::Binder::dummy( + ty::OutlivesPredicate(r, r_min), + ))) + } } Component::Param(p) => { let ty = tcx.mk_ty_param(p.index, p.name); - Some(ty::Predicate::TypeOutlives( - ty::Binder::dummy(ty::OutlivesPredicate(ty, r_min)))) + Some(ty::Predicate::TypeOutlives(ty::Binder::dummy( + ty::OutlivesPredicate(ty, r_min), + ))) } - Component::UnresolvedInferenceVariable(_) => { - None - } + Component::UnresolvedInferenceVariable(_) => None, - Component::Projection(_) | - Component::EscapingProjection(_) => { + Component::Projection(_) | Component::EscapingProjection(_) => { // We can probably do more here. This // corresponds to a case like `>::U: 'b`. None } }) - .filter(|p| visited.insert(p)) + .filter(|p| visited.insert(p)), ); } } @@ -289,17 +295,16 @@ pub struct TraitAliasExpansionInfo<'tcx> { impl<'tcx> TraitAliasExpansionInfo<'tcx> { fn new(trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> Self { - Self { - path: smallvec![(trait_ref, span)] - } + Self { path: smallvec![(trait_ref, span)] } } /// Adds diagnostic labels to `diag` for the expansion path of a trait through all intermediate /// trait aliases. - pub fn label_with_exp_info(&self, + pub fn label_with_exp_info( + &self, diag: &mut DiagnosticBuilder<'_>, top_label: &str, - use_desc: &str + use_desc: &str, ) { diag.span_label(self.top().1, top_label); if self.path.len() > 1 { @@ -307,8 +312,10 @@ impl<'tcx> TraitAliasExpansionInfo<'tcx> { diag.span_label(*sp, format!("referenced here ({})", use_desc)); } } - diag.span_label(self.bottom().1, - format!("trait alias used in trait object type ({})", use_desc)); + diag.span_label( + self.bottom().1, + format!("trait alias used in trait object type ({})", use_desc), + ); } pub fn trait_ref(&self) -> &ty::PolyTraitRef<'tcx> { @@ -327,9 +334,7 @@ impl<'tcx> TraitAliasExpansionInfo<'tcx> { let mut path = self.path.clone(); path.push((trait_ref, span)); - Self { - path - } + Self { path } } } @@ -365,22 +370,24 @@ impl<'tcx> TraitAliasExpander<'tcx> { // Don't recurse if this trait alias is already on the stack for the DFS search. let anon_pred = anonymize_predicate(tcx, &pred); - if item.path.iter().rev().skip(1) - .any(|(tr, _)| anonymize_predicate(tcx, &tr.to_predicate()) == anon_pred) { + if item + .path + .iter() + .rev() + .skip(1) + .any(|(tr, _)| anonymize_predicate(tcx, &tr.to_predicate()) == anon_pred) + { return false; } // Get components of trait alias. let predicates = tcx.super_predicates_of(trait_ref.def_id()); - let items = predicates.predicates - .iter() - .rev() - .filter_map(|(pred, span)| { - pred.subst_supertrait(tcx, &trait_ref) - .to_opt_poly_trait_ref() - .map(|trait_ref| item.clone_and_push(trait_ref, *span)) - }); + let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| { + pred.subst_supertrait(tcx, &trait_ref) + .to_opt_poly_trait_ref() + .map(|trait_ref| item.clone_and_push(trait_ref, *span)) + }); debug!("expand_trait_aliases: items={:?}", items.clone()); self.stack.extend(items); @@ -432,11 +439,13 @@ impl Iterator for SupertraitDefIds<'tcx> { let predicates = self.tcx.super_predicates_of(def_id); let visited = &mut self.visited; self.stack.extend( - predicates.predicates - .iter() - .filter_map(|(pred, _)| pred.to_opt_poly_trait_ref()) - .map(|trait_ref| trait_ref.def_id()) - .filter(|&super_def_id| visited.insert(super_def_id))); + predicates + .predicates + .iter() + .filter_map(|(pred, _)| pred.to_opt_poly_trait_ref()) + .map(|trait_ref| trait_ref.def_id()) + .filter(|&super_def_id| visited.insert(super_def_id)), + ); Some(def_id) } } @@ -448,7 +457,7 @@ impl Iterator for SupertraitDefIds<'tcx> { /// A filter around an iterator of predicates that makes it yield up /// just trait references. pub struct FilterToTraits { - base_iterator: I + base_iterator: I, } impl FilterToTraits { @@ -488,10 +497,8 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>( impl_def_id: DefId, impl_substs: SubstsRef<'tcx>, ) -> (ty::TraitRef<'tcx>, Vec>) { - let impl_trait_ref = - selcx.tcx().impl_trait_ref(impl_def_id).unwrap(); - let impl_trait_ref = - impl_trait_ref.subst(selcx.tcx(), impl_substs); + let impl_trait_ref = selcx.tcx().impl_trait_ref(impl_def_id).unwrap(); + let impl_trait_ref = impl_trait_ref.subst(selcx.tcx(), impl_substs); let Normalized { value: impl_trait_ref, obligations: normalization_obligations1 } = super::normalize(selcx, param_env, ObligationCause::dummy(), &impl_trait_ref); @@ -502,8 +509,8 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>( let impl_obligations = predicates_for_generics(ObligationCause::dummy(), 0, param_env, &predicates); - let impl_obligations: Vec<_> = - impl_obligations.into_iter() + let impl_obligations: Vec<_> = impl_obligations + .into_iter() .chain(normalization_obligations1) .chain(normalization_obligations2) .collect(); @@ -520,61 +527,55 @@ pub fn predicates_for_generics<'tcx>( ) -> Vec> { debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds); - generic_bounds.predicates.iter().map(|predicate| Obligation { - cause: cause.clone(), - recursion_depth, - param_env, - predicate: predicate.clone(), - }).collect() + generic_bounds + .predicates + .iter() + .map(|predicate| Obligation { + cause: cause.clone(), + recursion_depth, + param_env, + predicate: predicate.clone(), + }) + .collect() } pub fn predicate_for_trait_ref<'tcx>( cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, trait_ref: ty::TraitRef<'tcx>, - recursion_depth: usize) - -> PredicateObligation<'tcx> -{ - Obligation { - cause, - param_env, - recursion_depth, - predicate: trait_ref.to_predicate(), - } + recursion_depth: usize, +) -> PredicateObligation<'tcx> { + Obligation { cause, param_env, recursion_depth, predicate: trait_ref.to_predicate() } } impl<'tcx> TyCtxt<'tcx> { - pub fn predicate_for_trait_def(self, - param_env: ty::ParamEnv<'tcx>, - cause: ObligationCause<'tcx>, - trait_def_id: DefId, - recursion_depth: usize, - self_ty: Ty<'tcx>, - params: &[GenericArg<'tcx>]) - -> PredicateObligation<'tcx> - { - let trait_ref = ty::TraitRef { - def_id: trait_def_id, - substs: self.mk_substs_trait(self_ty, params) - }; + pub fn predicate_for_trait_def( + self, + param_env: ty::ParamEnv<'tcx>, + cause: ObligationCause<'tcx>, + trait_def_id: DefId, + recursion_depth: usize, + self_ty: Ty<'tcx>, + params: &[GenericArg<'tcx>], + ) -> PredicateObligation<'tcx> { + let trait_ref = + ty::TraitRef { def_id: trait_def_id, substs: self.mk_substs_trait(self_ty, params) }; predicate_for_trait_ref(cause, param_env, trait_ref, recursion_depth) } /// Casts a trait reference into a reference to one of its super /// traits; returns `None` if `target_trait_def_id` is not a /// supertrait. - pub fn upcast_choices(self, - source_trait_ref: ty::PolyTraitRef<'tcx>, - target_trait_def_id: DefId) - -> Vec> - { + pub fn upcast_choices( + self, + source_trait_ref: ty::PolyTraitRef<'tcx>, + target_trait_def_id: DefId, + ) -> Vec> { if source_trait_ref.def_id() == target_trait_def_id { return vec![source_trait_ref]; // Shortcut the most common case. } - supertraits(self, source_trait_ref) - .filter(|r| r.def_id() == target_trait_def_id) - .collect() + supertraits(self, source_trait_ref).filter(|r| r.def_id() == target_trait_def_id).collect() } /// Given a trait `trait_ref`, returns the number of vtable entries @@ -595,9 +596,11 @@ impl<'tcx> TyCtxt<'tcx> { /// Given an upcast trait object described by `object`, returns the /// index of the method `method_def_id` (which should be part of /// `object.upcast_trait_ref`) within the vtable for `object`. - pub fn get_vtable_index_of_object_method(self, - object: &super::VtableObjectData<'tcx, N>, - method_def_id: DefId) -> usize { + pub fn get_vtable_index_of_object_method( + self, + object: &super::VtableObjectData<'tcx, N>, + method_def_id: DefId, + ) -> usize { // Count number of methods preceding the one we are selecting and // add them to the total offset. // Skip over associated types and constants. @@ -613,21 +616,19 @@ impl<'tcx> TyCtxt<'tcx> { } } - bug!("get_vtable_index_of_object_method: {:?} was not found", - method_def_id); + bug!("get_vtable_index_of_object_method: {:?} was not found", method_def_id); } - pub fn closure_trait_ref_and_return_type(self, + pub fn closure_trait_ref_and_return_type( + self, fn_trait_def_id: DefId, self_ty: Ty<'tcx>, sig: ty::PolyFnSig<'tcx>, - tuple_arguments: TupleArgumentsFlag) - -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>)> - { + tuple_arguments: TupleArgumentsFlag, + ) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>)> { let arguments_tuple = match tuple_arguments { TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], - TupleArgumentsFlag::Yes => - self.intern_tup(sig.skip_binder().inputs()), + TupleArgumentsFlag::Yes => self.intern_tup(sig.skip_binder().inputs()), }; let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, @@ -636,16 +637,14 @@ impl<'tcx> TyCtxt<'tcx> { ty::Binder::bind((trait_ref, sig.skip_binder().output())) } - pub fn generator_trait_ref_and_outputs(self, + pub fn generator_trait_ref_and_outputs( + self, fn_trait_def_id: DefId, self_ty: Ty<'tcx>, - sig: ty::PolyGenSig<'tcx>) - -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> - { - let trait_ref = ty::TraitRef { - def_id: fn_trait_def_id, - substs: self.mk_substs_trait(self_ty, &[]), - }; + sig: ty::PolyGenSig<'tcx>, + ) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { + let trait_ref = + ty::TraitRef { def_id: fn_trait_def_id, substs: self.mk_substs_trait(self_ty, &[]) }; ty::Binder::bind((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty)) } @@ -659,10 +658,7 @@ impl<'tcx> TyCtxt<'tcx> { false } } - None => { - self.impl_defaultness(node_item_def_id) - .is_default() - } + None => self.impl_defaultness(node_item_def_id).is_default(), } } @@ -671,4 +667,7 @@ impl<'tcx> TyCtxt<'tcx> { } } -pub enum TupleArgumentsFlag { Yes, No } +pub enum TupleArgumentsFlag { + Yes, + No, +} diff --git a/src/librustc/ty/_match.rs b/src/librustc/ty/_match.rs index ea8a6ff2b2e52..35f8eb20475c7 100644 --- a/src/librustc/ty/_match.rs +++ b/src/librustc/ty/_match.rs @@ -1,6 +1,6 @@ -use crate::ty::{self, Ty, TyCtxt, InferConst}; use crate::ty::error::TypeError; -use crate::ty::relate::{self, Relate, TypeRelation, RelateResult}; +use crate::ty::relate::{self, Relate, RelateResult, TypeRelation}; +use crate::ty::{self, InferConst, Ty, TyCtxt}; /// A type "A" *matches* "B" if the fresh types in B could be /// substituted with values so as to make it equal to A. Matching is @@ -30,53 +30,55 @@ impl Match<'tcx> { } impl TypeRelation<'tcx> for Match<'tcx> { - fn tag(&self) -> &'static str { "Match" } - fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } - fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } - fn a_is_expected(&self) -> bool { true } // irrelevant - - fn relate_with_variance>(&mut self, - _: ty::Variance, - a: &T, - b: &T) - -> RelateResult<'tcx, T> - { + fn tag(&self) -> &'static str { + "Match" + } + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { + self.param_env + } + fn a_is_expected(&self) -> bool { + true + } // irrelevant + + fn relate_with_variance>( + &mut self, + _: ty::Variance, + a: &T, + b: &T, + ) -> RelateResult<'tcx, T> { self.relate(a, b) } - fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) - -> RelateResult<'tcx, ty::Region<'tcx>> { - debug!("{}.regions({:?}, {:?})", - self.tag(), - a, - b); + fn regions( + &mut self, + a: ty::Region<'tcx>, + b: ty::Region<'tcx>, + ) -> RelateResult<'tcx, ty::Region<'tcx>> { + debug!("{}.regions({:?}, {:?})", self.tag(), a, b); Ok(a) } fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { - debug!("{}.tys({:?}, {:?})", self.tag(), - a, b); - if a == b { return Ok(a); } + debug!("{}.tys({:?}, {:?})", self.tag(), a, b); + if a == b { + return Ok(a); + } match (&a.kind, &b.kind) { - (_, &ty::Infer(ty::FreshTy(_))) | - (_, &ty::Infer(ty::FreshIntTy(_))) | - (_, &ty::Infer(ty::FreshFloatTy(_))) => { - Ok(a) - } + (_, &ty::Infer(ty::FreshTy(_))) + | (_, &ty::Infer(ty::FreshIntTy(_))) + | (_, &ty::Infer(ty::FreshFloatTy(_))) => Ok(a), - (&ty::Infer(_), _) | - (_, &ty::Infer(_)) => { + (&ty::Infer(_), _) | (_, &ty::Infer(_)) => { Err(TypeError::Sorts(relate::expected_found(self, &a, &b))) } - (&ty::Error, _) | (_, &ty::Error) => { - Ok(self.tcx().types.err) - } + (&ty::Error, _) | (_, &ty::Error) => Ok(self.tcx().types.err), - _ => { - relate::super_relate_tys(self, a, b) - } + _ => relate::super_relate_tys(self, a, b), } } @@ -105,9 +107,13 @@ impl TypeRelation<'tcx> for Match<'tcx> { relate::super_relate_consts(self, a, b) } - fn binders(&mut self, a: &ty::Binder, b: &ty::Binder) - -> RelateResult<'tcx, ty::Binder> - where T: Relate<'tcx> + fn binders( + &mut self, + a: &ty::Binder, + b: &ty::Binder, + ) -> RelateResult<'tcx, ty::Binder> + where + T: Relate<'tcx>, { Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?)) } diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index 0c04ba96365ed..e1b63a6d9e703 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -1,10 +1,9 @@ use crate::hir; use crate::hir::def_id::DefId; -use crate::ty::{self, Ty, TyCtxt}; use crate::ty::subst::SubstsRef; +use crate::ty::{self, Ty, TyCtxt}; use rustc_macros::HashStable; - #[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)] pub enum PointerCast { /// Go from a fn-item type to a fn-pointer type. @@ -110,10 +109,13 @@ impl<'tcx> OverloadedDeref<'tcx> { pub fn method_call(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> (DefId, SubstsRef<'tcx>) { let trait_def_id = match self.mutbl { hir::Mutability::Not => tcx.lang_items().deref_trait(), - hir::Mutability::Mut => tcx.lang_items().deref_mut_trait() + hir::Mutability::Mut => tcx.lang_items().deref_mut_trait(), }; - let method_def_id = tcx.associated_items(trait_def_id.unwrap()) - .find(|m| m.kind == ty::AssocKind::Method).unwrap().def_id; + let method_def_id = tcx + .associated_items(trait_def_id.unwrap()) + .find(|m| m.kind == ty::AssocKind::Method) + .unwrap() + .def_id; (method_def_id, tcx.mk_substs_trait(source, &[])) } } @@ -133,7 +135,7 @@ impl<'tcx> OverloadedDeref<'tcx> { #[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)] pub enum AllowTwoPhase { Yes, - No + No, } #[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)] @@ -172,11 +174,11 @@ pub struct CoerceUnsizedInfo { /// coercion is it? This applies to impls of `CoerceUnsized` for /// structs, primarily, where we store a bit of info about which /// fields need to be coerced. - pub custom_kind: Option + pub custom_kind: Option, } #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum CustomCoerceUnsized { /// Records the index of the field being coerced. - Struct(usize) + Struct(usize), } diff --git a/src/librustc/ty/binding.rs b/src/librustc/ty/binding.rs index 00cff1f1be17f..222950785acd8 100644 --- a/src/librustc/ty/binding.rs +++ b/src/librustc/ty/binding.rs @@ -1,5 +1,5 @@ -use crate::hir::BindingAnnotation::*; use crate::hir::BindingAnnotation; +use crate::hir::BindingAnnotation::*; use crate::hir::Mutability; #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)] diff --git a/src/librustc/ty/cast.rs b/src/librustc/ty/cast.rs index fca53db1475a0..5ba3f80b82296 100644 --- a/src/librustc/ty/cast.rs +++ b/src/librustc/ty/cast.rs @@ -3,8 +3,8 @@ use crate::ty::{self, Ty}; -use syntax::ast; use rustc_macros::HashStable; +use syntax::ast; /// Types that are represented as ints. #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -13,7 +13,7 @@ pub enum IntTy { I, CEnum, Bool, - Char + Char, } // Valid types for the result of a non-coercion cast @@ -43,7 +43,7 @@ pub enum CastKind { U8CharCast, ArrayPtrCast, FnPtrPtrCast, - FnPtrAddrCast + FnPtrAddrCast, } impl<'tcx> CastTy<'tcx> { @@ -58,8 +58,7 @@ impl<'tcx> CastTy<'tcx> { ty::Infer(ty::InferTy::FloatVar(_)) => Some(CastTy::Float), ty::Uint(u) => Some(CastTy::Int(IntTy::U(u))), ty::Float(_) => Some(CastTy::Float), - ty::Adt(d,_) if d.is_enum() && d.is_payloadfree() => - Some(CastTy::Int(IntTy::CEnum)), + ty::Adt(d, _) if d.is_enum() && d.is_payloadfree() => Some(CastTy::Int(IntTy::CEnum)), ty::RawPtr(mt) => Some(CastTy::Ptr(mt)), ty::FnPtr(..) => Some(CastTy::FnPtr), _ => None, diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index 10c6a349ec801..d55b756adf6d1 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -7,15 +7,15 @@ // persisting to incr. comp. caches. use crate::arena::ArenaAllocatable; -use crate::hir::def_id::{DefId, CrateNum}; +use crate::hir::def_id::{CrateNum, DefId}; use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; +use crate::mir::{self, interpret::Allocation}; +use crate::ty::subst::SubstsRef; +use crate::ty::{self, List, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; -use rustc_serialize::{Decodable, Decoder, Encoder, Encodable, opaque}; +use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder}; use std::hash::Hash; use std::intrinsics; -use crate::ty::{self, List, Ty, TyCtxt}; -use crate::ty::subst::SubstsRef; -use crate::mir::{self, interpret::Allocation}; use syntax_pos::Span; /// The shorthand encoding uses an enum's variant index `usize` @@ -55,13 +55,11 @@ impl TyEncoder for opaque::Encoder { } /// Encode the given value or a previously cached shorthand. -pub fn encode_with_shorthand(encoder: &mut E, - value: &T, - cache: M) - -> Result<(), E::Error> - where E: TyEncoder, - M: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap, - T: EncodableWithShorthand, +pub fn encode_with_shorthand(encoder: &mut E, value: &T, cache: M) -> Result<(), E::Error> +where + E: TyEncoder, + M: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap, + T: EncodableWithShorthand, { let existing_shorthand = cache(encoder).get(value).cloned(); if let Some(shorthand) = existing_shorthand { @@ -98,8 +96,9 @@ pub fn encode_spanned_predicates<'tcx, E, C>( predicates: &'tcx [(ty::Predicate<'tcx>, Span)], cache: C, ) -> Result<(), E::Error> - where E: TyEncoder, - C: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap, usize>, +where + E: TyEncoder, + C: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap, usize>, { predicates.len().encode(encoder)?; for (predicate, span) in predicates { @@ -116,14 +115,17 @@ pub trait TyDecoder<'tcx>: Decoder { fn position(&self) -> usize; - fn cached_ty_for_shorthand(&mut self, - shorthand: usize, - or_insert_with: F) - -> Result, Self::Error> - where F: FnOnce(&mut Self) -> Result, Self::Error>; + fn cached_ty_for_shorthand( + &mut self, + shorthand: usize, + or_insert_with: F, + ) -> Result, Self::Error> + where + F: FnOnce(&mut Self) -> Result, Self::Error>; fn with_position(&mut self, pos: usize, f: F) -> R - where F: FnOnce(&mut Self) -> R; + where + F: FnOnce(&mut Self) -> R; fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum; @@ -191,20 +193,21 @@ where { let tcx = decoder.tcx(); Ok(tcx.arena.alloc_from_iter( - (0..decoder.read_usize()?).map(|_| { - // Handle shorthands first, if we have an usize > 0x80. - let predicate = if decoder.positioned_at_shorthand() { - let pos = decoder.read_usize()?; - assert!(pos >= SHORTHAND_OFFSET); - let shorthand = pos - SHORTHAND_OFFSET; - - decoder.with_position(shorthand, ty::Predicate::decode) - } else { - ty::Predicate::decode(decoder) - }?; - Ok((predicate, Decodable::decode(decoder)?)) - }) - .collect::, _>>()?, + (0..decoder.read_usize()?) + .map(|_| { + // Handle shorthands first, if we have an usize > 0x80. + let predicate = if decoder.positioned_at_shorthand() { + let pos = decoder.read_usize()?; + assert!(pos >= SHORTHAND_OFFSET); + let shorthand = pos - SHORTHAND_OFFSET; + + decoder.with_position(shorthand, ty::Predicate::decode) + } else { + ty::Predicate::decode(decoder) + }?; + Ok((predicate, Decodable::decode(decoder)?)) + }) + .collect::, _>>()?, )) } @@ -264,8 +267,7 @@ where D: TyDecoder<'tcx>, { let len = decoder.read_usize()?; - Ok(decoder.tcx() - .mk_existential_predicates((0..len).map(|_| Decodable::decode(decoder)))?) + Ok(decoder.tcx().mk_existential_predicates((0..len).map(|_| Decodable::decode(decoder)))?) } #[inline] @@ -274,10 +276,9 @@ where D: TyDecoder<'tcx>, { let len = decoder.read_usize()?; - let interned: Result, _> = (0..len).map(|_| Decodable::decode(decoder)) - .collect(); - Ok(decoder.tcx() - .intern_canonical_var_infos(interned?.as_slice())) + let interned: Result, _> = + (0..len).map(|_| Decodable::decode(decoder)).collect(); + Ok(decoder.tcx().intern_canonical_var_infos(interned?.as_slice())) } #[inline] diff --git a/src/librustc/ty/diagnostics.rs b/src/librustc/ty/diagnostics.rs index 3a55aefe85d3d..d1eb21e25ffaf 100644 --- a/src/librustc/ty/diagnostics.rs +++ b/src/librustc/ty/diagnostics.rs @@ -1,16 +1,23 @@ //! Diagnostics related methods for `TyS`. -use crate::ty::TyS; -use crate::ty::TyKind::*; use crate::ty::sty::InferTy; +use crate::ty::TyKind::*; +use crate::ty::TyS; impl<'tcx> TyS<'tcx> { /// Similar to `TyS::is_primitive`, but also considers inferred numeric values to be primitive. pub fn is_primitive_ty(&self) -> bool { match self.kind { - Bool | Char | Str | Int(_) | Uint(_) | Float(_) | - Infer(InferTy::IntVar(_)) | Infer(InferTy::FloatVar(_)) | - Infer(InferTy::FreshIntTy(_)) | Infer(InferTy::FreshFloatTy(_)) => true, + Bool + | Char + | Str + | Int(_) + | Uint(_) + | Float(_) + | Infer(InferTy::IntVar(_)) + | Infer(InferTy::FloatVar(_)) + | Infer(InferTy::FreshIntTy(_)) + | Infer(InferTy::FreshFloatTy(_)) => true, _ => false, } } @@ -19,9 +26,16 @@ impl<'tcx> TyS<'tcx> { /// description in error messages. This is used in the main error message. pub fn is_simple_ty(&self) -> bool { match self.kind { - Bool | Char | Str | Int(_) | Uint(_) | Float(_) | - Infer(InferTy::IntVar(_)) | Infer(InferTy::FloatVar(_)) | - Infer(InferTy::FreshIntTy(_)) | Infer(InferTy::FreshFloatTy(_)) => true, + Bool + | Char + | Str + | Int(_) + | Uint(_) + | Float(_) + | Infer(InferTy::IntVar(_)) + | Infer(InferTy::FloatVar(_)) + | Infer(InferTy::FreshIntTy(_)) + | Infer(InferTy::FreshFloatTy(_)) => true, Ref(_, x, _) | Array(x, _) | Slice(x) => x.peel_refs().is_simple_ty(), Tuple(tys) if tys.is_empty() => true, _ => false, @@ -43,13 +57,8 @@ impl<'tcx> TyS<'tcx> { /// Whether the type can be safely suggested during error recovery. pub fn is_suggestable(&self) -> bool { match self.kind { - Opaque(..) | - FnDef(..) | - FnPtr(..) | - Dynamic(..) | - Closure(..) | - Infer(..) | - Projection(..) => false, + Opaque(..) | FnDef(..) | FnPtr(..) | Dynamic(..) | Closure(..) | Infer(..) + | Projection(..) => false, _ => true, } } diff --git a/src/librustc/ty/erase_regions.rs b/src/librustc/ty/erase_regions.rs index 3dd1fd100f2a4..4bf08096edeb8 100644 --- a/src/librustc/ty/erase_regions.rs +++ b/src/librustc/ty/erase_regions.rs @@ -1,11 +1,8 @@ +use crate::ty::fold::{TypeFoldable, TypeFolder}; use crate::ty::{self, Ty, TyCtxt, TypeFlags}; -use crate::ty::fold::{TypeFolder, TypeFoldable}; pub(super) fn provide(providers: &mut ty::query::Providers<'_>) { - *providers = ty::query::Providers { - erase_regions_ty, - ..*providers - }; + *providers = ty::query::Providers { erase_regions_ty, ..*providers }; } fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { @@ -19,7 +16,8 @@ impl<'tcx> TyCtxt<'tcx> { /// that late-bound regions remain, because they are important for /// subtyping, but they are anonymized and normalized as well).. pub fn erase_regions(self, value: &T) -> T - where T : TypeFoldable<'tcx> + where + T: TypeFoldable<'tcx>, { // If there's nothing to erase avoid performing the query at all if !value.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) { @@ -42,15 +40,12 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if ty.has_local_value() { - ty.super_fold_with(self) - } else { - self.tcx.erase_regions_ty(ty) - } + if ty.has_local_value() { ty.super_fold_with(self) } else { self.tcx.erase_regions_ty(ty) } } fn fold_binder(&mut self, t: &ty::Binder) -> ty::Binder - where T : TypeFoldable<'tcx> + where + T: TypeFoldable<'tcx>, { let u = self.tcx.anonymize_late_bound_regions(t); u.super_fold_with(self) @@ -67,7 +62,7 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { // whenever a substitution occurs. match *r { ty::ReLateBound(..) => r, - _ => self.tcx.lifetimes.re_erased + _ => self.tcx.lifetimes.re_erased, } } } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 0218cb1d6fda7..c4a134926aed9 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -79,109 +79,102 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { } } - let br_string = |br: ty::BoundRegion| { - match br { - ty::BrNamed(_, name) => format!(" {}", name), - _ => String::new(), - } + let br_string = |br: ty::BoundRegion| match br { + ty::BrNamed(_, name) => format!(" {}", name), + _ => String::new(), }; match *self { CyclicTy(_) => write!(f, "cyclic type of infinite size"), Mismatch => write!(f, "types differ"), UnsafetyMismatch(values) => { - write!(f, "expected {} fn, found {} fn", - values.expected, - values.found) + write!(f, "expected {} fn, found {} fn", values.expected, values.found) } AbiMismatch(values) => { - write!(f, "expected {} fn, found {} fn", - values.expected, - values.found) + write!(f, "expected {} fn, found {} fn", values.expected, values.found) } Mutability => write!(f, "types differ in mutability"), - TupleSize(values) => { - write!(f, "expected a tuple with {} element{}, \ + TupleSize(values) => write!( + f, + "expected a tuple with {} element{}, \ found one with {} element{}", - values.expected, - pluralize!(values.expected), - values.found, - pluralize!(values.found)) - } - FixedArraySize(values) => { - write!(f, "expected an array with a fixed size of {} element{}, \ + values.expected, + pluralize!(values.expected), + values.found, + pluralize!(values.found) + ), + FixedArraySize(values) => write!( + f, + "expected an array with a fixed size of {} element{}, \ found one with {} element{}", - values.expected, - pluralize!(values.expected), - values.found, - pluralize!(values.found)) - } - ArgCount => { - write!(f, "incorrect number of function parameters") - } - RegionsDoesNotOutlive(..) => { - write!(f, "lifetime mismatch") - } - RegionsInsufficientlyPolymorphic(br, _) => { - write!(f, - "expected bound lifetime parameter{}, found concrete lifetime", - br_string(br)) - } - RegionsOverlyPolymorphic(br, _) => { - write!(f, - "expected concrete lifetime, found bound lifetime parameter{}", - br_string(br)) - } - RegionsPlaceholderMismatch => { - write!(f, "one type is more general than the other") - } + values.expected, + pluralize!(values.expected), + values.found, + pluralize!(values.found) + ), + ArgCount => write!(f, "incorrect number of function parameters"), + RegionsDoesNotOutlive(..) => write!(f, "lifetime mismatch"), + RegionsInsufficientlyPolymorphic(br, _) => write!( + f, + "expected bound lifetime parameter{}, found concrete lifetime", + br_string(br) + ), + RegionsOverlyPolymorphic(br, _) => write!( + f, + "expected concrete lifetime, found bound lifetime parameter{}", + br_string(br) + ), + RegionsPlaceholderMismatch => write!(f, "one type is more general than the other"), Sorts(values) => ty::tls::with(|tcx| { - report_maybe_different(f, &values.expected.sort_string(tcx), - &values.found.sort_string(tcx)) + report_maybe_different( + f, + &values.expected.sort_string(tcx), + &values.found.sort_string(tcx), + ) }), Traits(values) => ty::tls::with(|tcx| { - report_maybe_different(f, - &format!("trait `{}`", - tcx.def_path_str(values.expected)), - &format!("trait `{}`", - tcx.def_path_str(values.found))) + report_maybe_different( + f, + &format!("trait `{}`", tcx.def_path_str(values.expected)), + &format!("trait `{}`", tcx.def_path_str(values.found)), + ) }), IntMismatch(ref values) => { - write!(f, "expected `{:?}`, found `{:?}`", - values.expected, - values.found) + write!(f, "expected `{:?}`, found `{:?}`", values.expected, values.found) } FloatMismatch(ref values) => { - write!(f, "expected `{:?}`, found `{:?}`", - values.expected, - values.found) - } - VariadicMismatch(ref values) => { - write!(f, "expected {} fn, found {} function", - if values.expected { "variadic" } else { "non-variadic" }, - if values.found { "variadic" } else { "non-variadic" }) + write!(f, "expected `{:?}`, found `{:?}`", values.expected, values.found) } + VariadicMismatch(ref values) => write!( + f, + "expected {} fn, found {} function", + if values.expected { "variadic" } else { "non-variadic" }, + if values.found { "variadic" } else { "non-variadic" } + ), ProjectionMismatched(ref values) => ty::tls::with(|tcx| { - write!(f, "expected {}, found {}", - tcx.def_path_str(values.expected), - tcx.def_path_str(values.found)) + write!( + f, + "expected {}, found {}", + tcx.def_path_str(values.expected), + tcx.def_path_str(values.found) + ) }), - ProjectionBoundsLength(ref values) => { - write!(f, "expected {} associated type binding{}, found {}", - values.expected, - pluralize!(values.expected), - values.found) - }, - ExistentialMismatch(ref values) => { - report_maybe_different(f, &format!("trait `{}`", values.expected), - &format!("trait `{}`", values.found)) - } + ProjectionBoundsLength(ref values) => write!( + f, + "expected {} associated type binding{}, found {}", + values.expected, + pluralize!(values.expected), + values.found + ), + ExistentialMismatch(ref values) => report_maybe_different( + f, + &format!("trait `{}`", values.expected), + &format!("trait `{}`", values.found), + ), ConstMismatch(ref values) => { write!(f, "expected `{}`, found `{}`", values.expected, values.found) } - IntrinsicCast => { - write!(f, "cannot coerce intrinsics to function pointers") - } + IntrinsicCast => write!(f, "cannot coerce intrinsics to function pointers"), ObjectUnsafeCoercion(_) => write!(f, "coercion to object-unsafe trait object"), } } @@ -191,30 +184,23 @@ impl<'tcx> TypeError<'tcx> { pub fn must_include_note(&self) -> bool { use self::TypeError::*; match self { - CyclicTy(_) | - UnsafetyMismatch(_) | - Mismatch | - AbiMismatch(_) | - FixedArraySize(_) | - Sorts(_) | - IntMismatch(_) | - FloatMismatch(_) | - VariadicMismatch(_) => false, + CyclicTy(_) | UnsafetyMismatch(_) | Mismatch | AbiMismatch(_) | FixedArraySize(_) + | Sorts(_) | IntMismatch(_) | FloatMismatch(_) | VariadicMismatch(_) => false, - Mutability | - TupleSize(_) | - ArgCount | - RegionsDoesNotOutlive(..) | - RegionsInsufficientlyPolymorphic(..) | - RegionsOverlyPolymorphic(..) | - RegionsPlaceholderMismatch | - Traits(_) | - ProjectionMismatched(_) | - ProjectionBoundsLength(_) | - ExistentialMismatch(_) | - ConstMismatch(_) | - IntrinsicCast | - ObjectUnsafeCoercion(_) => true, + Mutability + | TupleSize(_) + | ArgCount + | RegionsDoesNotOutlive(..) + | RegionsInsufficientlyPolymorphic(..) + | RegionsOverlyPolymorphic(..) + | RegionsPlaceholderMismatch + | Traits(_) + | ProjectionMismatched(_) + | ProjectionBoundsLength(_) + | ExistentialMismatch(_) + | ConstMismatch(_) + | IntrinsicCast + | ObjectUnsafeCoercion(_) => true, } } } @@ -222,8 +208,9 @@ impl<'tcx> TypeError<'tcx> { impl<'tcx> ty::TyS<'tcx> { pub fn sort_string(&self, tcx: TyCtxt<'_>) -> Cow<'static, str> { match self.kind { - ty::Bool | ty::Char | ty::Int(_) | - ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => format!("`{}`", self).into(), + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => { + format!("`{}`", self).into() + } ty::Tuple(ref tys) if tys.is_empty() => format!("`{}`", self).into(), ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(), @@ -242,15 +229,17 @@ impl<'tcx> ty::TyS<'tcx> { ty::Ref(_, ty, mutbl) => { let tymut = ty::TypeAndMut { ty, mutbl }; let tymut_string = tymut.to_string(); - if tymut_string != "_" && ( - ty.is_simple_text() || tymut_string.len() < "mutable reference".len() - ) { + if tymut_string != "_" + && (ty.is_simple_text() || tymut_string.len() < "mutable reference".len()) + { format!("`&{}`", tymut_string).into() - } else { // Unknown type name, it's long or has type arguments + } else { + // Unknown type name, it's long or has type arguments match mutbl { hir::Mutability::Mut => "mutable reference", _ => "reference", - }.into() + } + .into() } } ty::FnDef(..) => "fn item".into(), @@ -284,8 +273,15 @@ impl<'tcx> ty::TyS<'tcx> { pub fn prefix_string(&self) -> Cow<'static, str> { match self.kind { - ty::Infer(_) | ty::Error | ty::Bool | ty::Char | ty::Int(_) | - ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => "type".into(), + ty::Infer(_) + | ty::Error + | ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Str + | ty::Never => "type".into(), ty::Tuple(ref tys) if tys.is_empty() => "unit type".into(), ty::Adt(def, _) => def.descr().into(), ty::Foreign(_) => "extern type".into(), @@ -294,8 +290,9 @@ impl<'tcx> ty::TyS<'tcx> { ty::RawPtr(_) => "raw pointer".into(), ty::Ref(.., mutbl) => match mutbl { hir::Mutability::Mut => "mutable reference", - _ => "reference" - }.into(), + _ => "reference", + } + .into(), ty::FnDef(..) => "fn item".into(), ty::FnPtr(_) => "fn pointer".into(), ty::Dynamic(..) => "trait object".into(), @@ -331,29 +328,36 @@ impl<'tcx> TyCtxt<'tcx> { db.note("no two closures, even if identical, have the same type"); db.help("consider boxing your closure and/or using it as a trait object"); } - if expected_str == found_str && expected_str == "opaque type" { // Issue #63167 + if expected_str == found_str && expected_str == "opaque type" { + // Issue #63167 db.note("distinct uses of `impl Trait` result in different opaque types"); let e_str = values.expected.to_string(); let f_str = values.found.to_string(); if &e_str == &f_str && &e_str == "impl std::future::Future" { // FIXME: use non-string based check. - db.help("if both `Future`s have the same `Output` type, consider \ - `.await`ing on both of them"); + db.help( + "if both `Future`s have the same `Output` type, consider \ + `.await`ing on both of them", + ); } } match (&values.expected.kind, &values.found.kind) { - (ty::Float(_), ty::Infer(ty::IntVar(_))) => if let Ok( // Issue #53280 - snippet, - ) = self.sess.source_map().span_to_snippet(sp) { - if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') { - db.span_suggestion( - sp, - "use a float literal", - format!("{}.0", snippet), - Applicability::MachineApplicable - ); + (ty::Float(_), ty::Infer(ty::IntVar(_))) => { + if let Ok( + // Issue #53280 + snippet, + ) = self.sess.source_map().span_to_snippet(sp) + { + if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') { + db.span_suggestion( + sp, + "use a float literal", + format!("{}.0", snippet), + Applicability::MachineApplicable, + ); + } } - }, + } (ty::Param(expected), ty::Param(found)) => { let generics = self.generics_of(body_owner_def_id); let e_span = self.def_span(generics.type_param(expected, self).def_id); @@ -364,11 +368,15 @@ impl<'tcx> TyCtxt<'tcx> { if !sp.contains(f_span) { db.span_label(f_span, "found type parameter"); } - db.note("a type parameter was expected, but a different one was found; \ - you might be missing a type parameter or trait bound"); - db.note("for more information, visit \ + db.note( + "a type parameter was expected, but a different one was found; \ + you might be missing a type parameter or trait bound", + ); + db.note( + "for more information, visit \ https://doc.rust-lang.org/book/ch10-02-traits.html\ - #traits-as-parameters"); + #traits-as-parameters", + ); } (ty::Projection(_), ty::Projection(_)) => { db.note("an associated type was expected, but a different one was found"); @@ -384,7 +392,8 @@ impl<'tcx> TyCtxt<'tcx> { } db.help("type parameters must be constrained to match other types"); if self.sess.teach(&db.get_code().unwrap()) { - db.help("given a type parameter `T` and a method `foo`: + db.help( + "given a type parameter `T` and a method `foo`: ``` trait Trait { fn foo(&self) -> T; } ``` @@ -406,22 +415,24 @@ impl Trait for X { impl Trait for X { fn foo(&self, x: T) -> T { x } } -```"); +```", + ); } - db.note("for more information, visit \ + db.note( + "for more information, visit \ https://doc.rust-lang.org/book/ch10-02-traits.html\ - #traits-as-parameters"); + #traits-as-parameters", + ); } (ty::Projection(_), _) => { db.note(&format!( "consider constraining the associated type `{}` to `{}` or calling a \ method that returns `{}`", - values.expected, - values.found, - values.expected, + values.expected, values.found, values.expected, )); if self.sess.teach(&db.get_code().unwrap()) { - db.help("given an associated type `T` and a method `foo`: + db.help( + "given an associated type `T` and a method `foo`: ``` trait Trait { type T; @@ -434,36 +445,39 @@ impl Trait for X { type T = String; fn foo(&self) -> Self::T { String::new() } } -```"); +```", + ); } - db.note("for more information, visit \ - https://doc.rust-lang.org/book/ch19-03-advanced-traits.html"); + db.note( + "for more information, visit \ + https://doc.rust-lang.org/book/ch19-03-advanced-traits.html", + ); } (_, ty::Projection(_)) => { db.note(&format!( "consider constraining the associated type `{}` to `{}`", - values.found, - values.expected, + values.found, values.expected, )); - db.note("for more information, visit \ - https://doc.rust-lang.org/book/ch19-03-advanced-traits.html"); + db.note( + "for more information, visit \ + https://doc.rust-lang.org/book/ch19-03-advanced-traits.html", + ); } _ => {} } debug!( "note_and_explain_type_err expected={:?} ({:?}) found={:?} ({:?})", - values.expected, - values.expected.kind, - values.found, - values.found.kind, + values.expected, values.expected.kind, values.found, values.found.kind, ); - }, + } CyclicTy(ty) => { // Watch out for various cases of cyclic types and try to explain. if ty.is_closure() || ty.is_generator() { - db.note("closures cannot capture themselves or take themselves as argument;\n\ + db.note( + "closures cannot capture themselves or take themselves as argument;\n\ this error may be the result of a recent compiler bug-fix,\n\ - see https://github.com/rust-lang/rust/issues/46062 for more details"); + see https://github.com/rust-lang/rust/issues/46062 for more details", + ); } } _ => {} diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 27a09b394b8fa..f5dce6b3958a2 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -1,11 +1,11 @@ use crate::hir::def_id::DefId; use crate::ich::StableHashingContext; -use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; +use crate::ty::{self, Ty, TyCtxt}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use std::fmt::Debug; use std::hash::Hash; use std::mem; use syntax::ast; -use crate::ty::{self, Ty, TyCtxt}; use self::SimplifiedTypeGen::*; @@ -19,7 +19,8 @@ pub type SimplifiedType = SimplifiedTypeGen; /// the non-stable but fast to construct DefId-version is the better choice. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, RustcEncodable, RustcDecodable)] pub enum SimplifiedTypeGen - where D: Copy + Debug + Ord + Eq +where + D: Copy + Debug + Ord + Eq, { BoolSimplifiedType, CharSimplifiedType, @@ -69,37 +70,26 @@ pub fn simplify_type( ty::Str => Some(StrSimplifiedType), ty::Array(..) | ty::Slice(_) => Some(ArraySimplifiedType), ty::RawPtr(_) => Some(PtrSimplifiedType), - ty::Dynamic(ref trait_info, ..) => { - match trait_info.principal_def_id() { - Some(principal_def_id) if !tcx.trait_is_auto(principal_def_id) => { - Some(TraitSimplifiedType(principal_def_id)) - } - _ => Some(MarkerTraitObjectSimplifiedType) + ty::Dynamic(ref trait_info, ..) => match trait_info.principal_def_id() { + Some(principal_def_id) if !tcx.trait_is_auto(principal_def_id) => { + Some(TraitSimplifiedType(principal_def_id)) } - } + _ => Some(MarkerTraitObjectSimplifiedType), + }, ty::Ref(_, ty, _) => { // since we introduce auto-refs during method lookup, we // just treat &T and T as equivalent from the point of // view of possibly unifying simplify_type(tcx, ty, can_simplify_params) } - ty::FnDef(def_id, _) | - ty::Closure(def_id, _) => { - Some(ClosureSimplifiedType(def_id)) - } - ty::Generator(def_id, _, _) => { - Some(GeneratorSimplifiedType(def_id)) - } + ty::FnDef(def_id, _) | ty::Closure(def_id, _) => Some(ClosureSimplifiedType(def_id)), + ty::Generator(def_id, _, _) => Some(GeneratorSimplifiedType(def_id)), ty::GeneratorWitness(ref tys) => { Some(GeneratorWitnessSimplifiedType(tys.skip_binder().len())) } ty::Never => Some(NeverSimplifiedType), - ty::Tuple(ref tys) => { - Some(TupleSimplifiedType(tys.len())) - } - ty::FnPtr(ref f) => { - Some(FunctionSimplifiedType(f.skip_binder().inputs().len())) - } + ty::Tuple(ref tys) => Some(TupleSimplifiedType(tys.len())), + ty::FnPtr(ref f) => Some(FunctionSimplifiedType(f.skip_binder().inputs().len())), ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), ty::Projection(_) | ty::Param(_) => { if can_simplify_params { @@ -113,20 +103,17 @@ pub fn simplify_type( None } } - ty::Opaque(def_id, _) => { - Some(OpaqueSimplifiedType(def_id)) - } - ty::Foreign(def_id) => { - Some(ForeignSimplifiedType(def_id)) - } + ty::Opaque(def_id, _) => Some(OpaqueSimplifiedType(def_id)), + ty::Foreign(def_id) => Some(ForeignSimplifiedType(def_id)), ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) | ty::Error => None, } } impl SimplifiedTypeGen { pub fn map_def(self, map: F) -> SimplifiedTypeGen - where F: Fn(D) -> U, - U: Copy + Debug + Ord + Eq, + where + F: Fn(D) -> U, + U: Copy + Debug + Ord + Eq, { match self { BoolSimplifiedType => BoolSimplifiedType, @@ -160,14 +147,14 @@ where fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { - BoolSimplifiedType | - CharSimplifiedType | - StrSimplifiedType | - ArraySimplifiedType | - PtrSimplifiedType | - NeverSimplifiedType | - ParameterSimplifiedType | - MarkerTraitObjectSimplifiedType => { + BoolSimplifiedType + | CharSimplifiedType + | StrSimplifiedType + | ArraySimplifiedType + | PtrSimplifiedType + | NeverSimplifiedType + | ParameterSimplifiedType + | MarkerTraitObjectSimplifiedType => { // nothing to do } IntSimplifiedType(t) => t.hash_stable(hcx, hasher), diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index aee0ec7806b76..b9aa12b466589 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -1,5 +1,5 @@ -use crate::ty::subst::{SubstsRef, GenericArgKind}; -use crate::ty::{self, Ty, TypeFlags, InferConst}; +use crate::ty::subst::{GenericArgKind, SubstsRef}; +use crate::ty::{self, InferConst, Ty, TypeFlags}; #[derive(Debug)] pub struct FlagComputation { @@ -11,10 +11,7 @@ pub struct FlagComputation { impl FlagComputation { fn new() -> FlagComputation { - FlagComputation { - flags: TypeFlags::empty(), - outer_exclusive_binder: ty::INNERMOST, - } + FlagComputation { flags: TypeFlags::empty(), outer_exclusive_binder: ty::INNERMOST } } #[allow(rustc::usage_of_ty_tykind)] @@ -64,15 +61,14 @@ impl FlagComputation { #[allow(rustc::usage_of_ty_tykind)] fn add_kind(&mut self, kind: &ty::TyKind<'_>) { match kind { - &ty::Bool | - &ty::Char | - &ty::Int(_) | - &ty::Float(_) | - &ty::Uint(_) | - &ty::Never | - &ty::Str | - &ty::Foreign(..) => { - } + &ty::Bool + | &ty::Char + | &ty::Int(_) + | &ty::Float(_) + | &ty::Uint(_) + | &ty::Never + | &ty::Str + | &ty::Foreign(..) => {} // You might think that we could just return Error for // any type containing Error as a component, and get @@ -81,9 +77,7 @@ impl FlagComputation { // But doing so caused sporadic memory corruption, and // neither I (tjc) nor nmatsakis could figure out why, // so we're doing it this way. - &ty::Error => { - self.add_flags(TypeFlags::HAS_TY_ERR) - } + &ty::Error => self.add_flags(TypeFlags::HAS_TY_ERR), &ty::Param(_) => { self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES); @@ -121,13 +115,9 @@ impl FlagComputation { self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES); // it might, right? self.add_flags(TypeFlags::HAS_TY_INFER); match infer { - ty::FreshTy(_) | - ty::FreshIntTy(_) | - ty::FreshFloatTy(_) => {} + ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {} - ty::TyVar(_) | - ty::IntVar(_) | - ty::FloatVar(_) => { + ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => { self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX) } } @@ -145,7 +135,7 @@ impl FlagComputation { &ty::UnnormalizedProjection(ref data) => { self.add_flags(TypeFlags::HAS_PROJECTION); self.add_projection_ty(data); - }, + } &ty::Opaque(_, substs) => { self.add_flags(TypeFlags::HAS_PROJECTION); @@ -174,9 +164,7 @@ impl FlagComputation { self.add_const(len); } - &ty::Slice(tt) => { - self.add_ty(tt) - } + &ty::Slice(tt) => self.add_ty(tt), &ty::RawPtr(ref m) => { self.add_ty(m.ty); @@ -234,7 +222,7 @@ impl FlagComputation { ty::ConstKind::Unevaluated(_, substs) => { self.add_substs(substs); self.add_flags(TypeFlags::HAS_PROJECTION); - }, + } ty::ConstKind::Infer(infer) => { self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_CT_INFER); match infer { diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 8b78b0f335d31..53a1727d1cc13 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -32,11 +32,11 @@ //! looking for, and does not need to visit anything else. use crate::hir::def_id::DefId; -use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags, flags::FlagComputation}; +use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags}; +use crate::util::nodemap::FxHashSet; use std::collections::BTreeMap; use std::fmt; -use crate::util::nodemap::FxHashSet; /// This trait is implemented for every type that can be folded. /// Basically, every type that has a corresponding method in `TypeFolder`. @@ -94,14 +94,14 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { } fn needs_infer(&self) -> bool { self.has_type_flags( - TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER | TypeFlags::HAS_CT_INFER + TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER | TypeFlags::HAS_CT_INFER, ) } fn has_placeholders(&self) -> bool { self.has_type_flags( - TypeFlags::HAS_RE_PLACEHOLDER | - TypeFlags::HAS_TY_PLACEHOLDER | - TypeFlags::HAS_CT_PLACEHOLDER + TypeFlags::HAS_RE_PLACEHOLDER + | TypeFlags::HAS_TY_PLACEHOLDER + | TypeFlags::HAS_CT_PLACEHOLDER, ) } fn needs_subst(&self) -> bool { @@ -138,7 +138,6 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { /// A visitor that does not recurse into types, works like `fn walk_shallow` in `Ty`. fn visit_tys_shallow(&self, visit: impl FnMut(Ty<'tcx>) -> bool) -> bool { - pub struct Visitor(F); impl<'tcx, F: FnMut(Ty<'tcx>) -> bool> TypeVisitor<'tcx> for Visitor { @@ -160,7 +159,8 @@ pub trait TypeFolder<'tcx>: Sized { fn tcx<'a>(&'a self) -> TyCtxt<'tcx>; fn fold_binder(&mut self, t: &Binder) -> Binder - where T : TypeFoldable<'tcx> + where + T: TypeFoldable<'tcx>, { t.super_fold_with(self) } @@ -178,7 +178,7 @@ pub trait TypeFolder<'tcx>: Sized { } } -pub trait TypeVisitor<'tcx> : Sized { +pub trait TypeVisitor<'tcx>: Sized { fn visit_binder>(&mut self, t: &Binder) -> bool { t.super_visit_with(self) } @@ -219,7 +219,7 @@ where { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx - } + } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { let t = ty.super_fold_with(self); @@ -243,11 +243,9 @@ where impl<'tcx> TyCtxt<'tcx> { /// Collects the free and escaping regions in `value` into `region_set`. Returns /// whether any late-bound regions were skipped - pub fn collect_regions(self, - value: &T, - region_set: &mut FxHashSet>) - -> bool - where T : TypeFoldable<'tcx> + pub fn collect_regions(self, value: &T, region_set: &mut FxHashSet>) -> bool + where + T: TypeFoldable<'tcx>, { let mut have_bound_regions = false; self.fold_regions(value, &mut have_bound_regions, |r, d| { @@ -267,7 +265,7 @@ impl<'tcx> TyCtxt<'tcx> { mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>, ) -> T where - T : TypeFoldable<'tcx>, + T: TypeFoldable<'tcx>, { value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f)) } @@ -299,10 +297,7 @@ impl<'tcx> TyCtxt<'tcx> { value: &impl TypeFoldable<'tcx>, callback: impl FnMut(ty::Region<'tcx>) -> bool, ) -> bool { - return value.visit_with(&mut RegionVisitor { - outer_index: ty::INNERMOST, - callback - }); + return value.visit_with(&mut RegionVisitor { outer_index: ty::INNERMOST, callback }); struct RegionVisitor { /// The index of a binder *just outside* the things we have @@ -327,7 +322,8 @@ impl<'tcx> TyCtxt<'tcx> { } impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor - where F: FnMut(ty::Region<'tcx>) -> bool + where + F: FnMut(ty::Region<'tcx>) -> bool, { fn visit_binder>(&mut self, t: &Binder) -> bool { self.outer_index.shift_in(1); @@ -389,19 +385,14 @@ impl<'a, 'tcx> RegionFolder<'a, 'tcx> { skipped_regions: &'a mut bool, fold_region_fn: &'a mut dyn FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>, ) -> RegionFolder<'a, 'tcx> { - RegionFolder { - tcx, - skipped_regions, - current_index: ty::INNERMOST, - fold_region_fn, - } + RegionFolder { tcx, skipped_regions, current_index: ty::INNERMOST, fold_region_fn } } } impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx - } + } fn fold_binder>(&mut self, t: &ty::Binder) -> ty::Binder { self.current_index.shift_in(1); @@ -413,14 +404,18 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReLateBound(debruijn, _) if debruijn < self.current_index => { - debug!("RegionFolder.fold_region({:?}) skipped bound region (current index={:?})", - r, self.current_index); + debug!( + "RegionFolder.fold_region({:?}) skipped bound region (current index={:?})", + r, self.current_index + ); *self.skipped_regions = true; r } _ => { - debug!("RegionFolder.fold_region({:?}) folding free region (current_index={:?})", - r, self.current_index); + debug!( + "RegionFolder.fold_region({:?}) folding free region (current_index={:?})", + r, self.current_index + ); (self.fold_region_fn)(r, self.current_index) } } @@ -450,20 +445,14 @@ impl<'a, 'tcx> BoundVarReplacer<'a, 'tcx> { G: FnMut(ty::BoundTy) -> Ty<'tcx>, H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>, { - BoundVarReplacer { - tcx, - current_index: ty::INNERMOST, - fld_r, - fld_t, - fld_c, - } + BoundVarReplacer { tcx, current_index: ty::INNERMOST, fld_r, fld_t, fld_c } } } impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx - } + } fn fold_binder>(&mut self, t: &ty::Binder) -> ty::Binder { self.current_index.shift_in(1); @@ -478,11 +467,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { if debruijn == self.current_index { let fld_t = &mut self.fld_t; let ty = fld_t(bound_ty); - ty::fold::shift_vars( - self.tcx, - &ty, - self.current_index.as_u32() - ) + ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32()) } else { t } @@ -514,7 +499,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { region } } - _ => r + _ => r, } } @@ -523,11 +508,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { if debruijn == self.current_index { let fld_c = &mut self.fld_c; let ct = fld_c(bound_const, ty); - ty::fold::shift_vars( - self.tcx, - &ct, - self.current_index.as_u32() - ) + ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32()) } else { ct } @@ -557,18 +538,16 @@ impl<'tcx> TyCtxt<'tcx> { pub fn replace_late_bound_regions( self, value: &Binder, - fld_r: F + fld_r: F, ) -> (T, BTreeMap>) - where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, - T: TypeFoldable<'tcx> + where + F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, + T: TypeFoldable<'tcx>, { // identity for bound types and consts let fld_t = |bound_ty| self.mk_ty(ty::Bound(ty::INNERMOST, bound_ty)); let fld_c = |bound_ct, ty| { - self.mk_const(ty::Const { - val: ty::ConstKind::Bound(ty::INNERMOST, bound_ct), - ty, - }) + self.mk_const(ty::Const { val: ty::ConstKind::Bound(ty::INNERMOST, bound_ct), ty }) }; self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t, fld_c) } @@ -583,10 +562,11 @@ impl<'tcx> TyCtxt<'tcx> { mut fld_t: G, mut fld_c: H, ) -> (T, BTreeMap>) - where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, - G: FnMut(ty::BoundTy) -> Ty<'tcx>, - H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>, - T: TypeFoldable<'tcx>, + where + F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, + G: FnMut(ty::BoundTy) -> Ty<'tcx>, + H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>, + T: TypeFoldable<'tcx>, { use rustc_data_structures::fx::FxHashMap; @@ -597,24 +577,16 @@ impl<'tcx> TyCtxt<'tcx> { if !value.has_escaping_bound_vars() { (value.clone(), region_map) } else { - let mut real_fld_r = |br| { - *region_map.entry(br).or_insert_with(|| fld_r(br)) - }; - - let mut real_fld_t = |bound_ty| { - *type_map.entry(bound_ty).or_insert_with(|| fld_t(bound_ty)) - }; - - let mut real_fld_c = |bound_ct, ty| { - *const_map.entry(bound_ct).or_insert_with(|| fld_c(bound_ct, ty)) - }; - - let mut replacer = BoundVarReplacer::new( - self, - &mut real_fld_r, - &mut real_fld_t, - &mut real_fld_c, - ); + let mut real_fld_r = |br| *region_map.entry(br).or_insert_with(|| fld_r(br)); + + let mut real_fld_t = + |bound_ty| *type_map.entry(bound_ty).or_insert_with(|| fld_t(bound_ty)); + + let mut real_fld_c = + |bound_ct, ty| *const_map.entry(bound_ct).or_insert_with(|| fld_c(bound_ct, ty)); + + let mut replacer = + BoundVarReplacer::new(self, &mut real_fld_r, &mut real_fld_t, &mut real_fld_c); let result = value.fold_with(&mut replacer); (result, region_map) } @@ -630,10 +602,11 @@ impl<'tcx> TyCtxt<'tcx> { fld_t: G, fld_c: H, ) -> (T, BTreeMap>) - where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, - G: FnMut(ty::BoundTy) -> Ty<'tcx>, - H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>, - T: TypeFoldable<'tcx> + where + F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, + G: FnMut(ty::BoundTy) -> Ty<'tcx>, + H: FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx>, + T: TypeFoldable<'tcx>, { self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t, fld_c) } @@ -643,39 +616,52 @@ impl<'tcx> TyCtxt<'tcx> { pub fn liberate_late_bound_regions( &self, all_outlive_scope: DefId, - value: &ty::Binder + value: &ty::Binder, ) -> T - where T: TypeFoldable<'tcx> { + where + T: TypeFoldable<'tcx>, + { self.replace_late_bound_regions(value, |br| { self.mk_region(ty::ReFree(ty::FreeRegion { scope: all_outlive_scope, - bound_region: br + bound_region: br, })) - }).0 + }) + .0 } /// Returns a set of all late-bound regions that are constrained /// by `value`, meaning that if we instantiate those LBR with /// variables and equate `value` with something else, those /// variables will also be equated. - pub fn collect_constrained_late_bound_regions(&self, value: &Binder) - -> FxHashSet - where T : TypeFoldable<'tcx> + pub fn collect_constrained_late_bound_regions( + &self, + value: &Binder, + ) -> FxHashSet + where + T: TypeFoldable<'tcx>, { self.collect_late_bound_regions(value, true) } /// Returns a set of all late-bound regions that appear in `value` anywhere. - pub fn collect_referenced_late_bound_regions(&self, value: &Binder) - -> FxHashSet - where T : TypeFoldable<'tcx> + pub fn collect_referenced_late_bound_regions( + &self, + value: &Binder, + ) -> FxHashSet + where + T: TypeFoldable<'tcx>, { self.collect_late_bound_regions(value, false) } - fn collect_late_bound_regions(&self, value: &Binder, just_constraint: bool) - -> FxHashSet - where T : TypeFoldable<'tcx> + fn collect_late_bound_regions( + &self, + value: &Binder, + just_constraint: bool, + ) -> FxHashSet + where + T: TypeFoldable<'tcx>, { let mut collector = LateBoundRegionsCollector::new(just_constraint); let result = value.skip_binder().visit_with(&mut collector); @@ -686,7 +672,8 @@ impl<'tcx> TyCtxt<'tcx> { /// Replaces any late-bound regions bound in `value` with `'erased`. Useful in codegen but also /// method lookup and a few other places where precise region relationships are not required. pub fn erase_late_bound_regions(self, value: &Binder) -> T - where T : TypeFoldable<'tcx> + where + T: TypeFoldable<'tcx>, { self.replace_late_bound_regions(value, |_| self.lifetimes.re_erased).0 } @@ -700,13 +687,17 @@ impl<'tcx> TyCtxt<'tcx> { /// structurally identical. For example, `for<'a, 'b> fn(&'a isize, &'b isize)` and /// `for<'a, 'b> fn(&'b isize, &'a isize)` will become identical after anonymization. pub fn anonymize_late_bound_regions(self, sig: &Binder) -> Binder - where T : TypeFoldable<'tcx>, + where + T: TypeFoldable<'tcx>, { let mut counter = 0; - Binder::bind(self.replace_late_bound_regions(sig, |_| { - counter += 1; - self.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(counter))) - }).0) + Binder::bind( + self.replace_late_bound_regions(sig, |_| { + counter += 1; + self.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(counter))) + }) + .0, + ) } } @@ -733,19 +724,14 @@ struct Shifter<'tcx> { impl Shifter<'tcx> { pub fn new(tcx: TyCtxt<'tcx>, amount: u32, direction: Direction) -> Self { - Shifter { - tcx, - current_index: ty::INNERMOST, - amount, - direction, - } + Shifter { tcx, current_index: ty::INNERMOST, amount, direction } } } impl TypeFolder<'tcx> for Shifter<'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx - } + } fn fold_binder>(&mut self, t: &ty::Binder) -> ty::Binder { self.current_index.shift_in(1); @@ -771,7 +757,7 @@ impl TypeFolder<'tcx> for Shifter<'tcx> { self.tcx.mk_region(shifted) } } - _ => r + _ => r, } } @@ -788,9 +774,7 @@ impl TypeFolder<'tcx> for Shifter<'tcx> { debruijn.shifted_out(self.amount) } }; - self.tcx.mk_ty( - ty::Bound(debruijn, bound_ty) - ) + self.tcx.mk_ty(ty::Bound(debruijn, bound_ty)) } } @@ -810,10 +794,7 @@ impl TypeFolder<'tcx> for Shifter<'tcx> { debruijn.shifted_out(self.amount) } }; - self.tcx.mk_const(ty::Const { - val: ty::ConstKind::Bound(debruijn, bound_ct), - ty, - }) + self.tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty }) } } else { ct.super_fold_with(self) @@ -830,9 +811,7 @@ pub fn shift_region<'tcx>( ty::ReLateBound(debruijn, br) if amount > 0 => { tcx.mk_region(ty::ReLateBound(debruijn.shifted_in(amount), *br)) } - _ => { - region - } + _ => region, } } @@ -840,8 +819,7 @@ pub fn shift_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: &T, amount: u32) -> T where T: TypeFoldable<'tcx>, { - debug!("shift_vars(value={:?}, amount={})", - value, amount); + debug!("shift_vars(value={:?}, amount={})", value, amount); value.fold_with(&mut Shifter::new(tcx, amount, Direction::In)) } @@ -850,8 +828,7 @@ pub fn shift_out_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: &T, amount: u32) -> T where T: TypeFoldable<'tcx>, { - debug!("shift_out_vars(value={:?}, amount={})", - value, amount); + debug!("shift_out_vars(value={:?}, amount={})", value, amount); value.fold_with(&mut Shifter::new(tcx, amount, Direction::Out)) } @@ -987,8 +964,10 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector { // in the normalized form if self.just_constrained { match t.kind { - ty::Projection(..) | ty::Opaque(..) => { return false; } - _ => { } + ty::Projection(..) | ty::Opaque(..) => { + return false; + } + _ => {} } } @@ -997,7 +976,7 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector { fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { if let ty::ReLateBound(debruijn, br) = *r { - if debruijn == self.current_index { + if debruijn == self.current_index { self.regions.insert(br); } } diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs index 227fbf967c0d7..5a2e19156535a 100644 --- a/src/librustc/ty/inhabitedness/def_id_forest.rs +++ b/src/librustc/ty/inhabitedness/def_id_forest.rs @@ -1,8 +1,8 @@ -use std::mem; -use smallvec::SmallVec; -use rustc::hir::CRATE_HIR_ID; use crate::ty::context::TyCtxt; use crate::ty::{DefId, DefIdTree}; +use rustc::hir::CRATE_HIR_ID; +use smallvec::SmallVec; +use std::mem; /// Represents a forest of `DefId`s closed under the ancestor relation. That is, /// if a `DefId` representing a module is contained in the forest then all @@ -24,9 +24,7 @@ pub struct DefIdForest { impl<'tcx> DefIdForest { /// Creates an empty forest. pub fn empty() -> DefIdForest { - DefIdForest { - root_ids: SmallVec::new(), - } + DefIdForest { root_ids: SmallVec::new() } } /// Creates a forest consisting of a single tree representing the entire @@ -41,9 +39,7 @@ impl<'tcx> DefIdForest { pub fn from_id(id: DefId) -> DefIdForest { let mut root_ids = SmallVec::new(); root_ids.push(id); - DefIdForest { - root_ids, - } + DefIdForest { root_ids } } /// Tests whether the forest is empty. diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index bc0cf4deaa47b..73ca0075994a5 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -1,11 +1,11 @@ pub use self::def_id_forest::DefIdForest; +use crate::ty; use crate::ty::context::TyCtxt; -use crate::ty::{AdtDef, VariantDef, FieldDef, Ty, TyS}; -use crate::ty::{DefId, SubstsRef}; -use crate::ty::{AdtKind, Visibility}; use crate::ty::TyKind::*; -use crate::ty; +use crate::ty::{AdtDef, FieldDef, Ty, TyS, VariantDef}; +use crate::ty::{AdtKind, Visibility}; +use crate::ty::{DefId, SubstsRef}; mod def_id_forest; @@ -115,9 +115,10 @@ impl<'tcx> AdtDef { if self.is_variant_list_non_exhaustive() && !self.did.is_local() { DefIdForest::empty() } else { - DefIdForest::intersection(tcx, self.variants.iter().map(|v| { - v.uninhabited_from(tcx, substs, self.adt_kind()) - })) + DefIdForest::intersection( + tcx, + self.variants.iter().map(|v| v.uninhabited_from(tcx, substs, self.adt_kind())), + ) } } } @@ -141,9 +142,10 @@ impl<'tcx> VariantDef { if self.is_field_list_non_exhaustive() && !self.def_id.is_local() { DefIdForest::empty() } else { - DefIdForest::union(tcx, self.fields.iter().map(|f| { - f.uninhabited_from(tcx, substs, is_enum) - })) + DefIdForest::union( + tcx, + self.fields.iter().map(|f| f.uninhabited_from(tcx, substs, is_enum)), + ) } } } @@ -156,9 +158,7 @@ impl<'tcx> FieldDef { substs: SubstsRef<'tcx>, is_enum: bool, ) -> DefIdForest { - let data_uninhabitedness = move || { - self.ty(tcx, substs).uninhabited_from(tcx) - }; + let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx); // FIXME(canndrew): Currently enum fields are (incorrectly) stored with // `Visibility::Invisible` so we need to override `self.vis` if we're // dealing with an enum. @@ -171,7 +171,7 @@ impl<'tcx> FieldDef { let forest = DefIdForest::from_id(from); let iter = Some(forest).into_iter().chain(Some(data_uninhabitedness())); DefIdForest::intersection(tcx, iter) - }, + } Visibility::Public => data_uninhabitedness(), } } @@ -187,16 +187,14 @@ impl<'tcx> TyS<'tcx> { Never => DefIdForest::full(tcx), Tuple(ref tys) => { - DefIdForest::union(tcx, tys.iter().map(|ty| { - ty.expect_ty().uninhabited_from(tcx) - })) + DefIdForest::union(tcx, tys.iter().map(|ty| ty.expect_ty().uninhabited_from(tcx))) } Array(ty, len) => match len.try_eval_usize(tcx, ty::ParamEnv::empty()) { // If the array is definitely non-empty, it's uninhabited if // the type of its elements is uninhabited. Some(n) if n != 0 => ty.uninhabited_from(tcx), - _ => DefIdForest::empty() + _ => DefIdForest::empty(), }, // References to uninitialised memory is valid for any type, including diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 366951bc9f494..faa83ceaddea2 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -1,12 +1,12 @@ -use crate::hir::CodegenFnAttrFlags; use crate::hir::def::Namespace; use crate::hir::def_id::DefId; -use crate::ty::{self, Ty, TypeFoldable, SubstsRef, TyCtxt}; -use crate::ty::print::{FmtPrinter, Printer}; -use crate::traits; +use crate::hir::CodegenFnAttrFlags; use crate::middle::lang_items::DropInPlaceFnLangItem; -use rustc_target::spec::abi::Abi; +use crate::traits; +use crate::ty::print::{FmtPrinter, Printer}; +use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable}; use rustc_macros::HashStable; +use rustc_target::spec::abi::Abi; use std::fmt; @@ -50,7 +50,9 @@ pub enum InstanceDef<'tcx> { Virtual(DefId, usize), /// `<[mut closure] as FnOnce>::call_once` - ClosureOnceShim { call_once: DefId }, + ClosureOnceShim { + call_once: DefId, + }, /// `drop_in_place::; None` for empty drop glue. DropGlue(DefId, Option>), @@ -62,11 +64,7 @@ pub enum InstanceDef<'tcx> { impl<'tcx> Instance<'tcx> { pub fn ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { let ty = tcx.type_of(self.def.def_id()); - tcx.subst_and_normalize_erasing_regions( - self.substs, - ty::ParamEnv::reveal_all(), - &ty, - ) + tcx.subst_and_normalize_erasing_regions(self.substs, ty::ParamEnv::reveal_all(), &ty) } } @@ -74,15 +72,15 @@ impl<'tcx> InstanceDef<'tcx> { #[inline] pub fn def_id(&self) -> DefId { match *self { - InstanceDef::Item(def_id) | - InstanceDef::VtableShim(def_id) | - InstanceDef::ReifyShim(def_id) | - InstanceDef::FnPtrShim(def_id, _) | - InstanceDef::Virtual(def_id, _) | - InstanceDef::Intrinsic(def_id, ) | - InstanceDef::ClosureOnceShim { call_once: def_id } | - InstanceDef::DropGlue(def_id, _) | - InstanceDef::CloneShim(def_id, _) => def_id + InstanceDef::Item(def_id) + | InstanceDef::VtableShim(def_id) + | InstanceDef::ReifyShim(def_id) + | InstanceDef::FnPtrShim(def_id, _) + | InstanceDef::Virtual(def_id, _) + | InstanceDef::Intrinsic(def_id) + | InstanceDef::ClosureOnceShim { call_once: def_id } + | InstanceDef::DropGlue(def_id, _) + | InstanceDef::CloneShim(def_id, _) => def_id, } } @@ -96,23 +94,23 @@ impl<'tcx> InstanceDef<'tcx> { let def_id = match *self { ty::InstanceDef::Item(def_id) => def_id, ty::InstanceDef::DropGlue(_, Some(_)) => return false, - _ => return true + _ => return true, }; match tcx.def_key(def_id).disambiguated_data.data { DefPathData::Ctor | DefPathData::ClosureExpr => true, - _ => false + _ => false, } } pub fn requires_local(&self, tcx: TyCtxt<'tcx>) -> bool { if self.is_inline(tcx) { - return true + return true; } if let ty::InstanceDef::DropGlue(..) = *self { // Drop glue wants to be instantiated at every codegen // unit, but without an #[inline] hint. We should make this // available to normal end-users. - return true + return true; } tcx.codegen_fn_attrs(self.def_id()).requests_inline() } @@ -133,40 +131,26 @@ impl<'tcx> fmt::Display for Instance<'tcx> { match self.def { InstanceDef::Item(_) => Ok(()), - InstanceDef::VtableShim(_) => { - write!(f, " - shim(vtable)") - } - InstanceDef::ReifyShim(_) => { - write!(f, " - shim(reify)") - } - InstanceDef::Intrinsic(_) => { - write!(f, " - intrinsic") - } - InstanceDef::Virtual(_, num) => { - write!(f, " - virtual#{}", num) - } - InstanceDef::FnPtrShim(_, ty) => { - write!(f, " - shim({:?})", ty) - } - InstanceDef::ClosureOnceShim { .. } => { - write!(f, " - shim") - } - InstanceDef::DropGlue(_, ty) => { - write!(f, " - shim({:?})", ty) - } - InstanceDef::CloneShim(_, ty) => { - write!(f, " - shim({:?})", ty) - } + InstanceDef::VtableShim(_) => write!(f, " - shim(vtable)"), + InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"), + InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"), + InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num), + InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({:?})", ty), + InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"), + InstanceDef::DropGlue(_, ty) => write!(f, " - shim({:?})", ty), + InstanceDef::CloneShim(_, ty) => write!(f, " - shim({:?})", ty), } } } impl<'tcx> Instance<'tcx> { - pub fn new(def_id: DefId, substs: SubstsRef<'tcx>) - -> Instance<'tcx> { - assert!(!substs.has_escaping_bound_vars(), - "substs of instance {:?} not normalized for codegen: {:?}", - def_id, substs); + pub fn new(def_id: DefId, substs: SubstsRef<'tcx>) -> Instance<'tcx> { + assert!( + !substs.has_escaping_bound_vars(), + "substs of instance {:?} not normalized for codegen: {:?}", + def_id, + substs + ); Instance { def: InstanceDef::Item(def_id), substs: substs } } @@ -210,18 +194,14 @@ impl<'tcx> Instance<'tcx> { resolve_associated_item(tcx, &item, param_env, trait_def_id, substs) } else { let ty = tcx.type_of(def_id); - let item_type = tcx.subst_and_normalize_erasing_regions( - substs, - param_env, - &ty, - ); + let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, &ty); let def = match item_type.kind { - ty::FnDef(..) if { - let f = item_type.fn_sig(tcx); - f.abi() == Abi::RustIntrinsic || - f.abi() == Abi::PlatformIntrinsic - } => + ty::FnDef(..) + if { + let f = item_type.fn_sig(tcx); + f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic + } => { debug!(" => intrinsic"); ty::InstanceDef::Intrinsic(def_id) @@ -242,10 +222,7 @@ impl<'tcx> Instance<'tcx> { } } }; - Some(Instance { - def: def, - substs: substs - }) + Some(Instance { def: def, substs: substs }) }; debug!("resolve(def_id={:?}, substs={:?}) = {:?}", def_id, substs, result); result @@ -288,10 +265,7 @@ impl<'tcx> Instance<'tcx> { && tcx.generics_of(def_id).has_self; if is_vtable_shim { debug!(" => associated item with unsizeable self: Self"); - Some(Instance { - def: InstanceDef::VtableShim(def_id), - substs, - }) + Some(Instance { def: InstanceDef::VtableShim(def_id), substs }) } else { Instance::resolve(tcx, param_env, def_id, substs) } @@ -307,7 +281,7 @@ impl<'tcx> Instance<'tcx> { match needs_fn_once_adapter_shim(actual_kind, requested_kind) { Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, substs), - _ => Instance::new(def_id, substs) + _ => Instance::new(def_id, substs), } } @@ -322,13 +296,13 @@ impl<'tcx> Instance<'tcx> { closure_did: DefId, substs: ty::SubstsRef<'tcx>, ) -> Instance<'tcx> { - debug!("fn_once_adapter_shim({:?}, {:?})", - closure_did, - substs); + debug!("fn_once_adapter_shim({:?}, {:?})", closure_did, substs); let fn_once = tcx.lang_items().fn_once_trait().unwrap(); - let call_once = tcx.associated_items(fn_once) + let call_once = tcx + .associated_items(fn_once) .find(|it| it.kind == ty::AssocKind::Method) - .unwrap().def_id; + .unwrap() + .def_id; let def = ty::InstanceDef::ClosureOnceShim { call_once }; let self_ty = tcx.mk_closure(closure_did, substs); @@ -343,11 +317,7 @@ impl<'tcx> Instance<'tcx> { } pub fn is_vtable_shim(&self) -> bool { - if let InstanceDef::VtableShim(..) = self.def { - true - } else { - false - } + if let InstanceDef::VtableShim(..) = self.def { true } else { false } } } @@ -359,11 +329,13 @@ fn resolve_associated_item<'tcx>( rcvr_substs: SubstsRef<'tcx>, ) -> Option> { let def_id = trait_item.def_id; - debug!("resolve_associated_item(trait_item={:?}, \ + debug!( + "resolve_associated_item(trait_item={:?}, \ param_env={:?}, \ trait_id={:?}, \ rcvr_substs={:?})", - def_id, param_env, trait_id, rcvr_substs); + def_id, param_env, trait_id, rcvr_substs + ); let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs); let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref))); @@ -372,48 +344,43 @@ fn resolve_associated_item<'tcx>( // the actual function: match vtbl { traits::VtableImpl(impl_data) => { - let (def_id, substs) = traits::find_associated_item( - tcx, param_env, trait_item, rcvr_substs, &impl_data); + let (def_id, substs) = + traits::find_associated_item(tcx, param_env, trait_item, rcvr_substs, &impl_data); let substs = tcx.erase_regions(&substs); Some(ty::Instance::new(def_id, substs)) } - traits::VtableGenerator(generator_data) => { - Some(Instance { - def: ty::InstanceDef::Item(generator_data.generator_def_id), - substs: generator_data.substs - }) - } + traits::VtableGenerator(generator_data) => Some(Instance { + def: ty::InstanceDef::Item(generator_data.generator_def_id), + substs: generator_data.substs, + }), traits::VtableClosure(closure_data) => { let trait_closure_kind = tcx.lang_items().fn_trait_kind(trait_id).unwrap(); - Some(Instance::resolve_closure(tcx, closure_data.closure_def_id, closure_data.substs, - trait_closure_kind)) - } - traits::VtableFnPointer(ref data) => { - Some(Instance { - def: ty::InstanceDef::FnPtrShim(trait_item.def_id, data.fn_ty), - substs: rcvr_substs - }) + Some(Instance::resolve_closure( + tcx, + closure_data.closure_def_id, + closure_data.substs, + trait_closure_kind, + )) } + traits::VtableFnPointer(ref data) => Some(Instance { + def: ty::InstanceDef::FnPtrShim(trait_item.def_id, data.fn_ty), + substs: rcvr_substs, + }), traits::VtableObject(ref data) => { let index = tcx.get_vtable_index_of_object_method(data, def_id); - Some(Instance { - def: ty::InstanceDef::Virtual(def_id, index), - substs: rcvr_substs - }) + Some(Instance { def: ty::InstanceDef::Virtual(def_id, index), substs: rcvr_substs }) } traits::VtableBuiltin(..) => { if tcx.lang_items().clone_trait().is_some() { Some(Instance { def: ty::InstanceDef::CloneShim(def_id, trait_ref.self_ty()), - substs: rcvr_substs + substs: rcvr_substs, }) } else { None } } - traits::VtableAutoImpl(..) | - traits::VtableParam(..) | - traits::VtableTraitAlias(..) => None + traits::VtableAutoImpl(..) | traits::VtableParam(..) | traits::VtableTraitAlias(..) => None, } } @@ -422,31 +389,30 @@ fn needs_fn_once_adapter_shim( trait_closure_kind: ty::ClosureKind, ) -> Result { match (actual_closure_kind, trait_closure_kind) { - (ty::ClosureKind::Fn, ty::ClosureKind::Fn) | - (ty::ClosureKind::FnMut, ty::ClosureKind::FnMut) | - (ty::ClosureKind::FnOnce, ty::ClosureKind::FnOnce) => { - // No adapter needed. - Ok(false) - } + (ty::ClosureKind::Fn, ty::ClosureKind::Fn) + | (ty::ClosureKind::FnMut, ty::ClosureKind::FnMut) + | (ty::ClosureKind::FnOnce, ty::ClosureKind::FnOnce) => { + // No adapter needed. + Ok(false) + } (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) => { // The closure fn `llfn` is a `fn(&self, ...)`. We want a // `fn(&mut self, ...)`. In fact, at codegen time, these are // basically the same thing, so we can just return llfn. Ok(false) } - (ty::ClosureKind::Fn, ty::ClosureKind::FnOnce) | - (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => { - // The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut - // self, ...)`. We want a `fn(self, ...)`. We can produce - // this by doing something like: - // - // fn call_once(self, ...) { call_mut(&self, ...) } - // fn call_once(mut self, ...) { call_mut(&mut self, ...) } - // - // These are both the same at codegen time. - Ok(true) + (ty::ClosureKind::Fn, ty::ClosureKind::FnOnce) + | (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => { + // The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut + // self, ...)`. We want a `fn(self, ...)`. We can produce + // this by doing something like: + // + // fn call_once(self, ...) { call_mut(&self, ...) } + // fn call_once(mut self, ...) { call_mut(&mut self, ...) } + // + // These are both the same at codegen time. + Ok(true) } - (ty::ClosureKind::FnMut, _) | - (ty::ClosureKind::FnOnce, _) => Err(()) + (ty::ClosureKind::FnMut, _) | (ty::ClosureKind::FnOnce, _) => Err(()), } } diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index a8c44aa507cd8..98aa299a70405 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1,5 +1,5 @@ use crate::session::{self, DataTypeKind}; -use crate::ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions, subst::SubstsRef}; +use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable}; use syntax::ast::{self, Ident, IntTy, UintTy}; use syntax::attr; @@ -16,15 +16,15 @@ use crate::hir; use crate::ich::StableHashingContext; use crate::mir::{GeneratorLayout, GeneratorSavedLocal}; use crate::ty::subst::Subst; -use rustc_index::bit_set::BitSet; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_index::vec::{IndexVec, Idx}; +use rustc_index::bit_set::BitSet; +use rustc_index::vec::{Idx, IndexVec}; -pub use rustc_target::abi::*; -use rustc_target::spec::{HasTargetSpec, abi::Abi as SpecAbi}; use rustc_target::abi::call::{ - ArgAttribute, ArgAttributes, ArgAbi, Conv, FnAbi, PassMode, Reg, RegKind + ArgAbi, ArgAttribute, ArgAttributes, Conv, FnAbi, PassMode, Reg, RegKind, }; +pub use rustc_target::abi::*; +use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec}; pub trait IntegerExt { fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx>; @@ -95,8 +95,11 @@ impl IntegerExt for Integer { let discr = Integer::from_attr(&tcx, ity); let fit = if ity.is_signed() { signed_fit } else { unsigned_fit }; if discr < fit { - bug!("Integer::repr_discr: `#[repr]` hint too small for \ - discriminant range of enum `{}", ty) + bug!( + "Integer::repr_discr: `#[repr]` hint too small for \ + discriminant range of enum `{}", + ty + ) } return (discr, ity.is_signed()); } @@ -164,15 +167,13 @@ pub const FAT_PTR_EXTRA: usize = 1; #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)] pub enum LayoutError<'tcx> { Unknown(Ty<'tcx>), - SizeOverflow(Ty<'tcx>) + SizeOverflow(Ty<'tcx>), } impl<'tcx> fmt::Display for LayoutError<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - LayoutError::Unknown(ty) => { - write!(f, "the type `{:?}` has an unknown layout", ty) - } + LayoutError::Unknown(ty) => write!(f, "the type `{:?}` has an unknown layout", ty), LayoutError::SizeOverflow(ty) => { write!(f, "the type `{:?}` is too big for the current architecture", ty) } @@ -189,15 +190,11 @@ fn layout_raw<'tcx>( let (param_env, ty) = query.into_parts(); if icx.layout_depth > rec_limit { - tcx.sess.fatal( - &format!("overflow representing the type `{}`", ty)); + tcx.sess.fatal(&format!("overflow representing the type `{}`", ty)); } // Update the ImplicitCtxt to increase the layout_depth - let icx = ty::tls::ImplicitCtxt { - layout_depth: icx.layout_depth + 1, - ..icx.clone() - }; + let icx = ty::tls::ImplicitCtxt { layout_depth: icx.layout_depth + 1, ..icx.clone() }; ty::tls::enter_context(&icx, |_| { let cx = LayoutCx { tcx, param_env }; @@ -214,10 +211,7 @@ fn layout_raw<'tcx>( } pub fn provide(providers: &mut ty::query::Providers<'_>) { - *providers = ty::query::Providers { - layout_raw, - ..*providers - }; + *providers = ty::query::Providers { layout_raw, ..*providers }; } pub struct LayoutCx<'tcx, C> { @@ -267,31 +261,29 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Arbitrary { offsets: vec![Size::ZERO, b_offset], - memory_index: vec![0, 1] + memory_index: vec![0, 1], }, abi: Abi::ScalarPair(a, b), largest_niche, align, - size + size, } } - fn univariant_uninterned(&self, - ty: Ty<'tcx>, - fields: &[TyLayout<'_>], - repr: &ReprOptions, - kind: StructKind) -> Result> { + fn univariant_uninterned( + &self, + ty: Ty<'tcx>, + fields: &[TyLayout<'_>], + repr: &ReprOptions, + kind: StructKind, + ) -> Result> { let dl = self.data_layout(); let pack = repr.pack; if pack.is_some() && repr.align.is_some() { bug!("struct cannot be packed and aligned"); } - let mut align = if pack.is_some() { - dl.i8_align - } else { - dl.aggregate_align - }; + let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align }; let mut sized = true; let mut offsets = vec![Size::ZERO; fields.len()]; @@ -303,18 +295,14 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } if optimize { - let end = if let StructKind::MaybeUnsized = kind { - fields.len() - 1 - } else { - fields.len() - }; + let end = + if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() }; let optimizing = &mut inverse_memory_index[..end]; let field_align = |f: &TyLayout<'_>| { if let Some(pack) = pack { f.align.abi.min(pack) } else { f.align.abi } }; match kind { - StructKind::AlwaysSized | - StructKind::MaybeUnsized => { + StructKind::AlwaysSized | StructKind::MaybeUnsized => { optimizing.sort_by_key(|&x| { // Place ZSTs first to avoid "interesting offsets", // especially with only one or two non-ZST fields. @@ -335,17 +323,13 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // At the bottom of this function, we invert `inverse_memory_index` to // produce `memory_index` (see `invert_mapping`). - let mut offset = Size::ZERO; let mut largest_niche = None; let mut largest_niche_available = 0; if let StructKind::Prefixed(prefix_size, prefix_align) = kind { - let prefix_align = if let Some(pack) = pack { - prefix_align.min(pack) - } else { - prefix_align - }; + let prefix_align = + if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align }; align = align.max(AbiAndPrefAlign::new(prefix_align)); offset = prefix_size.align_to(prefix_align); } @@ -353,8 +337,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { for &i in &inverse_memory_index { let field = fields[i as usize]; if !sized { - bug!("univariant: field #{} of `{}` comes after unsized field", - offsets.len(), ty); + bug!("univariant: field #{} of `{}` comes after unsized field", offsets.len(), ty); } if field.is_unsized() { @@ -382,8 +365,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } } - offset = offset.checked_add(field.size, dl) - .ok_or(LayoutError::SizeOverflow(ty))?; + offset = offset.checked_add(field.size, dl).ok_or(LayoutError::SizeOverflow(ty))?; } if let Some(repr_align) = repr.align { @@ -413,19 +395,18 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // Unpack newtype ABIs and find scalar pairs. if sized && size.bytes() > 0 { // All other fields must be ZSTs, and we need them to all start at 0. - let mut zst_offsets = - offsets.iter().enumerate().filter(|&(i, _)| fields[i].is_zst()); + let mut zst_offsets = offsets.iter().enumerate().filter(|&(i, _)| fields[i].is_zst()); if zst_offsets.all(|(_, o)| o.bytes() == 0) { - let mut non_zst_fields = - fields.iter().enumerate().filter(|&(_, f)| !f.is_zst()); + let mut non_zst_fields = fields.iter().enumerate().filter(|&(_, f)| !f.is_zst()); match (non_zst_fields.next(), non_zst_fields.next(), non_zst_fields.next()) { // We have exactly one non-ZST field. (Some((i, field)), None, None) => { // Field fills the struct and it has a scalar or scalar pair ABI. - if offsets[i].bytes() == 0 && - align.abi == field.align.abi && - size == field.size { + if offsets[i].bytes() == 0 + && align.abi == field.align.abi + && size == field.size + { match field.abi { // For plain scalars, or vectors of them, we can't unpack // newtypes for `#[repr(C)]`, as that affects C ABIs. @@ -443,11 +424,23 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } // Two non-ZST fields, and they're both scalars. - (Some((i, &TyLayout { - details: &LayoutDetails { abi: Abi::Scalar(ref a), .. }, .. - })), Some((j, &TyLayout { - details: &LayoutDetails { abi: Abi::Scalar(ref b), .. }, .. - })), None) => { + ( + Some(( + i, + &TyLayout { + details: &LayoutDetails { abi: Abi::Scalar(ref a), .. }, + .. + }, + )), + Some(( + j, + &TyLayout { + details: &LayoutDetails { abi: Abi::Scalar(ref b), .. }, + .. + }, + )), + None, + ) => { // Order by the memory placement, not source order. let ((i, a), (j, b)) = if offsets[i] < offsets[j] { ((i, a), (j, b)) @@ -456,19 +449,17 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { }; let pair = self.scalar_pair(a.clone(), b.clone()); let pair_offsets = match pair.fields { - FieldPlacement::Arbitrary { - ref offsets, - ref memory_index - } => { + FieldPlacement::Arbitrary { ref offsets, ref memory_index } => { assert_eq!(memory_index, &[0, 1]); offsets } - _ => bug!() + _ => bug!(), }; - if offsets[i] == pair_offsets[0] && - offsets[j] == pair_offsets[1] && - align == pair.align && - size == pair.size { + if offsets[i] == pair_offsets[0] + && offsets[j] == pair_offsets[1] + && align == pair.align + && size == pair.size + { // We can use `ScalarPair` only when it matches our // already computed layout (including `#[repr(C)]`). abi = pair.abi; @@ -486,14 +477,11 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { Ok(LayoutDetails { variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldPlacement::Arbitrary { - offsets, - memory_index - }, + fields: FieldPlacement::Arbitrary { offsets, memory_index }, abi, largest_niche, align, - size + size, }) } @@ -504,14 +492,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let scalar_unit = |value: Primitive| { let bits = value.size(dl).bits(); assert!(bits <= 128); - Scalar { - value, - valid_range: 0..=(!0 >> (128 - bits)) - } - }; - let scalar = |value: Primitive| { - tcx.intern_layout(LayoutDetails::scalar(self, scalar_unit(value))) + Scalar { value, valid_range: 0..=(!0 >> (128 - bits)) } }; + let scalar = + |value: Primitive| tcx.intern_layout(LayoutDetails::scalar(self, scalar_unit(value))); let univariant = |fields: &[TyLayout<'_>], repr: &ReprOptions, kind| { Ok(tcx.intern_layout(self.univariant_uninterned(ty, fields, repr, kind)?)) @@ -520,24 +504,16 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { Ok(match ty.kind { // Basic scalars. - ty::Bool => { - tcx.intern_layout(LayoutDetails::scalar(self, Scalar { - value: Int(I8, false), - valid_range: 0..=1 - })) - } - ty::Char => { - tcx.intern_layout(LayoutDetails::scalar(self, Scalar { - value: Int(I32, false), - valid_range: 0..=0x10FFFF - })) - } - ty::Int(ity) => { - scalar(Int(Integer::from_attr(dl, attr::SignedInt(ity)), true)) - } - ty::Uint(ity) => { - scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity)), false)) - } + ty::Bool => tcx.intern_layout(LayoutDetails::scalar( + self, + Scalar { value: Int(I8, false), valid_range: 0..=1 }, + )), + ty::Char => tcx.intern_layout(LayoutDetails::scalar( + self, + Scalar { value: Int(I32, false), valid_range: 0..=0x10FFFF }, + )), + ty::Int(ity) => scalar(Int(Integer::from_attr(dl, attr::SignedInt(ity)), true)), + ty::Uint(ity) => scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity)), false)), ty::Float(fty) => scalar(match fty { ast::FloatTy::F32 => F32, ast::FloatTy::F64 => F64, @@ -549,20 +525,17 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } // The never type. - ty::Never => { - tcx.intern_layout(LayoutDetails { - variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldPlacement::Union(0), - abi: Abi::Uninhabited, - largest_niche: None, - align: dl.i8_align, - size: Size::ZERO - }) - } + ty::Never => tcx.intern_layout(LayoutDetails { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields: FieldPlacement::Union(0), + abi: Abi::Uninhabited, + largest_niche: None, + align: dl.i8_align, + size: Size::ZERO, + }), // Potentially-fat pointers. - ty::Ref(_, pointee, _) | - ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { + ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { let mut data_ptr = scalar_unit(Pointer); if !ty.is_unsafe_ptr() { data_ptr.valid_range = 1..=*data_ptr.valid_range.end(); @@ -578,15 +551,13 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { ty::Foreign(..) => { return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr))); } - ty::Slice(_) | ty::Str => { - scalar_unit(Int(dl.ptr_sized_integer(), false)) - } + ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)), ty::Dynamic(..) => { let mut vtable = scalar_unit(Pointer); vtable.valid_range = 1..=*vtable.valid_range.end(); vtable } - _ => return Err(LayoutError::Unknown(unsized_part)) + _ => return Err(LayoutError::Unknown(unsized_part)), }; // Effectively a (ptr, meta) tuple. @@ -604,8 +575,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let count = count.try_eval_usize(tcx, param_env).ok_or(LayoutError::Unknown(ty))?; let element = self.layout_of(element)?; - let size = element.size.checked_mul(count, dl) - .ok_or(LayoutError::SizeOverflow(ty))?; + let size = + element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?; let abi = if count != 0 && ty.conservative_is_privately_uninhabited(tcx) { Abi::Uninhabited @@ -613,62 +584,49 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { Abi::Aggregate { sized: true } }; - let largest_niche = if count != 0 { - element.largest_niche.clone() - } else { - None - }; + let largest_niche = if count != 0 { element.largest_niche.clone() } else { None }; tcx.intern_layout(LayoutDetails { variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldPlacement::Array { - stride: element.size, - count - }, + fields: FieldPlacement::Array { stride: element.size, count }, abi, largest_niche, align: element.align, - size + size, }) } ty::Slice(element) => { let element = self.layout_of(element)?; tcx.intern_layout(LayoutDetails { variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldPlacement::Array { - stride: element.size, - count: 0 - }, + fields: FieldPlacement::Array { stride: element.size, count: 0 }, abi: Abi::Aggregate { sized: false }, largest_niche: None, align: element.align, - size: Size::ZERO - }) - } - ty::Str => { - tcx.intern_layout(LayoutDetails { - variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldPlacement::Array { - stride: Size::from_bytes(1), - count: 0 - }, - abi: Abi::Aggregate { sized: false }, - largest_niche: None, - align: dl.i8_align, - size: Size::ZERO + size: Size::ZERO, }) } + ty::Str => tcx.intern_layout(LayoutDetails { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields: FieldPlacement::Array { stride: Size::from_bytes(1), count: 0 }, + abi: Abi::Aggregate { sized: false }, + largest_niche: None, + align: dl.i8_align, + size: Size::ZERO, + }), // Odd unit types. - ty::FnDef(..) => { - univariant(&[], &ReprOptions::default(), StructKind::AlwaysSized)? - } + ty::FnDef(..) => univariant(&[], &ReprOptions::default(), StructKind::AlwaysSized)?, ty::Dynamic(..) | ty::Foreign(..) => { - let mut unit = self.univariant_uninterned(ty, &[], &ReprOptions::default(), - StructKind::AlwaysSized)?; + let mut unit = self.univariant_uninterned( + ty, + &[], + &ReprOptions::default(), + StructKind::AlwaysSized, + )?; match unit.abi { Abi::Aggregate { ref mut sized } => *sized = false, - _ => bug!() + _ => bug!(), } tcx.intern_layout(unit) } @@ -677,21 +635,24 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { ty::Closure(def_id, ref substs) => { let tys = substs.as_closure().upvar_tys(def_id, tcx); - univariant(&tys.map(|ty| self.layout_of(ty)).collect::, _>>()?, + univariant( + &tys.map(|ty| self.layout_of(ty)).collect::, _>>()?, &ReprOptions::default(), - StructKind::AlwaysSized)? + StructKind::AlwaysSized, + )? } ty::Tuple(tys) => { - let kind = if tys.len() == 0 { - StructKind::AlwaysSized - } else { - StructKind::MaybeUnsized - }; + let kind = + if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized }; - univariant(&tys.iter().map(|k| { - self.layout_of(k.expect_ty()) - }).collect::, _>>()?, &ReprOptions::default(), kind)? + univariant( + &tys.iter() + .map(|k| self.layout_of(k.expect_ty())) + .collect::, _>>()?, + &ReprOptions::default(), + kind, + )? } // SIMD vector types. @@ -702,26 +663,22 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let scalar = match element.abi { Abi::Scalar(ref scalar) => scalar.clone(), _ => { - tcx.sess.fatal(&format!("monomorphising SIMD type `{}` with \ + tcx.sess.fatal(&format!( + "monomorphising SIMD type `{}` with \ a non-machine element type `{}`", - ty, element.ty)); + ty, element.ty + )); } }; - let size = element.size.checked_mul(count, dl) - .ok_or(LayoutError::SizeOverflow(ty))?; + let size = + element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?; let align = dl.vector_align(size); let size = size.align_to(align.abi); tcx.intern_layout(LayoutDetails { variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldPlacement::Array { - stride: element.size, - count - }, - abi: Abi::Vector { - element: scalar, - count - }, + fields: FieldPlacement::Array { stride: element.size, count }, + abi: Abi::Vector { element: scalar, count }, largest_niche: element.largest_niche.clone(), size, align, @@ -731,22 +688,24 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // ADTs. ty::Adt(def, substs) => { // Cache the field layouts. - let variants = def.variants.iter().map(|v| { - v.fields.iter().map(|field| { - self.layout_of(field.ty(tcx, substs)) - }).collect::, _>>() - }).collect::, _>>()?; + let variants = def + .variants + .iter() + .map(|v| { + v.fields + .iter() + .map(|field| self.layout_of(field.ty(tcx, substs))) + .collect::, _>>() + }) + .collect::, _>>()?; if def.is_union() { if def.repr.pack.is_some() && def.repr.align.is_some() { bug!("union cannot be packed and aligned"); } - let mut align = if def.repr.pack.is_some() { - dl.i8_align - } else { - dl.aggregate_align - }; + let mut align = + if def.repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align }; if let Some(repr_align) = def.repr.align { align = align.max(AbiAndPrefAlign::new(repr_align)); @@ -766,25 +725,20 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let field_abi = match &field.abi { Abi::Scalar(x) => Abi::Scalar(scalar_unit(x.value)), Abi::ScalarPair(x, y) => { - Abi::ScalarPair( - scalar_unit(x.value), - scalar_unit(y.value), - ) + Abi::ScalarPair(scalar_unit(x.value), scalar_unit(y.value)) } Abi::Vector { element: x, count } => { - Abi::Vector { - element: scalar_unit(x.value), - count: *count, - } + Abi::Vector { element: scalar_unit(x.value), count: *count } + } + Abi::Uninhabited | Abi::Aggregate { .. } => { + Abi::Aggregate { sized: true } } - Abi::Uninhabited | - Abi::Aggregate { .. } => Abi::Aggregate { sized: true }, }; if size == Size::ZERO { // first non ZST: initialize 'abi' abi = field_abi; - } else if abi != field_abi { + } else if abi != field_abi { // different fields have different ABI: reset to Aggregate abi = Abi::Aggregate { sized: true }; } @@ -803,7 +757,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { abi, largest_niche: None, align, - size: size.align_to(align.abi) + size: size.align_to(align.abi), })); } @@ -818,13 +772,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { uninhabited && is_zst }; let (present_first, present_second) = { - let mut present_variants = variants.iter_enumerated().filter_map(|(i, v)| { - if absent(v) { - None - } else { - Some(i) - } - }); + let mut present_variants = variants + .iter_enumerated() + .filter_map(|(i, v)| if absent(v) { None } else { Some(i) }); (present_variants.next(), present_variants.next()) }; let present_first = match present_first { @@ -851,18 +801,20 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } else { let param_env = tcx.param_env(def.did); let last_field = def.variants[v].fields.last().unwrap(); - let always_sized = tcx.type_of(last_field.did) - .is_sized(tcx.at(DUMMY_SP), param_env); - if !always_sized { StructKind::MaybeUnsized } - else { StructKind::AlwaysSized } + let always_sized = + tcx.type_of(last_field.did).is_sized(tcx.at(DUMMY_SP), param_env); + if !always_sized { + StructKind::MaybeUnsized + } else { + StructKind::AlwaysSized + } }; let mut st = self.univariant_uninterned(ty, &variants[v], &def.repr, kind)?; st.variants = Variants::Single { index: v }; let (start, end) = self.tcx.layout_scalar_valid_range(def.did); match st.abi { - Abi::Scalar(ref mut scalar) | - Abi::ScalarPair(ref mut scalar, _) => { + Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => { // the asserts ensure that we are not using the // `#[rustc_layout_scalar_valid_range(n)]` // attribute to widen the range of anything as that would probably @@ -914,7 +866,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // The current code for niche-filling relies on variant indices // instead of actual discriminants, so dataful enums with // explicit discriminants (RFC #2363) would misbehave. - let no_explicit_discriminants = def.variants.iter_enumerated() + let no_explicit_discriminants = def + .variants + .iter_enumerated() .all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32())); // Niche-filling enum optimization. @@ -946,9 +900,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } if let Some(i) = dataful_variant { - let count = ( - niche_variants.end().as_u32() - niche_variants.start().as_u32() + 1 - ) as u128; + let count = (niche_variants.end().as_u32() + - niche_variants.start().as_u32() + + 1) as u128; // FIXME(#62691) use the largest niche across all fields, // not just the first one. for (field_index, &field) in variants[i].iter().enumerate() { @@ -962,15 +916,22 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { }; let mut align = dl.aggregate_align; - let st = variants.iter_enumerated().map(|(j, v)| { - let mut st = self.univariant_uninterned(ty, v, - &def.repr, StructKind::AlwaysSized)?; - st.variants = Variants::Single { index: j }; - - align = align.max(st.align); - - Ok(st) - }).collect::, _>>()?; + let st = variants + .iter_enumerated() + .map(|(j, v)| { + let mut st = self.univariant_uninterned( + ty, + v, + &def.repr, + StructKind::AlwaysSized, + )?; + st.variants = Variants::Single { index: j }; + + align = align.max(st.align); + + Ok(st) + }) + .collect::, _>>()?; let offset = st[i].fields.offset(field_index) + niche.offset; let size = st[i].size; @@ -1002,7 +963,6 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { abi = Abi::Uninhabited; } - let largest_niche = Niche::from_scalar(dl, offset, niche_scalar.clone()); @@ -1019,7 +979,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { }, fields: FieldPlacement::Arbitrary { offsets: vec![offset], - memory_index: vec![0] + memory_index: vec![0], }, abi, largest_niche, @@ -1042,8 +1002,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // sign extend the raw representation to be an i128 x = (x << (128 - bits)) >> (128 - bits); } - if x < min { min = x; } - if x > max { max = x; } + if x < min { + min = x; + } + if x > max { + max = x; + } } // We might have no inhabited variants, so pretend there's at least one. if (min, max) == (i128::max_value(), i128::min_value()) { @@ -1075,22 +1039,31 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } // Create the set of structs that represent each variant. - let mut layout_variants = variants.iter_enumerated().map(|(i, field_layouts)| { - let mut st = self.univariant_uninterned(ty, &field_layouts, - &def.repr, StructKind::Prefixed(min_ity.size(), prefix_align))?; - st.variants = Variants::Single { index: i }; - // Find the first field we can't move later - // to make room for a larger discriminant. - for field in st.fields.index_by_increasing_offset().map(|j| field_layouts[j]) { - if !field.is_zst() || field.align.abi.bytes() != 1 { - start_align = start_align.min(field.align.abi); - break; + let mut layout_variants = variants + .iter_enumerated() + .map(|(i, field_layouts)| { + let mut st = self.univariant_uninterned( + ty, + &field_layouts, + &def.repr, + StructKind::Prefixed(min_ity.size(), prefix_align), + )?; + st.variants = Variants::Single { index: i }; + // Find the first field we can't move later + // to make room for a larger discriminant. + for field in + st.fields.index_by_increasing_offset().map(|j| field_layouts[j]) + { + if !field.is_zst() || field.align.abi.bytes() != 1 { + start_align = start_align.min(field.align.abi); + break; + } } - } - size = cmp::max(size, st.size); - align = align.max(st.align); - Ok(st) - }).collect::, _>>()?; + size = cmp::max(size, st.size); + align = align.max(st.align); + Ok(st) + }) + .collect::, _>>()?; // Align the maximum variant size to the largest alignment. size = size.align_to(align.abi); @@ -1110,8 +1083,11 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // to store this 16-bit discriminant into 8-bit sized temporary some of the // space necessary to represent would have to be discarded (or layout is wrong // on thinking it needs 16 bits) - bug!("layout decided on a larger discriminant type ({:?}) than typeck ({:?})", - min_ity, typeck_ity); + bug!( + "layout decided on a larger discriminant type ({:?}) than typeck ({:?})", + min_ity, + typeck_ity + ); // However, it is fine to make discr type however large (as an optimisation) // after this point – we’ll just truncate the value we load in codegen. } @@ -1154,7 +1130,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { variant.size = new_ity_size; } } - _ => bug!() + _ => bug!(), } } } @@ -1175,10 +1151,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { FieldPlacement::Arbitrary { ref offsets, .. } => offsets, _ => bug!(), }; - let mut fields = field_layouts - .iter() - .zip(offsets) - .filter(|p| !p.0.is_zst()); + let mut fields = + field_layouts.iter().zip(offsets).filter(|p| !p.0.is_zst()); let (field, offset) = match (fields.next(), fields.next()) { (None, None) => continue, (Some(pair), None) => pair, @@ -1210,19 +1184,17 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { if let Some((prim, offset)) = common_prim { let pair = self.scalar_pair(tag.clone(), scalar_unit(prim)); let pair_offsets = match pair.fields { - FieldPlacement::Arbitrary { - ref offsets, - ref memory_index - } => { + FieldPlacement::Arbitrary { ref offsets, ref memory_index } => { assert_eq!(memory_index, &[0, 1]); offsets } - _ => bug!() + _ => bug!(), }; - if pair_offsets[0] == Size::ZERO && - pair_offsets[1] == *offset && - align == pair.align && - size == pair.size { + if pair_offsets[0] == Size::ZERO + && pair_offsets[1] == *offset + && align == pair.align + && size == pair.size + { // We can use `ScalarPair` only when it matches our // already computed layout (including `#[repr(C)]`). abi = pair.abi; @@ -1245,12 +1217,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { }, fields: FieldPlacement::Arbitrary { offsets: vec![Size::ZERO], - memory_index: vec![0] + memory_index: vec![0], }, largest_niche, abi, align, - size + size, }) } @@ -1263,13 +1235,11 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { tcx.layout_raw(param_env.and(normalized))? } - ty::Bound(..) | - ty::Placeholder(..) | - ty::UnnormalizedProjection(..) | - ty::GeneratorWitness(..) | - ty::Infer(_) => { - bug!("LayoutDetails::compute: unexpected type `{}`", ty) - } + ty::Bound(..) + | ty::Placeholder(..) + | ty::UnnormalizedProjection(..) + | ty::GeneratorWitness(..) + | ty::Infer(_) => bug!("LayoutDetails::compute: unexpected type `{}`", ty), ty::Param(_) | ty::Error => { return Err(LayoutError::Unknown(ty)); @@ -1307,8 +1277,10 @@ enum SavedLocalEligibility { // of any variant. impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { /// Compute the eligibility and assignment of each local. - fn generator_saved_local_eligibility(&self, info: &GeneratorLayout<'tcx>) - -> (BitSet, IndexVec) { + fn generator_saved_local_eligibility( + &self, + info: &GeneratorLayout<'tcx>, + ) -> (BitSet, IndexVec) { use SavedLocalEligibility::*; let mut assignments: IndexVec = @@ -1329,12 +1301,16 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { Assigned(idx) => { // We've already seen this local at another suspension // point, so it is no longer a candidate. - trace!("removing local {:?} in >1 variant ({:?}, {:?})", - local, variant_index, idx); + trace!( + "removing local {:?} in >1 variant ({:?}, {:?})", + local, + variant_index, + idx + ); ineligible_locals.insert(*local); assignments[*local] = Ineligible(None); } - Ineligible(_) => {}, + Ineligible(_) => {} } } } @@ -1352,8 +1328,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // cannot overlap in the generator layout. The only way to guarantee // this is if they are in the same variant, or one is ineligible // (which means it is stored in every variant). - if ineligible_locals.contains(local_b) || - assignments[local_a] == assignments[local_b] + if ineligible_locals.contains(local_b) + || assignments[local_a] == assignments[local_b] { continue; } @@ -1362,11 +1338,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // This is not always optimal; it's just a greedy heuristic that // seems to produce good results most of the time. let conflicts_b = info.storage_conflicts.count(local_b); - let (remove, other) = if conflicts_a > conflicts_b { - (local_a, local_b) - } else { - (local_b, local_a) - }; + let (remove, other) = + if conflicts_a > conflicts_b { (local_a, local_b) } else { (local_b, local_a) }; ineligible_locals.insert(remove); assignments[remove] = Ineligible(None); trace!("removing local {:?} due to conflict with {:?}", remove, other); @@ -1382,7 +1355,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let mut used_variants = BitSet::new_empty(info.variant_fields.len()); for assignment in &assignments { match assignment { - Assigned(idx) => { used_variants.insert(*idx); } + Assigned(idx) => { + used_variants.insert(*idx); + } _ => {} } } @@ -1417,7 +1392,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { use SavedLocalEligibility::*; let tcx = self.tcx; - let subst_field = |ty: Ty<'tcx>| { ty.subst(tcx, substs) }; + let subst_field = |ty: Ty<'tcx>| ty.subst(tcx, substs); let info = tcx.generator_layout(def_id); let (ineligible_locals, assignments) = self.generator_saved_local_eligibility(&info); @@ -1432,11 +1407,14 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { Abi::Scalar(s) => s.clone(), _ => bug!(), }; - let promoted_layouts = ineligible_locals.iter() + let promoted_layouts = ineligible_locals + .iter() .map(|local| subst_field(info.field_tys[local])) .map(|ty| tcx.mk_maybe_uninit(ty)) .map(|ty| self.layout_of(ty)); - let prefix_layouts = substs.as_generator().prefix_tys(def_id, tcx) + let prefix_layouts = substs + .as_generator() + .prefix_tys(def_id, tcx) .map(|ty| self.layout_of(ty)) .chain(iter::once(Ok(discr_layout))) .chain(promoted_layouts) @@ -1478,10 +1456,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let memory_index_a = invert_mapping(&inverse_memory_index_a); let memory_index_b = invert_mapping(&inverse_memory_index_b); - let outer_fields = FieldPlacement::Arbitrary { - offsets: offsets_a, - memory_index: memory_index_a, - }; + let outer_fields = + FieldPlacement::Arbitrary { offsets: offsets_a, memory_index: memory_index_a }; (outer_fields, offsets_b, memory_index_b) } _ => bug!(), @@ -1489,84 +1465,90 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let mut size = prefix.size; let mut align = prefix.align; - let variants = info.variant_fields.iter_enumerated().map(|(index, variant_fields)| { - // Only include overlap-eligible fields when we compute our variant layout. - let variant_only_tys = variant_fields - .iter() - .filter(|local| { - match assignments[**local] { + let variants = info + .variant_fields + .iter_enumerated() + .map(|(index, variant_fields)| { + // Only include overlap-eligible fields when we compute our variant layout. + let variant_only_tys = variant_fields + .iter() + .filter(|local| match assignments[**local] { Unassigned => bug!(), Assigned(v) if v == index => true, Assigned(_) => bug!("assignment does not match variant"), Ineligible(_) => false, - } - }) - .map(|local| subst_field(info.field_tys[*local])); - - let mut variant = self.univariant_uninterned( - ty, - &variant_only_tys - .map(|ty| self.layout_of(ty)) - .collect::, _>>()?, - &ReprOptions::default(), - StructKind::Prefixed(prefix_size, prefix_align.abi))?; - variant.variants = Variants::Single { index }; - - let (offsets, memory_index) = match variant.fields { - FieldPlacement::Arbitrary { offsets, memory_index } => { - (offsets, memory_index) - } - _ => bug!(), - }; + }) + .map(|local| subst_field(info.field_tys[*local])); - // Now, stitch the promoted and variant-only fields back together in - // the order they are mentioned by our GeneratorLayout. - // Because we only use some subset (that can differ between variants) - // of the promoted fields, we can't just pick those elements of the - // `promoted_memory_index` (as we'd end up with gaps). - // So instead, we build an "inverse memory_index", as if all of the - // promoted fields were being used, but leave the elements not in the - // subset as `INVALID_FIELD_IDX`, which we can filter out later to - // obtain a valid (bijective) mapping. - const INVALID_FIELD_IDX: u32 = !0; - let mut combined_inverse_memory_index = - vec![INVALID_FIELD_IDX; promoted_memory_index.len() + memory_index.len()]; - let mut offsets_and_memory_index = offsets.into_iter().zip(memory_index); - let combined_offsets = variant_fields.iter().enumerate().map(|(i, local)| { - let (offset, memory_index) = match assignments[*local] { - Unassigned => bug!(), - Assigned(_) => { - let (offset, memory_index) = offsets_and_memory_index.next().unwrap(); - (offset, promoted_memory_index.len() as u32 + memory_index) - } - Ineligible(field_idx) => { - let field_idx = field_idx.unwrap() as usize; - (promoted_offsets[field_idx], promoted_memory_index[field_idx]) - } + let mut variant = self.univariant_uninterned( + ty, + &variant_only_tys + .map(|ty| self.layout_of(ty)) + .collect::, _>>()?, + &ReprOptions::default(), + StructKind::Prefixed(prefix_size, prefix_align.abi), + )?; + variant.variants = Variants::Single { index }; + + let (offsets, memory_index) = match variant.fields { + FieldPlacement::Arbitrary { offsets, memory_index } => (offsets, memory_index), + _ => bug!(), }; - combined_inverse_memory_index[memory_index as usize] = i as u32; - offset - }).collect(); - - // Remove the unused slots and invert the mapping to obtain the - // combined `memory_index` (also see previous comment). - combined_inverse_memory_index.retain(|&i| i != INVALID_FIELD_IDX); - let combined_memory_index = invert_mapping(&combined_inverse_memory_index); - - variant.fields = FieldPlacement::Arbitrary { - offsets: combined_offsets, - memory_index: combined_memory_index, - }; - size = size.max(variant.size); - align = align.max(variant.align); - Ok(variant) - }).collect::, _>>()?; + // Now, stitch the promoted and variant-only fields back together in + // the order they are mentioned by our GeneratorLayout. + // Because we only use some subset (that can differ between variants) + // of the promoted fields, we can't just pick those elements of the + // `promoted_memory_index` (as we'd end up with gaps). + // So instead, we build an "inverse memory_index", as if all of the + // promoted fields were being used, but leave the elements not in the + // subset as `INVALID_FIELD_IDX`, which we can filter out later to + // obtain a valid (bijective) mapping. + const INVALID_FIELD_IDX: u32 = !0; + let mut combined_inverse_memory_index = + vec![INVALID_FIELD_IDX; promoted_memory_index.len() + memory_index.len()]; + let mut offsets_and_memory_index = offsets.into_iter().zip(memory_index); + let combined_offsets = variant_fields + .iter() + .enumerate() + .map(|(i, local)| { + let (offset, memory_index) = match assignments[*local] { + Unassigned => bug!(), + Assigned(_) => { + let (offset, memory_index) = + offsets_and_memory_index.next().unwrap(); + (offset, promoted_memory_index.len() as u32 + memory_index) + } + Ineligible(field_idx) => { + let field_idx = field_idx.unwrap() as usize; + (promoted_offsets[field_idx], promoted_memory_index[field_idx]) + } + }; + combined_inverse_memory_index[memory_index as usize] = i as u32; + offset + }) + .collect(); + + // Remove the unused slots and invert the mapping to obtain the + // combined `memory_index` (also see previous comment). + combined_inverse_memory_index.retain(|&i| i != INVALID_FIELD_IDX); + let combined_memory_index = invert_mapping(&combined_inverse_memory_index); + + variant.fields = FieldPlacement::Arbitrary { + offsets: combined_offsets, + memory_index: combined_memory_index, + }; + + size = size.max(variant.size); + align = align.max(variant.align); + Ok(variant) + }) + .collect::, _>>()?; size = size.align_to(align.abi); - let abi = if prefix.abi.is_uninhabited() || - variants.iter().all(|v| v.abi.is_uninhabited()) { + let abi = if prefix.abi.is_uninhabited() || variants.iter().all(|v| v.abi.is_uninhabited()) + { Abi::Uninhabited } else { Abi::Aggregate { sized: true } @@ -1604,23 +1586,22 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // Ignore layouts that are done with non-empty environments or // non-monomorphic layouts, as the user only wants to see the stuff // resulting from the final codegen session. - if - layout.ty.has_param_types() || - !self.param_env.caller_bounds.is_empty() - { + if layout.ty.has_param_types() || !self.param_env.caller_bounds.is_empty() { return; } // (delay format until we actually need it) let record = |kind, packed, opt_discr_size, variants| { let type_desc = format!("{:?}", layout.ty); - self.tcx.sess.code_stats.record_type_size(kind, - type_desc, - layout.align.abi, - layout.size, - packed, - opt_discr_size, - variants); + self.tcx.sess.code_stats.record_type_size( + kind, + type_desc, + layout.align.abi, + layout.size, + packed, + opt_discr_size, + variants, + ); }; let adt_def = match layout.ty.kind { @@ -1644,12 +1625,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let adt_kind = adt_def.adt_kind(); let adt_packed = adt_def.repr.pack.is_some(); - let build_variant_info = |n: Option, - flds: &[ast::Name], - layout: TyLayout<'tcx>| { + let build_variant_info = |n: Option, flds: &[ast::Name], layout: TyLayout<'tcx>| { let mut min_size = Size::ZERO; - let field_info: Vec<_> = flds.iter().enumerate().map(|(i, &name)| { - match layout.field(self, i) { + let field_info: Vec<_> = flds + .iter() + .enumerate() + .map(|(i, &name)| match layout.field(self, i) { Err(err) => { bug!("no layout found for field {}: `{:?}`", name, err); } @@ -1666,8 +1647,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { align: field_layout.align.abi.bytes(), } } - } - }).collect(); + }) + .collect(); session::VariantInfo { name: n.map(|n| n.to_string()), @@ -1677,29 +1658,23 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { session::SizeKind::Exact }, align: layout.align.abi.bytes(), - size: if min_size.bytes() == 0 { - layout.size.bytes() - } else { - min_size.bytes() - }, + size: if min_size.bytes() == 0 { layout.size.bytes() } else { min_size.bytes() }, fields: field_info, } }; match layout.variants { Variants::Single { index } => { - debug!("print-type-size `{:#?}` variant {}", - layout, adt_def.variants[index].ident); + debug!("print-type-size `{:#?}` variant {}", layout, adt_def.variants[index].ident); if !adt_def.variants.is_empty() { let variant_def = &adt_def.variants[index]; - let fields: Vec<_> = - variant_def.fields.iter().map(|f| f.ident.name).collect(); - record(adt_kind.into(), - adt_packed, - None, - vec![build_variant_info(Some(variant_def.ident), - &fields, - layout)]); + let fields: Vec<_> = variant_def.fields.iter().map(|f| f.ident.name).collect(); + record( + adt_kind.into(), + adt_packed, + None, + vec![build_variant_info(Some(variant_def.ident), &fields, layout)], + ); } else { // (This case arises for *empty* enums; so give it // zero variants.) @@ -1708,21 +1683,33 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } Variants::Multiple { ref discr, ref discr_kind, .. } => { - debug!("print-type-size `{:#?}` adt general variants def {}", - layout.ty, adt_def.variants.len()); - let variant_infos: Vec<_> = - adt_def.variants.iter_enumerated().map(|(i, variant_def)| { + debug!( + "print-type-size `{:#?}` adt general variants def {}", + layout.ty, + adt_def.variants.len() + ); + let variant_infos: Vec<_> = adt_def + .variants + .iter_enumerated() + .map(|(i, variant_def)| { let fields: Vec<_> = variant_def.fields.iter().map(|f| f.ident.name).collect(); - build_variant_info(Some(variant_def.ident), - &fields, - layout.for_variant(self, i)) + build_variant_info( + Some(variant_def.ident), + &fields, + layout.for_variant(self, i), + ) }) .collect(); - record(adt_kind.into(), adt_packed, match discr_kind { - DiscriminantKind::Tag => Some(discr.value.size(self)), - _ => None - }, variant_infos); + record( + adt_kind.into(), + adt_packed, + match discr_kind { + DiscriminantKind::Tag => Some(discr.value.size(self)), + _ => None, + }, + variant_infos, + ); } } } @@ -1744,8 +1731,8 @@ pub enum SizeSkeleton<'tcx> { /// The type which determines the unsized metadata, if any, /// of this pointer. Either a type parameter or a projection /// depending on one, with regions erased. - tail: Ty<'tcx> - } + tail: Ty<'tcx>, + }, } impl<'tcx> SizeSkeleton<'tcx> { @@ -1761,27 +1748,25 @@ impl<'tcx> SizeSkeleton<'tcx> { Ok(layout) => { return Ok(SizeSkeleton::Known(layout.size)); } - Err(err) => err + Err(err) => err, }; match ty.kind { - ty::Ref(_, pointee, _) | - ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { + ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { let non_zero = !ty.is_unsafe_ptr(); let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env); match tail.kind { ty::Param(_) | ty::Projection(_) => { debug_assert!(tail.has_param_types()); - Ok(SizeSkeleton::Pointer { - non_zero, - tail: tcx.erase_regions(&tail) - }) + Ok(SizeSkeleton::Pointer { non_zero, tail: tcx.erase_regions(&tail) }) } - _ => { - bug!("SizeSkeleton::compute({}): layout errored ({}), yet \ + _ => bug!( + "SizeSkeleton::compute({}): layout errored ({}), yet \ tail `{}` is not a type parameter or a projection", - ty, err, tail) - } + ty, + err, + tail + ), } } @@ -1794,9 +1779,10 @@ impl<'tcx> SizeSkeleton<'tcx> { // Get a zero-sized variant or a pointer newtype. let zero_or_ptr_variant = |i| { let i = VariantIdx::new(i); - let fields = def.variants[i].fields.iter().map(|field| { - SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env) - }); + let fields = def.variants[i] + .fields + .iter() + .map(|field| SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env)); let mut ptr = None; for field in fields { let field = field?; @@ -1806,7 +1792,7 @@ impl<'tcx> SizeSkeleton<'tcx> { return Err(err); } } - SizeSkeleton::Pointer {..} => { + SizeSkeleton::Pointer { .. } => { if ptr.is_some() { return Err(err); } @@ -1822,12 +1808,14 @@ impl<'tcx> SizeSkeleton<'tcx> { if def.variants.len() == 1 { if let Some(SizeSkeleton::Pointer { non_zero, tail }) = v0 { return Ok(SizeSkeleton::Pointer { - non_zero: non_zero || match tcx.layout_scalar_valid_range(def.did) { - (Bound::Included(start), Bound::Unbounded) => start > 0, - (Bound::Included(start), Bound::Included(end)) => - 0 < start && start < end, - _ => false, - }, + non_zero: non_zero + || match tcx.layout_scalar_valid_range(def.did) { + (Bound::Included(start), Bound::Unbounded) => start > 0, + (Bound::Included(start), Bound::Included(end)) => { + 0 < start && start < end + } + _ => false, + }, tail, }); } else { @@ -1838,14 +1826,11 @@ impl<'tcx> SizeSkeleton<'tcx> { let v1 = zero_or_ptr_variant(1)?; // Nullable pointer enum optimization. match (v0, v1) { - (Some(SizeSkeleton::Pointer { non_zero: true, tail }), None) | - (None, Some(SizeSkeleton::Pointer { non_zero: true, tail })) => { - Ok(SizeSkeleton::Pointer { - non_zero: false, - tail, - }) + (Some(SizeSkeleton::Pointer { non_zero: true, tail }), None) + | (None, Some(SizeSkeleton::Pointer { non_zero: true, tail })) => { + Ok(SizeSkeleton::Pointer { non_zero: false, tail }) } - _ => Err(err) + _ => Err(err), } } @@ -1858,16 +1843,17 @@ impl<'tcx> SizeSkeleton<'tcx> { } } - _ => Err(err) + _ => Err(err), } } pub fn same_size(self, other: SizeSkeleton<'_>) -> bool { match (self, other) { (SizeSkeleton::Known(a), SizeSkeleton::Known(b)) => a == b, - (SizeSkeleton::Pointer { tail: a, .. }, - SizeSkeleton::Pointer { tail: b, .. }) => a == b, - _ => false + (SizeSkeleton::Pointer { tail: a, .. }, SizeSkeleton::Pointer { tail: b, .. }) => { + a == b + } + _ => false, } } } @@ -1952,10 +1938,7 @@ impl<'tcx> LayoutOf for LayoutCx<'tcx, TyCtxt<'tcx>> { let param_env = self.param_env.with_reveal_all(); let ty = self.tcx.normalize_erasing_regions(param_env, ty); let details = self.tcx.layout_raw(param_env.and(ty))?; - let layout = TyLayout { - ty, - details - }; + let layout = TyLayout { ty, details }; // N.B., this recording is normally disabled; when enabled, it // can however trigger recursive invocations of `layout_of`. @@ -1979,10 +1962,7 @@ impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { let param_env = self.param_env.with_reveal_all(); let ty = self.tcx.normalize_erasing_regions(param_env, ty); let details = self.tcx.layout_raw(param_env.and(ty))?; - let layout = TyLayout { - ty, - details - }; + let layout = TyLayout { ty, details }; // N.B., this recording is normally disabled; when enabled, it // can however trigger recursive invocations of `layout_of`. @@ -1990,10 +1970,7 @@ impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { // completed, to avoid problems around recursive structures // and the like. (Admittedly, I wasn't able to reproduce a problem // here, but it seems like the right thing to do. -nmatsakis) - let cx = LayoutCx { - tcx: *self.tcx, - param_env: self.param_env - }; + let cx = LayoutCx { tcx: *self.tcx, param_env: self.param_env }; cx.record_layout_for_printing(layout); Ok(layout) @@ -2005,12 +1982,11 @@ impl TyCtxt<'tcx> { /// Computes the layout of a type. Note that this implicitly /// executes in "reveal all" mode. #[inline] - pub fn layout_of(self, param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) - -> Result, LayoutError<'tcx>> { - let cx = LayoutCx { - tcx: self, - param_env: param_env_and_ty.param_env - }; + pub fn layout_of( + self, + param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, + ) -> Result, LayoutError<'tcx>> { + let cx = LayoutCx { tcx: self, param_env: param_env_and_ty.param_env }; cx.layout_of(param_env_and_ty.value) } } @@ -2019,12 +1995,11 @@ impl ty::query::TyCtxtAt<'tcx> { /// Computes the layout of a type. Note that this implicitly /// executes in "reveal all" mode. #[inline] - pub fn layout_of(self, param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) - -> Result, LayoutError<'tcx>> { - let cx = LayoutCx { - tcx: self.at(self.span), - param_env: param_env_and_ty.param_env - }; + pub fn layout_of( + self, + param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, + ) -> Result, LayoutError<'tcx>> { + let cx = LayoutCx { tcx: self.at(self.span), param_env: param_env_and_ty.param_env }; cx.layout_of(param_env_and_ty.value) } } @@ -2047,7 +2022,7 @@ where let fields = match this.ty.kind { ty::Adt(def, _) => def.variants[variant_index].fields.len(), - _ => bug!() + _ => bug!(), }; let tcx = cx.tcx(); tcx.intern_layout(LayoutDetails { @@ -2056,21 +2031,16 @@ where abi: Abi::Uninhabited, largest_niche: None, align: tcx.data_layout.i8_align, - size: Size::ZERO + size: Size::ZERO, }) } - Variants::Multiple { ref variants, .. } => { - &variants[variant_index] - } + Variants::Multiple { ref variants, .. } => &variants[variant_index], }; assert_eq!(details.variants, Variants::Single { index: variant_index }); - TyLayout { - ty: this.ty, - details - } + TyLayout { ty: this.ty, details } } fn field(this: TyLayout<'tcx>, cx: &C, i: usize) -> C::TyLayout { @@ -2084,23 +2054,20 @@ where }; cx.layout_of(match this.ty.kind { - ty::Bool | - ty::Char | - ty::Int(_) | - ty::Uint(_) | - ty::Float(_) | - ty::FnPtr(_) | - ty::Never | - ty::FnDef(..) | - ty::GeneratorWitness(..) | - ty::Foreign(..) | - ty::Dynamic(..) => { - bug!("TyLayout::field_type({:?}): not applicable", this) - } + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::FnPtr(_) + | ty::Never + | ty::FnDef(..) + | ty::GeneratorWitness(..) + | ty::Foreign(..) + | ty::Dynamic(..) => bug!("TyLayout::field_type({:?}): not applicable", this), // Potentially-fat pointers. - ty::Ref(_, pointee, _) | - ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { + ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { assert!(i < this.fields.count()); // Reuse the fat `*T` type as its own thin pointer data field. @@ -2114,20 +2081,18 @@ where } else { tcx.mk_mut_ref(tcx.lifetimes.re_static, nil) }; - return MaybeResult::from(cx.layout_of(ptr_ty).to_result().map(|mut ptr_layout| { - ptr_layout.ty = this.ty; - ptr_layout - })); + return MaybeResult::from(cx.layout_of(ptr_ty).to_result().map( + |mut ptr_layout| { + ptr_layout.ty = this.ty; + ptr_layout + }, + )); } match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind { - ty::Slice(_) | - ty::Str => tcx.types.usize, + ty::Slice(_) | ty::Str => tcx.types.usize, ty::Dynamic(_, _) => { - tcx.mk_imm_ref( - tcx.lifetimes.re_static, - tcx.mk_array(tcx.types.usize, 3), - ) + tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.usize, 3)) /* FIXME: use actual fn pointers Warning: naively computing the number of entries in the vtable by counting the methods on the trait + methods on @@ -2142,13 +2107,12 @@ where ]) */ } - _ => bug!("TyLayout::field_type({:?}): not applicable", this) + _ => bug!("TyLayout::field_type({:?}): not applicable", this), } } // Arrays and slices. - ty::Array(element, _) | - ty::Slice(element) => element, + ty::Array(element, _) | ty::Slice(element) => element, ty::Str => tcx.types.u8, // Tuples, generators and closures. @@ -2156,35 +2120,31 @@ where substs.as_closure().upvar_tys(def_id, tcx).nth(i).unwrap() } - ty::Generator(def_id, ref substs, _) => { - match this.variants { - Variants::Single { index } => { - substs.as_generator().state_tys(def_id, tcx) - .nth(index.as_usize()).unwrap() - .nth(i).unwrap() - } - Variants::Multiple { ref discr, discr_index, .. } => { - if i == discr_index { - return discr_layout(discr); - } - substs.as_generator().prefix_tys(def_id, tcx).nth(i).unwrap() + ty::Generator(def_id, ref substs, _) => match this.variants { + Variants::Single { index } => substs + .as_generator() + .state_tys(def_id, tcx) + .nth(index.as_usize()) + .unwrap() + .nth(i) + .unwrap(), + Variants::Multiple { ref discr, discr_index, .. } => { + if i == discr_index { + return discr_layout(discr); } + substs.as_generator().prefix_tys(def_id, tcx).nth(i).unwrap() } - } + }, ty::Tuple(tys) => tys[i].expect_ty(), // SIMD vector types. - ty::Adt(def, ..) if def.repr.simd() => { - this.ty.simd_type(tcx) - } + ty::Adt(def, ..) if def.repr.simd() => this.ty.simd_type(tcx), // ADTs. ty::Adt(def, substs) => { match this.variants { - Variants::Single { index } => { - def.variants[index].fields[i].ty(tcx, substs) - } + Variants::Single { index } => def.variants[index].fields[i].ty(tcx, substs), // Discriminant field for enums (where applicable). Variants::Multiple { ref discr, .. } => { @@ -2194,38 +2154,38 @@ where } } - ty::Projection(_) | ty::UnnormalizedProjection(..) | ty::Bound(..) | - ty::Placeholder(..) | ty::Opaque(..) | ty::Param(_) | ty::Infer(_) | - ty::Error => { - bug!("TyLayout::field_type: unexpected type `{}`", this.ty) - } + ty::Projection(_) + | ty::UnnormalizedProjection(..) + | ty::Bound(..) + | ty::Placeholder(..) + | ty::Opaque(..) + | ty::Param(_) + | ty::Infer(_) + | ty::Error => bug!("TyLayout::field_type: unexpected type `{}`", this.ty), }) } - fn pointee_info_at( - this: TyLayout<'tcx>, - cx: &C, - offset: Size, - ) -> Option { + fn pointee_info_at(this: TyLayout<'tcx>, cx: &C, offset: Size) -> Option { match this.ty.kind { ty::RawPtr(mt) if offset.bytes() == 0 => { - cx.layout_of(mt.ty).to_result().ok() - .map(|layout| PointeeInfo { - size: layout.size, - align: layout.align.abi, - safe: None, - }) + cx.layout_of(mt.ty).to_result().ok().map(|layout| PointeeInfo { + size: layout.size, + align: layout.align.abi, + safe: None, + }) } ty::Ref(_, ty, mt) if offset.bytes() == 0 => { let tcx = cx.tcx(); let is_freeze = ty.is_freeze(tcx, cx.param_env(), DUMMY_SP); let kind = match mt { - hir::Mutability::Not => if is_freeze { - PointerKind::Frozen - } else { - PointerKind::Shared - }, + hir::Mutability::Not => { + if is_freeze { + PointerKind::Frozen + } else { + PointerKind::Shared + } + } hir::Mutability::Mut => { // Previously we would only emit noalias annotations for LLVM >= 6 or in // panic=abort mode. That was deemed right, as prior versions had many bugs @@ -2238,8 +2198,8 @@ where // // For now, do not enable mutable_noalias by default at all, while the // issue is being figured out. - let mutable_noalias = tcx.sess.opts.debugging_opts.mutable_noalias - .unwrap_or(false); + let mutable_noalias = + tcx.sess.opts.debugging_opts.mutable_noalias.unwrap_or(false); if mutable_noalias { PointerKind::UniqueBorrowed } else { @@ -2248,12 +2208,11 @@ where } }; - cx.layout_of(ty).to_result().ok() - .map(|layout| PointeeInfo { - size: layout.size, - align: layout.align.abi, - safe: Some(kind), - }) + cx.layout_of(ty).to_result().ok().map(|layout| PointeeInfo { + size: layout.size, + align: layout.align.abi, + safe: Some(kind), + }) } _ => { @@ -2270,14 +2229,12 @@ where // using more niches than just null (e.g., the first page of // the address space, or unaligned pointers). Variants::Multiple { - discr_kind: DiscriminantKind::Niche { - dataful_variant, - .. - }, + discr_kind: DiscriminantKind::Niche { dataful_variant, .. }, discr_index, .. - } if this.fields.offset(discr_index) == offset => - Some(this.for_variant(cx, dataful_variant)), + } if this.fields.offset(discr_index) == offset => { + Some(this.for_variant(cx, dataful_variant)) + } _ => Some(this), }; @@ -2296,15 +2253,14 @@ where let field_start = variant.fields.offset(i); if field_start <= offset { let field = variant.field(cx, i); - result = field.to_result().ok() - .and_then(|field| { - if ptr_end <= field_start + field.size { - // We found the right field, look inside it. - field.pointee_info_at(cx, offset - field_start) - } else { - None - } - }); + result = field.to_result().ok().and_then(|field| { + if ptr_end <= field_start + field.size { + // We found the right field, look inside it. + field.pointee_info_at(cx, offset - field_start) + } else { + None + } + }); if result.is_some() { break; } @@ -2333,13 +2289,11 @@ impl<'a, 'tcx> HashStable> for LayoutError<'tcx> { mem::discriminant(self).hash_stable(hcx, hasher); match *self { - Unknown(t) | - SizeOverflow(t) => t.hash_stable(hcx, hasher) + Unknown(t) | SizeOverflow(t) => t.hash_stable(hcx, hasher), } } } - impl<'tcx> ty::Instance<'tcx> { // NOTE(eddyb) this is private to avoid using it from outside of // `FnAbi::of_instance` - any other uses are either too high-level @@ -2495,10 +2449,7 @@ where } } - bug!( - "receiver has no non-zero-sized fields {:?}", - fat_pointer_layout - ); + bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout); } fat_pointer_layout.ty @@ -2524,9 +2475,7 @@ where ) -> Self { debug!("FnAbi::new_internal({:?}, {:?})", sig, extra_args); - let sig = cx - .tcx() - .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); + let sig = cx.tcx().normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); use rustc_target::spec::abi::Abi::*; let conv = match cx.tcx().sess.target.target.adjust_abi(sig.abi) { @@ -2619,7 +2568,7 @@ where // any time. Set their valid size to 0. attrs.pointee_size = match kind { PointerKind::UniqueOwned => Size::ZERO, - _ => pointee.size + _ => pointee.size, }; // `Box` pointer parameters never alias because ownership is transferred @@ -2758,10 +2707,7 @@ where // We want to pass small aggregates as immediates, but using // a LLVM aggregate type for this leads to bad optimizations, // so we pick an appropriately sized integer type instead. - arg.cast_to(Reg { - kind: RegKind::Integer, - size, - }); + arg.cast_to(Reg { kind: RegKind::Integer, size }); } }; fixup(&mut self.ret); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 30356d59a7ce6..8834e0e5a08c4 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1,38 +1,39 @@ // ignore-tidy-filelength -pub use self::Variance::*; +pub use self::fold::{TypeFoldable, TypeVisitor}; pub use self::AssocItemContainer::*; pub use self::BorrowKind::*; pub use self::IntVarValue::*; -pub use self::fold::{TypeFoldable, TypeVisitor}; +pub use self::Variance::*; -use crate::hir::{map as hir_map, GlobMap, TraitMap}; -use crate::hir::Node; -use crate::hir::def::{Res, DefKind, CtorOf, CtorKind, ExportMap}; +use crate::hir::def::{CtorKind, CtorOf, DefKind, ExportMap, Res}; use crate::hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; -use rustc_data_structures::svh::Svh; -use rustc_macros::HashStable; +use crate::hir::Node; +use crate::hir::{map as hir_map, GlobMap, TraitMap}; use crate::ich::Fingerprint; use crate::ich::StableHashingContext; use crate::infer::canonical::Canonical; use crate::middle::cstore::CrateStoreDyn; -use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; +use crate::middle::lang_items::{FnMutTraitLangItem, FnOnceTraitLangItem, FnTraitLangItem}; use crate::middle::resolve_lifetime::ObjectLifetimeDefault; -use crate::mir::ReadOnlyBodyAndCache; use crate::mir::interpret::ErrorHandled; use crate::mir::GeneratorLayout; +use crate::mir::ReadOnlyBodyAndCache; use crate::session::CrateDisambiguator; +use crate::session::DataTypeKind; use crate::traits::{self, Reveal}; use crate::ty; use crate::ty::layout::VariantIdx; -use crate::ty::subst::{Subst, InternalSubsts, SubstsRef}; -use crate::ty::util::{IntTypeExt, Discr}; +use crate::ty::subst::{InternalSubsts, Subst, SubstsRef}; +use crate::ty::util::{Discr, IntTypeExt}; use crate::ty::walk::TypeWalker; use crate::util::captures::Captures; -use crate::util::nodemap::{NodeMap, NodeSet, DefIdMap, FxHashMap}; +use crate::util::nodemap::{DefIdMap, FxHashMap, NodeMap, NodeSet}; use arena::SyncDroplessArena; -use crate::session::DataTypeKind; +use rustc_data_structures::svh::Svh; +use rustc_macros::HashStable; +use rustc_data_structures::sync::{self, par_iter, Lrc, ParallelIterator}; use rustc_serialize::{self, Encodable, Encoder}; use rustc_target::abi::Align; use std::cell::RefCell; @@ -40,47 +41,48 @@ use std::cmp::{self, Ordering}; use std::fmt; use std::hash::{Hash, Hasher}; use std::ops::Deref; -use rustc_data_structures::sync::{self, Lrc, ParallelIterator, par_iter}; +use std::ops::Range; use std::slice; use std::{mem, ptr}; -use std::ops::Range; -use syntax::ast::{self, Name, Ident, NodeId}; +use syntax::ast::{self, Ident, Name, NodeId}; use syntax::attr; -use syntax_pos::symbol::{kw, sym, Symbol}; use syntax_pos::hygiene::ExpnId; +use syntax_pos::symbol::{kw, sym, Symbol}; use syntax_pos::Span; -use smallvec; -use rustc_data_structures::fx::{FxIndexMap}; -use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; +use rustc_data_structures::fx::FxIndexMap; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_index::vec::{Idx, IndexVec}; +use smallvec; use crate::hir; -pub use self::sty::{Binder, BoundTy, BoundTyKind, BoundVar, DebruijnIndex, INNERMOST}; -pub use self::sty::{FnSig, GenSig, CanonicalPolyFnSig, PolyFnSig, PolyGenSig}; -pub use self::sty::{InferTy, ParamTy, ParamConst, InferConst, ProjectionTy, ExistentialPredicate}; -pub use self::sty::{ClosureSubsts, GeneratorSubsts, UpvarSubsts, TypeAndMut}; -pub use self::sty::{TraitRef, TyKind, PolyTraitRef}; -pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef}; -pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const, ConstKind}; -pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}; -pub use self::sty::RegionKind; -pub use self::sty::{TyVid, IntVid, FloatVid, ConstVid, RegionVid}; pub use self::sty::BoundRegion::*; pub use self::sty::InferTy::*; +pub use self::sty::RegionKind; pub use self::sty::RegionKind::*; pub use self::sty::TyKind::*; +pub use self::sty::{Binder, BoundTy, BoundTyKind, BoundVar, DebruijnIndex, INNERMOST}; +pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}; +pub use self::sty::{CanonicalPolyFnSig, FnSig, GenSig, PolyFnSig, PolyGenSig}; +pub use self::sty::{ClosureSubsts, GeneratorSubsts, TypeAndMut, UpvarSubsts}; +pub use self::sty::{Const, ConstKind, ExistentialProjection, PolyExistentialProjection}; +pub use self::sty::{ConstVid, FloatVid, IntVid, RegionVid, TyVid}; +pub use self::sty::{ExistentialPredicate, InferConst, InferTy, ParamConst, ParamTy, ProjectionTy}; +pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef}; +pub use self::sty::{PolyTraitRef, TraitRef, TyKind}; pub use crate::ty::diagnostics::*; pub use self::binding::BindingMode; pub use self::binding::BindingMode::*; -pub use self::context::{TyCtxt, FreeRegionInfo, AllArenas, tls, keep_local}; -pub use self::context::{Lift, GeneratorInteriorTypeCause, TypeckTables, CtxtInterners, GlobalCtxt}; +pub use self::context::{keep_local, tls, AllArenas, FreeRegionInfo, TyCtxt}; +pub use self::context::{ + CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ResolvedOpaqueTy, + UserType, UserTypeAnnotationIndex, +}; pub use self::context::{ - UserTypeAnnotationIndex, UserType, CanonicalUserType, - CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ResolvedOpaqueTy, + CtxtInterners, GeneratorInteriorTypeCause, GlobalCtxt, Lift, TypeckTables, }; pub use self::instance::{Instance, InstanceDef}; @@ -98,15 +100,15 @@ pub mod binding; pub mod cast; #[macro_use] pub mod codec; +pub mod _match; mod constness; -pub mod error; mod erase_regions; +pub mod error; pub mod fast_reject; pub mod flags; pub mod fold; pub mod inhabitedness; pub mod layout; -pub mod _match; pub mod outlives; pub mod print; pub mod query; @@ -114,16 +116,16 @@ pub mod relate; pub mod steal; pub mod subst; pub mod trait_def; +pub mod util; pub mod walk; pub mod wf; -pub mod util; mod context; +mod diagnostics; mod instance; mod structural_impls; mod structural_match; mod sty; -mod diagnostics; // Data types @@ -153,7 +155,7 @@ impl AssocItemContainer { pub fn assert_trait(&self) -> DefId { match *self { TraitContainer(id) => id, - _ => bug!("associated item has wrong container type: {:?}", self) + _ => bug!("associated item has wrong container type: {:?}", self), } } @@ -209,15 +211,14 @@ pub enum AssocKind { Const, Method, OpaqueTy, - Type + Type, } impl AssocKind { pub fn suggestion_descr(&self) -> &'static str { match self { ty::AssocKind::Method => "method call", - ty::AssocKind::Type | - ty::AssocKind::OpaqueTy => "associated type", + ty::AssocKind::Type | ty::AssocKind::OpaqueTy => "associated type", ty::AssocKind::Const => "associated constant", } } @@ -237,9 +238,7 @@ impl AssocItem { /// for ! pub fn relevant_for_never(&self) -> bool { match self.kind { - AssocKind::OpaqueTy | - AssocKind::Const | - AssocKind::Type => true, + AssocKind::OpaqueTy | AssocKind::Const | AssocKind::Type => true, // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited. AssocKind::Method => !self.method_has_self_argument, } @@ -353,10 +352,10 @@ impl Visibility { #[derive(Copy, Clone, PartialEq, RustcDecodable, RustcEncodable, HashStable)] pub enum Variance { - Covariant, // T <: T iff A <: B -- e.g., function return type - Invariant, // T <: T iff B == A -- e.g., type of mutable cell - Contravariant, // T <: T iff B <: A -- e.g., function param type - Bivariant, // T <: T -- e.g., unused type parameter + Covariant, // T <: T iff A <: B -- e.g., function return type + Invariant, // T <: T iff B == A -- e.g., type of mutable cell + Contravariant, // T <: T iff B <: A -- e.g., function param type + Bivariant, // T <: T -- e.g., unused type parameter } /// The crate variances map is computed during typeck and contains the @@ -589,7 +588,7 @@ impl<'tcx> rustc_serialize::UseSpecializedDecodable for Ty<'tcx> {} pub type CanonicalTy<'tcx> = Canonical<'tcx, Ty<'tcx>>; -extern { +extern "C" { /// A dummy type used to force `List` to be unsized while not requiring references to it be wide /// pointers. type OpaqueListContents; @@ -625,9 +624,7 @@ impl List { let size = offset + slice.len() * mem::size_of::(); - let mem = arena.alloc_raw( - size, - cmp::max(mem::align_of::(), mem::align_of::())); + let mem = arena.alloc_raw(size, cmp::max(mem::align_of::(), mem::align_of::())); unsafe { let result = &mut *(mem.as_mut_ptr() as *mut List); // Write the length @@ -655,17 +652,23 @@ impl Encodable for List { } } -impl Ord for List where T: Ord { +impl Ord for List +where + T: Ord, +{ fn cmp(&self, other: &List) -> Ordering { - if self == other { Ordering::Equal } else { - <[T] as Ord>::cmp(&**self, &**other) - } + if self == other { Ordering::Equal } else { <[T] as Ord>::cmp(&**self, &**other) } } } -impl PartialOrd for List where T: PartialOrd { +impl PartialOrd for List +where + T: PartialOrd, +{ fn partial_cmp(&self, other: &List) -> Option { - if self == other { Some(Ordering::Equal) } else { + if self == other { + Some(Ordering::Equal) + } else { <[T] as PartialOrd>::partial_cmp(&**self, &**other) } } @@ -697,9 +700,7 @@ impl Deref for List { impl AsRef<[T]> for List { #[inline(always)] fn as_ref(&self) -> &[T] { - unsafe { - slice::from_raw_parts(self.data.as_ptr(), self.len) - } + unsafe { slice::from_raw_parts(self.data.as_ptr(), self.len) } } } @@ -721,9 +722,7 @@ impl List { struct EmptySlice([u8; 64]); static EMPTY_SLICE: EmptySlice = EmptySlice([0; 64]); assert!(mem::align_of::() <= 64); - unsafe { - &*(&EMPTY_SLICE as *const _ as *const List) - } + unsafe { &*(&EMPTY_SLICE as *const _ as *const List) } } } @@ -784,7 +783,7 @@ pub enum BorrowKind { UniqueImmBorrow, /// Data is mutable and not aliasable. - MutBorrow + MutBorrow, } /// Information describing the capture of an upvar. This is computed @@ -870,11 +869,7 @@ pub struct GenericParamDef { impl GenericParamDef { pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion { if let GenericParamDefKind::Lifetime = self.kind { - ty::EarlyBoundRegion { - def_id: self.def_id, - index: self.index, - name: self.name, - } + ty::EarlyBoundRegion { def_id: self.def_id, index: self.index, name: self.name } } else { bug!("cannot convert a non-lifetime parameter def to an early bound region") } @@ -969,11 +964,11 @@ impl<'tcx> Generics { let param = &self.params[index as usize]; match param.kind { GenericParamDefKind::Lifetime => param, - _ => bug!("expected lifetime parameter, but found another generic parameter") + _ => bug!("expected lifetime parameter, but found another generic parameter"), } } else { tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?")) - .region_param(param, tcx) + .region_param(param, tcx) } } @@ -983,11 +978,11 @@ impl<'tcx> Generics { let param = &self.params[index as usize]; match param.kind { GenericParamDefKind::Type { .. } => param, - _ => bug!("expected type parameter, but found another generic parameter") + _ => bug!("expected type parameter, but found another generic parameter"), } } else { tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?")) - .type_param(param, tcx) + .type_param(param, tcx) } } @@ -997,7 +992,7 @@ impl<'tcx> Generics { let param = &self.params[index as usize]; match param.kind { GenericParamDefKind::Const => param, - _ => bug!("expected const parameter, but found another generic parameter") + _ => bug!("expected const parameter, but found another generic parameter"), } } else { tcx.generics_of(self.parent.expect("parent_count>0 but no parent?")) @@ -1043,9 +1038,7 @@ impl<'tcx> GenericPredicates<'tcx> { if let Some(def_id) = self.parent { tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs); } - instantiated.predicates.extend( - self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)), - ); + instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| p.subst(tcx, substs))); } pub fn instantiate_identity(&self, tcx: TyCtxt<'tcx>) -> InstantiatedPredicates<'tcx> { @@ -1072,9 +1065,11 @@ impl<'tcx> GenericPredicates<'tcx> { ) -> InstantiatedPredicates<'tcx> { assert_eq!(self.parent, None); InstantiatedPredicates { - predicates: self.predicates.iter().map(|(pred, _)| { - pred.subst_supertrait(tcx, poly_trait_ref) - }).collect() + predicates: self + .predicates + .iter() + .map(|(pred, _)| pred.subst_supertrait(tcx, poly_trait_ref)) + .collect(), } } } @@ -1208,24 +1203,29 @@ impl<'tcx> Predicate<'tcx> { let substs = &trait_ref.skip_binder().substs; match *self { - Predicate::Trait(ref binder) => - Predicate::Trait(binder.map_bound(|data| data.subst(tcx, substs))), - Predicate::Subtype(ref binder) => - Predicate::Subtype(binder.map_bound(|data| data.subst(tcx, substs))), - Predicate::RegionOutlives(ref binder) => - Predicate::RegionOutlives(binder.map_bound(|data| data.subst(tcx, substs))), - Predicate::TypeOutlives(ref binder) => - Predicate::TypeOutlives(binder.map_bound(|data| data.subst(tcx, substs))), - Predicate::Projection(ref binder) => - Predicate::Projection(binder.map_bound(|data| data.subst(tcx, substs))), - Predicate::WellFormed(data) => - Predicate::WellFormed(data.subst(tcx, substs)), - Predicate::ObjectSafe(trait_def_id) => - Predicate::ObjectSafe(trait_def_id), - Predicate::ClosureKind(closure_def_id, closure_substs, kind) => - Predicate::ClosureKind(closure_def_id, closure_substs.subst(tcx, substs), kind), - Predicate::ConstEvaluatable(def_id, const_substs) => - Predicate::ConstEvaluatable(def_id, const_substs.subst(tcx, substs)), + Predicate::Trait(ref binder) => { + Predicate::Trait(binder.map_bound(|data| data.subst(tcx, substs))) + } + Predicate::Subtype(ref binder) => { + Predicate::Subtype(binder.map_bound(|data| data.subst(tcx, substs))) + } + Predicate::RegionOutlives(ref binder) => { + Predicate::RegionOutlives(binder.map_bound(|data| data.subst(tcx, substs))) + } + Predicate::TypeOutlives(ref binder) => { + Predicate::TypeOutlives(binder.map_bound(|data| data.subst(tcx, substs))) + } + Predicate::Projection(ref binder) => { + Predicate::Projection(binder.map_bound(|data| data.subst(tcx, substs))) + } + Predicate::WellFormed(data) => Predicate::WellFormed(data.subst(tcx, substs)), + Predicate::ObjectSafe(trait_def_id) => Predicate::ObjectSafe(trait_def_id), + Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { + Predicate::ClosureKind(closure_def_id, closure_substs.subst(tcx, substs), kind) + } + Predicate::ConstEvaluatable(def_id, const_substs) => { + Predicate::ConstEvaluatable(def_id, const_substs.subst(tcx, substs)) + } } } } @@ -1233,7 +1233,7 @@ impl<'tcx> Predicate<'tcx> { #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] #[derive(HashStable, TypeFoldable)] pub struct TraitPredicate<'tcx> { - pub trait_ref: TraitRef<'tcx> + pub trait_ref: TraitRef<'tcx>, } pub type PolyTraitPredicate<'tcx> = ty::Binder>; @@ -1273,7 +1273,7 @@ pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder { pub a_is_expected: bool, pub a: Ty<'tcx>, - pub b: Ty<'tcx> + pub b: Ty<'tcx>, } pub type PolySubtypePredicate<'tcx> = ty::Binder>; @@ -1350,9 +1350,7 @@ pub trait ToPredicate<'tcx> { impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { fn to_predicate(&self) -> Predicate<'tcx> { - ty::Predicate::Trait(ty::Binder::dummy(ty::TraitPredicate { - trait_ref: self.clone() - })) + ty::Predicate::Trait(ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.clone() })) } } @@ -1382,22 +1380,24 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { // A custom iterator used by `Predicate::walk_tys`. enum WalkTysIter<'tcx, I, J, K> - where I: Iterator>, - J: Iterator>, - K: Iterator> +where + I: Iterator>, + J: Iterator>, + K: Iterator>, { None, One(Ty<'tcx>), Two(Ty<'tcx>, Ty<'tcx>), Types(I), InputTypes(J), - ProjectionTypes(K) + ProjectionTypes(K), } impl<'tcx, I, J, K> Iterator for WalkTysIter<'tcx, I, J, K> - where I: Iterator>, - J: Iterator>, - K: Iterator> +where + I: Iterator>, + J: Iterator>, + K: Iterator>, { type Item = Ty<'tcx>; @@ -1407,20 +1407,14 @@ impl<'tcx, I, J, K> Iterator for WalkTysIter<'tcx, I, J, K> WalkTysIter::One(item) => { *self = WalkTysIter::None; Some(item) - }, + } WalkTysIter::Two(item1, item2) => { *self = WalkTysIter::One(item2); Some(item1) - }, - WalkTysIter::Types(ref mut iter) => { - iter.next() - }, - WalkTysIter::InputTypes(ref mut iter) => { - iter.next() - }, - WalkTysIter::ProjectionTypes(ref mut iter) => { - iter.next() } + WalkTysIter::Types(ref mut iter) => iter.next(), + WalkTysIter::InputTypes(ref mut iter) => iter.next(), + WalkTysIter::ProjectionTypes(ref mut iter) => iter.next(), } } } @@ -1438,65 +1432,48 @@ impl<'tcx> Predicate<'tcx> { let SubtypePredicate { a, b, a_is_expected: _ } = binder.skip_binder(); WalkTysIter::Two(a, b) } - ty::Predicate::TypeOutlives(binder) => { - WalkTysIter::One(binder.skip_binder().0) - } - ty::Predicate::RegionOutlives(..) => { - WalkTysIter::None - } + ty::Predicate::TypeOutlives(binder) => WalkTysIter::One(binder.skip_binder().0), + ty::Predicate::RegionOutlives(..) => WalkTysIter::None, ty::Predicate::Projection(ref data) => { let inner = data.skip_binder(); WalkTysIter::ProjectionTypes( - inner.projection_ty.substs.types().chain(Some(inner.ty))) - } - ty::Predicate::WellFormed(data) => { - WalkTysIter::One(data) - } - ty::Predicate::ObjectSafe(_trait_def_id) => { - WalkTysIter::None + inner.projection_ty.substs.types().chain(Some(inner.ty)), + ) } + ty::Predicate::WellFormed(data) => WalkTysIter::One(data), + ty::Predicate::ObjectSafe(_trait_def_id) => WalkTysIter::None, ty::Predicate::ClosureKind(_closure_def_id, closure_substs, _kind) => { WalkTysIter::Types(closure_substs.types()) } - ty::Predicate::ConstEvaluatable(_, substs) => { - WalkTysIter::Types(substs.types()) - } + ty::Predicate::ConstEvaluatable(_, substs) => WalkTysIter::Types(substs.types()), } } pub fn to_opt_poly_trait_ref(&self) -> Option> { match *self { - Predicate::Trait(ref t) => { - Some(t.to_poly_trait_ref()) - } - Predicate::Projection(..) | - Predicate::Subtype(..) | - Predicate::RegionOutlives(..) | - Predicate::WellFormed(..) | - Predicate::ObjectSafe(..) | - Predicate::ClosureKind(..) | - Predicate::TypeOutlives(..) | - Predicate::ConstEvaluatable(..) => { - None - } + Predicate::Trait(ref t) => Some(t.to_poly_trait_ref()), + Predicate::Projection(..) + | Predicate::Subtype(..) + | Predicate::RegionOutlives(..) + | Predicate::WellFormed(..) + | Predicate::ObjectSafe(..) + | Predicate::ClosureKind(..) + | Predicate::TypeOutlives(..) + | Predicate::ConstEvaluatable(..) => None, } } pub fn to_opt_type_outlives(&self) -> Option> { match *self { - Predicate::TypeOutlives(data) => { - Some(data) - } - Predicate::Trait(..) | - Predicate::Projection(..) | - Predicate::Subtype(..) | - Predicate::RegionOutlives(..) | - Predicate::WellFormed(..) | - Predicate::ObjectSafe(..) | - Predicate::ClosureKind(..) | - Predicate::ConstEvaluatable(..) => { - None - } + Predicate::TypeOutlives(data) => Some(data), + Predicate::Trait(..) + | Predicate::Projection(..) + | Predicate::Subtype(..) + | Predicate::RegionOutlives(..) + | Predicate::WellFormed(..) + | Predicate::ObjectSafe(..) + | Predicate::ClosureKind(..) + | Predicate::ConstEvaluatable(..) => None, } } } @@ -1688,7 +1665,7 @@ impl<'tcx> ParamEnv<'tcx> { pub fn new( caller_bounds: &'tcx List>, reveal: Reveal, - def_id: Option + def_id: Option, ) -> Self { ty::ParamEnv { caller_bounds, reveal, def_id } } @@ -1722,27 +1699,13 @@ impl<'tcx> ParamEnv<'tcx> { /// although the surrounding function is never reachable. pub fn and>(self, value: T) -> ParamEnvAnd<'tcx, T> { match self.reveal { - Reveal::UserFacing => { - ParamEnvAnd { - param_env: self, - value, - } - } + Reveal::UserFacing => ParamEnvAnd { param_env: self, value }, Reveal::All => { - if value.has_placeholders() - || value.needs_infer() - || value.has_param_types() - { - ParamEnvAnd { - param_env: self, - value, - } + if value.has_placeholders() || value.needs_infer() || value.has_param_types() { + ParamEnvAnd { param_env: self, value } } else { - ParamEnvAnd { - param_env: self.without_caller_bounds(), - value, - } + ParamEnvAnd { param_env: self.without_caller_bounds(), value } } } } @@ -1766,10 +1729,7 @@ where T: HashStable>, { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let ParamEnvAnd { - ref param_env, - ref value - } = *self; + let ParamEnvAnd { ref param_env, ref value } = *self; param_env.hash_stable(hcx, hasher); value.hash_stable(hcx, hasher); @@ -1876,7 +1836,7 @@ impl<'tcx> VariantDef { debug!( "VariantDef::new(ident = {:?}, variant_did = {:?}, ctor_def_id = {:?}, discr = {:?}, fields = {:?}, ctor_kind = {:?}, adt_kind = {:?}, parent_did = {:?})", - ident, variant_did, ctor_def_id, discr, fields, ctor_kind, adt_kind, parent_did, + ident, variant_did, ctor_def_id, discr, fields, ctor_kind, adt_kind, parent_did, ); let mut flags = VariantFlags::NO_VARIANT_FLAGS; @@ -1967,7 +1927,9 @@ impl Ord for AdtDef { impl PartialEq for AdtDef { // `AdtDef`s are always interned, and this is part of `TyS` equality. #[inline] - fn eq(&self, other: &Self) -> bool { ptr::eq(self, other) } + fn eq(&self, other: &Self) -> bool { + ptr::eq(self, other) + } } impl Eq for AdtDef {} @@ -1996,12 +1958,7 @@ impl<'a> HashStable> for AdtDef { let hash: Fingerprint = CACHE.with(|cache| { let addr = self as *const AdtDef as usize; *cache.borrow_mut().entry(addr).or_insert_with(|| { - let ty::AdtDef { - did, - ref variants, - ref flags, - ref repr, - } = *self; + let ty::AdtDef { did, ref variants, ref flags, ref repr } = *self; let mut hasher = StableHasher::new(); did.hash_stable(hcx, &mut hasher); @@ -2010,7 +1967,7 @@ impl<'a> HashStable> for AdtDef { repr.hash_stable(hcx, &mut hasher); hasher.finish() - }) + }) }); hash.hash_stable(hcx, hasher); @@ -2018,7 +1975,11 @@ impl<'a> HashStable> for AdtDef { } #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub enum AdtKind { Struct, Union, Enum } +pub enum AdtKind { + Struct, + Union, + Enum, +} impl Into for AdtKind { fn into(self) -> DataTypeKind { @@ -2047,8 +2008,7 @@ bitflags! { } /// Represents the repr options provided by the user, -#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, - Default, HashStable)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Default, HashStable)] pub struct ReprOptions { pub int: Option, pub align: Option, @@ -2074,17 +2034,17 @@ impl ReprOptions { pack }); ReprFlags::empty() - }, + } attr::ReprTransparent => ReprFlags::IS_TRANSPARENT, attr::ReprSimd => ReprFlags::IS_SIMD, attr::ReprInt(i) => { size = Some(i); ReprFlags::empty() - }, + } attr::ReprAlign(align) => { max_align = max_align.max(Some(Align::from_bytes(align as u64).unwrap())); ReprFlags::empty() - }, + } }); } } @@ -2097,15 +2057,25 @@ impl ReprOptions { } #[inline] - pub fn simd(&self) -> bool { self.flags.contains(ReprFlags::IS_SIMD) } + pub fn simd(&self) -> bool { + self.flags.contains(ReprFlags::IS_SIMD) + } #[inline] - pub fn c(&self) -> bool { self.flags.contains(ReprFlags::IS_C) } + pub fn c(&self) -> bool { + self.flags.contains(ReprFlags::IS_C) + } #[inline] - pub fn packed(&self) -> bool { self.pack.is_some() } + pub fn packed(&self) -> bool { + self.pack.is_some() + } #[inline] - pub fn transparent(&self) -> bool { self.flags.contains(ReprFlags::IS_TRANSPARENT) } + pub fn transparent(&self) -> bool { + self.flags.contains(ReprFlags::IS_TRANSPARENT) + } #[inline] - pub fn linear(&self) -> bool { self.flags.contains(ReprFlags::IS_LINEAR) } + pub fn linear(&self) -> bool { + self.flags.contains(ReprFlags::IS_LINEAR) + } pub fn discr_type(&self) -> attr::IntType { self.int.unwrap_or(attr::SignedInt(ast::IntTy::Isize)) @@ -2179,12 +2149,7 @@ impl<'tcx> AdtDef { flags |= AdtFlags::IS_RC; } - AdtDef { - did, - variants, - flags, - repr, - } + AdtDef { did, variants, flags, repr } } /// Returns `true` if this is a struct. @@ -2296,47 +2261,56 @@ impl<'tcx> AdtDef { /// Returns an iterator over all fields contained /// by this ADT. #[inline] - pub fn all_fields(&self) -> impl Iterator + Clone { + pub fn all_fields(&self) -> impl Iterator + Clone { self.variants.iter().flat_map(|v| v.fields.iter()) } pub fn is_payloadfree(&self) -> bool { - !self.variants.is_empty() && - self.variants.iter().all(|v| v.fields.is_empty()) + !self.variants.is_empty() && self.variants.iter().all(|v| v.fields.is_empty()) } /// Return a `VariantDef` given a variant id. pub fn variant_with_id(&self, vid: DefId) -> &VariantDef { - self.variants.iter().find(|v| v.def_id == vid) - .expect("variant_with_id: unknown variant") + self.variants.iter().find(|v| v.def_id == vid).expect("variant_with_id: unknown variant") } /// Return a `VariantDef` given a constructor id. pub fn variant_with_ctor_id(&self, cid: DefId) -> &VariantDef { - self.variants.iter().find(|v| v.ctor_def_id == Some(cid)) + self.variants + .iter() + .find(|v| v.ctor_def_id == Some(cid)) .expect("variant_with_ctor_id: unknown variant") } /// Return the index of `VariantDef` given a variant id. pub fn variant_index_with_id(&self, vid: DefId) -> VariantIdx { - self.variants.iter_enumerated().find(|(_, v)| v.def_id == vid) - .expect("variant_index_with_id: unknown variant").0 + self.variants + .iter_enumerated() + .find(|(_, v)| v.def_id == vid) + .expect("variant_index_with_id: unknown variant") + .0 } /// Return the index of `VariantDef` given a constructor id. pub fn variant_index_with_ctor_id(&self, cid: DefId) -> VariantIdx { - self.variants.iter_enumerated().find(|(_, v)| v.ctor_def_id == Some(cid)) - .expect("variant_index_with_ctor_id: unknown variant").0 + self.variants + .iter_enumerated() + .find(|(_, v)| v.ctor_def_id == Some(cid)) + .expect("variant_index_with_ctor_id: unknown variant") + .0 } pub fn variant_of_res(&self, res: Res) -> &VariantDef { match res { Res::Def(DefKind::Variant, vid) => self.variant_with_id(vid), Res::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid), - Res::Def(DefKind::Struct, _) | Res::Def(DefKind::Union, _) | - Res::Def(DefKind::TyAlias, _) | Res::Def(DefKind::AssocTy, _) | Res::SelfTy(..) | - Res::SelfCtor(..) => self.non_enum_variant(), - _ => bug!("unexpected res {:?} in variant_of_res", res) + Res::Def(DefKind::Struct, _) + | Res::Def(DefKind::Union, _) + | Res::Def(DefKind::TyAlias, _) + | Res::Def(DefKind::AssocTy, _) + | Res::SelfTy(..) + | Res::SelfCtor(..) => self.non_enum_variant(), + _ => bug!("unexpected res {:?} in variant_of_res", res), } } @@ -2349,31 +2323,30 @@ impl<'tcx> AdtDef { // FIXME: Find the right type and use it instead of `val.ty` here if let Some(b) = val.try_eval_bits(tcx, param_env, val.ty) { trace!("discriminants: {} ({:?})", b, repr_type); - Some(Discr { - val: b, - ty: val.ty, - }) + Some(Discr { val: b, ty: val.ty }) } else { info!("invalid enum discriminant: {:#?}", val); crate::mir::interpret::struct_error( tcx.at(tcx.def_span(expr_did)), "constant evaluation of enum discriminant resulted in non-integer", - ).emit(); + ) + .emit(); None } } Err(ErrorHandled::Reported) => { if !expr_did.is_local() { - span_bug!(tcx.def_span(expr_did), + span_bug!( + tcx.def_span(expr_did), "variant discriminant evaluation succeeded \ - in its crate but failed locally"); + in its crate but failed locally" + ); } None } - Err(ErrorHandled::TooGeneric) => span_bug!( - tcx.def_span(expr_did), - "enum discriminant depends on generic arguments", - ), + Err(ErrorHandled::TooGeneric) => { + span_bug!(tcx.def_span(expr_did), "enum discriminant depends on generic arguments",) + } } } @@ -2424,10 +2397,7 @@ impl<'tcx> AdtDef { /// Yields a `DefId` for the discriminant and an offset to add to it /// Alternatively, if there is no explicit discriminant, returns the /// inferred discriminant directly. - pub fn discriminant_def_for_variant( - &self, - variant_index: VariantIdx, - ) -> (Option, u32) { + pub fn discriminant_def_for_variant(&self, variant_index: VariantIdx) -> (Option, u32) { let mut explicit_index = variant_index.as_u32(); let expr_did; loop { @@ -2435,7 +2405,7 @@ impl<'tcx> AdtDef { ty::VariantDiscr::Relative(0) => { expr_did = None; break; - }, + } ty::VariantDiscr::Relative(distance) => { explicit_index -= distance; } @@ -2468,38 +2438,28 @@ impl<'tcx> AdtDef { fn sized_constraint_for_ty(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Vec> { let result = match ty.kind { - Bool | Char | Int(..) | Uint(..) | Float(..) | - RawPtr(..) | Ref(..) | FnDef(..) | FnPtr(_) | - Array(..) | Closure(..) | Generator(..) | Never => { - vec![] - } + Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..) + | FnPtr(_) | Array(..) | Closure(..) | Generator(..) | Never => vec![], - Str | - Dynamic(..) | - Slice(_) | - Foreign(..) | - Error | - GeneratorWitness(..) => { + Str | Dynamic(..) | Slice(_) | Foreign(..) | Error | GeneratorWitness(..) => { // these are never sized - return the target type vec![ty] } - Tuple(ref tys) => { - match tys.last() { - None => vec![], - Some(ty) => self.sized_constraint_for_ty(tcx, ty.expect_ty()), - } - } + Tuple(ref tys) => match tys.last() { + None => vec![], + Some(ty) => self.sized_constraint_for_ty(tcx, ty.expect_ty()), + }, Adt(adt, substs) => { // recursive case let adt_tys = adt.sized_constraint(tcx); - debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", - ty, adt_tys); - adt_tys.iter() - .map(|ty| ty.subst(tcx, substs)) - .flat_map(|ty| self.sized_constraint_for_ty(tcx, ty)) - .collect() + debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys); + adt_tys + .iter() + .map(|ty| ty.subst(tcx, substs)) + .flat_map(|ty| self.sized_constraint_for_ty(tcx, ty)) + .collect() } Projection(..) | Opaque(..) => { @@ -2517,12 +2477,13 @@ impl<'tcx> AdtDef { let sized_trait = match tcx.lang_items().sized_trait() { Some(x) => x, - _ => return vec![ty] + _ => return vec![ty], }; let sized_predicate = Binder::dummy(TraitRef { def_id: sized_trait, - substs: tcx.mk_substs_trait(ty, &[]) - }).to_predicate(); + substs: tcx.mk_substs_trait(ty, &[]), + }) + .to_predicate(); let predicates = tcx.predicates_of(self.did).predicates; if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] @@ -2531,11 +2492,8 @@ impl<'tcx> AdtDef { } } - Placeholder(..) | - Bound(..) | - Infer(..) => { - bug!("unexpected type `{:?}` in sized_constraint_for_ty", - ty) + Placeholder(..) | Bound(..) | Infer(..) => { + bug!("unexpected type `{:?}` in sized_constraint_for_ty", ty) } }; debug!("sized_constraint_for_ty({:?}) = {:?}", ty, result); @@ -2557,8 +2515,19 @@ impl<'tcx> FieldDef { /// /// You can get the environment type of a closure using /// `tcx.closure_env_ty()`. -#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, - RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Clone, + Copy, + PartialOrd, + Ord, + PartialEq, + Eq, + Hash, + Debug, + RustcEncodable, + RustcDecodable, + HashStable +)] pub enum ClosureKind { // Warning: Ordering is significant here! The ordering is chosen // because the trait Fn is a subtrait of FnMut and so in turn, and @@ -2575,12 +2544,8 @@ impl<'tcx> ClosureKind { pub fn trait_did(&self, tcx: TyCtxt<'tcx>) -> DefId { match *self { ClosureKind::Fn => tcx.require_lang_item(FnTraitLangItem, None), - ClosureKind::FnMut => { - tcx.require_lang_item(FnMutTraitLangItem, None) - } - ClosureKind::FnOnce => { - tcx.require_lang_item(FnOnceTraitLangItem, None) - } + ClosureKind::FnMut => tcx.require_lang_item(FnMutTraitLangItem, None), + ClosureKind::FnOnce => tcx.require_lang_item(FnOnceTraitLangItem, None), } } @@ -2637,7 +2602,8 @@ impl<'tcx> TyS<'tcx> { /// /// Note: prefer `ty.walk()` where possible. pub fn maybe_walk(&'tcx self, mut f: F) - where F: FnMut(Ty<'tcx>) -> bool + where + F: FnMut(Ty<'tcx>) -> bool, { let mut walker = self.walk(); while let Some(ty) = walker.next() { @@ -2693,7 +2659,7 @@ impl<'tcx> ::std::ops::Deref for Attributes<'tcx> { fn deref(&self) -> &[ast::Attribute] { match self { &Attributes::Owned(ref data) => &data, - &Attributes::Borrowed(data) => data + &Attributes::Borrowed(data) => data, } } } @@ -2734,7 +2700,7 @@ pub enum ImplOverlapKind { /// 4. Neither of the impls can have any where-clauses. /// /// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed. - Issue33140 + Issue33140, } impl<'tcx> TyCtxt<'tcx> { @@ -2746,16 +2712,16 @@ impl<'tcx> TyCtxt<'tcx> { /// crate. If you would prefer to iterate over the bodies /// themselves, you can do `self.hir().krate().body_ids.iter()`. pub fn body_owners(self) -> impl Iterator + Captures<'tcx> + 'tcx { - self.hir().krate() - .body_ids - .iter() - .map(move |&body_id| self.hir().body_owner_def_id(body_id)) + self.hir() + .krate() + .body_ids + .iter() + .map(move |&body_id| self.hir().body_owner_def_id(body_id)) } pub fn par_body_owners(self, f: F) { - par_iter(&self.hir().krate().body_ids).for_each(|&body_id| { - f(self.hir().body_owner_def_id(body_id)) - }); + par_iter(&self.hir().krate().body_ids) + .for_each(|&body_id| f(self.hir().body_owner_def_id(body_id))); } pub fn provided_trait_methods(self, id: DefId) -> Vec { @@ -2765,9 +2731,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn trait_relevant_for_never(self, did: DefId) -> bool { - self.associated_items(did).any(|item| { - item.relevant_for_never() - }) + self.associated_items(did).any(|item| item.relevant_for_never()) } pub fn opt_item_name(self, def_id: DefId) -> Option { @@ -2782,9 +2746,7 @@ impl<'tcx> TyCtxt<'tcx> { } } else { match self.def_kind(def_id).expect("no def for `DefId`") { - DefKind::AssocConst - | DefKind::Method - | DefKind::AssocTy => true, + DefKind::AssocConst | DefKind::Method | DefKind::AssocTy => true, _ => false, } }; @@ -2792,17 +2754,16 @@ impl<'tcx> TyCtxt<'tcx> { is_associated_item.then(|| self.associated_item(def_id)) } - fn associated_item_from_trait_item_ref(self, - parent_def_id: DefId, - parent_vis: &hir::Visibility, - trait_item_ref: &hir::TraitItemRef) - -> AssocItem { + fn associated_item_from_trait_item_ref( + self, + parent_def_id: DefId, + parent_vis: &hir::Visibility, + trait_item_ref: &hir::TraitItemRef, + ) -> AssocItem { let def_id = self.hir().local_def_id(trait_item_ref.id.hir_id); let (kind, has_self) = match trait_item_ref.kind { hir::AssocItemKind::Const => (ty::AssocKind::Const, false), - hir::AssocItemKind::Method { has_self } => { - (ty::AssocKind::Method, has_self) - } + hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self), hir::AssocItemKind::Type => (ty::AssocKind::Type, false), hir::AssocItemKind::OpaqueTy => bug!("only impls can have opaque types"), }; @@ -2815,20 +2776,19 @@ impl<'tcx> TyCtxt<'tcx> { defaultness: trait_item_ref.defaultness, def_id, container: TraitContainer(parent_def_id), - method_has_self_argument: has_self + method_has_self_argument: has_self, } } - fn associated_item_from_impl_item_ref(self, - parent_def_id: DefId, - impl_item_ref: &hir::ImplItemRef) - -> AssocItem { + fn associated_item_from_impl_item_ref( + self, + parent_def_id: DefId, + impl_item_ref: &hir::ImplItemRef, + ) -> AssocItem { let def_id = self.hir().local_def_id(impl_item_ref.id.hir_id); let (kind, has_self) = match impl_item_ref.kind { hir::AssocItemKind::Const => (ty::AssocKind::Const, false), - hir::AssocItemKind::Method { has_self } => { - (ty::AssocKind::Method, has_self) - } + hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self), hir::AssocItemKind::Type => (ty::AssocKind::Type, false), hir::AssocItemKind::OpaqueTy => (ty::AssocKind::OpaqueTy, false), }; @@ -2841,7 +2801,7 @@ impl<'tcx> TyCtxt<'tcx> { defaultness: impl_item_ref.defaultness, def_id, container: ImplContainer(parent_def_id), - method_has_self_argument: has_self + method_has_self_argument: has_self, } } @@ -2850,9 +2810,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option { - variant.fields.iter().position(|field| { - self.hygienic_eq(ident, field.ident, variant.def_id) - }) + variant.fields.iter().position(|field| self.hygienic_eq(ident, field.ident, variant.def_id)) } pub fn associated_items(self, def_id: DefId) -> AssocItemsIterator<'tcx> { @@ -2870,44 +2828,48 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns `true` if the impls are the same polarity and the trait either /// has no items or is annotated #[marker] and prevents item overrides. - pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId) - -> Option - { + pub fn impls_are_allowed_to_overlap( + self, + def_id1: DefId, + def_id2: DefId, + ) -> Option { // If either trait impl references an error, they're allowed to overlap, // as one of them essentially doesn't exist. - if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.references_error()) || - self.impl_trait_ref(def_id2).map_or(false, |tr| tr.references_error()) { + if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.references_error()) + || self.impl_trait_ref(def_id2).map_or(false, |tr| tr.references_error()) + { return Some(ImplOverlapKind::Permitted); } match (self.impl_polarity(def_id1), self.impl_polarity(def_id2)) { - (ImplPolarity::Reservation, _) | - (_, ImplPolarity::Reservation) => { + (ImplPolarity::Reservation, _) | (_, ImplPolarity::Reservation) => { // `#[rustc_reservation_impl]` impls don't overlap with anything - debug!("impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)", - def_id1, def_id2); + debug!( + "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)", + def_id1, def_id2 + ); return Some(ImplOverlapKind::Permitted); } - (ImplPolarity::Positive, ImplPolarity::Negative) | - (ImplPolarity::Negative, ImplPolarity::Positive) => { + (ImplPolarity::Positive, ImplPolarity::Negative) + | (ImplPolarity::Negative, ImplPolarity::Positive) => { // `impl AutoTrait for Type` + `impl !AutoTrait for Type` - debug!("impls_are_allowed_to_overlap({:?}, {:?}) - None (differing polarities)", - def_id1, def_id2); + debug!( + "impls_are_allowed_to_overlap({:?}, {:?}) - None (differing polarities)", + def_id1, def_id2 + ); return None; } - (ImplPolarity::Positive, ImplPolarity::Positive) | - (ImplPolarity::Negative, ImplPolarity::Negative) => {} + (ImplPolarity::Positive, ImplPolarity::Positive) + | (ImplPolarity::Negative, ImplPolarity::Negative) => {} }; let is_marker_overlap = if self.features().overlapping_marker_traits { - let trait1_is_empty = self.impl_trait_ref(def_id1) - .map_or(false, |trait_ref| { - self.associated_item_def_ids(trait_ref.def_id).is_empty() - }); - let trait2_is_empty = self.impl_trait_ref(def_id2) - .map_or(false, |trait_ref| { - self.associated_item_def_ids(trait_ref.def_id).is_empty() - }); + let trait1_is_empty = self.impl_trait_ref(def_id1).map_or(false, |trait_ref| { + self.associated_item_def_ids(trait_ref.def_id).is_empty() + }); + let trait2_is_empty = self.impl_trait_ref(def_id2).map_or(false, |trait_ref| { + self.associated_item_def_ids(trait_ref.def_id).is_empty() + }); trait1_is_empty && trait2_is_empty } else { let is_marker_impl = |def_id: DefId| -> bool { @@ -2917,27 +2879,31 @@ impl<'tcx> TyCtxt<'tcx> { is_marker_impl(def_id1) && is_marker_impl(def_id2) }; - if is_marker_overlap { - debug!("impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap)", - def_id1, def_id2); + debug!( + "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap)", + def_id1, def_id2 + ); Some(ImplOverlapKind::Permitted) } else { if let Some(self_ty1) = self.issue33140_self_ty(def_id1) { if let Some(self_ty2) = self.issue33140_self_ty(def_id2) { if self_ty1 == self_ty2 { - debug!("impls_are_allowed_to_overlap({:?}, {:?}) - issue #33140 HACK", - def_id1, def_id2); + debug!( + "impls_are_allowed_to_overlap({:?}, {:?}) - issue #33140 HACK", + def_id1, def_id2 + ); return Some(ImplOverlapKind::Issue33140); } else { - debug!("impls_are_allowed_to_overlap({:?}, {:?}) - found {:?} != {:?}", - def_id1, def_id2, self_ty1, self_ty2); + debug!( + "impls_are_allowed_to_overlap({:?}, {:?}) - found {:?} != {:?}", + def_id1, def_id2, self_ty1, self_ty2 + ); } } } - debug!("impls_are_allowed_to_overlap({:?}, {:?}) = None", - def_id1, def_id2); + debug!("impls_are_allowed_to_overlap({:?}, {:?}) = None", def_id1, def_id2); None } } @@ -2962,7 +2928,7 @@ impl<'tcx> TyCtxt<'tcx> { let struct_did = self.parent(ctor_did).expect("struct ctor has no parent"); self.adt_def(struct_did).non_enum_variant() } - _ => bug!("expect_variant_res used with unexpected res {:?}", res) + _ => bug!("expect_variant_res used with unexpected res {:?}", res), } } @@ -2973,11 +2939,9 @@ impl<'tcx> TyCtxt<'tcx> { let def_key = self.def_key(id); match def_key.disambiguated_data.data { // The name of a constructor is that of its parent. - hir_map::DefPathData::Ctor => - self.item_name(DefId { - krate: id.krate, - index: def_key.parent.unwrap() - }), + hir_map::DefPathData::Ctor => { + self.item_name(DefId { krate: id.krate, index: def_key.parent.unwrap() }) + } _ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| { bug!("item_name: no name for {:?}", self.def_path(id)); }), @@ -2988,19 +2952,15 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair. pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> ReadOnlyBodyAndCache<'tcx, 'tcx> { match instance { - ty::InstanceDef::Item(did) => { - self.optimized_mir(did).unwrap_read_only() - } - ty::InstanceDef::VtableShim(..) | - ty::InstanceDef::ReifyShim(..) | - ty::InstanceDef::Intrinsic(..) | - ty::InstanceDef::FnPtrShim(..) | - ty::InstanceDef::Virtual(..) | - ty::InstanceDef::ClosureOnceShim { .. } | - ty::InstanceDef::DropGlue(..) | - ty::InstanceDef::CloneShim(..) => { - self.mir_shims(instance).unwrap_read_only() - } + ty::InstanceDef::Item(did) => self.optimized_mir(did).unwrap_read_only(), + ty::InstanceDef::VtableShim(..) + | ty::InstanceDef::ReifyShim(..) + | ty::InstanceDef::Intrinsic(..) + | ty::InstanceDef::FnPtrShim(..) + | ty::InstanceDef::Virtual(..) + | ty::InstanceDef::ClosureOnceShim { .. } + | ty::InstanceDef::DropGlue(..) + | ty::InstanceDef::CloneShim(..) => self.mir_shims(instance).unwrap_read_only(), } } @@ -3046,12 +3006,10 @@ impl<'tcx> TyCtxt<'tcx> { self.opt_associated_item(def_id) }; - item.and_then(|trait_item| - match trait_item.container { - TraitContainer(_) => None, - ImplContainer(def_id) => Some(def_id), - } - ) + item.and_then(|trait_item| match trait_item.container { + TraitContainer(_) => None, + ImplContainer(def_id) => Some(def_id), + }) } /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err` @@ -3072,9 +3030,11 @@ impl<'tcx> TyCtxt<'tcx> { // We could use `Ident::eq` here, but we deliberately don't. The name // comparison fails frequently, and we want to avoid the expensive // `modern()` calls required for the span comparison whenever possible. - use_name.name == def_name.name && - use_name.span.ctxt().hygienic_eq(def_name.span.ctxt(), - self.expansion_that_defined(def_parent_def_id)) + use_name.name == def_name.name + && use_name + .span + .ctxt() + .hygienic_eq(def_name.span.ctxt(), self.expansion_that_defined(def_parent_def_id)) } fn expansion_that_defined(self, scope: DefId) -> ExpnId { @@ -3089,11 +3049,16 @@ impl<'tcx> TyCtxt<'tcx> { ident } - pub fn adjust_ident_and_get_scope(self, mut ident: Ident, scope: DefId, block: hir::HirId) - -> (Ident, DefId) { + pub fn adjust_ident_and_get_scope( + self, + mut ident: Ident, + scope: DefId, + block: hir::HirId, + ) -> (Ident, DefId) { let scope = match ident.span.modernize_and_adjust(self.expansion_that_defined(scope)) { - Some(actual_expansion) => - self.hir().definitions().parent_module_of_macro_def(actual_expansion), + Some(actual_expansion) => { + self.hir().definitions().parent_module_of_macro_def(actual_expansion) + } None => self.hir().get_module_parent(block), }; (ident, scope) @@ -3125,8 +3090,8 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> AssocItem { match parent_item.kind { hir::ItemKind::Impl(.., ref impl_item_refs) => { if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) { - let assoc_item = tcx.associated_item_from_impl_item_ref(parent_def_id, - impl_item_ref); + let assoc_item = + tcx.associated_item_from_impl_item_ref(parent_def_id, impl_item_ref); debug_assert_eq!(assoc_item.def_id, def_id); return assoc_item; } @@ -3134,20 +3099,24 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> AssocItem { hir::ItemKind::Trait(.., ref trait_item_refs) => { if let Some(trait_item_ref) = trait_item_refs.iter().find(|i| i.id.hir_id == id) { - let assoc_item = tcx.associated_item_from_trait_item_ref(parent_def_id, - &parent_item.vis, - trait_item_ref); + let assoc_item = tcx.associated_item_from_trait_item_ref( + parent_def_id, + &parent_item.vis, + trait_item_ref, + ); debug_assert_eq!(assoc_item.def_id, def_id); return assoc_item; } } - _ => { } + _ => {} } - span_bug!(parent_item.span, - "unexpected parent of trait or impl item or item not found: {:?}", - parent_item.kind) + span_bug!( + parent_item.span, + "unexpected parent of trait or impl item or item not found: {:?}", + parent_item.kind + ) } #[derive(Clone, HashStable)] @@ -3165,11 +3134,12 @@ pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]); fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> AdtSizedConstraint<'_> { let def = tcx.adt_def(def_id); - let result = tcx.mk_type_list(def.variants.iter().flat_map(|v| { - v.fields.last() - }).flat_map(|f| { - def.sized_constraint_for_ty(tcx, tcx.type_of(f.did)) - })); + let result = tcx.mk_type_list( + def.variants + .iter() + .flat_map(|v| v.fields.last()) + .flat_map(|f| def.sized_constraint_for_ty(tcx, tcx.type_of(f.did))), + ); debug!("adt_sized_constraint: {:?} => {:?}", def, result); @@ -3180,22 +3150,20 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { let id = tcx.hir().as_local_hir_id(def_id).unwrap(); let item = tcx.hir().expect_item(id); match item.kind { - hir::ItemKind::Trait(.., ref trait_item_refs) => { - tcx.arena.alloc_from_iter( - trait_item_refs.iter() - .map(|trait_item_ref| trait_item_ref.id) - .map(|id| tcx.hir().local_def_id(id.hir_id)) - ) - } - hir::ItemKind::Impl(.., ref impl_item_refs) => { - tcx.arena.alloc_from_iter( - impl_item_refs.iter() - .map(|impl_item_ref| impl_item_ref.id) - .map(|id| tcx.hir().local_def_id(id.hir_id)) - ) - } + hir::ItemKind::Trait(.., ref trait_item_refs) => tcx.arena.alloc_from_iter( + trait_item_refs + .iter() + .map(|trait_item_ref| trait_item_ref.id) + .map(|id| tcx.hir().local_def_id(id.hir_id)), + ), + hir::ItemKind::Impl(.., ref impl_item_refs) => tcx.arena.alloc_from_iter( + impl_item_refs + .iter() + .map(|impl_item_ref| impl_item_ref.id) + .map(|id| tcx.hir().local_def_id(id.hir_id)), + ), hir::ItemKind::TraitAlias(..) => &[], - _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait") + _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"), } } @@ -3207,13 +3175,10 @@ fn def_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span { /// returns the `DefId` of the trait that the trait item belongs to; /// otherwise, returns `None`. fn trait_of_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option { - tcx.opt_associated_item(def_id) - .and_then(|associated_item| { - match associated_item.container { - TraitContainer(def_id) => Some(def_id), - ImplContainer(_) => None - } - }) + tcx.opt_associated_item(def_id).and_then(|associated_item| match associated_item.container { + TraitContainer(def_id) => Some(def_id), + ImplContainer(_) => None, + }) } /// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition. @@ -3236,8 +3201,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ParamEnv<'_> { } // Compute the bounds on Self and the type parameters. - let InstantiatedPredicates { predicates } = - tcx.predicates_of(def_id).instantiate_identity(tcx); + let InstantiatedPredicates { predicates } = tcx.predicates_of(def_id).instantiate_identity(tcx); // Finally, we have to normalize the bounds in the environment, in // case they contain any associated type projections. This process @@ -3281,13 +3245,12 @@ fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { fn instance_def_size_estimate<'tcx>(tcx: TyCtxt<'tcx>, instance_def: InstanceDef<'tcx>) -> usize { match instance_def { - InstanceDef::Item(..) | - InstanceDef::DropGlue(..) => { + InstanceDef::Item(..) | InstanceDef::DropGlue(..) => { let mir = tcx.instance_mir(instance_def); mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() - }, + } // Estimate the size of other compiler-generated shims to be 1. - _ => 1 + _ => 1, } } @@ -3297,15 +3260,14 @@ fn instance_def_size_estimate<'tcx>(tcx: TyCtxt<'tcx>, instance_def: InstanceDef fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { debug!("issue33140_self_ty({:?})", def_id); - let trait_ref = tcx.impl_trait_ref(def_id).unwrap_or_else(|| { - bug!("issue33140_self_ty called on inherent impl {:?}", def_id) - }); + let trait_ref = tcx + .impl_trait_ref(def_id) + .unwrap_or_else(|| bug!("issue33140_self_ty called on inherent impl {:?}", def_id)); debug!("issue33140_self_ty({:?}), trait-ref={:?}", def_id, trait_ref); - let is_marker_like = - tcx.impl_polarity(def_id) == ty::ImplPolarity::Positive && - tcx.associated_item_def_ids(trait_ref.def_id).is_empty(); + let is_marker_like = tcx.impl_polarity(def_id) == ty::ImplPolarity::Positive + && tcx.associated_item_def_ids(trait_ref.def_id).is_empty(); // Check whether these impls would be ok for a marker trait. if !is_marker_like { @@ -3328,7 +3290,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { let self_ty = trait_ref.self_ty(); let self_ty_matches = match self_ty.kind { ty::Dynamic(ref data, ty::ReStatic) => data.principal().is_none(), - _ => false + _ => false, }; if self_ty_matches { @@ -3342,9 +3304,10 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { /// Check if a function is async. fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { - let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap_or_else(|| { - bug!("asyncness: expected local `DefId`, got `{:?}`", def_id) - }); + let hir_id = tcx + .hir() + .as_local_hir_id(def_id) + .unwrap_or_else(|| bug!("asyncness: expected local `DefId`, got `{:?}`", def_id)); let node = tcx.hir().get(hir_id); @@ -3393,14 +3356,12 @@ pub struct CrateInherentImpls { pub struct SymbolName { // FIXME: we don't rely on interning or equality here - better have // this be a `&'tcx str`. - pub name: Symbol + pub name: Symbol, } impl SymbolName { pub fn new(name: &str) -> SymbolName { - SymbolName { - name: Symbol::intern(name) - } + SymbolName { name: Symbol::intern(name) } } } diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index 80e77cdfad0b6..383ccbd337a7d 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -2,8 +2,8 @@ // refers to rules defined in RFC 1214 (`OutlivesFooBar`), so see that // RFC for reference. -use smallvec::SmallVec; use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; +use smallvec::SmallVec; #[derive(Debug)] pub enum Component<'tcx> { @@ -48,8 +48,11 @@ pub enum Component<'tcx> { impl<'tcx> TyCtxt<'tcx> { /// Push onto `out` all the things that must outlive `'a` for the condition /// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**. - pub fn push_outlives_components(&self, ty0: Ty<'tcx>, - out: &mut SmallVec<[Component<'tcx>; 4]>) { + pub fn push_outlives_components( + &self, + ty0: Ty<'tcx>, + out: &mut SmallVec<[Component<'tcx>; 4]>, + ) { self.compute_components(ty0, out); debug!("components({:?}) = {:?}", ty0, out); } diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index d216c81f8a6c2..e58c912960817 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -1,7 +1,7 @@ -use crate::hir::map::{DefPathData, DisambiguatedDefPathData}; use crate::hir::def_id::{CrateNum, DefId}; -use crate::ty::{self, DefIdTree, Ty, TyCtxt}; +use crate::hir::map::{DefPathData, DisambiguatedDefPathData}; use crate::ty::subst::{GenericArg, Subst}; +use crate::ty::{self, DefIdTree, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashSet; @@ -58,30 +58,18 @@ pub trait Printer<'tcx>: Sized { self.default_print_impl_path(impl_def_id, substs, self_ty, trait_ref) } - fn print_region( - self, - region: ty::Region<'_>, - ) -> Result; + fn print_region(self, region: ty::Region<'_>) -> Result; - fn print_type( - self, - ty: Ty<'tcx>, - ) -> Result; + fn print_type(self, ty: Ty<'tcx>) -> Result; fn print_dyn_existential( self, predicates: &'tcx ty::List>, ) -> Result; - fn print_const( - self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result; + fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result; - fn path_crate( - self, - cnum: CrateNum, - ) -> Result; + fn path_crate(self, cnum: CrateNum) -> Result; fn path_qualified( self, @@ -152,33 +140,36 @@ pub trait Printer<'tcx>: Sized { // If we have any generic arguments to print, we do that // on top of the same path, but without its own generics. - _ => if !generics.params.is_empty() && substs.len() >= generics.count() { - let args = self.generic_args_to_print(generics, substs); - return self.path_generic_args( - |cx| cx.print_def_path(def_id, parent_substs), - args, - ); + _ => { + if !generics.params.is_empty() && substs.len() >= generics.count() { + let args = self.generic_args_to_print(generics, substs); + return self.path_generic_args( + |cx| cx.print_def_path(def_id, parent_substs), + args, + ); + } } } // FIXME(eddyb) try to move this into the parent's printing // logic, instead of doing it when printing the child. - trait_qualify_parent = - generics.has_self && - generics.parent == Some(parent_def_id) && - parent_substs.len() == generics.parent_count && - self.tcx().generics_of(parent_def_id).parent_count == 0; + trait_qualify_parent = generics.has_self + && generics.parent == Some(parent_def_id) + && parent_substs.len() == generics.parent_count + && self.tcx().generics_of(parent_def_id).parent_count == 0; } self.path_append( - |cx: Self| if trait_qualify_parent { - let trait_ref = ty::TraitRef::new( - parent_def_id, - cx.tcx().intern_substs(parent_substs), - ); - cx.path_qualified(trait_ref.self_ty(), Some(trait_ref)) - } else { - cx.print_def_path(parent_def_id, parent_substs) + |cx: Self| { + if trait_qualify_parent { + let trait_ref = ty::TraitRef::new( + parent_def_id, + cx.tcx().intern_substs(parent_substs), + ); + cx.path_qualified(trait_ref.self_ty(), Some(trait_ref)) + } else { + cx.print_def_path(parent_def_id, parent_substs) + } }, &key.disambiguated_data, ) @@ -199,17 +190,24 @@ pub trait Printer<'tcx>: Sized { } // Don't print args that are the defaults of their respective parameters. - own_params.end -= generics.params.iter().rev().take_while(|param| { - match param.kind { - ty::GenericParamDefKind::Lifetime => false, - ty::GenericParamDefKind::Type { has_default, .. } => { - has_default && substs[param.index as usize] == GenericArg::from( - self.tcx().type_of(param.def_id).subst(self.tcx(), substs) - ) + own_params.end -= generics + .params + .iter() + .rev() + .take_while(|param| { + match param.kind { + ty::GenericParamDefKind::Lifetime => false, + ty::GenericParamDefKind::Type { has_default, .. } => { + has_default + && substs[param.index as usize] + == GenericArg::from( + self.tcx().type_of(param.def_id).subst(self.tcx(), substs), + ) + } + ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) } - ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) - } - }).count(); + }) + .count(); &substs[own_params] } @@ -221,8 +219,10 @@ pub trait Printer<'tcx>: Sized { self_ty: Ty<'tcx>, impl_trait_ref: Option>, ) -> Result { - debug!("default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}", - impl_def_id, self_ty, impl_trait_ref); + debug!( + "default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}", + impl_def_id, self_ty, impl_trait_ref + ); let key = self.tcx().def_key(impl_def_id); let parent_def_id = DefId { index: key.parent.unwrap(), ..impl_def_id }; @@ -271,39 +271,38 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { ty::Dynamic(data, ..) => data.principal_def_id(), - ty::Array(subty, _) | - ty::Slice(subty) => characteristic_def_id_of_type(subty), + ty::Array(subty, _) | ty::Slice(subty) => characteristic_def_id_of_type(subty), ty::RawPtr(mt) => characteristic_def_id_of_type(mt.ty), ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty), - ty::Tuple(ref tys) => tys.iter() - .filter_map(|ty| characteristic_def_id_of_type(ty.expect_ty())) - .next(), - - ty::FnDef(def_id, _) | - ty::Closure(def_id, _) | - ty::Generator(def_id, _, _) | - ty::Foreign(def_id) => Some(def_id), - - ty::Bool | - ty::Char | - ty::Int(_) | - ty::Uint(_) | - ty::Str | - ty::FnPtr(_) | - ty::Projection(_) | - ty::Placeholder(..) | - ty::UnnormalizedProjection(..) | - ty::Param(_) | - ty::Opaque(..) | - ty::Infer(_) | - ty::Bound(..) | - ty::Error | - ty::GeneratorWitness(..) | - ty::Never | - ty::Float(_) => None, + ty::Tuple(ref tys) => { + tys.iter().filter_map(|ty| characteristic_def_id_of_type(ty.expect_ty())).next() + } + + ty::FnDef(def_id, _) + | ty::Closure(def_id, _) + | ty::Generator(def_id, _, _) + | ty::Foreign(def_id) => Some(def_id), + + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Str + | ty::FnPtr(_) + | ty::Projection(_) + | ty::Placeholder(..) + | ty::UnnormalizedProjection(..) + | ty::Param(_) + | ty::Opaque(..) + | ty::Infer(_) + | ty::Bound(..) + | ty::Error + | ty::GeneratorWitness(..) + | ty::Never + | ty::Float(_) => None, } } diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc/ty/print/obsolete.rs index 5e146119b51ac..7c3579d59205e 100644 --- a/src/librustc/ty/print/obsolete.rs +++ b/src/librustc/ty/print/obsolete.rs @@ -137,8 +137,7 @@ impl DefPathBasedNames<'tcx> { self.push_type_name(sig.output(), output, debug); } } - ty::Generator(def_id, substs, _) - | ty::Closure(def_id, substs) => { + 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); @@ -175,10 +174,7 @@ impl DefPathBasedNames<'tcx> { } else if debug { write!(output, "{:?}", c).unwrap() } else { - bug!( - "DefPathBasedNames: trying to create const name for unexpected const: {:?}", - c, - ); + bug!("DefPathBasedNames: trying to create const name for unexpected const: {:?}", c,); } output.push_str(": "); self.push_type_name(c.ty, output, debug); @@ -198,8 +194,7 @@ impl DefPathBasedNames<'tcx> { if self.omit_disambiguators { write!(output, "{}::", part.data.as_symbol()).unwrap(); } else { - write!(output, "{}[{}]::", part.data.as_symbol(), part.disambiguator) - .unwrap(); + write!(output, "{}[{}]::", part.data.as_symbol(), part.disambiguator).unwrap(); } } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index b4f1f9d779a69..9bd7701da1feb 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -1,13 +1,13 @@ use crate::hir; -use crate::hir::def::{Namespace, DefKind}; -use crate::hir::map::{DefPathData, DisambiguatedDefPathData}; +use crate::hir::def::{DefKind, Namespace}; use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use crate::hir::map::{DefPathData, DisambiguatedDefPathData}; use crate::middle::cstore::{ExternCrate, ExternCrateSource}; use crate::middle::region; -use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable}; -use crate::ty::subst::{GenericArg, Subst, GenericArgKind}; +use crate::mir::interpret::{sign_extend, truncate, ConstValue, Scalar}; use crate::ty::layout::{Integer, IntegerExt, Size}; -use crate::mir::interpret::{ConstValue, sign_extend, Scalar, truncate}; +use crate::ty::subst::{GenericArg, GenericArgKind, Subst}; +use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable}; use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; @@ -42,7 +42,9 @@ macro_rules! define_scoped_cx { ($cx:ident) => { #[allow(unused_macros)] macro_rules! scoped_cx { - () => ($cx) + () => { + $cx + }; } }; } @@ -134,37 +136,23 @@ impl RegionHighlightMode { } /// Highlights the region inference variable `vid` as `'N`. - pub fn highlighting_region( - &mut self, - region: ty::Region<'_>, - number: usize, - ) { + pub fn highlighting_region(&mut self, region: ty::Region<'_>, number: usize) { let num_slots = self.highlight_regions.len(); - let first_avail_slot = self.highlight_regions.iter_mut() - .filter(|s| s.is_none()) - .next() - .unwrap_or_else(|| { - bug!( - "can only highlight {} placeholders at a time", - num_slots, - ) + let first_avail_slot = + self.highlight_regions.iter_mut().filter(|s| s.is_none()).next().unwrap_or_else(|| { + bug!("can only highlight {} placeholders at a time", num_slots,) }); *first_avail_slot = Some((*region, number)); } /// Convenience wrapper for `highlighting_region`. - pub fn highlighting_region_vid( - &mut self, - vid: ty::RegionVid, - number: usize, - ) { + pub fn highlighting_region_vid(&mut self, vid: ty::RegionVid, number: usize) { self.highlighting_region(&ty::ReVar(vid), number) } /// Returns `Some(n)` with the number to use for the given region, if any. fn region_highlighted(&self, region: ty::Region<'_>) -> Option { - self - .highlight_regions + self.highlight_regions .iter() .filter_map(|h| match h { Some((r, n)) if r == region => Some(*n), @@ -176,11 +164,7 @@ impl RegionHighlightMode { /// Highlight the given bound region. /// We can only highlight one bound region at a time. See /// the field `highlight_bound_region` for more detailed notes. - pub fn highlighting_bound_region( - &mut self, - br: ty::BoundRegion, - number: usize, - ) { + pub fn highlighting_bound_region(&mut self, br: ty::BoundRegion, number: usize) { assert!(self.highlight_bound_region.is_none()); self.highlight_bound_region = Some((br, number)); } @@ -238,20 +222,14 @@ pub trait PrettyPrinter<'tcx>: /// Returns `true` if the region should be printed in /// optional positions, e.g., `&'a T` or `dyn Tr + 'b`. /// This is typically the case for all non-`'_` regions. - fn region_should_not_be_omitted( - &self, - region: ty::Region<'_>, - ) -> bool; + fn region_should_not_be_omitted(&self, region: ty::Region<'_>) -> bool; // Defaults (should not be overriden): /// If possible, this returns a global path resolving to `def_id` that is visible /// from at least one local module, and returns `true`. If the crate defining `def_id` is /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. - fn try_print_visible_def_path( - self, - def_id: DefId, - ) -> Result<(Self, bool), Self::Error> { + fn try_print_visible_def_path(self, def_id: DefId) -> Result<(Self, bool), Self::Error> { let mut callers = Vec::new(); self.try_print_visible_def_path_recur(def_id, &mut callers) } @@ -302,16 +280,19 @@ pub trait PrettyPrinter<'tcx>: .. }) => { debug!("try_print_visible_def_path: def_id={:?}", def_id); - return Ok((if !span.is_dummy() { - self.print_def_path(def_id, &[])? - } else { - self.path_crate(cnum)? - }, true)); + return Ok(( + if !span.is_dummy() { + self.print_def_path(def_id, &[])? + } else { + self.path_crate(cnum)? + }, + true, + )); } None => { return Ok((self.path_crate(cnum)?, true)); } - _ => {}, + _ => {} } } @@ -329,13 +310,14 @@ pub trait PrettyPrinter<'tcx>: DefPathData::Ctor => { let parent = DefId { krate: def_id.krate, - index: cur_def_key.parent + index: cur_def_key + .parent .expect("`DefPathData::Ctor` / `VariantData` missing a parent"), }; cur_def_key = self.tcx().def_key(parent); - }, - _ => {}, + } + _ => {} } let visible_parent = match visible_parent_map.get(&def_id).cloned() { @@ -400,7 +382,9 @@ pub trait PrettyPrinter<'tcx>: // `visible_parent_map`), looking for the specific child we currently have and then // have access to the re-exported name. DefPathData::TypeNs(ref mut name) if Some(visible_parent) != actual_parent => { - let reexport = self.tcx().item_children(visible_parent) + let reexport = self + .tcx() + .item_children(visible_parent) .iter() .find(|child| child.res.def_id() == def_id) .map(|child| child.ident.name); @@ -410,18 +394,13 @@ pub trait PrettyPrinter<'tcx>: } // Re-exported `extern crate` (#43189). DefPathData::CrateRoot => { - data = DefPathData::TypeNs( - self.tcx().original_crate_name(def_id.krate), - ); + data = DefPathData::TypeNs(self.tcx().original_crate_name(def_id.krate)); } _ => {} } debug!("try_print_visible_def_path: data={:?}", data); - Ok((self.path_append(Ok, &DisambiguatedDefPathData { - data, - disambiguator: 0, - })?, true)) + Ok((self.path_append(Ok, &DisambiguatedDefPathData { data, disambiguator: 0 })?, true)) } fn pretty_path_qualified( @@ -434,9 +413,14 @@ pub trait PrettyPrinter<'tcx>: // impl on `Foo`, but fallback to `::bar` if self-type is // anything other than a simple path. match self_ty.kind { - ty::Adt(..) | ty::Foreign(_) | - ty::Bool | ty::Char | ty::Str | - ty::Int(_) | ty::Uint(_) | ty::Float(_) => { + ty::Adt(..) + | ty::Foreign(_) + | ty::Bool + | ty::Char + | ty::Str + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) => { return self_ty.print(self); } @@ -476,10 +460,7 @@ pub trait PrettyPrinter<'tcx>: }) } - fn pretty_print_type( - mut self, - ty: Ty<'tcx>, - ) -> Result { + fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result { define_scoped_cx!(self); match ty.kind { @@ -489,10 +470,13 @@ pub trait PrettyPrinter<'tcx>: ty::Uint(t) => p!(write("{}", t.name_str())), ty::Float(t) => p!(write("{}", t.name_str())), ty::RawPtr(ref tm) => { - p!(write("*{} ", match tm.mutbl { - hir::Mutability::Mut => "mut", - hir::Mutability::Not => "const", - })); + p!(write( + "*{} ", + match tm.mutbl { + hir::Mutability::Mut => "mut", + hir::Mutability::Not => "const", + } + )); p!(print(tm.ty)) } ty::Ref(r, ty, mutbl) => { @@ -521,9 +505,7 @@ pub trait PrettyPrinter<'tcx>: let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs); p!(print(sig), write(" {{"), print_value_path(def_id, substs), write("}}")); } - ty::FnPtr(ref bare_fn) => { - p!(print(bare_fn)) - } + ty::FnPtr(ref bare_fn) => p!(print(bare_fn)), ty::Infer(infer_ty) => { if let ty::TyVar(ty_vid) = infer_ty { if let Some(name) = self.infer_ty_name(ty_vid) { @@ -534,22 +516,20 @@ pub trait PrettyPrinter<'tcx>: } else { p!(write("{}", infer_ty)) } - }, + } ty::Error => p!(write("[type error]")), ty::Param(ref param_ty) => p!(write("{}", param_ty)), - ty::Bound(debruijn, bound_ty) => { - match bound_ty.kind { - ty::BoundTyKind::Anon => { - if debruijn == ty::INNERMOST { - p!(write("^{}", bound_ty.var.index())) - } else { - p!(write("^{}_{}", debruijn.index(), bound_ty.var.index())) - } + ty::Bound(debruijn, bound_ty) => match bound_ty.kind { + ty::BoundTyKind::Anon => { + if debruijn == ty::INNERMOST { + p!(write("^{}", bound_ty.var.index())) + } else { + p!(write("^{}_{}", debruijn.index(), bound_ty.var.index())) } - - ty::BoundTyKind::Param(p) => p!(write("{}", p)), } - } + + ty::BoundTyKind::Param(p) => p!(write("{}", p)), + }, ty::Adt(def, substs) => { p!(print_def_path(def.did, substs)); } @@ -570,9 +550,7 @@ pub trait PrettyPrinter<'tcx>: ty::UnnormalizedProjection(ref data) => { p!(write("Unnormalized("), print(data), write(")")) } - ty::Placeholder(placeholder) => { - p!(write("Placeholder({:?})", placeholder)) - } + ty::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)), ty::Opaque(def_id, substs) => { // FIXME(eddyb) print this with `print_def_path`. // We use verbose printing in 'NO_QUERIES' mode, to @@ -580,13 +558,12 @@ pub trait PrettyPrinter<'tcx>: // only affect certain debug messages (e.g. messages printed // from `rustc::ty` during the computation of `tcx.predicates_of`), // and should have no effect on any compiler output. - if self.tcx().sess.verbose() || NO_QUERIES.with(|q| q.get()) { + if self.tcx().sess.verbose() || NO_QUERIES.with(|q| q.get()) { p!(write("Opaque({:?}, {:?})", def_id, substs)); return Ok(self); } return Ok(with_no_queries(|| { - let def_key = self.tcx().def_key(def_id); if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { p!(write("{}", name)); @@ -618,8 +595,9 @@ pub trait PrettyPrinter<'tcx>: } p!( - write("{}", if first { " " } else { "+" }), - print(trait_ref.print_only_trait_path())); + write("{}", if first { " " } else { "+" }), + print(trait_ref.print_only_trait_path()) + ); first = false; } } @@ -637,24 +615,17 @@ pub trait PrettyPrinter<'tcx>: let witness = substs.as_generator().witness(did, self.tcx()); match movability { hir::Movability::Movable => p!(write("[generator")), - hir::Movability::Static => p!(write("[static generator")), + hir::Movability::Static => p!(write("[static generator")), } // FIXME(eddyb) should use `def_span`. if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) { p!(write("@{:?}", self.tcx().hir().span(hir_id))); let mut sep = " "; - for (&var_id, upvar_ty) in self.tcx().upvars(did) - .as_ref() - .iter() - .flat_map(|v| v.keys()) - .zip(upvar_tys) + for (&var_id, upvar_ty) in + self.tcx().upvars(did).as_ref().iter().flat_map(|v| v.keys()).zip(upvar_tys) { - p!( - write("{}{}:", - sep, - self.tcx().hir().name(var_id)), - print(upvar_ty)); + p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty)); sep = ", "; } } else { @@ -663,15 +634,13 @@ pub trait PrettyPrinter<'tcx>: p!(write("@{:?}", did)); let mut sep = " "; for (index, upvar_ty) in upvar_tys.enumerate() { - p!( - write("{}{}:", sep, index), - print(upvar_ty)); + p!(write("{}{}:", sep, index), print(upvar_ty)); sep = ", "; } } p!(write(" "), print(witness), write("]")) - }, + } ty::GeneratorWitness(types) => { p!(in_binder(&types)); } @@ -687,17 +656,10 @@ pub trait PrettyPrinter<'tcx>: p!(write("@{:?}", self.tcx().hir().span(hir_id))); } let mut sep = " "; - for (&var_id, upvar_ty) in self.tcx().upvars(did) - .as_ref() - .iter() - .flat_map(|v| v.keys()) - .zip(upvar_tys) + for (&var_id, upvar_ty) in + self.tcx().upvars(did).as_ref().iter().flat_map(|v| v.keys()).zip(upvar_tys) { - p!( - write("{}{}:", - sep, - self.tcx().hir().name(var_id)), - print(upvar_ty)); + p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty)); sep = ", "; } } else { @@ -706,9 +668,7 @@ pub trait PrettyPrinter<'tcx>: p!(write("@{:?}", did)); let mut sep = " "; for (index, upvar_ty) in upvar_tys.enumerate() { - p!( - write("{}{}:", sep, index), - print(upvar_ty)); + p!(write("{}{}:", sep, index), print(upvar_ty)); sep = ", "; } } @@ -722,7 +682,7 @@ pub trait PrettyPrinter<'tcx>: } p!(write("]")) - }, + } ty::Array(ty, sz) => { p!(write("["), print(ty), write("; ")); if self.tcx().sess.verbose() { @@ -739,9 +699,7 @@ pub trait PrettyPrinter<'tcx>: } p!(write("]")) } - ty::Slice(ty) => { - p!(write("["), print(ty), write("]")) - } + ty::Slice(ty) => p!(write("["), print(ty), write("]")), } Ok(self) @@ -791,17 +749,13 @@ pub trait PrettyPrinter<'tcx>: ); // Don't print `'_` if there's no unerased regions. - let print_regions = args.iter().any(|arg| { - match arg.unpack() { - GenericArgKind::Lifetime(r) => *r != ty::ReErased, - _ => false, - } + let print_regions = args.iter().any(|arg| match arg.unpack() { + GenericArgKind::Lifetime(r) => *r != ty::ReErased, + _ => false, }); - let mut args = args.iter().cloned().filter(|arg| { - match arg.unpack() { - GenericArgKind::Lifetime(_) => print_regions, - _ => true, - } + let mut args = args.iter().cloned().filter(|arg| match arg.unpack() { + GenericArgKind::Lifetime(_) => print_regions, + _ => true, }); let mut projections = predicates.projection_bounds(); @@ -826,9 +780,8 @@ pub trait PrettyPrinter<'tcx>: // Builtin bounds. // FIXME(eddyb) avoid printing twice (needed to ensure // that the auto traits are sorted *and* printed via cx). - let mut auto_traits: Vec<_> = predicates.auto_traits().map(|did| { - (self.tcx().def_path_str(did), did) - }).collect(); + let mut auto_traits: Vec<_> = + predicates.auto_traits().map(|did| (self.tcx().def_path_str(did), did)).collect(); // The auto traits come ordered by `DefPathHash`. While // `DefPathHash` is *stable* in the sense that it depends on @@ -878,10 +831,7 @@ pub trait PrettyPrinter<'tcx>: Ok(self) } - fn pretty_print_const( - mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result { + fn pretty_print_const(mut self, ct: &'tcx ty::Const<'tcx>) -> Result { define_scoped_cx!(self); if self.tcx().sess.verbose() { @@ -890,13 +840,13 @@ pub trait PrettyPrinter<'tcx>: } match (ct.val, &ct.ty.kind) { - (_, ty::FnDef(did, substs)) => p!(print_value_path(*did, substs)), - (ty::ConstKind::Unevaluated(did, substs), _) => { - match self.tcx().def_kind(did) { - | Some(DefKind::Static) - | Some(DefKind::Const) - | Some(DefKind::AssocConst) => p!(print_value_path(did, substs)), - _ => if did.is_local() { + (_, ty::FnDef(did, substs)) => p!(print_value_path(*did, substs)), + (ty::ConstKind::Unevaluated(did, substs), _) => match self.tcx().def_kind(did) { + Some(DefKind::Static) | Some(DefKind::Const) | Some(DefKind::AssocConst) => { + p!(print_value_path(did, substs)) + } + _ => { + if did.is_local() { let span = self.tcx().def_span(did); if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span) { p!(write("{}", snip)) @@ -905,10 +855,10 @@ pub trait PrettyPrinter<'tcx>: } } else { p!(write("_: "), print(ct.ty)) - }, + } } }, - (ty::ConstKind::Infer(..), _) => p!(write("_: "), print(ct.ty)), + (ty::ConstKind::Infer(..), _) => p!(write("_: "), print(ct.ty)), (ty::ConstKind::Param(ParamConst { name, .. }), _) => p!(write("{}", name)), (ty::ConstKind::Value(value), _) => return self.pretty_print_const_value(value, ct.ty), @@ -935,12 +885,15 @@ pub trait PrettyPrinter<'tcx>: let u8 = self.tcx().types.u8; match (ct, &ty.kind) { - (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Bool) => - p!(write("{}", if data == 0 { "false" } else { "true" })), - (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Float(ast::FloatTy::F32)) => - p!(write("{}f32", Single::from_bits(data))), - (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Float(ast::FloatTy::F64)) => - p!(write("{}f64", Double::from_bits(data))), + (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Bool) => { + p!(write("{}", if data == 0 { "false" } else { "true" })) + } + (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Float(ast::FloatTy::F32)) => { + p!(write("{}f32", Single::from_bits(data))) + } + (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Float(ast::FloatTy::F64)) => { + p!(write("{}f64", Double::from_bits(data))) + } (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Uint(ui)) => { let bit_size = Integer::from_attr(&self.tcx(), UnsignedInt(*ui)).size(); let max = truncate(u128::max_value(), bit_size); @@ -951,26 +904,24 @@ pub trait PrettyPrinter<'tcx>: } else { p!(write("{}{}", data, ui_str)) }; - }, + } (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Int(i)) => { - let bit_size = Integer::from_attr(&self.tcx(), SignedInt(*i)) - .size().bits() as u128; + let bit_size = Integer::from_attr(&self.tcx(), SignedInt(*i)).size().bits() as u128; let min = 1u128 << (bit_size - 1); let max = min - 1; let ty = self.tcx().lift(&ty).unwrap(); - let size = self.tcx().layout_of(ty::ParamEnv::empty().and(ty)) - .unwrap() - .size; + let size = self.tcx().layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size; let i_str = i.name_str(); match data { d if d == min => p!(write("std::{}::MIN", i_str)), d if d == max => p!(write("std::{}::MAX", i_str)), - _ => p!(write("{}{}", sign_extend(data, size) as i128, i_str)) + _ => p!(write("{}{}", sign_extend(data, size) as i128, i_str)), } - }, - (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Char) => - p!(write("{:?}", ::std::char::from_u32(data as u32).unwrap())), + } + (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Char) => { + p!(write("{:?}", ::std::char::from_u32(data as u32).unwrap())) + } (ConstValue::Scalar(_), ty::RawPtr(_)) => p!(write("{{pointer}}")), (ConstValue::Scalar(Scalar::Ptr(ptr)), ty::FnPtr(_)) => { let instance = { @@ -978,23 +929,27 @@ pub trait PrettyPrinter<'tcx>: alloc_map.unwrap_fn(ptr.alloc_id) }; p!(print_value_path(instance.def_id(), instance.substs)); - }, + } _ => { let printed = if let ty::Ref(_, ref_ty, _) = ty.kind { let byte_str = match (ct, &ref_ty.kind) { (ConstValue::Scalar(Scalar::Ptr(ptr)), ty::Array(t, n)) if *t == u8 => { let n = n.eval_usize(self.tcx(), ty::ParamEnv::empty()); - Some(self.tcx() - .alloc_map.lock() - .unwrap_memory(ptr.alloc_id) - .get_bytes(&self.tcx(), ptr, Size::from_bytes(n)).unwrap()) - }, + Some( + self.tcx() + .alloc_map + .lock() + .unwrap_memory(ptr.alloc_id) + .get_bytes(&self.tcx(), ptr, Size::from_bytes(n)) + .unwrap(), + ) + } (ConstValue::Slice { data, start, end }, ty::Slice(t)) if *t == u8 => { // The `inspect` here is okay since we checked the bounds, and there are // no relocations (we have an active slice reference here). We don't use // this result to affect interpreter execution. Some(data.inspect_with_undef_and_ptr_outside_interpreter(start..end)) - }, + } _ => None, }; @@ -1014,8 +969,7 @@ pub trait PrettyPrinter<'tcx>: // relocations (we have an active `str` reference here). We don't use this // result to affect interpreter execution. let slice = data.inspect_with_undef_and_ptr_outside_interpreter(start..end); - let s = ::std::str::from_utf8(slice) - .expect("non utf8 str from miri"); + let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri"); p!(write("{:?}", s)); true } else { @@ -1087,9 +1041,9 @@ impl TyCtxt<'t> { // (but also some things just print a `DefId` generally so maybe we need this?) fn guess_def_namespace(self, def_id: DefId) -> Namespace { match self.def_key(def_id).disambiguated_data.data { - DefPathData::TypeNs(..) - | DefPathData::CrateRoot - | DefPathData::ImplTrait => Namespace::TypeNS, + DefPathData::TypeNs(..) | DefPathData::CrateRoot | DefPathData::ImplTrait => { + Namespace::TypeNS + } DefPathData::ValueNs(..) | DefPathData::AnonConst @@ -1154,12 +1108,11 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { if let DefPathData::Impl = key.disambiguated_data.data { // Always use types for non-local impls, where types are always // available, and filename/line-number is mostly uninteresting. - let use_types = - !def_id.is_local() || { - // Otherwise, use filename/line-number if forced. - let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); - !force_no_types - }; + let use_types = !def_id.is_local() || { + // Otherwise, use filename/line-number if forced. + let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); + !force_no_types + }; if !use_types { // If no type info is available, fall back to @@ -1185,17 +1138,11 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { self.default_print_def_path(def_id, substs) } - fn print_region( - self, - region: ty::Region<'_>, - ) -> Result { + fn print_region(self, region: ty::Region<'_>) -> Result { self.pretty_print_region(region) } - fn print_type( - self, - ty: Ty<'tcx>, - ) -> Result { + fn print_type(self, ty: Ty<'tcx>) -> Result { self.pretty_print_type(ty) } @@ -1206,17 +1153,11 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { self.pretty_print_dyn_existential(predicates) } - fn print_const( - self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result { + fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result { self.pretty_print_const(ct) } - fn path_crate( - mut self, - cnum: CrateNum, - ) -> Result { + fn path_crate(mut self, cnum: CrateNum) -> Result { self.empty_path = true; if cnum == LOCAL_CRATE { if self.tcx.sess.rust_2018() { @@ -1250,14 +1191,18 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { - self = self.pretty_path_append_impl(|mut cx| { - cx = print_prefix(cx)?; - if !cx.empty_path { - write!(cx, "::")?; - } + self = self.pretty_path_append_impl( + |mut cx| { + cx = print_prefix(cx)?; + if !cx.empty_path { + write!(cx, "::")?; + } - Ok(cx) - }, self_ty, trait_ref)?; + Ok(cx) + }, + self_ty, + trait_ref, + )?; self.empty_path = false; Ok(self) } @@ -1290,9 +1235,8 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { // FIXME(eddyb) this will print e.g. `{{closure}}#3`, but it // might be nicer to use something else, e.g. `{closure#3}`. let dis = disambiguated_data.disambiguator; - let print_dis = - disambiguated_data.data.get_opt_name().is_none() || - dis != 0 && self.tcx.sess.verbose(); + let print_dis = disambiguated_data.data.get_opt_name().is_none() + || dis != 0 && self.tcx.sess.verbose(); if print_dis { write!(self, "#{}", dis)?; } @@ -1311,17 +1255,13 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { self = print_prefix(self)?; // Don't print `'_` if there's no unerased regions. - let print_regions = args.iter().any(|arg| { - match arg.unpack() { - GenericArgKind::Lifetime(r) => *r != ty::ReErased, - _ => false, - } + let print_regions = args.iter().any(|arg| match arg.unpack() { + GenericArgKind::Lifetime(r) => *r != ty::ReErased, + _ => false, }); - let args = args.iter().cloned().filter(|arg| { - match arg.unpack() { - GenericArgKind::Lifetime(_) => print_regions, - _ => true, - } + let args = args.iter().cloned().filter(|arg| match arg.unpack() { + GenericArgKind::Lifetime(_) => print_regions, + _ => true, }); if args.clone().next().is_some() { @@ -1373,10 +1313,7 @@ impl PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { Ok(inner) } - fn region_should_not_be_omitted( - &self, - region: ty::Region<'_>, - ) -> bool { + fn region_should_not_be_omitted(&self, region: ty::Region<'_>) -> bool { let highlight = self.region_highlight_mode; if highlight.region_highlighted(region).is_some() { return true; @@ -1390,16 +1327,14 @@ impl PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { match *region { ty::ReEarlyBound(ref data) => { - data.name != kw::Invalid && - data.name != kw::UnderscoreLifetime + data.name != kw::Invalid && data.name != kw::UnderscoreLifetime } - ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | - ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + ty::ReLateBound(_, br) + | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) + | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { if let ty::BrNamed(_, name) = br { - if name != kw::Invalid && - name != kw::UnderscoreLifetime { + if name != kw::Invalid && name != kw::UnderscoreLifetime { return true; } } @@ -1413,26 +1348,18 @@ impl PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { false } - ty::ReScope(_) | - ty::ReVar(_) if identify_regions => true, + ty::ReScope(_) | ty::ReVar(_) if identify_regions => true, - ty::ReVar(_) | - ty::ReScope(_) | - ty::ReErased => false, + ty::ReVar(_) | ty::ReScope(_) | ty::ReErased => false, - ty::ReStatic | - ty::ReEmpty | - ty::ReClosureBound(_) => true, + ty::ReStatic | ty::ReEmpty | ty::ReClosureBound(_) => true, } } } // HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`. impl FmtPrinter<'_, '_, F> { - pub fn pretty_print_region( - mut self, - region: ty::Region<'_>, - ) -> Result { + pub fn pretty_print_region(mut self, region: ty::Region<'_>) -> Result { define_scoped_cx!(self); // Watch out for region highlights. @@ -1460,12 +1387,11 @@ impl FmtPrinter<'_, '_, F> { return Ok(self); } } - ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | - ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + ty::ReLateBound(_, br) + | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) + | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { if let ty::BrNamed(_, name) = br { - if name != kw::Invalid && - name != kw::UnderscoreLifetime { + if name != kw::Invalid && name != kw::UnderscoreLifetime { p!(write("{}", name)); return Ok(self); } @@ -1480,14 +1406,16 @@ impl FmtPrinter<'_, '_, F> { } ty::ReScope(scope) if identify_regions => { match scope.data { - region::ScopeData::Node => - p!(write("'{}s", scope.item_local_id().as_usize())), - region::ScopeData::CallSite => - p!(write("'{}cs", scope.item_local_id().as_usize())), - region::ScopeData::Arguments => - p!(write("'{}as", scope.item_local_id().as_usize())), - region::ScopeData::Destruction => - p!(write("'{}ds", scope.item_local_id().as_usize())), + region::ScopeData::Node => p!(write("'{}s", scope.item_local_id().as_usize())), + region::ScopeData::CallSite => { + p!(write("'{}cs", scope.item_local_id().as_usize())) + } + region::ScopeData::Arguments => { + p!(write("'{}as", scope.item_local_id().as_usize())) + } + region::ScopeData::Destruction => { + p!(write("'{}ds", scope.item_local_id().as_usize())) + } region::ScopeData::Remainder(first_statement_index) => p!(write( "'{}_{}rs", scope.item_local_id().as_usize(), @@ -1501,8 +1429,7 @@ impl FmtPrinter<'_, '_, F> { return Ok(self); } ty::ReVar(_) => {} - ty::ReScope(_) | - ty::ReErased => {} + ty::ReScope(_) | ty::ReErased => {} ty::ReStatic => { p!(write("'static")); return Ok(self); @@ -1539,7 +1466,7 @@ impl FmtPrinter<'_, 'tcx, F> { match index { 0 => Symbol::intern("'r"), 1 => Symbol::intern("'s"), - i => Symbol::intern(&format!("'t{}", i-2)), + i => Symbol::intern(&format!("'t{}", i - 2)), } } @@ -1554,12 +1481,16 @@ impl FmtPrinter<'_, 'tcx, F> { let mut empty = true; let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { - write!(cx, "{}", if empty { - empty = false; - start - } else { - cont - }) + write!( + cx, + "{}", + if empty { + empty = false; + start + } else { + cont + } + ) }; define_scoped_cx!(self); @@ -1572,8 +1503,7 @@ impl FmtPrinter<'_, 'tcx, F> { let _ = write!(self, "{}", name); br } - ty::BrAnon(_) | - ty::BrEnv => { + ty::BrAnon(_) | ty::BrEnv => { let name = loop { let name = name_by_region_index(region_index); region_index += 1; @@ -1607,17 +1537,17 @@ impl FmtPrinter<'_, 'tcx, F> { } fn prepare_late_bound_region_info(&mut self, value: &ty::Binder) - where T: TypeFoldable<'tcx> + where + T: TypeFoldable<'tcx>, { - struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet); impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> { fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { match *r { ty::ReLateBound(_, ty::BrNamed(_, name)) => { self.0.insert(name); - }, - _ => {}, + } + _ => {} } r.super_visit_with(self) } diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 7e126459dcc73..5af0e78b04616 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -1,19 +1,19 @@ use crate::dep_graph::SerializedDepNodeIndex; use crate::dep_graph::{DepKind, DepNode}; use crate::hir::def_id::{CrateNum, DefId}; -use crate::ty::TyCtxt; +use crate::ty::query::plumbing::CycleError; use crate::ty::query::queries; -use crate::ty::query::{Query, QueryName}; use crate::ty::query::QueryCache; -use crate::ty::query::plumbing::CycleError; +use crate::ty::query::{Query, QueryName}; +use crate::ty::TyCtxt; use rustc_data_structures::profiling::ProfileCategory; +use crate::ich::StableHashingContext; +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::sharded::Sharded; use std::borrow::Cow; -use std::hash::Hash; use std::fmt::Debug; -use rustc_data_structures::sharded::Sharded; -use rustc_data_structures::fingerprint::Fingerprint; -use crate::ich::StableHashingContext; +use std::hash::Hash; // Query configuration and description traits. @@ -43,10 +43,8 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> { // Don't use this method to compute query results, instead use the methods on TyCtxt fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value; - fn hash_result( - hcx: &mut StableHashingContext<'_>, - result: &Self::Value - ) -> Option; + fn hash_result(hcx: &mut StableHashingContext<'_>, result: &Self::Value) + -> Option; fn handle_cycle_error(tcx: TyCtxt<'tcx>, error: CycleError<'tcx>) -> Self::Value; } diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs index 2f30b797fb151..7361485c55d9f 100644 --- a/src/librustc/ty/query/job.rs +++ b/src/librustc/ty/query/job.rs @@ -11,15 +11,15 @@ use std::ptr; #[cfg(parallel_compiler)] use { - parking_lot::{Mutex, Condvar}, - rustc_data_structures::{jobserver, OnDrop}, + parking_lot::{Condvar, Mutex}, rustc_data_structures::fx::FxHashSet, - rustc_data_structures::stable_hasher::{StableHasher, HashStable}, + rustc_data_structures::stable_hasher::{HashStable, StableHasher}, rustc_data_structures::sync::Lock, + rustc_data_structures::{jobserver, OnDrop}, rustc_rayon_core as rayon_core, - syntax_pos::DUMMY_SP, - std::{mem, process, thread}, std::iter::FromIterator, + std::{mem, process, thread}, + syntax_pos::DUMMY_SP, }; /// Represents a span and a query key. @@ -55,11 +55,7 @@ impl<'tcx> QueryJob<'tcx> { /// Awaits for the query job to complete. #[cfg(parallel_compiler)] - pub(super) fn r#await( - &self, - tcx: TyCtxt<'tcx>, - span: Span, - ) -> Result<(), CycleError<'tcx>> { + pub(super) fn r#await(&self, tcx: TyCtxt<'tcx>, span: Span) -> Result<(), CycleError<'tcx>> { tls::with_related_context(tcx, move |icx| { let waiter = Lrc::new(QueryWaiter { query: icx.query.clone(), @@ -74,7 +70,7 @@ impl<'tcx> QueryJob<'tcx> { let mut cycle = waiter.cycle.lock(); match cycle.take() { None => Ok(()), - Some(cycle) => Err(cycle) + Some(cycle) => Err(cycle), } }) } @@ -97,9 +93,8 @@ impl<'tcx> QueryJob<'tcx> { // Replace it with the span which caused the cycle to form cycle[0].span = span; // Find out why the cycle itself was used - let usage = job.parent.as_ref().map(|parent| { - (job.info.span, parent.info.query.clone()) - }); + let usage = + job.parent.as_ref().map(|parent| (job.info.span, parent.info.query.clone())); return CycleError { usage, cycle }; } @@ -154,12 +149,7 @@ struct QueryLatch<'tcx> { #[cfg(parallel_compiler)] impl<'tcx> QueryLatch<'tcx> { fn new() -> Self { - QueryLatch { - info: Mutex::new(QueryLatchInfo { - complete: false, - waiters: Vec::new(), - }), - } + QueryLatch { info: Mutex::new(QueryLatchInfo { complete: false, waiters: Vec::new() }) } } /// Awaits the caller on this latch by blocking the current thread. @@ -197,10 +187,7 @@ impl<'tcx> QueryLatch<'tcx> { /// Removes a single waiter from the list of waiters. /// This is used to break query cycles. - fn extract_waiter( - &self, - waiter: usize, - ) -> Lrc> { + fn extract_waiter(&self, waiter: usize) -> Lrc> { let mut info = self.info.lock(); debug_assert!(!info.complete); // Remove the waiter from the list of waiters @@ -224,7 +211,7 @@ type Waiter<'tcx> = (Lrc>, usize); #[cfg(parallel_compiler)] fn visit_waiters<'tcx, F>(query: Lrc>, mut visit: F) -> Option>> where - F: FnMut(Span, Lrc>) -> Option>> + F: FnMut(Span, Lrc>) -> Option>>, { // Visit the parent query which is a non-resumable waiter since it's on the same stack if let Some(ref parent) = query.parent { @@ -250,10 +237,11 @@ where /// If a cycle is detected, this initial value is replaced with the span causing /// the cycle. #[cfg(parallel_compiler)] -fn cycle_check<'tcx>(query: Lrc>, - span: Span, - stack: &mut Vec<(Span, Lrc>)>, - visited: &mut FxHashSet<*const QueryJob<'tcx>> +fn cycle_check<'tcx>( + query: Lrc>, + span: Span, + stack: &mut Vec<(Span, Lrc>)>, + visited: &mut FxHashSet<*const QueryJob<'tcx>>, ) -> Option>> { if !visited.insert(query.as_ptr()) { return if let Some(p) = stack.iter().position(|q| q.1.as_ptr() == query.as_ptr()) { @@ -266,16 +254,14 @@ fn cycle_check<'tcx>(query: Lrc>, Some(None) } else { None - } + }; } // Query marked as visited is added it to the stack stack.push((span, query.clone())); // Visit all the waiters - let r = visit_waiters(query, |span, successor| { - cycle_check(successor, span, stack, visited) - }); + let r = visit_waiters(query, |span, successor| cycle_check(successor, span, stack, visited)); // Remove the entry in our stack if we didn't find a cycle if r.is_none() { @@ -291,7 +277,7 @@ fn cycle_check<'tcx>(query: Lrc>, #[cfg(parallel_compiler)] fn connected_to_root<'tcx>( query: Lrc>, - visited: &mut FxHashSet<*const QueryJob<'tcx>> + visited: &mut FxHashSet<*const QueryJob<'tcx>>, ) -> bool { // We already visited this or we're deliberately ignoring it if !visited.insert(query.as_ptr()) { @@ -317,16 +303,19 @@ fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, Lrc>)>( // Deterministically pick an entry point // FIXME: Sort this instead let mut hcx = tcx.create_stable_hashing_context(); - queries.iter().min_by_key(|v| { - let (span, query) = f(v); - let mut stable_hasher = StableHasher::new(); - query.info.query.hash_stable(&mut hcx, &mut stable_hasher); - // Prefer entry points which have valid spans for nicer error messages - // We add an integer to the tuple ensuring that entry points - // with valid spans are picked first - let span_cmp = if span == DUMMY_SP { 1 } else { 0 }; - (span_cmp, stable_hasher.finish::()) - }).unwrap() + queries + .iter() + .min_by_key(|v| { + let (span, query) = f(v); + let mut stable_hasher = StableHasher::new(); + query.info.query.hash_stable(&mut hcx, &mut stable_hasher); + // Prefer entry points which have valid spans for nicer error messages + // We add an integer to the tuple ensuring that entry points + // with valid spans are picked first + let span_cmp = if span == DUMMY_SP { 1 } else { 0 }; + (span_cmp, stable_hasher.finish::()) + }) + .unwrap() } /// Looks for query cycles starting from the last query in `jobs`. @@ -343,10 +332,7 @@ fn remove_cycle<'tcx>( let mut visited = FxHashSet::default(); let mut stack = Vec::new(); // Look for a cycle starting with the last query in `jobs` - if let Some(waiter) = cycle_check(jobs.pop().unwrap(), - DUMMY_SP, - &mut stack, - &mut visited) { + if let Some(waiter) = cycle_check(jobs.pop().unwrap(), DUMMY_SP, &mut stack, &mut visited) { // The stack is a vector of pairs of spans and queries; reverse it so that // the earlier entries require later entries let (mut spans, queries): (Vec<_>, Vec<_>) = stack.into_iter().rev().unzip(); @@ -366,40 +352,42 @@ fn remove_cycle<'tcx>( // Find the queries in the cycle which are // connected to queries outside the cycle - let entry_points = stack.iter().filter_map(|(span, query)| { - if query.parent.is_none() { - // This query is connected to the root (it has no query parent) - Some((*span, query.clone(), None)) - } else { - let mut waiters = Vec::new(); - // Find all the direct waiters who lead to the root - visit_waiters(query.clone(), |span, waiter| { - // Mark all the other queries in the cycle as already visited - let mut visited = FxHashSet::from_iter(stack.iter().map(|q| q.1.as_ptr())); - - if connected_to_root(waiter.clone(), &mut visited) { - waiters.push((span, waiter)); - } - - None - }); - if waiters.is_empty() { - None + let entry_points = stack + .iter() + .filter_map(|(span, query)| { + if query.parent.is_none() { + // This query is connected to the root (it has no query parent) + Some((*span, query.clone(), None)) } else { - // Deterministically pick one of the waiters to show to the user - let waiter = pick_query(tcx, &waiters, |s| s.clone()).clone(); - Some((*span, query.clone(), Some(waiter))) + let mut waiters = Vec::new(); + // Find all the direct waiters who lead to the root + visit_waiters(query.clone(), |span, waiter| { + // Mark all the other queries in the cycle as already visited + let mut visited = FxHashSet::from_iter(stack.iter().map(|q| q.1.as_ptr())); + + if connected_to_root(waiter.clone(), &mut visited) { + waiters.push((span, waiter)); + } + + None + }); + if waiters.is_empty() { + None + } else { + // Deterministically pick one of the waiters to show to the user + let waiter = pick_query(tcx, &waiters, |s| s.clone()).clone(); + Some((*span, query.clone(), Some(waiter))) + } } - } - }).collect::>, Option<(Span, Lrc>)>)>>(); + }) + .collect::>, Option<(Span, Lrc>)>)>>(); // Deterministically pick an entry point let (_, entry_point, usage) = pick_query(tcx, &entry_points, |e| (e.0, e.1.clone())); // Shift the stack so that our entry point is first - let entry_point_pos = stack.iter().position(|(_, query)| { - query.as_ptr() == entry_point.as_ptr() - }); + let entry_point_pos = + stack.iter().position(|(_, query)| query.as_ptr() == entry_point.as_ptr()); if let Some(pos) = entry_point_pos { stack.rotate_left(pos); } @@ -409,10 +397,10 @@ fn remove_cycle<'tcx>( // Create the cycle error let error = CycleError { usage, - cycle: stack.iter().map(|&(s, ref q)| QueryInfo { - span: s, - query: q.info.query.clone(), - } ).collect(), + cycle: stack + .iter() + .map(|&(s, ref q)| QueryInfo { span: s, query: q.info.query.clone() }) + .collect(), }; // We unwrap `waiter` here since there must always be one @@ -441,22 +429,17 @@ fn remove_cycle<'tcx>( pub unsafe fn handle_deadlock() { let registry = rayon_core::Registry::current(); - let gcx_ptr = tls::GCX_PTR.with(|gcx_ptr| { - gcx_ptr as *const _ - }); + let gcx_ptr = tls::GCX_PTR.with(|gcx_ptr| gcx_ptr as *const _); let gcx_ptr = &*gcx_ptr; - let syntax_pos_globals = syntax_pos::GLOBALS.with(|syntax_pos_globals| { - syntax_pos_globals as *const _ - }); + let syntax_pos_globals = + syntax_pos::GLOBALS.with(|syntax_pos_globals| syntax_pos_globals as *const _); let syntax_pos_globals = &*syntax_pos_globals; thread::spawn(move || { tls::GCX_PTR.set(gcx_ptr, || { syntax_pos::GLOBALS.set(syntax_pos_globals, || { syntax_pos::GLOBALS.set(syntax_pos_globals, || { - tls::with_thread_locals(|| { - tls::with_global(|tcx| deadlock(tcx, ®istry)) - }) + tls::with_thread_locals(|| tls::with_global(|tcx| deadlock(tcx, ®istry))) }) }) }) diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index a9e0a5d6ab564..78e97f701ea57 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -1,15 +1,15 @@ //! Defines the set of legal keys that can be used in queries. +use crate::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; use crate::infer::canonical::Canonical; -use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, DefIndex}; +use crate::mir; use crate::traits; -use crate::ty::{self, Ty, TyCtxt}; -use crate::ty::subst::SubstsRef; use crate::ty::fast_reject::SimplifiedType; -use crate::mir; +use crate::ty::subst::SubstsRef; +use crate::ty::{self, Ty, TyCtxt}; -use syntax_pos::{Span, DUMMY_SP}; use syntax_pos::symbol::Symbol; +use syntax_pos::{Span, DUMMY_SP}; /// The `Key` trait controls what types can legally be used as the key /// for a query. diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 5b4a6ac8a2d3c..8be0536a18ec6 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -1,62 +1,61 @@ use crate::dep_graph::{self, DepNode}; -use crate::hir::def_id::{CrateNum, DefId, DefIndex}; use crate::hir::def::{DefKind, Export}; -use crate::hir::{self, TraitCandidate, ItemLocalId, CodegenFnAttrs}; +use crate::hir::def_id::{CrateNum, DefId, DefIndex}; +use crate::hir::{self, CodegenFnAttrs, ItemLocalId, TraitCandidate}; use crate::infer::canonical::{self, Canonical}; use crate::lint; -use crate::middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary, ForeignModule}; -use crate::middle::cstore::{NativeLibraryKind, DepKind, CrateSource}; +use crate::middle::cstore::{CrateSource, DepKind, NativeLibraryKind}; +use crate::middle::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLibrary}; +use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; +use crate::middle::lang_items::{LangItem, LanguageItems}; +use crate::middle::lib_features::LibFeatures; use crate::middle::privacy::AccessLevels; use crate::middle::reachable::ReachableSet; use crate::middle::region; -use crate::middle::resolve_lifetime::{ResolveLifetimes, Region, ObjectLifetimeDefault}; +use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes}; use crate::middle::stability::{self, DeprecationEntry}; -use crate::middle::lib_features::LibFeatures; -use crate::middle::lang_items::{LanguageItems, LangItem}; -use crate::middle::exported_symbols::{SymbolExportLevel, ExportedSymbol}; -use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult}; -use crate::mir::mono::CodegenUnit; use crate::mir; use crate::mir::interpret::GlobalId; +use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult}; +use crate::mir::mono::CodegenUnit; +use crate::session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; use crate::session::CrateDisambiguator; -use crate::session::config::{EntryFnType, OutputFilenames, OptLevel, SymbolManglingVersion}; -use crate::traits::{self, Vtable}; -use crate::traits::query::{ - CanonicalPredicateGoal, CanonicalProjectionGoal, - CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, - CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal, CanonicalTypeOpProvePredicateGoal, - CanonicalTypeOpNormalizeGoal, NoSolution, -}; +use crate::traits::query::dropck_outlives::{DropckOutlivesResult, DtorckConstraint}; use crate::traits::query::method_autoderef::MethodAutoderefStepsResult; -use crate::traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult}; use crate::traits::query::normalize::NormalizationResult; use crate::traits::query::outlives_bounds::OutlivesBound; +use crate::traits::query::{ + CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, + CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal, + CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution, +}; use crate::traits::specialization_graph; use crate::traits::Clauses; -use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt, AdtSizedConstraint}; +use crate::traits::{self, Vtable}; use crate::ty::steal::Steal; -use crate::ty::util::NeedsDrop; use crate::ty::subst::SubstsRef; -use crate::util::nodemap::{DefIdSet, DefIdMap}; +use crate::ty::util::NeedsDrop; +use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; use crate::util::common::ErrorReported; +use crate::util::nodemap::{DefIdMap, DefIdSet}; use rustc_data_structures::profiling::ProfileCategory::*; -use rustc_data_structures::svh::Svh; -use rustc_index::vec::IndexVec; -use rustc_data_structures::fx::{FxIndexMap, FxHashMap, FxHashSet}; +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::stable_hasher::StableVec; +use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; -use rustc_data_structures::fingerprint::Fingerprint; +use rustc_index::vec::IndexVec; use rustc_target::spec::PanicStrategy; +use std::any::type_name; use std::borrow::Cow; use std::ops::Deref; use std::sync::Arc; -use std::any::type_name; -use syntax_pos::{Span, DUMMY_SP}; -use syntax::attr; use syntax::ast; +use syntax::attr; use syntax::symbol::Symbol; +use syntax_pos::{Span, DUMMY_SP}; #[macro_use] mod plumbing; @@ -64,9 +63,9 @@ use self::plumbing::*; pub use self::plumbing::{force_from_dep_node, CycleError}; mod job; -pub use self::job::{QueryJob, QueryInfo}; #[cfg(parallel_compiler)] pub use self::job::handle_deadlock; +pub use self::job::{QueryInfo, QueryJob}; mod keys; use self::keys::Key; @@ -75,9 +74,9 @@ mod values; use self::values::Value; mod config; -pub(crate) use self::config::QueryDescription; -pub use self::config::QueryConfig; use self::config::QueryAccessors; +pub use self::config::QueryConfig; +pub(crate) use self::config::QueryDescription; mod on_disk_cache; pub use self::on_disk_cache::OnDiskCache; diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 4031eb6219432..2a03413ee603d 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -1,30 +1,30 @@ use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; use crate::hir; -use crate::hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId, LOCAL_CRATE}; +use crate::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE}; use crate::hir::map::definitions::DefPathHash; use crate::ich::{CachingSourceMapView, Fingerprint}; -use crate::mir::{self, interpret}; use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState}; +use crate::mir::{self, interpret}; use crate::session::{CrateDisambiguator, Session}; -use crate::ty::{self, Ty}; use crate::ty::codec::{self as ty_codec, TyDecoder, TyEncoder}; use crate::ty::context::TyCtxt; +use crate::ty::{self, Ty}; use crate::util::common::{time, time_ext}; use errors::Diagnostic; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, Once}; use rustc_data_structures::thin_vec::ThinVec; -use rustc_data_structures::sync::{Lrc, Lock, HashMapExt, Once}; -use rustc_index::vec::{IndexVec, Idx}; +use rustc_index::vec::{Idx, IndexVec}; use rustc_serialize::{ - Decodable, Decoder, Encodable, Encoder, SpecializedDecoder, SpecializedEncoder, - UseSpecializedDecodable, UseSpecializedEncodable, opaque, + opaque, Decodable, Decoder, Encodable, Encoder, SpecializedDecoder, SpecializedEncoder, + UseSpecializedDecodable, UseSpecializedEncodable, }; use std::mem; use syntax::ast::{Ident, NodeId}; use syntax::source_map::{SourceMap, StableSourceFileId}; -use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile}; use syntax_pos::hygiene::{ExpnId, SyntaxContext}; +use syntax_pos::{BytePos, SourceFile, Span, DUMMY_SP}; const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE; @@ -165,10 +165,10 @@ impl<'sess> OnDiskCache<'sess> { // Allocate `SourceFileIndex`es. let (file_to_file_index, file_index_to_stable_id) = { let files = tcx.sess.source_map().files(); - let mut file_to_file_index = FxHashMap::with_capacity_and_hasher( - files.len(), Default::default()); - let mut file_index_to_stable_id = FxHashMap::with_capacity_and_hasher( - files.len(), Default::default()); + let mut file_to_file_index = + FxHashMap::with_capacity_and_hasher(files.len(), Default::default()); + let mut file_index_to_stable_id = + FxHashMap::with_capacity_and_hasher(files.len(), Default::default()); for (index, file) in files.iter().enumerate() { let index = SourceFileIndex(index as u32); @@ -222,7 +222,9 @@ impl<'sess> OnDiskCache<'sess> { })?; // Encode diagnostics. - let diagnostics_index: EncodedDiagnosticsIndex = self.current_diagnostics.borrow() + let diagnostics_index: EncodedDiagnosticsIndex = self + .current_diagnostics + .borrow() .iter() .map(|(dep_node_index, diagnostics)| { let pos = AbsoluteBytePos::new(encoder.position()); @@ -250,11 +252,7 @@ impl<'sess> OnDiskCache<'sess> { let id = encoder.interpret_allocs_inverse[idx]; let pos = encoder.position() as u32; interpret_alloc_index.push(pos); - interpret::specialized_encode_alloc_id( - &mut encoder, - tcx, - id, - )?; + interpret::specialized_encode_alloc_id(&mut encoder, tcx, id)?; } n = new_n; } @@ -262,7 +260,8 @@ impl<'sess> OnDiskCache<'sess> { }; let sorted_cnums = sorted_cnums_including_local_crate(tcx); - let prev_cnums: Vec<_> = sorted_cnums.iter() + let prev_cnums: Vec<_> = sorted_cnums + .iter() .map(|&cnum| { let crate_name = tcx.original_crate_name(cnum).to_string(); let crate_disambiguator = tcx.crate_disambiguator(cnum); @@ -272,13 +271,16 @@ impl<'sess> OnDiskCache<'sess> { // Encode the file footer. let footer_pos = encoder.position() as u64; - encoder.encode_tagged(TAG_FILE_FOOTER, &Footer { - file_index_to_stable_id, - prev_cnums, - query_result_index, - diagnostics_index, - interpret_alloc_index, - })?; + encoder.encode_tagged( + TAG_FILE_FOOTER, + &Footer { + file_index_to_stable_id, + prev_cnums, + query_result_index, + diagnostics_index, + interpret_alloc_index, + }, + )?; // Encode the position of the footer as the last 8 bytes of the // file so we know where to look for it. @@ -306,11 +308,8 @@ impl<'sess> OnDiskCache<'sess> { tcx: TyCtxt<'_>, dep_node_index: SerializedDepNodeIndex, ) -> Vec { - let diagnostics: Option = self.load_indexed( - tcx, - dep_node_index, - &self.prev_diagnostics_index, - "diagnostics"); + let diagnostics: Option = + self.load_indexed(tcx, dep_node_index, &self.prev_diagnostics_index, "diagnostics"); diagnostics.unwrap_or_default() } @@ -320,9 +319,11 @@ impl<'sess> OnDiskCache<'sess> { /// the next compilation session. #[inline(never)] #[cold] - pub fn store_diagnostics(&self, - dep_node_index: DepNodeIndex, - diagnostics: ThinVec) { + pub fn store_diagnostics( + &self, + dep_node_index: DepNodeIndex, + diagnostics: ThinVec, + ) { let mut current_diagnostics = self.current_diagnostics.borrow_mut(); let prev = current_diagnostics.insert(dep_node_index, diagnostics.into()); debug_assert!(prev.is_none()); @@ -338,10 +339,7 @@ impl<'sess> OnDiskCache<'sess> { where T: Decodable, { - self.load_indexed(tcx, - dep_node_index, - &self.query_result_index, - "query result") + self.load_indexed(tcx, dep_node_index, &self.query_result_index, "query result") } /// Stores a diagnostic emitted during computation of an anonymous query. @@ -350,9 +348,11 @@ impl<'sess> OnDiskCache<'sess> { /// 1:1 relationship between query-key and `DepNode`. #[inline(never)] #[cold] - pub fn store_diagnostics_for_anon_node(&self, - dep_node_index: DepNodeIndex, - diagnostics: ThinVec) { + pub fn store_diagnostics_for_anon_node( + &self, + dep_node_index: DepNodeIndex, + diagnostics: ThinVec, + ) { let mut current_diagnostics = self.current_diagnostics.borrow_mut(); let x = current_diagnostics.entry(dep_node_index).or_insert(Vec::new()); @@ -373,9 +373,7 @@ impl<'sess> OnDiskCache<'sess> { let pos = index.get(&dep_node_index).cloned()?; // Initialize `cnum_map` using the value from the thread that finishes the closure first. - self.cnum_map.init_nonlocking_same(|| { - Self::compute_cnum_map(tcx, &self.prev_cnums[..]) - }); + self.cnum_map.init_nonlocking_same(|| Self::compute_cnum_map(tcx, &self.prev_cnums[..])); let mut decoder = CacheDecoder { tcx, @@ -403,17 +401,17 @@ impl<'sess> OnDiskCache<'sess> { prev_cnums: &[(u32, String, CrateDisambiguator)], ) -> IndexVec> { tcx.dep_graph.with_ignore(|| { - let current_cnums = tcx.all_crate_nums(LOCAL_CRATE).iter().map(|&cnum| { - let crate_name = tcx.original_crate_name(cnum) - .to_string(); - let crate_disambiguator = tcx.crate_disambiguator(cnum); - ((crate_name, crate_disambiguator), cnum) - }).collect::>(); - - let map_size = prev_cnums.iter() - .map(|&(cnum, ..)| cnum) - .max() - .unwrap_or(0) + 1; + let current_cnums = tcx + .all_crate_nums(LOCAL_CRATE) + .iter() + .map(|&cnum| { + let crate_name = tcx.original_crate_name(cnum).to_string(); + let crate_disambiguator = tcx.crate_disambiguator(cnum); + ((crate_name, crate_disambiguator), cnum) + }) + .collect::>(); + + let map_size = prev_cnums.iter().map(|&(cnum, ..)| cnum).max().unwrap_or(0) + 1; let mut map = IndexVec::from_elem_n(None, map_size as usize); for &(prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums { @@ -452,11 +450,16 @@ impl<'a, 'tcx> CacheDecoder<'a, 'tcx> { .. } = *self; - file_index_to_file.borrow_mut().entry(index).or_insert_with(|| { - let stable_id = file_index_to_stable_id[&index]; - source_map.source_file_by_stable_id(stable_id) - .expect("failed to lookup `SourceFile` in new context") - }).clone() + file_index_to_file + .borrow_mut() + .entry(index) + .or_insert_with(|| { + let stable_id = file_index_to_stable_id[&index]; + source_map + .source_file_by_stable_id(stable_id) + .expect("failed to lookup `SourceFile` in new context") + }) + .clone() } } @@ -513,18 +516,18 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> { self.opaque.data[self.opaque.position()] } - fn cached_ty_for_shorthand(&mut self, - shorthand: usize, - or_insert_with: F) - -> Result, Self::Error> - where F: FnOnce(&mut Self) -> Result, Self::Error> + fn cached_ty_for_shorthand( + &mut self, + shorthand: usize, + or_insert_with: F, + ) -> Result, Self::Error> + where + F: FnOnce(&mut Self) -> Result, Self::Error>, { let tcx = self.tcx(); - let cache_key = ty::CReaderCacheKey { - cnum: CrateNum::ReservedForIncrCompCache, - pos: shorthand, - }; + let cache_key = + ty::CReaderCacheKey { cnum: CrateNum::ReservedForIncrCompCache, pos: shorthand }; if let Some(&ty) = tcx.rcache.borrow().get(&cache_key) { return Ok(ty); @@ -537,7 +540,8 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> { } fn with_position(&mut self, pos: usize, f: F) -> R - where F: FnOnce(&mut Self) -> R + where + F: FnOnce(&mut Self) -> R, { debug_assert!(pos < self.opaque.data.len()); @@ -549,9 +553,7 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> { } fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum { - self.cnum_map[cnum].unwrap_or_else(|| { - bug!("could not find new `CrateNum` for {:?}", cnum) - }) + self.cnum_map[cnum].unwrap_or_else(|| bug!("could not find new `CrateNum` for {:?}", cnum)) } } @@ -597,13 +599,14 @@ impl<'a, 'tcx> SpecializedDecoder for CacheDecoder<'a, 'tcx> { span }; Ok(match expn_data_tag { - TAG_NO_EXPN_DATA => { - location() - } + TAG_NO_EXPN_DATA => location(), TAG_EXPN_DATA_INLINE => { let (expn_data, transparency) = Decodable::decode(self)?; recover_from_expn_data( - self, expn_data, transparency, AbsoluteBytePos::new(self.opaque.position()) + self, + expn_data, + transparency, + AbsoluteBytePos::new(self.opaque.position()), ) } TAG_EXPN_DATA_SHORTHAND => { @@ -617,9 +620,7 @@ impl<'a, 'tcx> SpecializedDecoder for CacheDecoder<'a, 'tcx> { recover_from_expn_data(self, expn_data, transparency, pos) } } - _ => { - unreachable!() - } + _ => unreachable!(), }) } } @@ -668,10 +669,7 @@ impl<'a, 'tcx> SpecializedDecoder for CacheDecoder<'a, 'tcx> { let def_path_hash = DefPathHash::decode(self)?; // Use the `DefPathHash` to map to the current `DefId`. - let def_id = self.tcx() - .def_path_hash_to_def_id - .as_ref() - .unwrap()[&def_path_hash]; + let def_id = self.tcx().def_path_hash_to_def_id.as_ref().unwrap()[&def_path_hash]; debug_assert!(def_id.is_local()); @@ -680,10 +678,7 @@ impl<'a, 'tcx> SpecializedDecoder for CacheDecoder<'a, 'tcx> { // Reconstruct the `HirId` and look up the corresponding `NodeId` in the // context of the current session. - Ok(hir::HirId { - owner: def_id.index, - local_id - }) + Ok(hir::HirId { owner: def_id.index, local_id }) } } @@ -716,9 +711,7 @@ impl<'a, 'tcx, T: Decodable> SpecializedDecoder> let val = T::decode(self)?; Ok(mir::ClearCrossCrate::Set(val)) } - _ => { - unreachable!() - } + _ => unreachable!(), } } } @@ -754,7 +747,7 @@ where fn encode_tagged( &mut self, tag: T, - value: &V + value: &V, ) -> Result<(), E::Error> { let start_pos = self.position(); @@ -779,7 +772,7 @@ where self.interpret_allocs_inverse.push(*alloc_id); e.insert(idx); idx - }, + } }; index.encode(self) @@ -796,11 +789,11 @@ where } let span_data = span.data(); - let (file_lo, line_lo, col_lo) = match self.source_map - .byte_pos_to_line_and_col(span_data.lo) { - Some(pos) => pos, - None => return TAG_INVALID_SPAN.encode(self) - }; + let (file_lo, line_lo, col_lo) = + match self.source_map.byte_pos_to_line_and_col(span_data.lo) { + Some(pos) => pos, + None => return TAG_INVALID_SPAN.encode(self), + }; if !file_lo.contains(span_data.hi) { return TAG_INVALID_SPAN.encode(self); @@ -872,8 +865,7 @@ where { #[inline] fn specialized_encode(&mut self, ty: &Ty<'tcx>) -> Result<(), Self::Error> { - ty_codec::encode_with_shorthand(self, ty, - |encoder| &mut encoder.type_shorthands) + ty_codec::encode_with_shorthand(self, ty, |encoder| &mut encoder.type_shorthands) } } @@ -883,11 +875,13 @@ where E: 'a + TyEncoder, { #[inline] - fn specialized_encode(&mut self, - predicates: &&'tcx [(ty::Predicate<'tcx>, Span)]) - -> Result<(), Self::Error> { - ty_codec::encode_spanned_predicates(self, predicates, - |encoder| &mut encoder.predicate_shorthands) + fn specialized_encode( + &mut self, + predicates: &&'tcx [(ty::Predicate<'tcx>, Span)], + ) -> Result<(), Self::Error> { + ty_codec::encode_spanned_predicates(self, predicates, |encoder| { + &mut encoder.predicate_shorthands + }) } } @@ -897,10 +891,7 @@ where { #[inline] fn specialized_encode(&mut self, id: &hir::HirId) -> Result<(), Self::Error> { - let hir::HirId { - owner, - local_id, - } = *id; + let hir::HirId { owner, local_id } = *id; let def_path_hash = self.tcx.hir().definitions().def_path_hash(owner); @@ -964,13 +955,9 @@ where T: Encodable, { #[inline] - fn specialized_encode(&mut self, - val: &mir::ClearCrossCrate) - -> Result<(), Self::Error> { + fn specialized_encode(&mut self, val: &mir::ClearCrossCrate) -> Result<(), Self::Error> { match *val { - mir::ClearCrossCrate::Clear => { - TAG_CLEAR_CROSS_CRATE_CLEAR.encode(self) - } + mir::ClearCrossCrate::Clear => TAG_CLEAR_CROSS_CRATE_CLEAR.encode(self), mir::ClearCrossCrate::Set(ref val) => { TAG_CLEAR_CROSS_CRATE_SET.encode(self)?; val.encode(self) @@ -1047,7 +1034,7 @@ impl<'a> SpecializedDecoder for opaque::Decoder<'a> { let mut value: u64 = 0; let start_pos = self.position(); - for i in 0 .. IntEncodedWithFixedSize::ENCODED_SIZE { + for i in 0..IntEncodedWithFixedSize::ENCODED_SIZE { let byte: u8 = Decodable::decode(self)?; value |= (byte as u64) << (i * 8); } @@ -1068,8 +1055,7 @@ where Q: super::config::QueryDescription<'tcx, Value: Encodable>, E: 'a + TyEncoder, { - let desc = &format!("encode_query_results for {}", - ::std::any::type_name::()); + let desc = &format!("encode_query_results for {}", ::std::any::type_name::()); time_ext(tcx.sess.time_extended(), desc, || { let shards = Q::query_cache(tcx).lock_shards(); diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index fc55b665c1d0e..0114cd9076a88 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -2,30 +2,30 @@ //! generate the actual methods on tcx which find and execute the provider, //! manage the caches, and so forth. -use crate::dep_graph::{DepNodeIndex, DepNode, DepKind, SerializedDepNodeIndex}; +use crate::dep_graph::{DepKind, DepNode, DepNodeIndex, SerializedDepNodeIndex}; +use crate::ty::query::config::{QueryConfig, QueryDescription}; +use crate::ty::query::job::{QueryInfo, QueryJob}; +use crate::ty::query::Query; use crate::ty::tls; use crate::ty::{self, TyCtxt}; -use crate::ty::query::Query; -use crate::ty::query::config::{QueryConfig, QueryDescription}; -use crate::ty::query::job::{QueryJob, QueryInfo}; -use errors::DiagnosticBuilder; -use errors::Level; use errors::Diagnostic; +use errors::DiagnosticBuilder; use errors::FatalError; use errors::Handler; -use rustc_data_structures::fx::{FxHasher, FxHashMap}; -use rustc_data_structures::sync::{Lrc, Lock}; -use rustc_data_structures::sharded::Sharded; -use rustc_data_structures::thin_vec::ThinVec; +use errors::Level; #[cfg(not(parallel_compiler))] use rustc_data_structures::cold_path; +use rustc_data_structures::fx::{FxHashMap, FxHasher}; +use rustc_data_structures::sharded::Sharded; +use rustc_data_structures::sync::{Lock, Lrc}; +use rustc_data_structures::thin_vec::ThinVec; +use std::collections::hash_map::Entry; use std::hash::{Hash, Hasher}; use std::mem; use std::ptr; -use std::collections::hash_map::Entry; -use syntax_pos::Span; use syntax::source_map::DUMMY_SP; +use syntax_pos::Span; use rustc_error_codes::*; @@ -42,13 +42,8 @@ pub(super) struct QueryValue { } impl QueryValue { - pub(super) fn new(value: T, - dep_node_index: DepNodeIndex) - -> QueryValue { - QueryValue { - value, - index: dep_node_index, - } + pub(super) fn new(value: T, dep_node_index: DepNodeIndex) -> QueryValue { + QueryValue { value, index: dep_node_index } } } @@ -129,7 +124,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { } job.clone() - }, + } QueryResult::Poisoned => FatalError.raise(), } } @@ -139,19 +134,12 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { // Create the `parent` variable before `info`. This allows LLVM // to elide the move of `info` let parent = icx.query.clone(); - let info = QueryInfo { - span, - query: Q::query(key.clone()), - }; + let info = QueryInfo { span, query: Q::query(key.clone()) }; let job = Lrc::new(QueryJob::new(info, parent)); - let owner = JobOwner { - cache, - job: job.clone(), - key: (*key).clone(), - }; + let owner = JobOwner { cache, job: job.clone(), key: (*key).clone() }; entry.insert(QueryResult::Started(job)); TryGetJob::NotYetStarted(owner) - }) + }); } }; mem::drop(lock); @@ -207,7 +195,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { #[inline(always)] fn with_diagnostics(f: F) -> (R, ThinVec) where - F: FnOnce(Option<&Lock>>) -> R + F: FnOnce(Option<&Lock>>) -> R, { let diagnostics = Lock::new(ThinVec::new()); let result = f(Some(&diagnostics)); @@ -276,9 +264,7 @@ impl<'tcx> TyCtxt<'tcx> { }; // Use the `ImplicitCtxt` while we execute the query. - tls::enter_context(&new_icx, |_| { - compute(self) - }) + tls::enter_context(&new_icx, |_| compute(self)) }) } @@ -300,11 +286,13 @@ impl<'tcx> TyCtxt<'tcx> { // collect/coherence phases anyhow.) ty::print::with_forced_impl_filename_line(|| { let span = fix_span(stack[1 % stack.len()].span, &stack[0].query); - let mut err = struct_span_err!(self.sess, - span, - E0391, - "cycle detected when {}", - stack[0].query.describe(self)); + let mut err = struct_span_err!( + self.sess, + span, + E0391, + "cycle detected when {}", + stack[0].query.describe(self) + ); for i in 1..stack.len() { let query = &stack[i].query; @@ -312,12 +300,16 @@ impl<'tcx> TyCtxt<'tcx> { err.span_note(span, &format!("...which requires {}...", query.describe(self))); } - err.note(&format!("...which again requires {}, completing the cycle", - stack[0].query.describe(self))); + err.note(&format!( + "...which again requires {}, completing the cycle", + stack[0].query.describe(self) + )); if let Some((span, query)) = usage { - err.span_note(fix_span(span, &query), - &format!("cycle used when {}", query.describe(self))); + err.span_note( + fix_span(span, &query), + &format!("cycle used when {}", query.describe(self)), + ); } err @@ -336,11 +328,15 @@ impl<'tcx> TyCtxt<'tcx> { let mut i = 0; while let Some(query) = current_query { - let mut diag = Diagnostic::new(Level::FailureNote, - &format!("#{} [{}] {}", - i, - query.info.query.name(), - query.info.query.describe(icx.tcx))); + let mut diag = Diagnostic::new( + Level::FailureNote, + &format!( + "#{} [{}] {}", + i, + query.info.query.name(), + query.info.query.describe(icx.tcx) + ), + ); diag.span = icx.tcx.sess.source_map().def_span(query.info.span).into(); handler.force_print_diagnostic(diag); @@ -355,17 +351,14 @@ impl<'tcx> TyCtxt<'tcx> { #[inline(never)] pub(super) fn get_query>(self, span: Span, key: Q::Key) -> Q::Value { - debug!("ty::query::get_query<{}>(key={:?}, span={:?})", - Q::NAME.as_str(), - key, - span); + debug!("ty::query::get_query<{}>(key={:?}, span={:?})", Q::NAME.as_str(), key, span); let job = match JobOwner::try_get(self, span, &key) { TryGetJob::NotYetStarted(job) => job, TryGetJob::Cycle(result) => return result, TryGetJob::JobCompleted((v, index)) => { self.dep_graph.read_index(index); - return v + return v; } }; @@ -377,14 +370,11 @@ impl<'tcx> TyCtxt<'tcx> { } if Q::ANON { - let prof_timer = self.prof.query_provider(Q::NAME); let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| { self.start_query(job.job.clone(), diagnostics, |tcx| { - tcx.dep_graph.with_anon_task(Q::dep_kind(), || { - Q::compute(tcx, key) - }) + tcx.dep_graph.with_anon_task(Q::dep_kind(), || Q::compute(tcx, key)) }) }); @@ -393,7 +383,8 @@ impl<'tcx> TyCtxt<'tcx> { self.dep_graph.read_index(dep_node_index); if unlikely!(!diagnostics.is_empty()) { - self.queries.on_disk_cache + self.queries + .on_disk_cache .store_diagnostics_for_anon_node(dep_node_index, diagnostics); } @@ -411,12 +402,15 @@ impl<'tcx> TyCtxt<'tcx> { let loaded = self.start_query(job.job.clone(), None, |tcx| { let marked = tcx.dep_graph.try_mark_green_and_read(tcx, &dep_node); marked.map(|(prev_dep_node_index, dep_node_index)| { - (tcx.load_from_disk_and_cache_in_memory::( - key.clone(), - prev_dep_node_index, + ( + tcx.load_from_disk_and_cache_in_memory::( + key.clone(), + prev_dep_node_index, + dep_node_index, + &dep_node, + ), dep_node_index, - &dep_node - ), dep_node_index) + ) }) }); if let Some((result, dep_node_index)) = loaded { @@ -443,17 +437,19 @@ impl<'tcx> TyCtxt<'tcx> { debug_assert!(self.dep_graph.is_green(dep_node)); // First we try to load the result from the on-disk cache. - let result = if Q::cache_on_disk(self, key.clone(), None) && - self.sess.opts.debugging_opts.incremental_queries { + let result = if Q::cache_on_disk(self, key.clone(), None) + && self.sess.opts.debugging_opts.incremental_queries + { let _prof_timer = self.prof.incr_cache_loading(Q::NAME); let result = Q::try_load_from_disk(self, prev_dep_node_index); // We always expect to find a cached result for things that // can be forced from `DepNode`. - debug_assert!(!dep_node.kind.can_reconstruct_query_key() || - result.is_some(), - "missing on-disk cache entry for {:?}", - dep_node); + debug_assert!( + !dep_node.kind.can_reconstruct_query_key() || result.is_some(), + "missing on-disk cache entry for {:?}", + dep_node + ); result } else { // Some things are never cached on disk. @@ -468,9 +464,7 @@ impl<'tcx> TyCtxt<'tcx> { let _prof_timer = self.prof.query_provider(Q::NAME); // The dep-graph for this computation is already in-place. - let result = self.dep_graph.with_ignore(|| { - Q::compute(self, key) - }); + let result = self.dep_graph.with_ignore(|| Q::compute(self, key)); result }; @@ -495,8 +489,8 @@ impl<'tcx> TyCtxt<'tcx> { use crate::ich::Fingerprint; assert!( - Some(self.dep_graph.fingerprint_of(dep_node_index)) == - self.dep_graph.prev_fingerprint_of(dep_node), + Some(self.dep_graph.fingerprint_of(dep_node_index)) + == self.dep_graph.prev_fingerprint_of(dep_node), "fingerprint for green query instance not loaded from cache: {:?}", dep_node, ); @@ -509,11 +503,7 @@ impl<'tcx> TyCtxt<'tcx> { let old_hash = self.dep_graph.fingerprint_of(dep_node_index); - assert!( - new_hash == old_hash, - "found unstable fingerprints for {:?}", - dep_node, - ); + assert!(new_hash == old_hash, "found unstable fingerprints for {:?}", dep_node,); } #[inline(always)] @@ -528,28 +518,29 @@ impl<'tcx> TyCtxt<'tcx> { // in `DepGraph::try_mark_green()`. // 2. Two distinct query keys get mapped to the same `DepNode` // (see for example #48923). - assert!(!self.dep_graph.dep_node_exists(&dep_node), - "forcing query with already existing `DepNode`\n\ + assert!( + !self.dep_graph.dep_node_exists(&dep_node), + "forcing query with already existing `DepNode`\n\ - query-key: {:?}\n\ - dep-node: {:?}", - key, dep_node); + key, + dep_node + ); let prof_timer = self.prof.query_provider(Q::NAME); let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| { self.start_query(job.job.clone(), diagnostics, |tcx| { if Q::EVAL_ALWAYS { - tcx.dep_graph.with_eval_always_task(dep_node, - tcx, - key, - Q::compute, - Q::hash_result) + tcx.dep_graph.with_eval_always_task( + dep_node, + tcx, + key, + Q::compute, + Q::hash_result, + ) } else { - tcx.dep_graph.with_task(dep_node, - tcx, - key, - Q::compute, - Q::hash_result) + tcx.dep_graph.with_task(dep_node, tcx, key, Q::compute, Q::hash_result) } }) }); @@ -558,8 +549,7 @@ impl<'tcx> TyCtxt<'tcx> { if unlikely!(!diagnostics.is_empty()) { if dep_node.kind != crate::dep_graph::DepKind::Null { - self.queries.on_disk_cache - .store_diagnostics(dep_node_index, diagnostics); + self.queries.on_disk_cache.store_diagnostics(dep_node_index, diagnostics); } } @@ -606,10 +596,7 @@ impl<'tcx> TyCtxt<'tcx> { // Ensure that only one of them runs the query. let job = match JobOwner::try_get(self, span, &key) { TryGetJob::NotYetStarted(job) => job, - TryGetJob::Cycle(_) | - TryGetJob::JobCompleted(_) => { - return - } + TryGetJob::Cycle(_) | TryGetJob::JobCompleted(_) => return, }; self.force_query_with_job::(key, job, dep_node); } @@ -1110,7 +1097,6 @@ macro_rules! define_provider_struct { }; } - /// The red/green evaluation system will try to mark a specific DepNode in the /// dependency graph as green by recursively trying to mark the dependencies of /// that `DepNode` as green. While doing so, it will sometimes encounter a `DepNode` @@ -1169,11 +1155,13 @@ pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool { // each CGU, right after partitioning. This way `try_mark_green` will always // hit the cache instead of having to go through `force_from_dep_node`. // This assertion makes sure, we actually keep applying the solution above. - debug_assert!(dep_node.kind != DepKind::codegen_unit, - "calling force_from_dep_node() on DepKind::codegen_unit"); + debug_assert!( + dep_node.kind != DepKind::codegen_unit, + "calling force_from_dep_node() on DepKind::codegen_unit" + ); if !dep_node.kind.can_reconstruct_query_key() { - return false + return false; } rustc_dep_node_force!([dep_node, tcx] diff --git a/src/librustc/ty/query/values.rs b/src/librustc/ty/query/values.rs index f0d1639f72f59..65298ed65d197 100644 --- a/src/librustc/ty/query/values.rs +++ b/src/librustc/ty/query/values.rs @@ -1,5 +1,5 @@ -use crate::ty::{self, Ty, TyCtxt, AdtSizedConstraint}; use crate::ty::util::NeedsDrop; +use crate::ty::{self, AdtSizedConstraint, Ty, TyCtxt}; use syntax::symbol::Symbol; diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 15b14c51c7843..933358dce018b 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -4,16 +4,16 @@ //! types or regions but can be other things. Examples of type relations are //! subtyping, type equality, etc. +use crate::hir as ast; use crate::hir::def_id::DefId; +use crate::mir::interpret::{get_slice_bytes, ConstValue}; +use crate::traits; +use crate::ty::error::{ExpectedFound, TypeError}; use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; -use crate::ty::error::{ExpectedFound, TypeError}; -use crate::mir::interpret::{ConstValue, get_slice_bytes}; -use std::rc::Rc; -use std::iter; use rustc_target::spec::abi; -use crate::hir as ast; -use crate::traits; +use std::iter; +use std::rc::Rc; pub type RelateResult<'tcx, T> = Result>; @@ -34,8 +34,9 @@ pub trait TypeRelation<'tcx>: Sized { /// relation. Just affects error messages. fn a_is_expected(&self) -> bool; - fn with_cause(&mut self, _cause: Cause, f: F) -> R - where F: FnOnce(&mut Self) -> R + fn with_cause(&mut self, _cause: Cause, f: F) -> R + where + F: FnOnce(&mut Self) -> R, { f(self) } @@ -48,27 +49,28 @@ pub trait TypeRelation<'tcx>: Sized { /// Relate the two substitutions for the given item. The default /// is to look up the variance for the item and proceed /// accordingly. - fn relate_item_substs(&mut self, - item_def_id: DefId, - a_subst: SubstsRef<'tcx>, - b_subst: SubstsRef<'tcx>) - -> RelateResult<'tcx, SubstsRef<'tcx>> - { - debug!("relate_item_substs(item_def_id={:?}, a_subst={:?}, b_subst={:?})", - item_def_id, - a_subst, - b_subst); + fn relate_item_substs( + &mut self, + item_def_id: DefId, + a_subst: SubstsRef<'tcx>, + b_subst: SubstsRef<'tcx>, + ) -> RelateResult<'tcx, SubstsRef<'tcx>> { + debug!( + "relate_item_substs(item_def_id={:?}, a_subst={:?}, b_subst={:?})", + item_def_id, a_subst, b_subst + ); let opt_variances = self.tcx().variances_of(item_def_id); relate_substs(self, Some(opt_variances), a_subst, b_subst) } /// Switch variance for the purpose of relating `a` and `b`. - fn relate_with_variance>(&mut self, - variance: ty::Variance, - a: &T, - b: &T) - -> RelateResult<'tcx, T>; + fn relate_with_variance>( + &mut self, + variance: ty::Variance, + a: &T, + b: &T, + ) -> RelateResult<'tcx, T>; // Overrideable relations. You shouldn't typically call these // directly, instead call `relate()`, which in turn calls @@ -81,18 +83,22 @@ pub trait TypeRelation<'tcx>: Sized { fn regions( &mut self, a: ty::Region<'tcx>, - b: ty::Region<'tcx> + b: ty::Region<'tcx>, ) -> RelateResult<'tcx, ty::Region<'tcx>>; fn consts( &mut self, a: &'tcx ty::Const<'tcx>, - b: &'tcx ty::Const<'tcx> + b: &'tcx ty::Const<'tcx>, ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>; - fn binders(&mut self, a: &ty::Binder, b: &ty::Binder) - -> RelateResult<'tcx, ty::Binder> - where T: Relate<'tcx>; + fn binders( + &mut self, + a: &ty::Binder, + b: &ty::Binder, + ) -> RelateResult<'tcx, ty::Binder> + where + T: Relate<'tcx>; } pub trait Relate<'tcx>: TypeFoldable<'tcx> { @@ -112,10 +118,7 @@ impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> { a: &ty::TypeAndMut<'tcx>, b: &ty::TypeAndMut<'tcx>, ) -> RelateResult<'tcx, ty::TypeAndMut<'tcx>> { - debug!("{}.mts({:?}, {:?})", - relation.tag(), - a, - b); + debug!("{}.mts({:?}, {:?})", relation.tag(), a, b); if a.mutbl != b.mutbl { Err(TypeError::Mutability) } else { @@ -155,8 +158,11 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { let tcx = relation.tcx(); if a.c_variadic != b.c_variadic { - return Err(TypeError::VariadicMismatch( - expected_found(relation, &a.c_variadic, &b.c_variadic))); + return Err(TypeError::VariadicMismatch(expected_found( + relation, + &a.c_variadic, + &b.c_variadic, + ))); } let unsafety = relation.relate(&a.unsafety, &b.unsafety)?; let abi = relation.relate(&a.abi, &b.abi)?; @@ -165,7 +171,10 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { return Err(TypeError::ArgCount); } - let inputs_and_output = a.inputs().iter().cloned() + let inputs_and_output = a + .inputs() + .iter() + .cloned() .zip(b.inputs().iter().cloned()) .map(|x| (x, false)) .chain(iter::once(((a.output(), b.output()), true))) @@ -205,11 +214,7 @@ impl<'tcx> Relate<'tcx> for abi::Abi { a: &abi::Abi, b: &abi::Abi, ) -> RelateResult<'tcx, abi::Abi> { - if a == b { - Ok(*a) - } else { - Err(TypeError::AbiMismatch(expected_found(relation, a, b))) - } + if a == b { Ok(*a) } else { Err(TypeError::AbiMismatch(expected_found(relation, a, b))) } } } @@ -220,14 +225,14 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionTy<'tcx> { b: &ty::ProjectionTy<'tcx>, ) -> RelateResult<'tcx, ty::ProjectionTy<'tcx>> { if a.item_def_id != b.item_def_id { - Err(TypeError::ProjectionMismatched( - expected_found(relation, &a.item_def_id, &b.item_def_id))) + Err(TypeError::ProjectionMismatched(expected_found( + relation, + &a.item_def_id, + &b.item_def_id, + ))) } else { let substs = relation.relate(&a.substs, &b.substs)?; - Ok(ty::ProjectionTy { - item_def_id: a.item_def_id, - substs: &substs, - }) + Ok(ty::ProjectionTy { item_def_id: a.item_def_id, substs: &substs }) } } } @@ -239,16 +244,15 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> { b: &ty::ExistentialProjection<'tcx>, ) -> RelateResult<'tcx, ty::ExistentialProjection<'tcx>> { if a.item_def_id != b.item_def_id { - Err(TypeError::ProjectionMismatched( - expected_found(relation, &a.item_def_id, &b.item_def_id))) + Err(TypeError::ProjectionMismatched(expected_found( + relation, + &a.item_def_id, + &b.item_def_id, + ))) } else { let ty = relation.relate(&a.ty, &b.ty)?; let substs = relation.relate(&a.substs, &b.substs)?; - Ok(ty::ExistentialProjection { - item_def_id: a.item_def_id, - substs, - ty, - }) + Ok(ty::ExistentialProjection { item_def_id: a.item_def_id, substs, ty }) } } } @@ -267,10 +271,7 @@ impl<'tcx> Relate<'tcx> for Vec> { if a.len() != b.len() { Err(TypeError::ProjectionBoundsLength(expected_found(relation, &a.len(), &b.len()))) } else { - a.iter() - .zip(b) - .map(|(a, b)| relation.relate(a, b)) - .collect() + a.iter().zip(b).map(|(a, b)| relation.relate(a, b)).collect() } } } @@ -344,9 +345,7 @@ pub fn super_relate_tys>( let tcx = relation.tcx(); debug!("super_relate_tys: a={:?} b={:?}", a, b); match (&a.kind, &b.kind) { - (&ty::Infer(_), _) | - (_, &ty::Infer(_)) => - { + (&ty::Infer(_), _) | (_, &ty::Infer(_)) => { // The caller should handle these cases! bug!("var types encountered in super_relate_tys") } @@ -355,59 +354,39 @@ pub fn super_relate_tys>( bug!("bound types encountered in super_relate_tys") } - (&ty::Error, _) | (_, &ty::Error) => - { - Ok(tcx.types.err) - } + (&ty::Error, _) | (_, &ty::Error) => Ok(tcx.types.err), - (&ty::Never, _) | - (&ty::Char, _) | - (&ty::Bool, _) | - (&ty::Int(_), _) | - (&ty::Uint(_), _) | - (&ty::Float(_), _) | - (&ty::Str, _) + (&ty::Never, _) + | (&ty::Char, _) + | (&ty::Bool, _) + | (&ty::Int(_), _) + | (&ty::Uint(_), _) + | (&ty::Float(_), _) + | (&ty::Str, _) if a == b => { Ok(a) } - (&ty::Param(ref a_p), &ty::Param(ref b_p)) - if a_p.index == b_p.index => - { - Ok(a) - } + (&ty::Param(ref a_p), &ty::Param(ref b_p)) if a_p.index == b_p.index => Ok(a), - (ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => { - Ok(a) - } + (ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => Ok(a), - (&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs)) - if a_def == b_def => - { + (&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs)) if a_def == b_def => { let substs = relation.relate_item_substs(a_def.did, a_substs, b_substs)?; Ok(tcx.mk_adt(a_def, substs)) } - (&ty::Foreign(a_id), &ty::Foreign(b_id)) - if a_id == b_id => - { - Ok(tcx.mk_foreign(a_id)) - } + (&ty::Foreign(a_id), &ty::Foreign(b_id)) if a_id == b_id => Ok(tcx.mk_foreign(a_id)), (&ty::Dynamic(ref a_obj, ref a_region), &ty::Dynamic(ref b_obj, ref b_region)) => { - let region_bound = relation.with_cause(Cause::ExistentialRegionBound, - |relation| { - relation.relate_with_variance( - ty::Contravariant, - a_region, - b_region) - })?; + let region_bound = relation.with_cause(Cause::ExistentialRegionBound, |relation| { + relation.relate_with_variance(ty::Contravariant, a_region, b_region) + })?; Ok(tcx.mk_dynamic(relation.relate(a_obj, b_obj)?, region_bound)) } - (&ty::Generator(a_id, a_substs, movability), - &ty::Generator(b_id, b_substs, _)) + (&ty::Generator(a_id, a_substs, movability), &ty::Generator(b_id, b_substs, _)) if a_id == b_id => { // All Generator types with the same id represent @@ -417,8 +396,7 @@ pub fn super_relate_tys>( Ok(tcx.mk_generator(a_id, substs, movability)) } - (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => - { + (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => { // Wrap our types with a temporary GeneratorWitness struct // inside the binder so we can related them let a_types = a_types.map_bound(GeneratorWitness); @@ -428,10 +406,7 @@ pub fn super_relate_tys>( Ok(tcx.mk_generator_witness(types)) } - (&ty::Closure(a_id, a_substs), - &ty::Closure(b_id, b_substs)) - if a_id == b_id => - { + (&ty::Closure(a_id, a_substs), &ty::Closure(b_id, b_substs)) if a_id == b_id => { // All Closure types with the same id represent // the (anonymous) type of the same closure expression. So // all of their regions should be equated. @@ -439,14 +414,12 @@ pub fn super_relate_tys>( Ok(tcx.mk_closure(a_id, &substs)) } - (&ty::RawPtr(ref a_mt), &ty::RawPtr(ref b_mt)) => - { + (&ty::RawPtr(ref a_mt), &ty::RawPtr(ref b_mt)) => { let mt = relation.relate(a_mt, b_mt)?; Ok(tcx.mk_ptr(mt)) } - (&ty::Ref(a_r, a_ty, a_mutbl), &ty::Ref(b_r, b_ty, b_mutbl)) => - { + (&ty::Ref(a_r, a_ty, a_mutbl), &ty::Ref(b_r, b_ty, b_mutbl)) => { let r = relation.relate_with_variance(ty::Contravariant, &a_r, &b_r)?; let a_mt = ty::TypeAndMut { ty: a_ty, mutbl: a_mutbl }; let b_mt = ty::TypeAndMut { ty: b_ty, mutbl: b_mutbl }; @@ -454,8 +427,7 @@ pub fn super_relate_tys>( Ok(tcx.mk_ref(r, mt)) } - (&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) => - { + (&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) => { let t = relation.relate(&a_t, &b_t)?; match relation.relate(&sz_a, &sz_b) { Ok(sz) => Ok(tcx.mk_ty(ty::Array(t, sz))), @@ -465,32 +437,29 @@ pub fn super_relate_tys>( let sz_a = sz_a.try_eval_usize(tcx, relation.param_env()); let sz_b = sz_b.try_eval_usize(tcx, relation.param_env()); match (sz_a, sz_b) { - (Some(sz_a_val), Some(sz_b_val)) => { - Err(TypeError::FixedArraySize( - expected_found(relation, &sz_a_val, &sz_b_val) - )) - } + (Some(sz_a_val), Some(sz_b_val)) => Err(TypeError::FixedArraySize( + expected_found(relation, &sz_a_val, &sz_b_val), + )), _ => return Err(err), } } } } - (&ty::Slice(a_t), &ty::Slice(b_t)) => - { + (&ty::Slice(a_t), &ty::Slice(b_t)) => { let t = relation.relate(&a_t, &b_t)?; Ok(tcx.mk_slice(t)) } - (&ty::Tuple(as_), &ty::Tuple(bs)) => - { + (&ty::Tuple(as_), &ty::Tuple(bs)) => { if as_.len() == bs.len() { - Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| { - relation.relate(&a.expect_ty(), &b.expect_ty()) - }))?) + Ok(tcx.mk_tup( + as_.iter() + .zip(bs) + .map(|(a, b)| relation.relate(&a.expect_ty(), &b.expect_ty())), + )?) } else if !(as_.is_empty() || bs.is_empty()) { - Err(TypeError::TupleSize( - expected_found(relation, &as_.len(), &bs.len()))) + Err(TypeError::TupleSize(expected_found(relation, &as_.len(), &bs.len()))) } else { Err(TypeError::Sorts(expected_found(relation, &a, &b))) } @@ -503,8 +472,7 @@ pub fn super_relate_tys>( Ok(tcx.mk_fn_def(a_def_id, substs)) } - (&ty::FnPtr(a_fty), &ty::FnPtr(b_fty)) => - { + (&ty::FnPtr(a_fty), &ty::FnPtr(b_fty)) => { let fty = relation.relate(&a_fty, &b_fty)?; Ok(tcx.mk_fn_ptr(fty)) } @@ -527,10 +495,7 @@ pub fn super_relate_tys>( Ok(tcx.mk_opaque(a_def_id, substs)) } - _ => - { - Err(TypeError::Sorts(expected_found(relation, &a, &b))) - } + _ => Err(TypeError::Sorts(expected_found(relation, &a, &b))), } } @@ -595,26 +560,24 @@ pub fn super_relate_consts>( } // FIXME(const_generics): handle `ConstValue::ByRef`. - - _ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))), + _ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))), }; new_val.map(ty::ConstKind::Value) - }, + } // FIXME(const_generics): this is wrong, as it is a projection - (ty::ConstKind::Unevaluated(a_def_id, a_substs), - ty::ConstKind::Unevaluated(b_def_id, b_substs)) if a_def_id == b_def_id => { + ( + ty::ConstKind::Unevaluated(a_def_id, a_substs), + ty::ConstKind::Unevaluated(b_def_id, b_substs), + ) if a_def_id == b_def_id => { let substs = relation.relate_with_variance(ty::Variance::Invariant, &a_substs, &b_substs)?; Ok(ty::ConstKind::Unevaluated(a_def_id, &substs)) } - _ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))), + _ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))), }; - new_const_val.map(|val| tcx.mk_const(ty::Const { - val, - ty: a.ty, - })) + new_const_val.map(|val| tcx.mk_const(ty::Const { val, ty: a.ty })) } impl<'tcx> Relate<'tcx> for &'tcx ty::List> { @@ -634,7 +597,7 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List> { (Trait(ref a), Trait(ref b)) => Ok(Trait(relation.relate(a, b)?)), (Projection(ref a), Projection(ref b)) => Ok(Projection(relation.relate(a, b)?)), (AutoTrait(ref a), AutoTrait(ref b)) if a == b => Ok(AutoTrait(*a)), - _ => Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))) + _ => Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))), } }); Ok(tcx.mk_existential_predicates(v)?) @@ -762,9 +725,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> { a: &ty::TraitPredicate<'tcx>, b: &ty::TraitPredicate<'tcx>, ) -> RelateResult<'tcx, ty::TraitPredicate<'tcx>> { - Ok(ty::TraitPredicate { - trait_ref: relation.relate(&a.trait_ref, &b.trait_ref)?, - }) + Ok(ty::TraitPredicate { trait_ref: relation.relate(&a.trait_ref, &b.trait_ref)? }) } } @@ -811,7 +772,7 @@ impl<'tcx> Relate<'tcx> for traits::WhereClause<'tcx> { ))) } - _ => Err(TypeError::Mismatch), + _ => Err(TypeError::Mismatch), } } } @@ -826,7 +787,7 @@ impl<'tcx> Relate<'tcx> for traits::WellFormed<'tcx> { match (a, b) { (Trait(a_pred), Trait(b_pred)) => Ok(Trait(relation.relate(a_pred, b_pred)?)), (Ty(a_ty), Ty(b_ty)) => Ok(Ty(relation.relate(a_ty, b_ty)?)), - _ => Err(TypeError::Mismatch), + _ => Err(TypeError::Mismatch), } } } @@ -841,7 +802,7 @@ impl<'tcx> Relate<'tcx> for traits::FromEnv<'tcx> { match (a, b) { (Trait(a_pred), Trait(b_pred)) => Ok(Trait(relation.relate(a_pred, b_pred)?)), (Ty(a_ty), Ty(b_ty)) => Ok(Ty(relation.relate(a_ty, b_ty)?)), - _ => Err(TypeError::Mismatch), + _ => Err(TypeError::Mismatch), } } } @@ -862,7 +823,7 @@ impl<'tcx> Relate<'tcx> for traits::DomainGoal<'tcx> { Ok(Normalize(relation.relate(a_pred, b_pred)?)) } - _ => Err(TypeError::Mismatch), + _ => Err(TypeError::Mismatch), } } } @@ -897,9 +858,7 @@ impl<'tcx> Relate<'tcx> for traits::Goal<'tcx> { Ok(relation.tcx().mk_goal(DomainGoal(goal))) } - (Quantified(a_qkind, a_goal), Quantified(b_qkind, b_goal)) - if a_qkind == b_qkind => - { + (Quantified(a_qkind, a_goal), Quantified(b_qkind, b_goal)) if a_qkind == b_qkind => { let goal = relation.relate(a_goal, b_goal)?; Ok(relation.tcx().mk_goal(Quantified(*a_qkind, goal))) } @@ -986,9 +945,7 @@ impl<'tcx> Relate<'tcx> for traits::Environment<'tcx> { a: &traits::Environment<'tcx>, b: &traits::Environment<'tcx>, ) -> RelateResult<'tcx, traits::Environment<'tcx>> { - Ok(traits::Environment { - clauses: relation.relate(&a.clauses, &b.clauses)?, - }) + Ok(traits::Environment { clauses: relation.relate(&a.clauses, &b.clauses)? }) } } @@ -1019,17 +976,15 @@ where expected_found_bool(relation.a_is_expected(), a, b) } -pub fn expected_found_bool(a_is_expected: bool, - a: &T, - b: &T) - -> ExpectedFound - where T: Clone +pub fn expected_found_bool(a_is_expected: bool, a: &T, b: &T) -> ExpectedFound +where + T: Clone, { let a = a.clone(); let b = b.clone(); if a_is_expected { - ExpectedFound {expected: a, found: b} + ExpectedFound { expected: a, found: b } } else { - ExpectedFound {expected: b, found: a} + ExpectedFound { expected: b, found: a } } } diff --git a/src/librustc/ty/steal.rs b/src/librustc/ty/steal.rs index 711e59dbcc9d2..224e76845d708 100644 --- a/src/librustc/ty/steal.rs +++ b/src/librustc/ty/steal.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::sync::{RwLock, ReadGuard, MappedReadGuard}; +use rustc_data_structures::sync::{MappedReadGuard, ReadGuard, RwLock}; /// The `Steal` struct is intended to used as the value for a query. /// Specifically, we sometimes have queries (*cough* MIR *cough*) @@ -21,20 +21,18 @@ use rustc_data_structures::sync::{RwLock, ReadGuard, MappedReadGuard}; // // FIXME(#41710): what is the best way to model linear queries? pub struct Steal { - value: RwLock> + value: RwLock>, } impl Steal { pub fn new(value: T) -> Self { - Steal { - value: RwLock::new(Some(value)) - } + Steal { value: RwLock::new(Some(value)) } } pub fn borrow(&self) -> MappedReadGuard<'_, T> { ReadGuard::map(self.value.borrow(), |opt| match *opt { None => bug!("attempted to read from stolen value"), - Some(ref v) => v + Some(ref v) => v, }) } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index ce76a4c831b58..61ee7288a9bdf 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -4,13 +4,13 @@ use crate::hir::def::Namespace; use crate::hir::def_id::CRATE_DEF_INDEX; -use crate::mir::ProjectionKind; use crate::mir::interpret; -use crate::ty::{self, Lift, Ty, TyCtxt, InferConst}; +use crate::mir::ProjectionKind; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::print::{FmtPrinter, Printer}; +use crate::ty::{self, InferConst, Lift, Ty, TyCtxt}; -use rustc_index::vec::{IndexVec, Idx}; +use rustc_index::vec::{Idx, IndexVec}; use smallvec::SmallVec; use std::fmt; @@ -21,22 +21,17 @@ impl fmt::Debug for ty::GenericParamDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let type_name = match self.kind { ty::GenericParamDefKind::Lifetime => "Lifetime", - ty::GenericParamDefKind::Type {..} => "Type", + ty::GenericParamDefKind::Type { .. } => "Type", ty::GenericParamDefKind::Const => "Const", }; - write!(f, "{}({}, {:?}, {})", - type_name, - self.name, - self.def_id, - self.index) + write!(f, "{}({}, {:?}, {})", type_name, self.name, self.def_id, self.index) } } impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ty::tls::with(|tcx| { - FmtPrinter::new(tcx, f, Namespace::TypeNS) - .print_def_path(self.def_id, &[])?; + FmtPrinter::new(tcx, f, Namespace::TypeNS).print_def_path(self.def_id, &[])?; Ok(()) }) } @@ -45,8 +40,7 @@ impl fmt::Debug for ty::TraitDef { impl fmt::Debug for ty::AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ty::tls::with(|tcx| { - FmtPrinter::new(tcx, f, Namespace::TypeNS) - .print_def_path(self.did, &[])?; + FmtPrinter::new(tcx, f, Namespace::TypeNS).print_def_path(self.did, &[])?; Ok(()) }) } @@ -54,28 +48,20 @@ impl fmt::Debug for ty::AdtDef { impl fmt::Debug for ty::ClosureUpvar<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ClosureUpvar({:?},{:?})", - self.res, - self.ty) + write!(f, "ClosureUpvar({:?},{:?})", self.res, self.ty) } } impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let name = ty::tls::with(|tcx| { - tcx.hir().name(self.var_path.hir_id) - }); - write!(f, "UpvarId({:?};`{}`;{:?})", - self.var_path.hir_id, - name, - self.closure_expr_id) + let name = ty::tls::with(|tcx| tcx.hir().name(self.var_path.hir_id)); + write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, name, self.closure_expr_id) } } impl fmt::Debug for ty::UpvarBorrow<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "UpvarBorrow({:?}, {:?})", - self.kind, self.region) + write!(f, "UpvarBorrow({:?}, {:?})", self.kind, self.region) } } @@ -110,15 +96,9 @@ impl fmt::Debug for ty::BoundRegion { impl fmt::Debug for ty::RegionKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - ty::ReEarlyBound(ref data) => { - write!(f, "ReEarlyBound({}, {})", - data.index, - data.name) - } + ty::ReEarlyBound(ref data) => write!(f, "ReEarlyBound({}, {})", data.index, data.name), - ty::ReClosureBound(ref vid) => { - write!(f, "ReClosureBound({:?})", vid) - } + ty::ReClosureBound(ref vid) => write!(f, "ReClosureBound({:?})", vid), ty::ReLateBound(binder_id, ref bound_region) => { write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region) @@ -132,9 +112,7 @@ impl fmt::Debug for ty::RegionKind { ty::ReVar(ref vid) => vid.fmt(f), - ty::RePlaceholder(placeholder) => { - write!(f, "RePlaceholder({:?})", placeholder) - } + ty::RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder), ty::ReEmpty => write!(f, "ReEmpty"), @@ -162,8 +140,7 @@ impl fmt::Debug for ty::Variance { impl fmt::Debug for ty::FnSig<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "({:?}; c_variadic: {})->{:?}", - self.inputs(), self.c_variadic, self.output()) + write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output()) } } @@ -270,12 +247,9 @@ impl fmt::Debug for ty::Predicate<'tcx> { ty::Predicate::TypeOutlives(ref pair) => pair.fmt(f), ty::Predicate::Projection(ref pair) => pair.fmt(f), ty::Predicate::WellFormed(ty) => write!(f, "WellFormed({:?})", ty), - ty::Predicate::ObjectSafe(trait_def_id) => { - write!(f, "ObjectSafe({:?})", trait_def_id) - } + ty::Predicate::ObjectSafe(trait_def_id) => write!(f, "ObjectSafe({:?})", trait_def_id), ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { - write!(f, "ClosureKind({:?}, {:?}, {:?})", - closure_def_id, closure_substs, kind) + write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind) } ty::Predicate::ConstEvaluatable(def_id, substs) => { write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs) @@ -346,10 +320,9 @@ impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) { impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) { type Lifted = (A::Lifted, B::Lifted, C::Lifted); fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.0).and_then(|a| { - tcx.lift(&self.1).and_then(|b| tcx.lift(&self.2).map(|c| (a, b, c))) - }) - } + tcx.lift(&self.0) + .and_then(|a| tcx.lift(&self.1).and_then(|b| tcx.lift(&self.2).map(|c| (a, b, c)))) + } } impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option { @@ -357,7 +330,7 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option { fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { match *self { Some(ref x) => tcx.lift(x).map(Some), - None => Some(None) + None => Some(None), } } } @@ -367,7 +340,7 @@ impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result { fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { match *self { Ok(ref x) => tcx.lift(x).map(Ok), - Err(ref e) => tcx.lift(e).map(Err) + Err(ref e) => tcx.lift(e).map(Err), } } } @@ -397,8 +370,7 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] { type Lifted = Vec; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { // type annotation needed to inform `projection_must_outlive` - let mut result : Vec<>::Lifted> - = Vec::with_capacity(self.len()); + let mut result: Vec<>::Lifted> = Vec::with_capacity(self.len()); for x in self { if let Some(value) = tcx.lift(x) { result.push(value); @@ -420,29 +392,21 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec { impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec { type Lifted = IndexVec; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - self.iter() - .map(|e| tcx.lift(e)) - .collect() + self.iter().map(|e| tcx.lift(e)).collect() } } impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> { type Lifted = ty::TraitRef<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.substs).map(|substs| ty::TraitRef { - def_id: self.def_id, - substs, - }) + tcx.lift(&self.substs).map(|substs| ty::TraitRef { def_id: self.def_id, substs }) } } impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> { type Lifted = ty::ExistentialTraitRef<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.substs).map(|substs| ty::ExistentialTraitRef { - def_id: self.def_id, - substs, - }) + tcx.lift(&self.substs).map(|substs| ty::ExistentialTraitRef { def_id: self.def_id, substs }) } } @@ -450,9 +414,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> { type Lifted = ty::ExistentialPredicate<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { match self { - ty::ExistentialPredicate::Trait(x) => { - tcx.lift(x).map(ty::ExistentialPredicate::Trait) - } + ty::ExistentialPredicate::Trait(x) => tcx.lift(x).map(ty::ExistentialPredicate::Trait), ty::ExistentialPredicate::Projection(x) => { tcx.lift(x).map(ty::ExistentialPredicate::Projection) } @@ -466,9 +428,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> { impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> { type Lifted = ty::TraitPredicate<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option> { - tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate { - trait_ref, - }) + tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate { trait_ref }) } } @@ -493,36 +453,26 @@ impl<'tcx, A: Copy + Lift<'tcx>, B: Copy + Lift<'tcx>> Lift<'tcx> for ty::Outliv impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> { type Lifted = ty::ProjectionTy<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option> { - tcx.lift(&self.substs).map(|substs| { - ty::ProjectionTy { - item_def_id: self.item_def_id, - substs, - } - }) + tcx.lift(&self.substs) + .map(|substs| ty::ProjectionTy { item_def_id: self.item_def_id, substs }) } } impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> { type Lifted = ty::ProjectionPredicate<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option> { - tcx.lift(&(self.projection_ty, self.ty)).map(|(projection_ty, ty)| { - ty::ProjectionPredicate { - projection_ty, - ty, - } - }) + tcx.lift(&(self.projection_ty, self.ty)) + .map(|(projection_ty, ty)| ty::ProjectionPredicate { projection_ty, ty }) } } impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> { type Lifted = ty::ExistentialProjection<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.substs).map(|substs| { - ty::ExistentialProjection { - substs, - ty: tcx.lift(&self.ty).expect("type must lift when substs do"), - item_def_id: self.item_def_id, - } + tcx.lift(&self.substs).map(|substs| ty::ExistentialProjection { + substs, + ty: tcx.lift(&self.ty).expect("type must lift when substs do"), + item_def_id: self.item_def_id, }) } } @@ -531,12 +481,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> { type Lifted = ty::Predicate<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { match *self { - ty::Predicate::Trait(ref binder) => { - tcx.lift(binder).map(ty::Predicate::Trait) - } - ty::Predicate::Subtype(ref binder) => { - tcx.lift(binder).map(ty::Predicate::Subtype) - } + ty::Predicate::Trait(ref binder) => tcx.lift(binder).map(ty::Predicate::Trait), + ty::Predicate::Subtype(ref binder) => tcx.lift(binder).map(ty::Predicate::Subtype), ty::Predicate::RegionOutlives(ref binder) => { tcx.lift(binder).map(ty::Predicate::RegionOutlives) } @@ -546,22 +492,17 @@ impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> { ty::Predicate::Projection(ref binder) => { tcx.lift(binder).map(ty::Predicate::Projection) } - ty::Predicate::WellFormed(ty) => { - tcx.lift(&ty).map(ty::Predicate::WellFormed) - } + ty::Predicate::WellFormed(ty) => tcx.lift(&ty).map(ty::Predicate::WellFormed), ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { - tcx.lift(&closure_substs) - .map(|closure_substs| ty::Predicate::ClosureKind(closure_def_id, - closure_substs, - kind)) + tcx.lift(&closure_substs).map(|closure_substs| { + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) + }) } ty::Predicate::ObjectSafe(trait_def_id) => { Some(ty::Predicate::ObjectSafe(trait_def_id)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { - tcx.lift(&substs).map(|substs| { - ty::Predicate::ConstEvaluatable(def_id, substs) - }) + tcx.lift(&substs).map(|substs| ty::Predicate::ConstEvaluatable(def_id, substs)) } } } @@ -577,12 +518,10 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder { impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { type Lifted = ty::ParamEnv<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.caller_bounds).map(|caller_bounds| { - ty::ParamEnv { - reveal: self.reveal, - caller_bounds, - def_id: self.def_id, - } + tcx.lift(&self.caller_bounds).map(|caller_bounds| ty::ParamEnv { + reveal: self.reveal, + caller_bounds, + def_id: self.def_id, }) } } @@ -591,12 +530,7 @@ impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> { type Lifted = ty::ParamEnvAnd<'tcx, T::Lifted>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { tcx.lift(&self.param_env).and_then(|param_env| { - tcx.lift(&self.value).map(|value| { - ty::ParamEnvAnd { - param_env, - value, - } - }) + tcx.lift(&self.value).map(|value| ty::ParamEnvAnd { param_env, value }) }) } } @@ -604,18 +538,14 @@ impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> { impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> { type Lifted = ty::ClosureSubsts<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.substs).map(|substs| { - ty::ClosureSubsts { substs } - }) + tcx.lift(&self.substs).map(|substs| ty::ClosureSubsts { substs }) } } impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> { type Lifted = ty::GeneratorSubsts<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.substs).map(|substs| { - ty::GeneratorSubsts { substs } - }) + tcx.lift(&self.substs).map(|substs| ty::GeneratorSubsts { substs }) } } @@ -623,9 +553,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjustment<'a> { type Lifted = ty::adjustment::Adjustment<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { tcx.lift(&self.kind).and_then(|kind| { - tcx.lift(&self.target).map(|target| { - ty::adjustment::Adjustment { kind, target } - }) + tcx.lift(&self.target).map(|target| ty::adjustment::Adjustment { kind, target }) }) } } @@ -634,10 +562,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> { type Lifted = ty::adjustment::Adjust<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { match *self { - ty::adjustment::Adjust::NeverToAny => - Some(ty::adjustment::Adjust::NeverToAny), - ty::adjustment::Adjust::Pointer(ptr) => - Some(ty::adjustment::Adjust::Pointer(ptr)), + ty::adjustment::Adjust::NeverToAny => Some(ty::adjustment::Adjust::NeverToAny), + ty::adjustment::Adjust::Pointer(ptr) => Some(ty::adjustment::Adjust::Pointer(ptr)), ty::adjustment::Adjust::Deref(ref overloaded) => { tcx.lift(overloaded).map(ty::adjustment::Adjust::Deref) } @@ -651,12 +577,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> { impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::OverloadedDeref<'a> { type Lifted = ty::adjustment::OverloadedDeref<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.region).map(|region| { - ty::adjustment::OverloadedDeref { - region, - mutbl: self.mutbl, - } - }) + tcx.lift(&self.region) + .map(|region| ty::adjustment::OverloadedDeref { region, mutbl: self.mutbl }) } } @@ -667,9 +589,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> { ty::adjustment::AutoBorrow::Ref(r, m) => { tcx.lift(&r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m)) } - ty::adjustment::AutoBorrow::RawPtr(m) => { - Some(ty::adjustment::AutoBorrow::RawPtr(m)) - } + ty::adjustment::AutoBorrow::RawPtr(m) => Some(ty::adjustment::AutoBorrow::RawPtr(m)), } } } @@ -678,25 +598,18 @@ impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> { type Lifted = ty::GenSig<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { tcx.lift(&(self.yield_ty, self.return_ty)) - .map(|(yield_ty, return_ty)| { - ty::GenSig { - yield_ty, - return_ty, - } - }) + .map(|(yield_ty, return_ty)| ty::GenSig { yield_ty, return_ty }) } } impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> { type Lifted = ty::FnSig<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - tcx.lift(&self.inputs_and_output).map(|x| { - ty::FnSig { - inputs_and_output: x, - c_variadic: self.c_variadic, - unsafety: self.unsafety, - abi: self.abi, - } + tcx.lift(&self.inputs_and_output).map(|x| ty::FnSig { + inputs_and_output: x, + c_variadic: self.c_variadic, + unsafety: self.unsafety, + abi: self.abi, }) } } @@ -705,12 +618,7 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound { type Lifted = ty::error::ExpectedFound; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { tcx.lift(&self.expected).and_then(|expected| { - tcx.lift(&self.found).map(|found| { - ty::error::ExpectedFound { - expected, - found, - } - }) + tcx.lift(&self.found).map(|found| ty::error::ExpectedFound { expected, found }) }) } } @@ -729,13 +637,13 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { FixedArraySize(x) => FixedArraySize(x), ArgCount => ArgCount, RegionsDoesNotOutlive(a, b) => { - return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b)) + return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b)); } RegionsInsufficientlyPolymorphic(a, b) => { - return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b)) + return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b)); } RegionsOverlyPolymorphic(a, b) => { - return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b)) + return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b)); } RegionsPlaceholderMismatch => RegionsPlaceholderMismatch, IntMismatch(x) => IntMismatch(x), @@ -758,24 +666,23 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> { type Lifted = ty::InstanceDef<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { match *self { - ty::InstanceDef::Item(def_id) => - Some(ty::InstanceDef::Item(def_id)), - ty::InstanceDef::VtableShim(def_id) => - Some(ty::InstanceDef::VtableShim(def_id)), - ty::InstanceDef::ReifyShim(def_id) => - Some(ty::InstanceDef::ReifyShim(def_id)), - ty::InstanceDef::Intrinsic(def_id) => - Some(ty::InstanceDef::Intrinsic(def_id)), - ty::InstanceDef::FnPtrShim(def_id, ref ty) => - Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?)), - ty::InstanceDef::Virtual(def_id, n) => - Some(ty::InstanceDef::Virtual(def_id, n)), - ty::InstanceDef::ClosureOnceShim { call_once } => - Some(ty::InstanceDef::ClosureOnceShim { call_once }), - ty::InstanceDef::DropGlue(def_id, ref ty) => - Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?)), - ty::InstanceDef::CloneShim(def_id, ref ty) => - Some(ty::InstanceDef::CloneShim(def_id, tcx.lift(ty)?)), + ty::InstanceDef::Item(def_id) => Some(ty::InstanceDef::Item(def_id)), + ty::InstanceDef::VtableShim(def_id) => Some(ty::InstanceDef::VtableShim(def_id)), + ty::InstanceDef::ReifyShim(def_id) => Some(ty::InstanceDef::ReifyShim(def_id)), + ty::InstanceDef::Intrinsic(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)), + ty::InstanceDef::FnPtrShim(def_id, ref ty) => { + Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?)) + } + ty::InstanceDef::Virtual(def_id, n) => Some(ty::InstanceDef::Virtual(def_id, n)), + ty::InstanceDef::ClosureOnceShim { call_once } => { + Some(ty::InstanceDef::ClosureOnceShim { call_once }) + } + ty::InstanceDef::DropGlue(def_id, ref ty) => { + Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?)) + } + ty::InstanceDef::CloneShim(def_id, ref ty) => { + Some(ty::InstanceDef::CloneShim(def_id, tcx.lift(ty)?)) + } } } } @@ -938,53 +845,36 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { VtableShim(did) => VtableShim(did.fold_with(folder)), ReifyShim(did) => ReifyShim(did.fold_with(folder)), Intrinsic(did) => Intrinsic(did.fold_with(folder)), - FnPtrShim(did, ty) => FnPtrShim( - did.fold_with(folder), - ty.fold_with(folder), - ), - Virtual(did, i) => Virtual( - did.fold_with(folder), - i, - ), - ClosureOnceShim { call_once } => ClosureOnceShim { - call_once: call_once.fold_with(folder), - }, - DropGlue(did, ty) => DropGlue( - did.fold_with(folder), - ty.fold_with(folder), - ), - CloneShim(did, ty) => CloneShim( - did.fold_with(folder), - ty.fold_with(folder), - ), + FnPtrShim(did, ty) => FnPtrShim(did.fold_with(folder), ty.fold_with(folder)), + Virtual(did, i) => Virtual(did.fold_with(folder), i), + ClosureOnceShim { call_once } => { + ClosureOnceShim { call_once: call_once.fold_with(folder) } + } + DropGlue(did, ty) => DropGlue(did.fold_with(folder), ty.fold_with(folder)), + CloneShim(did, ty) => CloneShim(did.fold_with(folder), ty.fold_with(folder)), }, } } fn super_visit_with>(&self, visitor: &mut V) -> bool { use crate::ty::InstanceDef::*; - self.substs.visit_with(visitor) || - match self.def { - Item(did) | VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => { - did.visit_with(visitor) - }, - FnPtrShim(did, ty) | CloneShim(did, ty) => { - did.visit_with(visitor) || ty.visit_with(visitor) - }, - DropGlue(did, ty) => { - did.visit_with(visitor) || ty.visit_with(visitor) - }, - ClosureOnceShim { call_once } => call_once.visit_with(visitor), - } + self.substs.visit_with(visitor) + || match self.def { + Item(did) | VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => { + did.visit_with(visitor) + } + FnPtrShim(did, ty) | CloneShim(did, ty) => { + did.visit_with(visitor) || ty.visit_with(visitor) + } + DropGlue(did, ty) => did.visit_with(visitor) || ty.visit_with(visitor), + ClosureOnceShim { call_once } => call_once.visit_with(visitor), + } } } impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { - Self { - instance: self.instance.fold_with(folder), - promoted: self.promoted - } + Self { instance: self.instance.fold_with(folder), promoted: self.promoted } } fn super_visit_with>(&self, visitor: &mut V) -> bool { @@ -999,21 +889,15 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::Array(typ, sz) => ty::Array(typ.fold_with(folder), sz.fold_with(folder)), ty::Slice(typ) => ty::Slice(typ.fold_with(folder)), ty::Adt(tid, substs) => ty::Adt(tid, substs.fold_with(folder)), - ty::Dynamic(ref trait_ty, ref region) => - ty::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder)), - ty::Tuple(ts) => ty::Tuple(ts.fold_with(folder)), - ty::FnDef(def_id, substs) => { - ty::FnDef(def_id, substs.fold_with(folder)) + ty::Dynamic(ref trait_ty, ref region) => { + ty::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder)) } + ty::Tuple(ts) => ty::Tuple(ts.fold_with(folder)), + ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.fold_with(folder)), ty::FnPtr(f) => ty::FnPtr(f.fold_with(folder)), - ty::Ref(ref r, ty, mutbl) => { - ty::Ref(r.fold_with(folder), ty.fold_with(folder), mutbl) - } + ty::Ref(ref r, ty, mutbl) => ty::Ref(r.fold_with(folder), ty.fold_with(folder), mutbl), ty::Generator(did, substs, movability) => { - ty::Generator( - did, - substs.fold_with(folder), - movability) + ty::Generator(did, substs.fold_with(folder), movability) } ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)), ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)), @@ -1023,26 +907,22 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { } ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)), - ty::Bool | - ty::Char | - ty::Str | - ty::Int(_) | - ty::Uint(_) | - ty::Float(_) | - ty::Error | - ty::Infer(_) | - ty::Param(..) | - ty::Bound(..) | - ty::Placeholder(..) | - ty::Never | - ty::Foreign(..) => return self, + ty::Bool + | ty::Char + | ty::Str + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Error + | ty::Infer(_) + | ty::Param(..) + | ty::Bound(..) + | ty::Placeholder(..) + | ty::Never + | ty::Foreign(..) => return self, }; - if self.kind == kind { - self - } else { - folder.tcx().mk_ty(kind) - } + if self.kind == kind { self } else { folder.tcx().mk_ty(kind) } } fn fold_with>(&self, folder: &mut F) -> Self { @@ -1055,15 +935,14 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::Array(typ, sz) => typ.visit_with(visitor) || sz.visit_with(visitor), ty::Slice(typ) => typ.visit_with(visitor), ty::Adt(_, substs) => substs.visit_with(visitor), - ty::Dynamic(ref trait_ty, ref reg) => - trait_ty.visit_with(visitor) || reg.visit_with(visitor), + ty::Dynamic(ref trait_ty, ref reg) => { + trait_ty.visit_with(visitor) || reg.visit_with(visitor) + } ty::Tuple(ts) => ts.visit_with(visitor), ty::FnDef(_, substs) => substs.visit_with(visitor), ty::FnPtr(ref f) => f.visit_with(visitor), ty::Ref(r, ty, _) => r.visit_with(visitor) || ty.visit_with(visitor), - ty::Generator(_did, ref substs, _) => { - substs.visit_with(visitor) - } + ty::Generator(_did, ref substs, _) => substs.visit_with(visitor), ty::GeneratorWitness(ref types) => types.visit_with(visitor), ty::Closure(_did, ref substs) => substs.visit_with(visitor), ty::Projection(ref data) | ty::UnnormalizedProjection(ref data) => { @@ -1071,19 +950,19 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { } ty::Opaque(_, ref substs) => substs.visit_with(visitor), - ty::Bool | - ty::Char | - ty::Str | - ty::Int(_) | - ty::Uint(_) | - ty::Float(_) | - ty::Error | - ty::Infer(_) | - ty::Bound(..) | - ty::Placeholder(..) | - ty::Param(..) | - ty::Never | - ty::Foreign(..) => false, + ty::Bool + | ty::Char + | ty::Str + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Error + | ty::Infer(_) + | ty::Bound(..) + | ty::Placeholder(..) + | ty::Param(..) + | ty::Never + | ty::Foreign(..) => false, } } @@ -1121,11 +1000,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { // Don't bother interning if nothing changed, which is the common // case. let v = self.iter().map(|p| p.fold_with(folder)).collect::>(); - if v[..] == self[..] { - self - } else { - folder.tcx().intern_predicates(&v) - } + if v[..] == self[..] { self } else { folder.tcx().intern_predicates(&v) } } } @@ -1148,10 +1023,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { let ty = self.ty.fold_with(folder); let val = self.val.fold_with(folder); - folder.tcx().mk_const(ty::Const { - ty, - val - }) + folder.tcx().mk_const(ty::Const { ty, val }) } fn fold_with>(&self, folder: &mut F) -> Self { @@ -1172,10 +1044,12 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { match *self { ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)), ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)), - ty::ConstKind::Unevaluated(did, substs) - => ty::ConstKind::Unevaluated(did, substs.fold_with(folder)), - ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) - | ty::ConstKind::Placeholder(..) => *self, + ty::ConstKind::Unevaluated(did, substs) => { + ty::ConstKind::Unevaluated(did, substs.fold_with(folder)) + } + ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) => { + *self + } } } @@ -1184,8 +1058,9 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { ty::ConstKind::Infer(ic) => ic.visit_with(visitor), ty::ConstKind::Param(p) => p.visit_with(visitor), ty::ConstKind::Unevaluated(_, substs) => substs.visit_with(visitor), - ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) - | ty::ConstKind::Placeholder(_) => false, + ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { + false + } } } } diff --git a/src/librustc/ty/structural_match.rs b/src/librustc/ty/structural_match.rs index cdf5734f5a506..426dd93c55732 100644 --- a/src/librustc/ty/structural_match.rs +++ b/src/librustc/ty/structural_match.rs @@ -1,14 +1,14 @@ use crate::hir; use rustc::infer::InferCtxt; -use rustc::traits::{self, ConstPatternStructural, TraitEngine}; use rustc::traits::ObligationCause; +use rustc::traits::{self, ConstPatternStructural, TraitEngine}; -use rustc_data_structures::fx::{FxHashSet}; +use rustc_data_structures::fx::FxHashSet; use syntax_pos::Span; -use crate::ty::{self, AdtDef, Ty, TyCtxt}; use crate::ty::fold::{TypeFoldable, TypeVisitor}; +use crate::ty::{self, AdtDef, Ty, TyCtxt}; #[derive(Debug)] pub enum NonStructuralMatchTy<'tcx> { @@ -62,24 +62,34 @@ pub fn search_for_structural_match_violation<'tcx>( /// /// Note that this does *not* recursively check if the substructure of `adt_ty` /// implements the traits. -pub fn type_marked_structural(id: hir::HirId, - span: Span, - infcx: &InferCtxt<'_, 'tcx>, - adt_ty: Ty<'tcx>) - -> bool -{ +pub fn type_marked_structural( + id: hir::HirId, + span: Span, + infcx: &InferCtxt<'_, 'tcx>, + adt_ty: Ty<'tcx>, +) -> bool { let mut fulfillment_cx = traits::FulfillmentContext::new(); let cause = ObligationCause::new(span, id, ConstPatternStructural); // require `#[derive(PartialEq)]` let structural_peq_def_id = infcx.tcx.lang_items().structural_peq_trait().unwrap(); fulfillment_cx.register_bound( - infcx, ty::ParamEnv::empty(), adt_ty, structural_peq_def_id, cause); + infcx, + ty::ParamEnv::empty(), + adt_ty, + structural_peq_def_id, + cause, + ); // for now, require `#[derive(Eq)]`. (Doing so is a hack to work around // the type `for<'a> fn(&'a ())` failing to implement `Eq` itself.) let cause = ObligationCause::new(span, id, ConstPatternStructural); let structural_teq_def_id = infcx.tcx.lang_items().structural_teq_trait().unwrap(); fulfillment_cx.register_bound( - infcx, ty::ParamEnv::empty(), adt_ty, structural_teq_def_id, cause); + infcx, + ty::ParamEnv::empty(), + adt_ty, + structural_teq_def_id, + cause, + ); // We deliberately skip *reporting* fulfillment errors (via // `report_fulfillment_errors`), for two reasons: @@ -156,9 +166,9 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> { // (But still tell caller to continue search.) return false; } - ty::Array(_, n) if { - n.try_eval_usize(self.tcx(), ty::ParamEnv::reveal_all()) == Some(0) - } => { + ty::Array(_, n) + if { n.try_eval_usize(self.tcx(), ty::ParamEnv::reveal_all()) == Some(0) } => + { // rust-lang/rust#62336: ignore type of contents // for empty array. return false; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 604dc03ea17bc..c17fff29810d4 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -8,14 +8,14 @@ use self::TyKind::*; use crate::hir; use crate::hir::def_id::DefId; use crate::infer::canonical::Canonical; -use crate::mir::interpret::ConstValue; use crate::middle::region; -use crate::ty::subst::{InternalSubsts, Subst, SubstsRef, GenericArg, GenericArgKind}; -use crate::ty::{self, AdtDef, Discr, DefIdTree, TypeFlags, Ty, TyCtxt, TypeFoldable}; -use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv}; +use crate::mir::interpret::ConstValue; +use crate::mir::interpret::Scalar; use crate::ty::layout::VariantIdx; +use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef}; +use crate::ty::{self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable}; +use crate::ty::{List, ParamEnv, ParamEnvAnd, TyS}; use crate::util::captures::Captures; -use crate::mir::interpret::Scalar; use polonius_engine::Atom; use rustc_index::vec::Idx; @@ -30,8 +30,19 @@ use syntax::ast::{self, Ident}; use syntax::symbol::{kw, Symbol}; #[derive( - Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable, - HashStable, TypeFoldable, Lift, + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Debug, + RustcEncodable, + RustcDecodable, + HashStable, + TypeFoldable, + Lift )] pub struct TypeAndMut<'tcx> { pub ty: Ty<'tcx>, @@ -39,7 +50,16 @@ pub struct TypeAndMut<'tcx> { } #[derive( - Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable, RustcDecodable, Copy, HashStable, + Clone, + PartialEq, + PartialOrd, + Eq, + Ord, + Hash, + RustcEncodable, + RustcDecodable, + Copy, + HashStable )] /// A "free" region `fr` can be interpreted as "some region /// at least as big as the scope `fr.scope`". @@ -49,7 +69,16 @@ pub struct FreeRegion { } #[derive( - Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable, RustcDecodable, Copy, HashStable, + Clone, + PartialEq, + PartialOrd, + Eq, + Ord, + Hash, + RustcEncodable, + RustcDecodable, + Copy, + HashStable )] pub enum BoundRegion { /// An anonymous region parameter for a given fn (&T) @@ -88,8 +117,18 @@ impl BoundRegion { /// N.B., if you change this, you'll probably want to change the corresponding /// AST structure in `libsyntax/ast.rs` as well. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, - RustcEncodable, RustcDecodable, HashStable, Debug)] +#[derive( + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + RustcEncodable, + RustcDecodable, + HashStable, + Debug +)] #[rustc_diagnostic_item = "TyKind"] pub enum TyKind<'tcx> { /// The primitive boolean type. Written as `bool`. @@ -467,10 +506,7 @@ impl<'tcx> GeneratorSubsts<'tcx> { /// Returns the "generator signature", which consists of its yield /// and return types. pub fn sig(self, def_id: DefId, tcx: TyCtxt<'_>) -> GenSig<'tcx> { - ty::GenSig { - yield_ty: self.yield_ty(def_id, tcx), - return_ty: self.return_ty(def_id, tcx), - } + ty::GenSig { yield_ty: self.yield_ty(def_id, tcx), return_ty: self.return_ty(def_id, tcx) } } } @@ -530,7 +566,7 @@ impl<'tcx> GeneratorSubsts<'tcx> { Self::UNRESUMED => Cow::from(Self::UNRESUMED_NAME), Self::RETURNED => Cow::from(Self::RETURNED_NAME), Self::POISONED => Cow::from(Self::POISONED_NAME), - _ => Cow::from(format!("Suspend{}", v.as_usize() - 3)) + _ => Cow::from(format!("Suspend{}", v.as_usize() - 3)), } } @@ -554,9 +590,7 @@ impl<'tcx> GeneratorSubsts<'tcx> { ) -> impl Iterator> + Captures<'tcx>> { let layout = tcx.generator_layout(def_id); layout.variant_fields.iter().map(move |variant| { - variant.iter().map(move |field| { - layout.field_tys[*field].subst(tcx, self.substs) - }) + variant.iter().map(move |field| layout.field_tys[*field].subst(tcx, self.substs)) }) } @@ -613,10 +647,12 @@ impl<'tcx> ExistentialPredicate<'tcx> { use self::ExistentialPredicate::*; match (*self, *other) { (Trait(_), Trait(_)) => Ordering::Equal, - (Projection(ref a), Projection(ref b)) => - tcx.def_path_hash(a.item_def_id).cmp(&tcx.def_path_hash(b.item_def_id)), - (AutoTrait(ref a), AutoTrait(ref b)) => - tcx.trait_def(*a).def_path_hash.cmp(&tcx.trait_def(*b).def_path_hash), + (Projection(ref a), Projection(ref b)) => { + tcx.def_path_hash(a.item_def_id).cmp(&tcx.def_path_hash(b.item_def_id)) + } + (AutoTrait(ref a), AutoTrait(ref b)) => { + tcx.trait_def(*a).def_path_hash.cmp(&tcx.trait_def(*b).def_path_hash) + } (Trait(_), _) => Ordering::Less, (Projection(_), Trait(_)) => Ordering::Greater, (Projection(_), _) => Ordering::Less, @@ -630,13 +666,12 @@ impl<'tcx> Binder> { use crate::ty::ToPredicate; match *self.skip_binder() { ExistentialPredicate::Trait(tr) => Binder(tr).with_self_ty(tcx, self_ty).to_predicate(), - ExistentialPredicate::Projection(p) => - ty::Predicate::Projection(Binder(p.with_self_ty(tcx, self_ty))), + ExistentialPredicate::Projection(p) => { + ty::Predicate::Projection(Binder(p.with_self_ty(tcx, self_ty))) + } ExistentialPredicate::AutoTrait(did) => { - let trait_ref = Binder(ty::TraitRef { - def_id: did, - substs: tcx.mk_substs_trait(self_ty, &[]), - }); + let trait_ref = + Binder(ty::TraitRef { def_id: did, substs: tcx.mk_substs_trait(self_ty, &[]) }); trait_ref.to_predicate() } } @@ -683,24 +718,20 @@ impl<'tcx> List> { } #[inline] - pub fn projection_bounds<'a>(&'a self) -> - impl Iterator> + 'a - { - self.iter().filter_map(|predicate| { - match *predicate { - ExistentialPredicate::Projection(projection) => Some(projection), - _ => None, - } + pub fn projection_bounds<'a>( + &'a self, + ) -> impl Iterator> + 'a { + self.iter().filter_map(|predicate| match *predicate { + ExistentialPredicate::Projection(projection) => Some(projection), + _ => None, }) } #[inline] pub fn auto_traits<'a>(&'a self) -> impl Iterator + 'a { - self.iter().filter_map(|predicate| { - match *predicate { - ExistentialPredicate::AutoTrait(did) => Some(did), - _ => None, - } + self.iter().filter_map(|predicate| match *predicate { + ExistentialPredicate::AutoTrait(did) => Some(did), + _ => None, }) } } @@ -715,8 +746,9 @@ impl<'tcx> Binder<&'tcx List>> { } #[inline] - pub fn projection_bounds<'a>(&'a self) -> - impl Iterator> + 'a { + pub fn projection_bounds<'a>( + &'a self, + ) -> impl Iterator> + 'a { self.skip_binder().projection_bounds().map(Binder::bind) } @@ -725,9 +757,9 @@ impl<'tcx> Binder<&'tcx List>> { self.skip_binder().auto_traits() } - pub fn iter<'a>(&'a self) - -> impl DoubleEndedIterator>> + 'tcx - { + pub fn iter<'a>( + &'a self, + ) -> impl DoubleEndedIterator>> + 'tcx { self.skip_binder().iter().cloned().map(Binder::bind) } } @@ -762,10 +794,7 @@ impl<'tcx> TraitRef<'tcx> { /// Returns a `TraitRef` of the form `P0: Foo` where `Pi` /// are the parameters defined on trait. pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> { - TraitRef { - def_id, - substs: InternalSubsts::identity_for_item(tcx, def_id), - } + TraitRef { def_id, substs: InternalSubsts::identity_for_item(tcx, def_id) } } #[inline] @@ -788,10 +817,7 @@ impl<'tcx> TraitRef<'tcx> { ) -> ty::TraitRef<'tcx> { let defs = tcx.generics_of(trait_id); - ty::TraitRef { - def_id: trait_id, - substs: tcx.intern_substs(&substs[..defs.params.len()]) - } + ty::TraitRef { def_id: trait_id, substs: tcx.intern_substs(&substs[..defs.params.len()]) } } } @@ -844,7 +870,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> { ty::ExistentialTraitRef { def_id: trait_ref.def_id, - substs: tcx.intern_substs(&trait_ref.substs[1..]) + substs: tcx.intern_substs(&trait_ref.substs[1..]), } } @@ -856,10 +882,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> { // otherwise the escaping vars would be captured by the binder // debug_assert!(!self_ty.has_escaping_bound_vars()); - ty::TraitRef { - def_id: self.def_id, - substs: tcx.mk_substs_trait(self_ty, self.substs) - } + ty::TraitRef { def_id: self.def_id, substs: tcx.mk_substs_trait(self_ty, self.substs) } } } @@ -895,7 +918,8 @@ impl Binder { /// binder. This is commonly used to 'inject' a value T into a /// different binding level. pub fn dummy<'tcx>(value: T) -> Binder - where T: TypeFoldable<'tcx> + where + T: TypeFoldable<'tcx>, { debug_assert!(!value.has_escaping_bound_vars()); Binder(value) @@ -931,13 +955,15 @@ impl Binder { } pub fn map_bound_ref(&self, f: F) -> Binder - where F: FnOnce(&T) -> U + where + F: FnOnce(&T) -> U, { self.as_ref().map_bound(f) } pub fn map_bound(self, f: F) -> Binder - where F: FnOnce(T) -> U + where + F: FnOnce(T) -> U, { Binder(f(self.0)) } @@ -953,7 +979,8 @@ impl Binder { /// indices, and given the shallow binding structure we often use, /// would not be that useful.) pub fn no_bound_vars<'tcx>(self) -> Option - where T: TypeFoldable<'tcx> + where + T: TypeFoldable<'tcx>, { if self.skip_binder().has_escaping_bound_vars() { None @@ -969,8 +996,9 @@ impl Binder { /// `f` should consider bound regions at depth 1 to be free, and /// anything it produces with bound regions at depth 1 will be /// bound in the resulting return value. - pub fn fuse(self, u: Binder, f: F) -> Binder - where F: FnOnce(T, U) -> R + pub fn fuse(self, u: Binder, f: F) -> Binder + where + F: FnOnce(T, U) -> R, { Binder(f(self.0, u.0)) } @@ -981,8 +1009,9 @@ impl Binder { /// `f` should consider bound regions at depth 1 to be free, and /// anything it produces with bound regions at depth 1 will be /// bound in the resulting return values. - pub fn split(self, f: F) -> (Binder, Binder) - where F: FnOnce(T) -> (U, V) + pub fn split(self, f: F) -> (Binder, Binder) + where + F: FnOnce(T) -> (U, V), { let (u, v) = f(self.0); (Binder(u), Binder(v)) @@ -1012,15 +1041,16 @@ impl<'tcx> ProjectionTy<'tcx> { trait_ref: ty::TraitRef<'tcx>, item_name: Ident, ) -> ProjectionTy<'tcx> { - let item_def_id = tcx.associated_items(trait_ref.def_id).find(|item| { - item.kind == ty::AssocKind::Type && - tcx.hygienic_eq(item_name, item.ident, trait_ref.def_id) - }).unwrap().def_id; + let item_def_id = tcx + .associated_items(trait_ref.def_id) + .find(|item| { + item.kind == ty::AssocKind::Type + && tcx.hygienic_eq(item_name, item.ident, trait_ref.def_id) + }) + .unwrap() + .def_id; - ProjectionTy { - substs: trait_ref.substs, - item_def_id, - } + ProjectionTy { substs: trait_ref.substs, item_def_id } } /// Extracts the underlying trait reference from this projection. @@ -1028,10 +1058,7 @@ impl<'tcx> ProjectionTy<'tcx> { /// then this function would return a `T: Iterator` trait reference. pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> { let def_id = tcx.associated_item(self.item_def_id).container.id(); - ty::TraitRef { - def_id, - substs: self.substs.truncate_to(tcx, tcx.generics_of(def_id)), - } + ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, tcx.generics_of(def_id)) } } pub fn self_ty(&self) -> Ty<'tcx> { @@ -1123,8 +1150,18 @@ impl<'tcx> PolyFnSig<'tcx> { pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder>>; -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, - Hash, RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + RustcEncodable, + RustcDecodable, + HashStable +)] pub struct ParamTy { pub index: u32, pub name: Symbol, @@ -1148,8 +1185,18 @@ impl<'tcx> ParamTy { } } -#[derive(Copy, Clone, Hash, RustcEncodable, RustcDecodable, - Eq, PartialEq, Ord, PartialOrd, HashStable)] +#[derive( + Copy, + Clone, + Hash, + RustcEncodable, + RustcDecodable, + Eq, + PartialEq, + Ord, + PartialOrd, + HashStable +)] pub struct ParamConst { pub index: u32, pub name: Symbol, @@ -1366,8 +1413,18 @@ impl Atom for RegionVid { } } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, - Hash, RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + RustcEncodable, + RustcDecodable, + HashStable +)] pub enum InferTy { TyVar(TyVid), IntVar(IntVid), @@ -1385,15 +1442,37 @@ rustc_index::newtype_index! { pub struct BoundVar { .. } } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, - RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Debug, + RustcEncodable, + RustcDecodable, + HashStable +)] pub struct BoundTy { pub var: BoundVar, pub kind: BoundTyKind, } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, - RustcEncodable, RustcDecodable, HashStable)] +#[derive( + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Debug, + RustcEncodable, + RustcDecodable, + HashStable +)] pub enum BoundTyKind { Anon, Param(Symbol), @@ -1401,10 +1480,7 @@ pub enum BoundTyKind { impl From for BoundTy { fn from(var: BoundVar) -> Self { - BoundTy { - var, - kind: BoundTyKind::Anon, - } + BoundTy { var, kind: BoundTyKind::Anon } } } @@ -1426,10 +1502,7 @@ impl<'tcx> ExistentialProjection<'tcx> { /// reference. pub fn trait_ref(&self, tcx: TyCtxt<'_>) -> ty::ExistentialTraitRef<'tcx> { let def_id = tcx.associated_item(self.item_def_id).container.id(); - ty::ExistentialTraitRef{ - def_id, - substs: self.substs, - } + ty::ExistentialTraitRef { def_id, substs: self.substs } } pub fn with_self_ty( @@ -1584,20 +1657,15 @@ impl RegionKind { /// error (and should fail an assertion failure). pub fn shifted_out_to_binder(&self, to_binder: ty::DebruijnIndex) -> RegionKind { match *self { - ty::ReLateBound(debruijn, r) => ty::ReLateBound( - debruijn.shifted_out_to_binder(to_binder), - r, - ), - r => r + ty::ReLateBound(debruijn, r) => { + ty::ReLateBound(debruijn.shifted_out_to_binder(to_binder), r) + } + r => r, } } pub fn keep_in_local_tcx(&self) -> bool { - if let ty::ReVar(..) = self { - true - } else { - false - } + if let ty::ReVar(..) = self { true } else { false } } pub fn type_flags(&self) -> TypeFlags { @@ -1623,14 +1691,10 @@ impl RegionKind { flags = flags | TypeFlags::HAS_FREE_REGIONS; flags = flags | TypeFlags::HAS_RE_EARLY_BOUND; } - ty::ReEmpty | - ty::ReStatic | - ty::ReFree { .. } | - ty::ReScope { .. } => { + ty::ReEmpty | ty::ReStatic | ty::ReFree { .. } | ty::ReScope { .. } => { flags = flags | TypeFlags::HAS_FREE_REGIONS; } - ty::ReErased => { - } + ty::ReErased => {} ty::ReClosureBound(..) => { flags = flags | TypeFlags::HAS_FREE_REGIONS; } @@ -1667,9 +1731,7 @@ impl RegionKind { /// function might return the `DefId` of a closure. pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_>) -> DefId { match self { - ty::ReEarlyBound(br) => { - tcx.parent(br.def_id).unwrap() - } + ty::ReEarlyBound(br) => tcx.parent(br.def_id).unwrap(), ty::ReFree(fr) => fr.scope, _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self), } @@ -1720,15 +1782,15 @@ impl<'tcx> TyS<'tcx> { }) }) } - ty::Tuple(..) => self.tuple_fields().any(|ty| { - ty.conservative_is_privately_uninhabited(tcx) - }), + ty::Tuple(..) => { + self.tuple_fields().any(|ty| ty.conservative_is_privately_uninhabited(tcx)) + } ty::Array(ty, len) => { match len.try_eval_usize(tcx, ParamEnv::empty()) { // If the array is definitely non-empty, it's uninhabited if // the type of its elements is uninhabited. Some(n) if n != 0 => ty.conservative_is_privately_uninhabited(tcx), - _ => false + _ => false, } } ty::Ref(..) => { @@ -1767,19 +1829,19 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_phantom_data(&self) -> bool { - if let Adt(def, _) = self.kind { - def.is_phantom_data() - } else { - false - } + if let Adt(def, _) = self.kind { def.is_phantom_data() } else { false } } #[inline] - pub fn is_bool(&self) -> bool { self.kind == Bool } + pub fn is_bool(&self) -> bool { + self.kind == Bool + } /// Returns `true` if this type is a `str`. #[inline] - pub fn is_str(&self) -> bool { self.kind == Str } + pub fn is_str(&self) -> bool { + self.kind == Str + } #[inline] pub fn is_param(&self, index: u32) -> bool { @@ -1796,7 +1858,7 @@ impl<'tcx> TyS<'tcx> { Slice(_) | Str => true, _ => false, }, - _ => false + _ => false, } } @@ -1853,9 +1915,9 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_mutable_ptr(&self) -> bool { match self.kind { - RawPtr(TypeAndMut { mutbl: hir::Mutability::Mut, .. }) | - Ref(_, _, hir::Mutability::Mut) => true, - _ => false + RawPtr(TypeAndMut { mutbl: hir::Mutability::Mut, .. }) + | Ref(_, _, hir::Mutability::Mut) => true, + _ => false, } } @@ -1913,10 +1975,9 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_scalar(&self) -> bool { match self.kind { - Bool | Char | Int(_) | Float(_) | Uint(_) | - Infer(IntVar(_)) | Infer(FloatVar(_)) | - FnDef(..) | FnPtr(_) | RawPtr(_) => true, - _ => false + Bool | Char | Int(_) | Float(_) | Uint(_) | Infer(IntVar(_)) | Infer(FloatVar(_)) + | FnDef(..) | FnPtr(_) | RawPtr(_) => true, + _ => false, } } @@ -1924,8 +1985,7 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_floating_point(&self) -> bool { match self.kind { - Float(_) | - Infer(FloatVar(_)) => true, + Float(_) | Infer(FloatVar(_)) => true, _ => false, } } @@ -1941,9 +2001,7 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_enum(&self) -> bool { match self.kind { - Adt(adt_def, _) => { - adt_def.is_enum() - } + Adt(adt_def, _) => adt_def.is_enum(), _ => false, } } @@ -1968,7 +2026,7 @@ impl<'tcx> TyS<'tcx> { pub fn is_integral(&self) -> bool { match self.kind { Infer(IntVar(_)) | Int(_) | Uint(_) => true, - _ => false + _ => false, } } @@ -2042,11 +2100,8 @@ impl<'tcx> TyS<'tcx> { pub fn builtin_deref(&self, explicit: bool) -> Option> { match self.kind { Adt(def, _) if def.is_box() => { - Some(TypeAndMut { - ty: self.boxed_ty(), - mutbl: hir::Mutability::Not, - }) - }, + Some(TypeAndMut { ty: self.boxed_ty(), mutbl: hir::Mutability::Not }) + } Ref(_, ty, mutbl) => Some(TypeAndMut { ty, mutbl }), RawPtr(mt) if explicit => Some(mt), _ => None, @@ -2063,17 +2118,16 @@ impl<'tcx> TyS<'tcx> { pub fn fn_sig(&self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> { match self.kind { - FnDef(def_id, substs) => { - tcx.fn_sig(def_id).subst(tcx, substs) - } + FnDef(def_id, substs) => tcx.fn_sig(def_id).subst(tcx, substs), FnPtr(f) => f, - Error => { // ignore errors (#54954) + Error => { + // ignore errors (#54954) ty::Binder::dummy(FnSig::fake()) } - Closure(..) => bug!( - "to get the signature of a closure, use `closure_sig()` not `fn_sig()`", - ), - _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self) + Closure(..) => { + bug!("to get the signature of a closure, use `closure_sig()` not `fn_sig()`",) + } + _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self), } } @@ -2111,7 +2165,7 @@ impl<'tcx> TyS<'tcx> { /// Iterates over tuple fields. /// Panics when called on anything but a tuple. - pub fn tuple_fields(&self) -> impl DoubleEndedIterator> { + pub fn tuple_fields(&self) -> impl DoubleEndedIterator> { match self.kind { Tuple(substs) => substs.iter().map(|field| field.expect_ty()), _ => bug!("tuple_fields called on non-tuple"), @@ -2125,8 +2179,9 @@ impl<'tcx> TyS<'tcx> { pub fn variant_range(&self, tcx: TyCtxt<'tcx>) -> Option> { match self.kind { TyKind::Adt(adt, _) => Some(adt.variant_range()), - TyKind::Generator(def_id, substs, _) => - Some(substs.as_generator().variant_range(def_id, tcx)), + TyKind::Generator(def_id, substs, _) => { + Some(substs.as_generator().variant_range(def_id, tcx)) + } _ => None, } } @@ -2143,8 +2198,9 @@ impl<'tcx> TyS<'tcx> { ) -> Option> { match self.kind { TyKind::Adt(adt, _) => Some(adt.discriminant_for_variant(tcx, variant_index)), - TyKind::Generator(def_id, substs, _) => - Some(substs.as_generator().discriminant_for_variant(def_id, tcx, variant_index)), + TyKind::Generator(def_id, substs, _) => { + Some(substs.as_generator().discriminant_for_variant(def_id, tcx, variant_index)) + } _ => None, } } @@ -2163,36 +2219,14 @@ impl<'tcx> TyS<'tcx> { out.extend(principal.skip_binder().substs.regions()); } } - Adt(_, substs) | Opaque(_, substs) => { - out.extend(substs.regions()) - } - Closure(_, ref substs ) | - Generator(_, ref substs, _) => { - out.extend(substs.regions()) - } + Adt(_, substs) | Opaque(_, substs) => out.extend(substs.regions()), + Closure(_, ref substs) | Generator(_, ref substs, _) => out.extend(substs.regions()), Projection(ref data) | UnnormalizedProjection(ref data) => { out.extend(data.substs.regions()) } - FnDef(..) | - FnPtr(_) | - GeneratorWitness(..) | - Bool | - Char | - Int(_) | - Uint(_) | - Float(_) | - Str | - Array(..) | - Slice(_) | - RawPtr(_) | - Never | - Tuple(..) | - Foreign(..) | - Param(_) | - Bound(..) | - Placeholder(..) | - Infer(_) | - Error => {} + FnDef(..) | FnPtr(_) | GeneratorWitness(..) | Bool | Char | Int(_) | Uint(_) + | Float(_) | Str | Array(..) | Slice(_) | RawPtr(_) | Never | Tuple(..) + | Foreign(..) | Param(_) | Bound(..) | Placeholder(..) | Infer(_) | Error => {} } } @@ -2233,23 +2267,29 @@ impl<'tcx> TyS<'tcx> { /// `false` means nothing -- could be sized, might not be. pub fn is_trivially_sized(&self, tcx: TyCtxt<'tcx>) -> bool { match self.kind { - ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) | - ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Float(_) | - ty::FnDef(..) | ty::FnPtr(_) | ty::RawPtr(..) | - ty::Char | ty::Ref(..) | ty::Generator(..) | - ty::GeneratorWitness(..) | ty::Array(..) | ty::Closure(..) | - ty::Never | ty::Error => - true, - - ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => - false, - - ty::Tuple(tys) => { - tys.iter().all(|ty| ty.expect_ty().is_trivially_sized(tcx)) - } - - ty::Adt(def, _substs) => - def.sized_constraint(tcx).is_empty(), + ty::Infer(ty::IntVar(_)) + | ty::Infer(ty::FloatVar(_)) + | ty::Uint(_) + | ty::Int(_) + | ty::Bool + | ty::Float(_) + | ty::FnDef(..) + | ty::FnPtr(_) + | ty::RawPtr(..) + | ty::Char + | ty::Ref(..) + | ty::Generator(..) + | ty::GeneratorWitness(..) + | ty::Array(..) + | ty::Closure(..) + | ty::Never + | ty::Error => true, + + ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => false, + + ty::Tuple(tys) => tys.iter().all(|ty| ty.expect_ty().is_trivially_sized(tcx)), + + ty::Adt(def, _substs) => def.sized_constraint(tcx).is_empty(), ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => false, @@ -2257,19 +2297,31 @@ impl<'tcx> TyS<'tcx> { ty::Infer(ty::TyVar(_)) => false, - ty::Bound(..) | - ty::Placeholder(..) | - ty::Infer(ty::FreshTy(_)) | - ty::Infer(ty::FreshIntTy(_)) | - ty::Infer(ty::FreshFloatTy(_)) => - bug!("`is_trivially_sized` applied to unexpected type: {:?}", self), + ty::Bound(..) + | ty::Placeholder(..) + | ty::Infer(ty::FreshTy(_)) + | ty::Infer(ty::FreshIntTy(_)) + | ty::Infer(ty::FreshFloatTy(_)) => { + bug!("`is_trivially_sized` applied to unexpected type: {:?}", self) + } } } } /// Typed constant value. -#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, - Eq, PartialEq, Ord, PartialOrd, HashStable)] +#[derive( + Copy, + Clone, + Debug, + Hash, + RustcEncodable, + RustcDecodable, + Eq, + PartialEq, + Ord, + PartialOrd, + HashStable +)] pub struct Const<'tcx> { pub ty: Ty<'tcx>, @@ -2282,17 +2334,15 @@ static_assert_size!(Const<'_>, 48); impl<'tcx> Const<'tcx> { #[inline] pub fn from_scalar(tcx: TyCtxt<'tcx>, val: Scalar, ty: Ty<'tcx>) -> &'tcx Self { - tcx.mk_const(Self { - val: ConstKind::Value(ConstValue::Scalar(val)), - ty, - }) + tcx.mk_const(Self { val: ConstKind::Value(ConstValue::Scalar(val)), ty }) } #[inline] pub fn from_bits(tcx: TyCtxt<'tcx>, bits: u128, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> &'tcx Self { - let size = tcx.layout_of(ty).unwrap_or_else(|e| { - panic!("could not compute layout for {:?}: {:?}", ty, e) - }).size; + let size = tcx + .layout_of(ty) + .unwrap_or_else(|e| panic!("could not compute layout for {:?}: {:?}", ty, e)) + .size; Self::from_scalar(tcx, Scalar::from_uint(bits, size), ty.value) } @@ -2325,11 +2375,7 @@ impl<'tcx> Const<'tcx> { } #[inline] - pub fn eval( - &self, - tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, - ) -> &Const<'tcx> { + pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> { let try_const_eval = |did, param_env: ParamEnv<'tcx>, substs| { let param_env_and_substs = param_env.with_reveal_all().and(substs); @@ -2363,7 +2409,7 @@ impl<'tcx> Const<'tcx> { } else { try_const_eval(did, param_env, substs).unwrap_or(self) } - }, + } _ => self, } } @@ -2384,8 +2430,8 @@ impl<'tcx> Const<'tcx> { #[inline] pub fn eval_bits(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 { - self.try_eval_bits(tcx, param_env, ty).unwrap_or_else(|| - bug!("expected bits of {:#?}, got {:#?}", ty, self)) + self.try_eval_bits(tcx, param_env, ty) + .unwrap_or_else(|| bug!("expected bits of {:#?}, got {:#?}", ty, self)) } #[inline] @@ -2397,8 +2443,19 @@ impl<'tcx> Const<'tcx> { impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx Const<'tcx> {} /// Represents a constant in Rust. -#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, - RustcEncodable, RustcDecodable, Hash, HashStable)] +#[derive( + Copy, + Clone, + Debug, + Eq, + PartialEq, + PartialOrd, + Ord, + RustcEncodable, + RustcDecodable, + Hash, + HashStable +)] pub enum ConstKind<'tcx> { /// A const generic parameter. Param(ParamConst), @@ -2426,11 +2483,7 @@ static_assert_size!(ConstKind<'_>, 40); impl<'tcx> ConstKind<'tcx> { #[inline] pub fn try_to_scalar(&self) -> Option { - if let ConstKind::Value(val) = self { - val.try_to_scalar() - } else { - None - } + if let ConstKind::Value(val) = self { val.try_to_scalar() } else { None } } #[inline] @@ -2440,8 +2493,19 @@ impl<'tcx> ConstKind<'tcx> { } /// An inference variable for a const, for use in const generics. -#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, - Ord, RustcEncodable, RustcDecodable, Hash, HashStable)] +#[derive( + Copy, + Clone, + Debug, + Eq, + PartialEq, + PartialOrd, + Ord, + RustcEncodable, + RustcDecodable, + Hash, + HashStable +)] pub enum InferConst<'tcx> { /// Infer the value of the const. Var(ConstVid<'tcx>), diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 217188a6f04c2..3804b5aed7161 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -2,18 +2,18 @@ use crate::hir::def_id::DefId; use crate::infer::canonical::Canonical; -use crate::ty::{self, Lift, List, Ty, TyCtxt, ParamConst}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::sty::{ClosureSubsts, GeneratorSubsts}; +use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; -use rustc_serialize::{self, Encodable, Encoder, Decodable, Decoder}; -use syntax_pos::{Span, DUMMY_SP}; -use smallvec::SmallVec; use rustc_macros::HashStable; +use rustc_serialize::{self, Decodable, Decoder, Encodable, Encoder}; +use smallvec::SmallVec; +use syntax_pos::{Span, DUMMY_SP}; use core::intrinsics; -use std::fmt; use std::cmp::Ordering; +use std::fmt; use std::marker::PhantomData; use std::mem; use std::num::NonZeroUsize; @@ -26,7 +26,7 @@ use std::num::NonZeroUsize; #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct GenericArg<'tcx> { ptr: NonZeroUsize, - marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, &'tcx ty::Const<'tcx>)> + marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, &'tcx ty::Const<'tcx>)>, } const TAG_MASK: usize = 0b11; @@ -61,12 +61,7 @@ impl<'tcx> GenericArgKind<'tcx> { } }; - GenericArg { - ptr: unsafe { - NonZeroUsize::new_unchecked(ptr | tag) - }, - marker: PhantomData - } + GenericArg { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData } } } @@ -119,7 +114,7 @@ impl<'tcx> GenericArg<'tcx> { REGION_TAG => GenericArgKind::Lifetime(&*((ptr & !TAG_MASK) as *const _)), TYPE_TAG => GenericArgKind::Type(&*((ptr & !TAG_MASK) as *const _)), CONST_TAG => GenericArgKind::Const(&*((ptr & !TAG_MASK) as *const _)), - _ => intrinsics::unreachable() + _ => intrinsics::unreachable(), } } } @@ -188,9 +183,7 @@ impl<'a, 'tcx> InternalSubsts<'tcx> { /// compiler that encodes information like the signature and closure kind; /// see `ty::ClosureSubsts` struct for more comments. pub fn as_closure(&'a self) -> ClosureSubsts<'a> { - ClosureSubsts { - substs: self, - } + ClosureSubsts { substs: self } } /// Interpret these substitutions as the substitutions of a generator type. @@ -203,9 +196,7 @@ impl<'a, 'tcx> InternalSubsts<'tcx> { /// Creates a `InternalSubsts` that maps each generic parameter to itself. pub fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> { - Self::for_item(tcx, def_id, |param, _| { - tcx.mk_param_from_def(param) - }) + Self::for_item(tcx, def_id, |param, _| tcx.mk_param_from_def(param)) } /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked @@ -213,31 +204,30 @@ impl<'a, 'tcx> InternalSubsts<'tcx> { /// the type parameter index. For regions, we use the `BoundRegion::BrNamed` /// variant (which has a `DefId`). pub fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> { - Self::for_item(tcx, def_id, |param, _| { - match param.kind { - ty::GenericParamDefKind::Type { .. } => { - tcx.mk_ty( - ty::Bound(ty::INNERMOST, ty::BoundTy { - var: ty::BoundVar::from(param.index), - kind: ty::BoundTyKind::Param(param.name), - }) - ).into() - } - - ty::GenericParamDefKind::Lifetime => { - tcx.mk_region(ty::RegionKind::ReLateBound( - ty::INNERMOST, - ty::BoundRegion::BrNamed(param.def_id, param.name) - )).into() - } - - ty::GenericParamDefKind::Const => { - tcx.mk_const(ty::Const { - val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)), - ty: tcx.type_of(param.def_id), - }).into() - } - } + Self::for_item(tcx, def_id, |param, _| match param.kind { + ty::GenericParamDefKind::Type { .. } => tcx + .mk_ty(ty::Bound( + ty::INNERMOST, + ty::BoundTy { + var: ty::BoundVar::from(param.index), + kind: ty::BoundTyKind::Param(param.name), + }, + )) + .into(), + + ty::GenericParamDefKind::Lifetime => tcx + .mk_region(ty::RegionKind::ReLateBound( + ty::INNERMOST, + ty::BoundRegion::BrNamed(param.def_id, param.name), + )) + .into(), + + ty::GenericParamDefKind::Const => tcx + .mk_const(ty::Const { + val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)), + ty: tcx.type_of(param.def_id), + }) + .into(), }) } @@ -262,9 +252,7 @@ impl<'a, 'tcx> InternalSubsts<'tcx> { F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>, { Self::for_item(tcx, def_id, |param, substs| { - self.get(param.index as usize) - .cloned() - .unwrap_or_else(|| mk_kind(param, substs)) + self.get(param.index as usize).cloned().unwrap_or_else(|| mk_kind(param, substs)) }) } @@ -283,10 +271,12 @@ impl<'a, 'tcx> InternalSubsts<'tcx> { Self::fill_single(substs, defs, mk_kind) } - fn fill_single(substs: &mut SmallVec<[GenericArg<'tcx>; 8]>, - defs: &ty::Generics, - mk_kind: &mut F) - where F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx> + fn fill_single( + substs: &mut SmallVec<[GenericArg<'tcx>; 8]>, + defs: &ty::Generics, + mk_kind: &mut F, + ) where + F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>, { substs.reserve(defs.params.len()); for param in &defs.params { @@ -302,46 +292,31 @@ impl<'a, 'tcx> InternalSubsts<'tcx> { #[inline] pub fn types(&'a self) -> impl DoubleEndedIterator> + 'a { - self.iter().filter_map(|k| { - if let GenericArgKind::Type(ty) = k.unpack() { - Some(ty) - } else { - None - } - }) + self.iter() + .filter_map(|k| if let GenericArgKind::Type(ty) = k.unpack() { Some(ty) } else { None }) } #[inline] pub fn regions(&'a self) -> impl DoubleEndedIterator> + 'a { self.iter().filter_map(|k| { - if let GenericArgKind::Lifetime(lt) = k.unpack() { - Some(lt) - } else { - None - } + if let GenericArgKind::Lifetime(lt) = k.unpack() { Some(lt) } else { None } }) } #[inline] pub fn consts(&'a self) -> impl DoubleEndedIterator> + 'a { self.iter().filter_map(|k| { - if let GenericArgKind::Const(ct) = k.unpack() { - Some(ct) - } else { - None - } + if let GenericArgKind::Const(ct) = k.unpack() { Some(ct) } else { None } }) } #[inline] pub fn non_erasable_generics( - &'a self + &'a self, ) -> impl DoubleEndedIterator> + 'a { - self.iter().filter_map(|k| { - match k.unpack() { - GenericArgKind::Lifetime(_) => None, - generic => Some(generic), - } + self.iter().filter_map(|k| match k.unpack() { + GenericArgKind::Lifetime(_) => None, + generic => Some(generic), }) } @@ -408,11 +383,7 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { match self.len() { 1 => { let param0 = self[0].fold_with(folder); - if param0 == self[0] { - self - } else { - folder.tcx().intern_substs(&[param0]) - } + if param0 == self[0] { self } else { folder.tcx().intern_substs(&[param0]) } } 2 => { let param0 = self[0].fold_with(folder); @@ -423,16 +394,10 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { folder.tcx().intern_substs(&[param0, param1]) } } - 0 => { - self - } + 0 => self, _ => { let params: SmallVec<[_; 8]> = self.iter().map(|k| k.fold_with(folder)).collect(); - if params[..] == self[..] { - self - } else { - folder.tcx().intern_substs(¶ms) - } + if params[..] == self[..] { self } else { folder.tcx().intern_substs(¶ms) } } } } @@ -471,12 +436,8 @@ impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T { substs: &[GenericArg<'tcx>], span: Option, ) -> T { - let mut folder = SubstFolder { tcx, - substs, - span, - root_ty: None, - ty_stack_depth: 0, - binders_passed: 0 }; + let mut folder = + SubstFolder { tcx, substs, span, root_ty: None, ty_stack_depth: 0, binders_passed: 0 }; (*self).fold_with(&mut folder) } } @@ -502,7 +463,9 @@ struct SubstFolder<'a, 'tcx> { } impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } + fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + self.tcx + } fn fold_binder>(&mut self, t: &ty::Binder) -> ty::Binder { self.binders_passed += 1; @@ -521,23 +484,20 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { ty::ReEarlyBound(data) => { let rk = self.substs.get(data.index as usize).map(|k| k.unpack()); match rk { - Some(GenericArgKind::Lifetime(lt)) => { - self.shift_region_through_binders(lt) - } + Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt), _ => { let span = self.span.unwrap_or(DUMMY_SP); let msg = format!( "Region parameter out of range \ when substituting in region {} (root type={:?}) \ (index={})", - data.name, - self.root_ty, - data.index); + data.name, self.root_ty, data.index + ); span_bug!(span, "{}", msg); } } } - _ => r + _ => r, } } @@ -554,12 +514,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { self.ty_stack_depth += 1; let t1 = match t.kind { - ty::Param(p) => { - self.ty_for_param(p, t) - } - _ => { - t.super_fold_with(self) - } + ty::Param(p) => self.ty_for_param(p, t), + _ => t.super_fold_with(self), }; assert_eq!(depth + 1, self.ty_stack_depth); @@ -625,7 +581,7 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { fn const_for_param( &self, p: ParamConst, - source_ct: &'tcx ty::Const<'tcx> + source_ct: &'tcx ty::Const<'tcx>, ) -> &'tcx ty::Const<'tcx> { // Look up the const in the substitutions. It really should be in there. let opt_ct = self.substs.get(p.index as usize).map(|k| k.unpack()); @@ -704,8 +660,12 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { /// first case we do not increase the De Bruijn index and in the second case we do. The reason /// is that only in the second case have we passed through a fn binder. fn shift_vars_through_binders>(&self, val: T) -> T { - debug!("shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})", - val, self.binders_passed, val.has_escaping_bound_vars()); + debug!( + "shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})", + val, + self.binders_passed, + val.has_escaping_bound_vars() + ); if self.binders_passed == 0 || !val.has_escaping_bound_vars() { return val; diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 49ec908231548..422d1b1173792 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -46,21 +46,15 @@ pub struct TraitImpls { } impl<'tcx> TraitDef { - pub fn new(def_id: DefId, - unsafety: hir::Unsafety, - paren_sugar: bool, - has_auto_impl: bool, - is_marker: bool, - def_path_hash: DefPathHash) - -> TraitDef { - TraitDef { - def_id, - unsafety, - paren_sugar, - has_auto_impl, - is_marker, - def_path_hash, - } + pub fn new( + def_id: DefId, + unsafety: hir::Unsafety, + paren_sugar: bool, + has_auto_impl: bool, + is_marker: bool, + def_path_hash: DefPathHash, + ) -> TraitDef { + TraitDef { def_id, unsafety, paren_sugar, has_auto_impl, is_marker, def_path_hash } } pub fn ancestors( @@ -89,11 +83,12 @@ impl<'tcx> TyCtxt<'tcx> { /// Iterate over every impl that could possibly match the /// self type `self_ty`. - pub fn for_each_relevant_impl(self, - def_id: DefId, - self_ty: Ty<'tcx>, - mut f: F) - { + pub fn for_each_relevant_impl( + self, + def_id: DefId, + self_ty: Ty<'tcx>, + mut f: F, + ) { let impls = self.trait_impls_of(def_id); for &impl_def_id in impls.blanket_impls.iter() { @@ -142,17 +137,17 @@ impl<'tcx> TyCtxt<'tcx> { pub fn all_impls(self, def_id: DefId) -> Vec { let impls = self.trait_impls_of(def_id); - impls.blanket_impls.iter().chain( - impls.non_blanket_impls.values().flatten() - ).cloned().collect() + impls + .blanket_impls + .iter() + .chain(impls.non_blanket_impls.values().flatten()) + .cloned() + .collect() } } // Query provider for `trait_impls_of`. -pub(super) fn trait_impls_of_provider( - tcx: TyCtxt<'_>, - trait_id: DefId, -) -> &TraitImpls { +pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> &TraitImpls { let mut impls = TraitImpls::default(); { @@ -162,13 +157,8 @@ pub(super) fn trait_impls_of_provider( return; } - if let Some(simplified_self_ty) = - fast_reject::simplify_type(tcx, impl_self_ty, false) - { - impls.non_blanket_impls - .entry(simplified_self_ty) - .or_default() - .push(impl_def_id); + if let Some(simplified_self_ty) = fast_reject::simplify_type(tcx, impl_self_ty, false) { + impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id); } else { impls.blanket_impls.push(impl_def_id); } @@ -194,10 +184,7 @@ pub(super) fn trait_impls_of_provider( impl<'a> HashStable> for TraitImpls { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let TraitImpls { - ref blanket_impls, - ref non_blanket_impls, - } = *self; + let TraitImpls { ref blanket_impls, ref non_blanket_impls } = *self; ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, non_blanket_impls); } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index f054a630e4b8e..41b3d0f7391b2 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -4,19 +4,19 @@ use crate::hir; use crate::hir::def::DefKind; use crate::hir::def_id::DefId; use crate::hir::map::DefPathData; -use crate::mir::interpret::{sign_extend, truncate}; use crate::ich::NodeIdHashingMode; +use crate::middle::lang_items; +use crate::mir::interpret::{sign_extend, truncate}; use crate::traits::{self, ObligationCause}; -use crate::ty::{self, DefIdTree, Ty, TyCtxt, GenericParamDefKind, TypeFoldable}; -use crate::ty::subst::{Subst, InternalSubsts, SubstsRef, GenericArgKind}; +use crate::ty::layout::{Integer, IntegerExt}; use crate::ty::query::TyCtxtAt; +use crate::ty::subst::{GenericArgKind, InternalSubsts, Subst, SubstsRef}; use crate::ty::TyKind::*; -use crate::ty::layout::{Integer, IntegerExt}; +use crate::ty::{self, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable}; use crate::util::common::ErrorReported; -use crate::middle::lang_items; -use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable; use std::{cmp, fmt}; use syntax::ast; @@ -27,21 +27,19 @@ use syntax_pos::{Span, DUMMY_SP}; pub struct Discr<'tcx> { /// Bit representation of the discriminant (e.g., `-128i8` is `0xFF_u128`). pub val: u128, - pub ty: Ty<'tcx> + pub ty: Ty<'tcx>, } impl<'tcx> fmt::Display for Discr<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match self.ty.kind { ty::Int(ity) => { - let size = ty::tls::with(|tcx| { - Integer::from_attr(&tcx, SignedInt(ity)).size() - }); + let size = ty::tls::with(|tcx| Integer::from_attr(&tcx, SignedInt(ity)).size()); let x = self.val; // sign extend the raw representation to be an i128 let x = sign_extend(x, size) as i128; write!(fmt, "{}", x) - }, + } _ => write!(fmt, "{}", self.val), } } @@ -63,40 +61,24 @@ impl<'tcx> Discr<'tcx> { let bit_size = int.size().bits(); let shift = 128 - bit_size; if signed { - let sext = |u| { - sign_extend(u, size) as i128 - }; + let sext = |u| sign_extend(u, size) as i128; let min = sext(1_u128 << (bit_size - 1)); let max = i128::max_value() >> shift; let val = sext(self.val); assert!(n < (i128::max_value() as u128)); let n = n as i128; let oflo = val > max - n; - let val = if oflo { - min + (n - (max - val) - 1) - } else { - val + n - }; + let val = if oflo { min + (n - (max - val) - 1) } else { val + n }; // zero the upper bits let val = val as u128; let val = truncate(val, size); - (Self { - val: val as u128, - ty: self.ty, - }, oflo) + (Self { val: val as u128, ty: self.ty }, oflo) } else { let max = u128::max_value() >> shift; let val = self.val; let oflo = val > max - n; - let val = if oflo { - n - (max - val) - 1 - } else { - val + n - }; - (Self { - val: val, - ty: self.ty, - }, oflo) + let val = if oflo { n - (max - val) - 1 } else { val + n }; + (Self { val: val, ty: self.ty }, oflo) } } } @@ -110,44 +92,36 @@ pub trait IntTypeExt { impl IntTypeExt for attr::IntType { fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { match *self { - SignedInt(ast::IntTy::I8) => tcx.types.i8, - SignedInt(ast::IntTy::I16) => tcx.types.i16, - SignedInt(ast::IntTy::I32) => tcx.types.i32, - SignedInt(ast::IntTy::I64) => tcx.types.i64, - SignedInt(ast::IntTy::I128) => tcx.types.i128, - SignedInt(ast::IntTy::Isize) => tcx.types.isize, - UnsignedInt(ast::UintTy::U8) => tcx.types.u8, - UnsignedInt(ast::UintTy::U16) => tcx.types.u16, - UnsignedInt(ast::UintTy::U32) => tcx.types.u32, - UnsignedInt(ast::UintTy::U64) => tcx.types.u64, - UnsignedInt(ast::UintTy::U128) => tcx.types.u128, + SignedInt(ast::IntTy::I8) => tcx.types.i8, + SignedInt(ast::IntTy::I16) => tcx.types.i16, + SignedInt(ast::IntTy::I32) => tcx.types.i32, + SignedInt(ast::IntTy::I64) => tcx.types.i64, + SignedInt(ast::IntTy::I128) => tcx.types.i128, + SignedInt(ast::IntTy::Isize) => tcx.types.isize, + UnsignedInt(ast::UintTy::U8) => tcx.types.u8, + UnsignedInt(ast::UintTy::U16) => tcx.types.u16, + UnsignedInt(ast::UintTy::U32) => tcx.types.u32, + UnsignedInt(ast::UintTy::U64) => tcx.types.u64, + UnsignedInt(ast::UintTy::U128) => tcx.types.u128, UnsignedInt(ast::UintTy::Usize) => tcx.types.usize, } } fn initial_discriminant<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Discr<'tcx> { - Discr { - val: 0, - ty: self.to_ty(tcx) - } + Discr { val: 0, ty: self.to_ty(tcx) } } fn disr_incr<'tcx>(&self, tcx: TyCtxt<'tcx>, val: Option>) -> Option> { if let Some(val) = val { assert_eq!(self.to_ty(tcx), val.ty); let (new, oflo) = val.checked_add(tcx, 1); - if oflo { - None - } else { - Some(new) - } + if oflo { None } else { Some(new) } } else { Some(self.initial_discriminant(tcx)) } } } - #[derive(Clone)] pub enum CopyImplementationError<'tcx> { InfrigingFields(Vec<&'tcx ty::FieldDef>), @@ -181,9 +155,14 @@ impl<'tcx> ty::ParamEnv<'tcx> { let (adt, substs) = match self_type.kind { // These types used to have a builtin impl. // Now libcore provides that impl. - ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Float(_) | - ty::Char | ty::RawPtr(..) | ty::Never | - ty::Ref(_, _, hir::Mutability::Not) => return Ok(()), + ty::Uint(_) + | ty::Int(_) + | ty::Bool + | ty::Float(_) + | ty::Char + | ty::RawPtr(..) + | ty::Never + | ty::Ref(_, _, hir::Mutability::Not) => return Ok(()), ty::Adt(adt, substs) => (adt, substs), @@ -201,8 +180,10 @@ impl<'tcx> ty::ParamEnv<'tcx> { let cause = ObligationCause { span, ..ObligationCause::dummy() }; let ctx = traits::FulfillmentContext::new(); match traits::fully_normalize(&infcx, ctx, cause, self, &ty) { - Ok(ty) => if !infcx.type_is_copy_modulo_regions(self, ty, span) { - infringing.push(field); + Ok(ty) => { + if !infcx.type_is_copy_modulo_regions(self, ty, span) { + infringing.push(field); + } } Err(errors) => { infcx.report_fulfillment_errors(&errors, None, false); @@ -259,8 +240,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Attempts to returns the deeply last field of nested structures, but /// does not apply any normalization in its search. Returns the same type /// if input `ty` is not a structure at all. - pub fn struct_tail_without_normalization(self, ty: Ty<'tcx>) -> Ty<'tcx> - { + pub fn struct_tail_without_normalization(self, ty: Ty<'tcx>) -> Ty<'tcx> { let tcx = self; tcx.struct_tail_with_normalize(ty, |ty| ty) } @@ -272,11 +252,11 @@ impl<'tcx> TyCtxt<'tcx> { /// Should only be called if `ty` has no inference variables and does not /// need its lifetimes preserved (e.g. as part of codegen); otherwise /// normalization attempt may cause compiler bugs. - pub fn struct_tail_erasing_lifetimes(self, - ty: Ty<'tcx>, - param_env: ty::ParamEnv<'tcx>) - -> Ty<'tcx> - { + pub fn struct_tail_erasing_lifetimes( + self, + ty: Ty<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) -> Ty<'tcx> { let tcx = self; tcx.struct_tail_with_normalize(ty, |ty| tcx.normalize_erasing_regions(param_env, ty)) } @@ -291,11 +271,11 @@ impl<'tcx> TyCtxt<'tcx> { /// /// See also `struct_tail_erasing_lifetimes`, which is suitable for use /// during codegen. - pub fn struct_tail_with_normalize(self, - mut ty: Ty<'tcx>, - normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>) - -> Ty<'tcx> - { + pub fn struct_tail_with_normalize( + self, + mut ty: Ty<'tcx>, + normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>, + ) -> Ty<'tcx> { loop { match ty.kind { ty::Adt(def, substs) => { @@ -342,15 +322,16 @@ impl<'tcx> TyCtxt<'tcx> { /// Should only be called if the types have no inference variables and do /// not need their lifetimes preserved (e.g., as part of codegen); otherwise, /// normalization attempt may cause compiler bugs. - pub fn struct_lockstep_tails_erasing_lifetimes(self, - source: Ty<'tcx>, - target: Ty<'tcx>, - param_env: ty::ParamEnv<'tcx>) - -> (Ty<'tcx>, Ty<'tcx>) - { + pub fn struct_lockstep_tails_erasing_lifetimes( + self, + source: Ty<'tcx>, + target: Ty<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) -> (Ty<'tcx>, Ty<'tcx>) { let tcx = self; - tcx.struct_lockstep_tails_with_normalize( - source, target, |ty| tcx.normalize_erasing_regions(param_env, ty)) + tcx.struct_lockstep_tails_with_normalize(source, target, |ty| { + tcx.normalize_erasing_regions(param_env, ty) + }) } /// Same as applying `struct_tail` on `source` and `target`, but only @@ -361,35 +342,37 @@ impl<'tcx> TyCtxt<'tcx> { /// /// See also `struct_lockstep_tails_erasing_lifetimes`, which is suitable for use /// during codegen. - pub fn struct_lockstep_tails_with_normalize(self, - source: Ty<'tcx>, - target: Ty<'tcx>, - normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>) - -> (Ty<'tcx>, Ty<'tcx>) - { + pub fn struct_lockstep_tails_with_normalize( + self, + source: Ty<'tcx>, + target: Ty<'tcx>, + normalize: impl Fn(Ty<'tcx>) -> Ty<'tcx>, + ) -> (Ty<'tcx>, Ty<'tcx>) { let (mut a, mut b) = (source, target); loop { match (&a.kind, &b.kind) { (&Adt(a_def, a_substs), &Adt(b_def, b_substs)) - if a_def == b_def && a_def.is_struct() => { + if a_def == b_def && a_def.is_struct() => + { if let Some(f) = a_def.non_enum_variant().fields.last() { a = f.ty(self, a_substs); b = f.ty(self, b_substs); } else { break; } - }, - (&Tuple(a_tys), &Tuple(b_tys)) - if a_tys.len() == b_tys.len() => { + } + (&Tuple(a_tys), &Tuple(b_tys)) if a_tys.len() == b_tys.len() => { if let Some(a_last) = a_tys.last() { a = a_last.expect_ty(); b = b_tys.last().unwrap().expect_ty(); } else { break; } - }, - (ty::Projection(_), _) | (ty::Opaque(..), _) | - (_, ty::Projection(_)) | (_, ty::Opaque(..)) => { + } + (ty::Projection(_), _) + | (ty::Opaque(..), _) + | (_, ty::Projection(_)) + | (_, ty::Opaque(..)) => { // If either side is a projection, attempt to // progress via normalization. (Should be safe to // apply to both sides as normalization is @@ -429,29 +412,29 @@ impl<'tcx> TyCtxt<'tcx> { // // FIXME: callers may only have a `&[Predicate]`, not a `Vec`, so that's // what this code should accept. - pub fn required_region_bounds(self, - erased_self_ty: Ty<'tcx>, - predicates: Vec>) - -> Vec> { - debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})", - erased_self_ty, - predicates); + pub fn required_region_bounds( + self, + erased_self_ty: Ty<'tcx>, + predicates: Vec>, + ) -> Vec> { + debug!( + "required_region_bounds(erased_self_ty={:?}, predicates={:?})", + erased_self_ty, predicates + ); assert!(!erased_self_ty.has_escaping_bound_vars()); traits::elaborate_predicates(self, predicates) .filter_map(|predicate| { match predicate { - ty::Predicate::Projection(..) | - ty::Predicate::Trait(..) | - ty::Predicate::Subtype(..) | - ty::Predicate::WellFormed(..) | - ty::Predicate::ObjectSafe(..) | - ty::Predicate::ClosureKind(..) | - ty::Predicate::RegionOutlives(..) | - ty::Predicate::ConstEvaluatable(..) => { - None - } + ty::Predicate::Projection(..) + | ty::Predicate::Trait(..) + | ty::Predicate::Subtype(..) + | ty::Predicate::WellFormed(..) + | ty::Predicate::ObjectSafe(..) + | ty::Predicate::ClosureKind(..) + | ty::Predicate::RegionOutlives(..) + | ty::Predicate::ConstEvaluatable(..) => None, ty::Predicate::TypeOutlives(predicate) => { // Search for a bound of the form `erased_self_ty // : 'a`, but be wary of something like `for<'a> @@ -478,7 +461,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn calculate_dtor( self, adt_did: DefId, - validate: &mut dyn FnMut(Self, DefId) -> Result<(), ErrorReported> + validate: &mut dyn FnMut(Self, DefId) -> Result<(), ErrorReported>, ) -> Option { let drop_trait = if let Some(def_id) = self.lang_items().drop_trait() { def_id @@ -508,15 +491,13 @@ impl<'tcx> TyCtxt<'tcx> { /// Note that this returns only the constraints for the /// destructor of `def` itself. For the destructors of the /// contents, you need `adt_dtorck_constraint`. - pub fn destructor_constraints(self, def: &'tcx ty::AdtDef) - -> Vec> - { + pub fn destructor_constraints(self, def: &'tcx ty::AdtDef) -> Vec> { let dtor = match def.destructor(self) { None => { debug!("destructor_constraints({:?}) - no dtor", def.did); - return vec![] + return vec![]; } - Some(dtor) => dtor.did + Some(dtor) => dtor.did, }; let impl_def_id = self.associated_item(dtor).container.id(); @@ -545,34 +526,31 @@ impl<'tcx> TyCtxt<'tcx> { let impl_substs = match self.type_of(impl_def_id).kind { ty::Adt(def_, substs) if def_ == def => substs, - _ => bug!() + _ => bug!(), }; let item_substs = match self.type_of(def.did).kind { ty::Adt(def_, substs) if def_ == def => substs, - _ => bug!() + _ => bug!(), }; - let result = item_substs.iter().zip(impl_substs.iter()) + let result = item_substs + .iter() + .zip(impl_substs.iter()) .filter(|&(_, &k)| { match k.unpack() { GenericArgKind::Lifetime(&ty::RegionKind::ReEarlyBound(ref ebr)) => { !impl_generics.region_param(ebr, self).pure_wrt_drop } - GenericArgKind::Type(&ty::TyS { - kind: ty::Param(ref pt), .. - }) => { + GenericArgKind::Type(&ty::TyS { kind: ty::Param(ref pt), .. }) => { !impl_generics.type_param(pt, self).pure_wrt_drop } GenericArgKind::Const(&ty::Const { - val: ty::ConstKind::Param(ref pc), - .. - }) => { - !impl_generics.const_param(pc, self).pure_wrt_drop - } - GenericArgKind::Lifetime(_) | - GenericArgKind::Type(_) | - GenericArgKind::Const(_) => { + val: ty::ConstKind::Param(ref pc), .. + }) => !impl_generics.const_param(pc, self).pure_wrt_drop, + GenericArgKind::Lifetime(_) + | GenericArgKind::Type(_) + | GenericArgKind::Const(_) => { // Not a type, const or region param: this should be reported // as an error. false @@ -639,11 +617,11 @@ impl<'tcx> TyCtxt<'tcx> { /// /// Note that the return value is a late-bound region and hence /// wrapped in a binder. - pub fn closure_env_ty(self, - closure_def_id: DefId, - closure_substs: SubstsRef<'tcx>) - -> Option>> - { + pub fn closure_env_ty( + self, + closure_def_id: DefId, + closure_substs: SubstsRef<'tcx>, + ) -> Option>> { let closure_ty = self.mk_closure(closure_def_id, closure_substs); let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv); let closure_kind_ty = closure_substs.as_closure().kind_ty(closure_def_id, self); @@ -659,15 +637,13 @@ impl<'tcx> TyCtxt<'tcx> { /// Given the `DefId` of some item that has no type or const parameters, make /// a suitable "empty substs" for it. pub fn empty_substs_for_def_id(self, item_def_id: DefId) -> SubstsRef<'tcx> { - InternalSubsts::for_item(self, item_def_id, |param, _| { - match param.kind { - GenericParamDefKind::Lifetime => self.lifetimes.re_erased.into(), - GenericParamDefKind::Type { .. } => { - bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id) - } - GenericParamDefKind::Const { .. } => { - bug!("empty_substs_for_def_id: {:?} has const parameters", item_def_id) - } + InternalSubsts::for_item(self, item_def_id, |param, _| match param.kind { + GenericParamDefKind::Lifetime => self.lifetimes.re_erased.into(), + GenericParamDefKind::Type { .. } => { + bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id) + } + GenericParamDefKind::Const { .. } => { + bug!("empty_substs_for_def_id: {:?} has const parameters", item_def_id) } }) } @@ -685,10 +661,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Get the type of the pointer to the static that we use in MIR. pub fn static_ptr_ty(&self, def_id: DefId) -> Ty<'tcx> { // Make sure that any constants in the static's type are evaluated. - let static_ty = self.normalize_erasing_regions( - ty::ParamEnv::empty(), - self.type_of(def_id), - ); + let static_ty = self.normalize_erasing_regions(ty::ParamEnv::empty(), self.type_of(def_id)); if self.is_mutable_static(def_id) { self.mk_mut_ptr(static_ty) @@ -777,11 +750,7 @@ impl<'tcx> TyCtxt<'tcx> { tcx: self, }; let expanded_type = visitor.expand_opaque_ty(def_id, substs).unwrap(); - if visitor.found_recursion { - Err(expanded_type) - } else { - Ok(expanded_type) - } + if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) } } } @@ -858,15 +827,12 @@ impl<'tcx> ty::TyS<'tcx> { /// structural recursion. This check is needed for structs and enums. pub fn is_representable(&'tcx self, tcx: TyCtxt<'tcx>, sp: Span) -> Representability { // Iterate until something non-representable is found - fn fold_repr>(iter: It) -> Representability { - iter.fold(Representability::Representable, |r1, r2| { - match (r1, r2) { - (Representability::SelfRecursive(v1), - Representability::SelfRecursive(v2)) => { - Representability::SelfRecursive(v1.into_iter().chain(v2).collect()) - } - (r1, r2) => cmp::max(r1, r2) + fn fold_repr>(iter: It) -> Representability { + iter.fold(Representability::Representable, |r1, r2| match (r1, r2) { + (Representability::SelfRecursive(v1), Representability::SelfRecursive(v2)) => { + Representability::SelfRecursive(v1.into_iter().chain(v2).collect()) } + (r1, r2) => cmp::max(r1, r2), }) } @@ -881,13 +847,7 @@ impl<'tcx> ty::TyS<'tcx> { Tuple(..) => { // Find non representable fold_repr(ty.tuple_fields().map(|ty| { - is_type_structurally_recursive( - tcx, - sp, - seen, - representable_cache, - ty, - ) + is_type_structurally_recursive(tcx, sp, seen, representable_cache, ty) })) } // Fixed-length vectors. @@ -900,9 +860,13 @@ impl<'tcx> ty::TyS<'tcx> { fold_repr(def.all_fields().map(|field| { let ty = field.ty(tcx, substs); let span = tcx.hir().span_if_local(field.did).unwrap_or(sp); - match is_type_structurally_recursive(tcx, span, seen, - representable_cache, ty) - { + match is_type_structurally_recursive( + tcx, + span, + seen, + representable_cache, + ty, + ) { Representability::SelfRecursive(_) => { Representability::SelfRecursive(vec![span]) } @@ -921,10 +885,8 @@ impl<'tcx> ty::TyS<'tcx> { fn same_struct_or_enum<'tcx>(ty: Ty<'tcx>, def: &'tcx ty::AdtDef) -> bool { match ty.kind { - Adt(ty_def, _) => { - ty_def == def - } - _ => false + Adt(ty_def, _) => ty_def == def, + _ => false, } } @@ -939,13 +901,15 @@ impl<'tcx> ty::TyS<'tcx> { ) -> Representability { debug!("is_type_structurally_recursive: {:?} {:?}", ty, sp); if let Some(representability) = representable_cache.get(ty) { - debug!("is_type_structurally_recursive: {:?} {:?} - (cached) {:?}", - ty, sp, representability); + debug!( + "is_type_structurally_recursive: {:?} {:?} - (cached) {:?}", + ty, sp, representability + ); return representability.clone(); } - let representability = is_type_structurally_recursive_inner( - tcx, sp, seen, representable_cache, ty); + let representability = + is_type_structurally_recursive_inner(tcx, sp, seen, representable_cache, ty); representable_cache.insert(ty, representability.clone()); representability @@ -974,9 +938,7 @@ impl<'tcx> ty::TyS<'tcx> { if let Some(&seen_type) = iter.next() { if same_struct_or_enum(seen_type, def) { - debug!("SelfRecursive: {:?} contains {:?}", - seen_type, - ty); + debug!("SelfRecursive: {:?} contains {:?}", seen_type, ty); return Representability::SelfRecursive(vec![sp]); } } @@ -993,9 +955,7 @@ impl<'tcx> ty::TyS<'tcx> { for &seen_type in iter { if ty::TyS::same_type(ty, seen_type) { - debug!("ContainsRecursive: {:?} contains {:?}", - seen_type, - ty); + debug!("ContainsRecursive: {:?} contains {:?}", seen_type, ty); return Representability::ContainsRecursive; } } @@ -1022,8 +982,7 @@ impl<'tcx> ty::TyS<'tcx> { // of seen types and check recursion for each of them (issues #3008, #3779). let mut seen: Vec> = Vec::new(); let mut representable_cache = FxHashMap::default(); - let r = is_type_structurally_recursive( - tcx, sp, &mut seen, &mut representable_cache, self); + let r = is_type_structurally_recursive(tcx, sp, &mut seen, &mut representable_cache, self); debug!("is_type_representable: {:?} is {:?}", self, r); r } @@ -1053,7 +1012,6 @@ fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) fn is_sized_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { is_item_raw(tcx, query, lang_items::SizedTraitLangItem) - } fn is_freeze_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { @@ -1067,14 +1025,15 @@ fn is_item_raw<'tcx>( ) -> bool { let (param_env, ty) = query.into_parts(); let trait_def_id = tcx.require_lang_item(item, None); - tcx.infer_ctxt() - .enter(|infcx| traits::type_known_to_meet_bound_modulo_regions( + tcx.infer_ctxt().enter(|infcx| { + traits::type_known_to_meet_bound_modulo_regions( &infcx, param_env, ty, trait_def_id, DUMMY_SP, - )) + ) + }) } #[derive(Clone, HashStable)] @@ -1083,18 +1042,26 @@ pub struct NeedsDrop(pub bool); fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> NeedsDrop { let (param_env, ty) = query.into_parts(); - let needs_drop = |ty: Ty<'tcx>| -> bool { - tcx.needs_drop_raw(param_env.and(ty)).0 - }; + let needs_drop = |ty: Ty<'tcx>| -> bool { tcx.needs_drop_raw(param_env.and(ty)).0 }; assert!(!ty.needs_infer()); NeedsDrop(match ty.kind { // Fast-path for primitive types - ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshFloatTy(_)) | - ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Never | - ty::FnDef(..) | ty::FnPtr(_) | ty::Char | ty::GeneratorWitness(..) | - ty::RawPtr(_) | ty::Ref(..) | ty::Str => false, + ty::Infer(ty::FreshIntTy(_)) + | ty::Infer(ty::FreshFloatTy(_)) + | ty::Bool + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Never + | ty::FnDef(..) + | ty::FnPtr(_) + | ty::Char + | ty::GeneratorWitness(..) + | ty::RawPtr(_) + | ty::Ref(..) + | ty::Str => false, // Foreign types can never have destructors ty::Foreign(..) => false, @@ -1122,8 +1089,14 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx> // Can refer to a type which may drop. // FIXME(eddyb) check this against a ParamEnv. - ty::Dynamic(..) | ty::Projection(..) | ty::Param(_) | ty::Bound(..) | - ty::Placeholder(..) | ty::Opaque(..) | ty::Infer(_) | ty::Error => true, + ty::Dynamic(..) + | ty::Projection(..) + | ty::Param(_) + | ty::Bound(..) + | ty::Placeholder(..) + | ty::Opaque(..) + | ty::Infer(_) + | ty::Error => true, ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), @@ -1148,10 +1121,10 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx> // only if they manually implement `Drop` (handled above). ty::Adt(def, _) if def.is_union() => false, - ty::Adt(def, substs) => - def.variants.iter().any( - |variant| variant.fields.iter().any( - |field| needs_drop(field.ty(tcx, substs)))), + ty::Adt(def, substs) => def + .variants + .iter() + .any(|variant| variant.fields.iter().any(|field| needs_drop(field.ty(tcx, substs)))), }) } @@ -1160,7 +1133,7 @@ pub enum ExplicitSelf<'tcx> { ByReference(ty::Region<'tcx>, hir::Mutability), ByRawPointer(hir::Mutability), ByBox, - Other + Other, } impl<'tcx> ExplicitSelf<'tcx> { @@ -1188,27 +1161,18 @@ impl<'tcx> ExplicitSelf<'tcx> { /// } /// ``` /// - pub fn determine

( - self_arg_ty: Ty<'tcx>, - is_self_ty: P - ) -> ExplicitSelf<'tcx> + pub fn determine

(self_arg_ty: Ty<'tcx>, is_self_ty: P) -> ExplicitSelf<'tcx> where - P: Fn(Ty<'tcx>) -> bool + P: Fn(Ty<'tcx>) -> bool, { use self::ExplicitSelf::*; match self_arg_ty.kind { _ if is_self_ty(self_arg_ty) => ByValue, - ty::Ref(region, ty, mutbl) if is_self_ty(ty) => { - ByReference(region, mutbl) - } - ty::RawPtr(ty::TypeAndMut { ty, mutbl }) if is_self_ty(ty) => { - ByRawPointer(mutbl) - } - ty::Adt(def, _) if def.is_box() && is_self_ty(self_arg_ty.boxed_ty()) => { - ByBox - } - _ => Other + ty::Ref(region, ty, mutbl) if is_self_ty(ty) => ByReference(region, mutbl), + ty::RawPtr(ty::TypeAndMut { ty, mutbl }) if is_self_ty(ty) => ByRawPointer(mutbl), + ty::Adt(def, _) if def.is_box() && is_self_ty(self_arg_ty.boxed_ty()) => ByBox, + _ => Other, } } } diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 8d0f9a4716247..9e0dd8e067a20 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -16,7 +16,7 @@ pub struct TypeWalker<'tcx> { impl<'tcx> TypeWalker<'tcx> { pub fn new(ty: Ty<'tcx>) -> TypeWalker<'tcx> { - TypeWalker { stack: smallvec![ty], last_subtree: 1, } + TypeWalker { stack: smallvec![ty], last_subtree: 1 } } /// Skips the subtree of types corresponding to the last type @@ -42,9 +42,7 @@ impl<'tcx> Iterator for TypeWalker<'tcx> { fn next(&mut self) -> Option> { debug!("next(): stack={:?}", self.stack); match self.stack.pop() { - None => { - None - } + None => None, Some(ty) => { self.last_subtree = self.stack.len(); push_subtypes(&mut self.stack, ty); @@ -69,10 +67,19 @@ pub fn walk_shallow(ty: Ty<'_>) -> smallvec::IntoIter> { // types as they are written). fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { match parent_ty.kind { - ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | - ty::Str | ty::Infer(_) | ty::Param(_) | ty::Never | ty::Error | - ty::Placeholder(..) | ty::Bound(..) | ty::Foreign(..) => { - } + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Str + | ty::Infer(_) + | ty::Param(_) + | ty::Never + | ty::Error + | ty::Placeholder(..) + | ty::Bound(..) + | ty::Foreign(..) => {} ty::Array(ty, len) => { if let ty::ConstKind::Unevaluated(_, substs) = len.val { stack.extend(substs.types().rev()); @@ -96,11 +103,12 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { stack.extend(obj.iter().rev().flat_map(|predicate| { let (substs, opt_ty) = match *predicate.skip_binder() { ty::ExistentialPredicate::Trait(tr) => (tr.substs, None), - ty::ExistentialPredicate::Projection(p) => - (p.substs, Some(p.ty)), + ty::ExistentialPredicate::Projection(p) => (p.substs, Some(p.ty)), ty::ExistentialPredicate::AutoTrait(_) => - // Empty iterator - (ty::InternalSubsts::empty(), None), + // Empty iterator + { + (ty::InternalSubsts::empty(), None) + } }; substs.types().rev().chain(opt_ty) @@ -109,8 +117,7 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { ty::Adt(_, substs) | ty::Opaque(_, substs) => { stack.extend(substs.types().rev()); } - ty::Closure(_, ref substs) - | ty::Generator(_, ref substs, _) => { + ty::Closure(_, ref substs) | ty::Generator(_, ref substs, _) => { stack.extend(substs.types().rev()); } ty::GeneratorWitness(ts) => { diff --git a/src/librustc/util/bug.rs b/src/librustc/util/bug.rs index 02ddfab6d826e..8c1f416235a6c 100644 --- a/src/librustc/util/bug.rs +++ b/src/librustc/util/bug.rs @@ -2,7 +2,7 @@ use crate::ty::tls; use std::fmt; -use syntax_pos::{Span, MultiSpan}; +use syntax_pos::{MultiSpan, Span}; #[cold] #[inline(never)] diff --git a/src/librustc/util/captures.rs b/src/librustc/util/captures.rs index dee9a7c3f4a78..26b90ebfd5f11 100644 --- a/src/librustc/util/captures.rs +++ b/src/librustc/util/captures.rs @@ -5,6 +5,6 @@ /// [this comment]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999 // FIXME(eddyb) false positive, the lifetime parameter is "phantom" but needed. #[allow(unused_lifetimes)] -pub trait Captures<'a> { } +pub trait Captures<'a> {} -impl<'a, T: ?Sized> Captures<'a> for T { } +impl<'a, T: ?Sized> Captures<'a> for T {} diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 7515d30e46994..581f1c0ab6a2d 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -6,8 +6,8 @@ use std::cell::Cell; use std::fmt::Debug; use std::time::{Duration, Instant}; -use syntax::symbol::{Symbol, sym}; use crate::session::Session; +use syntax::symbol::{sym, Symbol}; #[cfg(test)] mod tests; @@ -39,16 +39,20 @@ pub fn set_time_depth(depth: usize) { TIME_DEPTH.with(|slot| slot.set(depth)); } -pub fn time(sess: &Session, what: &str, f: F) -> T where +pub fn time(sess: &Session, what: &str, f: F) -> T +where F: FnOnce() -> T, { time_ext(sess.time_passes(), what, f) } -pub fn time_ext(do_it: bool, what: &str, f: F) -> T where +pub fn time_ext(do_it: bool, what: &str, f: F) -> T +where F: FnOnce() -> T, { - if !do_it { return f(); } + if !do_it { + return f(); + } let old = TIME_DEPTH.with(|slot| { let r = slot.get(); @@ -69,7 +73,7 @@ pub fn time_ext(do_it: bool, what: &str, f: F) -> T where pub fn print_time_passes_entry(do_it: bool, what: &str, dur: Duration) { if !do_it { - return + return; } let indentation = TIME_DEPTH.with(|slot| slot.get()); @@ -81,11 +85,13 @@ pub fn print_time_passes_entry(do_it: bool, what: &str, dur: Duration) { } None => String::new(), }; - println!("{}time: {}{}\t{}", - " ".repeat(indentation), - duration_to_secs_str(dur), - mem_string, - what); + println!( + "{}time: {}{}\t{}", + " ".repeat(indentation), + duration_to_secs_str(dur), + mem_string, + what + ); } pub use rustc_session::utils::duration_to_secs_str; @@ -110,7 +116,8 @@ pub fn to_readable_str(mut val: usize) -> String { groups.join("_") } -pub fn record_time(accu: &Lock, f: F) -> T where +pub fn record_time(accu: &Lock, f: F) -> T +where F: FnOnce() -> T, { let start = Instant::now(); @@ -159,9 +166,11 @@ fn get_resident() -> Option { #[link(name = "psapi")] extern "system" { fn GetCurrentProcess() -> HANDLE; - fn GetProcessMemoryInfo(Process: HANDLE, - ppsmemCounters: PPROCESS_MEMORY_COUNTERS, - cb: DWORD) -> BOOL; + fn GetProcessMemoryInfo( + Process: HANDLE, + ppsmemCounters: PPROCESS_MEMORY_COUNTERS, + cb: DWORD, + ) -> BOOL; } let mut pmc: PROCESS_MEMORY_COUNTERS = unsafe { mem::zeroed() }; pmc.cb = mem::size_of_val(&pmc) as DWORD; @@ -171,7 +180,8 @@ fn get_resident() -> Option { } } -pub fn indent(op: F) -> R where +pub fn indent(op: F) -> R +where R: Debug, F: FnOnce() -> R, { @@ -188,7 +198,9 @@ pub struct Indenter { } impl Drop for Indenter { - fn drop(&mut self) { debug!("<<"); } + fn drop(&mut self) { + debug!("<<"); + } } pub fn indenter() -> Indenter { diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs index 63c7b76d1b6a5..ce0f77e0b6d37 100644 --- a/src/librustc/util/nodemap.rs +++ b/src/librustc/util/nodemap.rs @@ -11,7 +11,7 @@ macro_rules! define_id_collections { ($map_name:ident, $set_name:ident, $key:ty) => { pub type $map_name = FxHashMap<$key, T>; pub type $set_name = FxHashSet<$key>; - } + }; } define_id_collections!(NodeMap, NodeSet, ast::NodeId); diff --git a/src/librustc_apfloat/ieee.rs b/src/librustc_apfloat/ieee.rs index 4abb86a5251a5..dd56835edbac5 100644 --- a/src/librustc_apfloat/ieee.rs +++ b/src/librustc_apfloat/ieee.rs @@ -7,7 +7,7 @@ use core::fmt::{self, Write}; use core::marker::PhantomData; use core::mem; use core::ops::Neg; -use smallvec::{SmallVec, smallvec}; +use smallvec::{smallvec, SmallVec}; #[must_use] pub struct IeeeFloat { @@ -42,9 +42,9 @@ fn limbs_for_bits(bits: usize) -> usize { #[derive(Copy, Clone, PartialEq, Eq, Debug)] enum Loss { // Example of truncated bits: - ExactlyZero, // 000000 + ExactlyZero, // 000000 LessThanHalf, // 0xxxxx x's not all zero - ExactlyHalf, // 100000 + ExactlyHalf, // 100000 MoreThanHalf, // 1xxxxx x's not all zero } @@ -264,18 +264,19 @@ impl PartialEq for IeeeFloat { impl PartialOrd for IeeeFloat { fn partial_cmp(&self, rhs: &Self) -> Option { match (self.category, rhs.category) { - (Category::NaN, _) | - (_, Category::NaN) => None, + (Category::NaN, _) | (_, Category::NaN) => None, (Category::Infinity, Category::Infinity) => Some((!self.sign).cmp(&(!rhs.sign))), (Category::Zero, Category::Zero) => Some(Ordering::Equal), - (Category::Infinity, _) | - (Category::Normal, Category::Zero) => Some((!self.sign).cmp(&self.sign)), + (Category::Infinity, _) | (Category::Normal, Category::Zero) => { + Some((!self.sign).cmp(&self.sign)) + } - (_, Category::Infinity) | - (Category::Zero, Category::Normal) => Some(rhs.sign.cmp(&(!rhs.sign))), + (_, Category::Infinity) | (Category::Zero, Category::Normal) => { + Some(rhs.sign.cmp(&(!rhs.sign))) + } (Category::Normal, Category::Normal) => { // Two normal numbers. Do they have the same sign? @@ -615,11 +616,15 @@ impl fmt::Display for IeeeFloat { impl fmt::Debug for IeeeFloat { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}({:?} | {}{:?} * 2^{})", - self, self.category, - if self.sign { "-" } else { "+" }, - self.sig, - self.exp) + write!( + f, + "{}({:?} | {}{:?} * 2^{})", + self, + self.category, + if self.sign { "-" } else { "+" }, + self.sig, + self.exp + ) } } @@ -656,13 +661,11 @@ impl Float for IeeeFloat { fn qnan(payload: Option) -> Self { IeeeFloat { - sig: [ - S::QNAN_SIGNIFICAND | - payload.map_or(0, |payload| { - // Zero out the excess bits of the significand. - payload & ((1 << S::QNAN_BIT) - 1) - }), - ], + sig: [S::QNAN_SIGNIFICAND + | payload.map_or(0, |payload| { + // Zero out the excess bits of the significand. + payload & ((1 << S::QNAN_BIT) - 1) + })], exp: S::MAX_EXP + 1, category: Category::NaN, sign: false, @@ -737,13 +740,11 @@ impl Float for IeeeFloat { } // Sign may depend on rounding mode; handled below. - (_, Category::Zero) | - (Category::NaN, _) | - (Category::Infinity, Category::Normal) => Status::OK, + (_, Category::Zero) | (Category::NaN, _) | (Category::Infinity, Category::Normal) => { + Status::OK + } - (Category::Zero, _) | - (_, Category::NaN) | - (_, Category::Infinity) => { + (Category::Zero, _) | (_, Category::NaN) | (_, Category::Infinity) => { self = rhs; Status::OK } @@ -771,8 +772,8 @@ impl Float for IeeeFloat { // If two numbers add (exactly) to zero, IEEE 754 decrees it is a // positive zero unless rounding to minus infinity, except that // adding two like-signed zeroes gives that zero. - if self.category == Category::Zero && - (rhs.category != Category::Zero || self.sign != rhs.sign) + if self.category == Category::Zero + && (rhs.category != Category::Zero || self.sign != rhs.sign) { self.sign = round == Round::TowardNegative; } @@ -796,17 +797,16 @@ impl Float for IeeeFloat { Status::OK.and(self) } - (Category::Zero, Category::Infinity) | - (Category::Infinity, Category::Zero) => Status::INVALID_OP.and(Self::NAN), + (Category::Zero, Category::Infinity) | (Category::Infinity, Category::Zero) => { + Status::INVALID_OP.and(Self::NAN) + } - (_, Category::Infinity) | - (Category::Infinity, _) => { + (_, Category::Infinity) | (Category::Infinity, _) => { self.category = Category::Infinity; Status::OK.and(self) } - (Category::Zero, _) | - (_, Category::Zero) => { + (Category::Zero, _) | (_, Category::Zero) => { self.category = Category::Zero; Status::OK.and(self) } @@ -814,13 +814,8 @@ impl Float for IeeeFloat { (Category::Normal, Category::Normal) => { self.exp += rhs.exp; let mut wide_sig = [0; 2]; - let loss = sig::mul( - &mut wide_sig, - &mut self.exp, - &self.sig, - &rhs.sig, - S::PRECISION, - ); + let loss = + sig::mul(&mut wide_sig, &mut self.exp, &self.sig, &rhs.sig, S::PRECISION); self.sig = [wide_sig[0]]; let mut status; self = unpack!(status=, self.normalize(round, loss)); @@ -891,11 +886,7 @@ impl Float for IeeeFloat { // Extend the addend significand to ext_precision - 1. This guarantees // that the high bit of the significand is zero (same as wide_sig), // so the addition will overflow (if it does overflow at all) into the top bit. - sig::shift_left( - &mut ext_addend_sig, - &mut 0, - ext_precision - 1 - S::PRECISION, - ); + sig::shift_left(&mut ext_addend_sig, &mut 0, ext_precision - 1 - S::PRECISION); loss = sig::add_or_sub( &mut wide_sig, &mut self.exp, @@ -933,8 +924,9 @@ impl Float for IeeeFloat { // If two numbers add (exactly) to zero, IEEE 754 decrees it is a // positive zero unless rounding to minus infinity, except that // adding two like-signed zeroes gives that zero. - if self.category == Category::Zero && !status.intersects(Status::UNDERFLOW) && - self.sign != addend.sign + if self.category == Category::Zero + && !status.intersects(Status::UNDERFLOW) + && self.sign != addend.sign { self.sign = round == Round::TowardNegative; } @@ -958,11 +950,11 @@ impl Float for IeeeFloat { Status::OK.and(self) } - (Category::Infinity, Category::Infinity) | - (Category::Zero, Category::Zero) => Status::INVALID_OP.and(Self::NAN), + (Category::Infinity, Category::Infinity) | (Category::Zero, Category::Zero) => { + Status::INVALID_OP.and(Self::NAN) + } - (Category::Infinity, _) | - (Category::Zero, _) => Status::OK.and(self), + (Category::Infinity, _) | (Category::Zero, _) => Status::OK.and(self), (Category::Normal, Category::Infinity) => { self.category = Category::Zero; @@ -996,10 +988,10 @@ impl Float for IeeeFloat { fn c_fmod(mut self, rhs: Self) -> StatusAnd { match (self.category, rhs.category) { - (Category::NaN, _) | - (Category::Zero, Category::Infinity) | - (Category::Zero, Category::Normal) | - (Category::Normal, Category::Infinity) => Status::OK.and(self), + (Category::NaN, _) + | (Category::Zero, Category::Infinity) + | (Category::Zero, Category::Normal) + | (Category::Normal, Category::Infinity) => Status::OK.and(self), (_, Category::NaN) => { self.sign = false; @@ -1008,12 +1000,12 @@ impl Float for IeeeFloat { Status::OK.and(self) } - (Category::Infinity, _) | - (_, Category::Zero) => Status::INVALID_OP.and(Self::NAN), + (Category::Infinity, _) | (_, Category::Zero) => Status::INVALID_OP.and(Self::NAN), (Category::Normal, Category::Normal) => { - while self.is_finite_non_zero() && rhs.is_finite_non_zero() && - self.cmp_abs_normal(rhs) != Ordering::Less + while self.is_finite_non_zero() + && rhs.is_finite_non_zero() + && self.cmp_abs_normal(rhs) != Ordering::Less { let mut v = rhs.scalbn(self.ilogb() - rhs.ilogb()); if self.cmp_abs_normal(v) == Ordering::Less { @@ -1113,8 +1105,8 @@ impl Float for IeeeFloat { // 1. exponent != S::MIN_EXP. This implies we are not in the // smallest binade or are dealing with denormals. // 2. Our significand excluding the integral bit is all zeros. - let crossing_binade_boundary = self.exp != S::MIN_EXP && - self.sig[0] & sig_mask == 0; + let crossing_binade_boundary = + self.exp != S::MIN_EXP && self.sig[0] & sig_mask == 0; // Decrement the significand. // @@ -1147,8 +1139,8 @@ impl Float for IeeeFloat { // the integral bit to 1, and increment the exponent. If we have a // denormal always increment since moving denormals and the numbers in the // smallest normal binade have the same exponent in our representation. - let crossing_binade_boundary = !self.is_denormal() && - self.sig[0] & sig_mask == sig_mask; + let crossing_binade_boundary = + !self.is_denormal() && self.sig[0] & sig_mask == sig_mask; if crossing_binade_boundary { self.sig = [0]; @@ -1181,7 +1173,8 @@ impl Float for IeeeFloat { category: Category::Normal, sign: false, marker: PhantomData, - }.normalize(round, Loss::ExactlyZero) + } + .normalize(round, Loss::ExactlyZero) } fn from_str_r(mut s: &str, mut round: Round) -> Result, ParseError> { @@ -1289,8 +1282,8 @@ impl Float for IeeeFloat { let mut loss = Loss::ExactlyZero; if truncated_bits > 0 { loss = Loss::through_truncation(&self.sig, truncated_bits); - if loss != Loss::ExactlyZero && - self.round_away_from_zero(round, loss, truncated_bits) + if loss != Loss::ExactlyZero + && self.round_away_from_zero(round, loss, truncated_bits) { r = r.wrapping_add(1); if r == 0 { @@ -1319,9 +1312,7 @@ impl Float for IeeeFloat { assert!(rhs.is_finite_non_zero()); // If exponents are equal, do an unsigned comparison of the significands. - self.exp.cmp(&rhs.exp).then_with( - || sig::cmp(&self.sig, &rhs.sig), - ) + self.exp.cmp(&rhs.exp).then_with(|| sig::cmp(&self.sig, &rhs.sig)) } fn bitwise_eq(self, rhs: Self) -> bool { @@ -1345,8 +1336,9 @@ impl Float for IeeeFloat { } fn is_denormal(self) -> bool { - self.is_finite_non_zero() && self.exp == S::MIN_EXP && - !sig::get_bit(&self.sig, S::PRECISION - 1) + self.is_finite_non_zero() + && self.exp == S::MIN_EXP + && !sig::get_bit(&self.sig, S::PRECISION - 1) } fn is_signaling(self) -> bool { @@ -1407,8 +1399,7 @@ impl Float for IeeeFloat { let sig_bits = (S::PRECISION - 1) as ExpInt; self.exp += sig_bits; - self = self.normalize(Round::NearestTiesToEven, Loss::ExactlyZero) - .value; + self = self.normalize(Round::NearestTiesToEven, Loss::ExactlyZero).value; self.exp - sig_bits } @@ -1471,9 +1462,10 @@ impl FloatConvert> for IeeeFloat { fn is_x87_double_extended() -> bool { S::QNAN_SIGNIFICAND == X87DoubleExtendedS::QNAN_SIGNIFICAND } - let x87_special_nan = is_x87_double_extended::() && !is_x87_double_extended::() && - r.category == Category::NaN && - (r.sig[0] & S::QNAN_SIGNIFICAND) != S::QNAN_SIGNIFICAND; + let x87_special_nan = is_x87_double_extended::() + && !is_x87_double_extended::() + && r.category == Category::NaN + && (r.sig[0] & S::QNAN_SIGNIFICAND) != S::QNAN_SIGNIFICAND; // If this is a truncation of a denormal number, and the target semantics // has larger exponent range than the source semantics (this can happen @@ -1593,9 +1585,7 @@ impl IeeeFloat { // OMSB is numbered from 1. We want to place it in the integer // bit numbered PRECISION if possible, with a compensating change in // the exponent. - let mut final_exp = self.exp.saturating_add( - omsb as ExpInt - S::PRECISION as ExpInt, - ); + let mut final_exp = self.exp.saturating_add(omsb as ExpInt - S::PRECISION as ExpInt); // If the resulting exponent is too high, overflow according to // the rounding mode. @@ -1910,8 +1900,8 @@ impl IeeeFloat { } else { dec_exp = dec_exp.saturating_sub((last_sig_digit - dot) as i32); } - let significand_digits = last_sig_digit - first_sig_digit + 1 - - (dot > first_sig_digit && dot < last_sig_digit) as usize; + let significand_digits = last_sig_digit - first_sig_digit + 1 + - (dot > first_sig_digit && dot < last_sig_digit) as usize; let normalized_exp = dec_exp.saturating_add(significand_digits as i32 - 1); // Handle the cases where exponents are obviously too large or too @@ -1936,15 +1926,12 @@ impl IeeeFloat { } // Check for MIN_EXP. - if normalized_exp.saturating_add(1).saturating_mul(28738) <= - 8651 * (S::MIN_EXP as i32 - S::PRECISION as i32) + if normalized_exp.saturating_add(1).saturating_mul(28738) + <= 8651 * (S::MIN_EXP as i32 - S::PRECISION as i32) { // Underflow to zero and round. - let r = if round == Round::TowardPositive { - IeeeFloat::SMALLEST - } else { - IeeeFloat::ZERO - }; + let r = + if round == Round::TowardPositive { IeeeFloat::SMALLEST } else { IeeeFloat::ZERO }; return Ok((Status::UNDERFLOW | Status::INEXACT).and(r)); } @@ -2030,13 +2017,8 @@ impl IeeeFloat { if power & 1 != 0 { r_scratch.resize(r.len() + p5.len(), 0); - let _: Loss = sig::mul( - &mut r_scratch, - &mut 0, - &r, - &p5, - (r.len() + p5.len()) * LIMB_BITS, - ); + let _: Loss = + sig::mul(&mut r_scratch, &mut 0, &r, &p5, (r.len() + p5.len()) * LIMB_BITS); while r_scratch.last() == Some(&0) { r_scratch.pop(); } @@ -2168,8 +2150,8 @@ impl IeeeFloat { used_bits = calc_precision.saturating_sub(truncated_bits); } // Extra half-ulp lost in reciprocal of exponent. - half_ulp_err2 = 2 * - (pow5_status != Status::OK || calc_loss != Loss::ExactlyZero) as Limb; + half_ulp_err2 = + 2 * (pow5_status != Status::OK || calc_loss != Loss::ExactlyZero) as Limb; } // Both sig::mul and sig::div return the @@ -2182,9 +2164,7 @@ impl IeeeFloat { // than the returned value. // // See "How to Read Floating Point Numbers Accurately" by William D Clinger. - assert!( - half_ulp_err1 < 2 || half_ulp_err2 < 2 || (half_ulp_err1 + half_ulp_err2 < 8) - ); + assert!(half_ulp_err1 < 2 || half_ulp_err2 < 2 || (half_ulp_err1 + half_ulp_err2 < 8)); let inexact = (calc_loss != Loss::ExactlyZero) as Limb; let half_ulp_err = if half_ulp_err1 + half_ulp_err2 == 0 { @@ -2287,9 +2267,9 @@ impl Loss { /// Implementation details of IeeeFloat significands, such as big integer arithmetic. /// As a rule of thumb, no functions in this module should dynamically allocate. mod sig { + use super::{limbs_for_bits, ExpInt, Limb, Loss, LIMB_BITS}; use core::cmp::Ordering; use core::mem; - use super::{ExpInt, Limb, LIMB_BITS, limbs_for_bits, Loss}; pub(super) fn is_all_zeros(limbs: &[Limb]) -> bool { limbs.iter().all(|&l| l == 0) @@ -2297,14 +2277,20 @@ mod sig { /// One, not zero, based LSB. That is, returns 0 for a zeroed significand. pub(super) fn olsb(limbs: &[Limb]) -> usize { - limbs.iter().enumerate().find(|(_, &limb)| limb != 0).map_or(0, - |(i, limb)| i * LIMB_BITS + limb.trailing_zeros() as usize + 1) + limbs + .iter() + .enumerate() + .find(|(_, &limb)| limb != 0) + .map_or(0, |(i, limb)| i * LIMB_BITS + limb.trailing_zeros() as usize + 1) } /// One, not zero, based MSB. That is, returns 0 for a zeroed significand. pub(super) fn omsb(limbs: &[Limb]) -> usize { - limbs.iter().enumerate().rfind(|(_, &limb)| limb != 0).map_or(0, - |(i, limb)| (i + 1) * LIMB_BITS - limb.leading_zeros() as usize) + limbs + .iter() + .enumerate() + .rfind(|(_, &limb)| limb != 0) + .map_or(0, |(i, limb)| (i + 1) * LIMB_BITS - limb.leading_zeros() as usize) } /// Comparison (unsigned) of two significands. @@ -2444,10 +2430,7 @@ mod sig { if precision <= omsb { extract(dst, src, precision, omsb - precision); - ( - Loss::through_truncation(src, omsb - precision), - omsb as ExpInt - 1, - ) + (Loss::through_truncation(src, omsb - precision), omsb as ExpInt - 1) } else { extract(dst, src, omsb, 0); (Loss::ExactlyZero, precision as ExpInt - 1) @@ -2670,11 +2653,7 @@ mod sig { // caller needs to call IeeeFloat::normalize() if normalized value is // expected. let omsb = omsb(dst); - if omsb <= precision { - Loss::ExactlyZero - } else { - shift_right(dst, exp, omsb - precision) - } + if omsb <= precision { Loss::ExactlyZero } else { shift_right(dst, exp, omsb - precision) } } /// `quotient = dividend / divisor`. Returns the lost fraction. @@ -2686,7 +2665,6 @@ mod sig { divisor: &mut [Limb], precision: usize, ) -> Loss { - // Normalize the divisor. let bits = precision - omsb(divisor); shift_left(divisor, &mut 0, bits); @@ -2712,16 +2690,14 @@ mod sig { } // Helper for figuring out the lost fraction. - let lost_fraction = |dividend: &[Limb], divisor: &[Limb]| { - match cmp(dividend, divisor) { - Ordering::Greater => Loss::MoreThanHalf, - Ordering::Equal => Loss::ExactlyHalf, - Ordering::Less => { - if is_all_zeros(dividend) { - Loss::ExactlyZero - } else { - Loss::LessThanHalf - } + let lost_fraction = |dividend: &[Limb], divisor: &[Limb]| match cmp(dividend, divisor) { + Ordering::Greater => Loss::MoreThanHalf, + Ordering::Equal => Loss::ExactlyHalf, + Ordering::Less => { + if is_all_zeros(dividend) { + Loss::ExactlyZero + } else { + Loss::LessThanHalf } } }; @@ -2751,7 +2727,7 @@ mod sig { return lost_fraction(&[(rem as Limb) << 1], &[divisor as Limb]); } - } + }; } try_short_div!(u32, u16, 16); diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs index 5efe4fda8ccf8..d08ff60a366cc 100644 --- a/src/librustc_apfloat/lib.rs +++ b/src/librustc_apfloat/lib.rs @@ -33,7 +33,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![no_std] #![forbid(unsafe_code)] - #![feature(nll)] #[macro_use] @@ -41,8 +40,8 @@ extern crate alloc; use core::cmp::Ordering; use core::fmt; -use core::ops::{Neg, Add, Sub, Mul, Div, Rem}; -use core::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign}; +use core::ops::{Add, Div, Mul, Neg, Rem, Sub}; +use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign}; use core::str::FromStr; bitflags::bitflags! { @@ -69,19 +68,13 @@ pub struct StatusAnd { impl Status { pub fn and(self, value: T) -> StatusAnd { - StatusAnd { - status: self, - value, - } + StatusAnd { status: self, value } } } impl StatusAnd { pub fn map U, U>(self, f: F) -> StatusAnd { - StatusAnd { - status: self.status, - value: f(self.value), - } + StatusAnd { status: self.status, value: f(self.value) } } } @@ -102,7 +95,7 @@ macro_rules! unpack { value } } - } + }; } /// Category of internally-represented number. @@ -219,8 +212,8 @@ pub struct ParseError(pub &'static str); /// /// New operations: sqrt, nexttoward. /// -pub trait Float - : Copy +pub trait Float: + Copy + Default + FromStr + PartialOrd @@ -235,7 +228,8 @@ pub trait Float + Sub> + Mul> + Div> - + Rem> { + + Rem> +{ /// Total number of bits in the in-memory format. const BITS: usize; @@ -348,11 +342,7 @@ pub trait Float if self.is_negative() { -self } else { self } } fn copy_sign(self, rhs: Self) -> Self { - if self.is_negative() != rhs.is_negative() { - -self - } else { - self - } + if self.is_negative() != rhs.is_negative() { -self } else { self } } // Conversions @@ -409,9 +399,7 @@ pub trait Float } else { // Positive case is simpler, can pretend it's a smaller unsigned // integer, and `to_u128` will take care of all the edge cases. - self.to_u128_r(width - 1, round, is_exact).map( - |r| r as i128, - ) + self.to_u128_r(width - 1, round, is_exact).map(|r| r as i128) } } fn to_i128(self, width: usize) -> StatusAnd { @@ -535,9 +523,7 @@ pub trait Float if !self.is_finite() { return false; } - self.round_to_integral(Round::TowardZero).value.bitwise_eq( - self, - ) + self.round_to_integral(Round::TowardZero).value.bitwise_eq(self) } /// If this value has an exact multiplicative inverse, return it. @@ -586,13 +572,19 @@ pub trait FloatConvert: Float { macro_rules! float_common_impls { ($ty:ident<$t:tt>) => { - impl<$t> Default for $ty<$t> where Self: Float { + impl<$t> Default for $ty<$t> + where + Self: Float, + { fn default() -> Self { Self::ZERO } } - impl<$t> ::core::str::FromStr for $ty<$t> where Self: Float { + impl<$t> ::core::str::FromStr for $ty<$t> + where + Self: Float, + { type Err = ParseError; fn from_str(s: &str) -> Result { Self::from_str_r(s, Round::NearestTiesToEven).map(|x| x.value) @@ -601,71 +593,101 @@ macro_rules! float_common_impls { // Rounding ties to the nearest even, by default. - impl<$t> ::core::ops::Add for $ty<$t> where Self: Float { + impl<$t> ::core::ops::Add for $ty<$t> + where + Self: Float, + { type Output = StatusAnd; fn add(self, rhs: Self) -> StatusAnd { self.add_r(rhs, Round::NearestTiesToEven) } } - impl<$t> ::core::ops::Sub for $ty<$t> where Self: Float { + impl<$t> ::core::ops::Sub for $ty<$t> + where + Self: Float, + { type Output = StatusAnd; fn sub(self, rhs: Self) -> StatusAnd { self.sub_r(rhs, Round::NearestTiesToEven) } } - impl<$t> ::core::ops::Mul for $ty<$t> where Self: Float { + impl<$t> ::core::ops::Mul for $ty<$t> + where + Self: Float, + { type Output = StatusAnd; fn mul(self, rhs: Self) -> StatusAnd { self.mul_r(rhs, Round::NearestTiesToEven) } } - impl<$t> ::core::ops::Div for $ty<$t> where Self: Float { + impl<$t> ::core::ops::Div for $ty<$t> + where + Self: Float, + { type Output = StatusAnd; fn div(self, rhs: Self) -> StatusAnd { self.div_r(rhs, Round::NearestTiesToEven) } } - impl<$t> ::core::ops::Rem for $ty<$t> where Self: Float { + impl<$t> ::core::ops::Rem for $ty<$t> + where + Self: Float, + { type Output = StatusAnd; fn rem(self, rhs: Self) -> StatusAnd { self.c_fmod(rhs) } } - impl<$t> ::core::ops::AddAssign for $ty<$t> where Self: Float { + impl<$t> ::core::ops::AddAssign for $ty<$t> + where + Self: Float, + { fn add_assign(&mut self, rhs: Self) { *self = (*self + rhs).value; } } - impl<$t> ::core::ops::SubAssign for $ty<$t> where Self: Float { + impl<$t> ::core::ops::SubAssign for $ty<$t> + where + Self: Float, + { fn sub_assign(&mut self, rhs: Self) { *self = (*self - rhs).value; } } - impl<$t> ::core::ops::MulAssign for $ty<$t> where Self: Float { + impl<$t> ::core::ops::MulAssign for $ty<$t> + where + Self: Float, + { fn mul_assign(&mut self, rhs: Self) { *self = (*self * rhs).value; } } - impl<$t> ::core::ops::DivAssign for $ty<$t> where Self: Float { + impl<$t> ::core::ops::DivAssign for $ty<$t> + where + Self: Float, + { fn div_assign(&mut self, rhs: Self) { *self = (*self / rhs).value; } } - impl<$t> ::core::ops::RemAssign for $ty<$t> where Self: Float { + impl<$t> ::core::ops::RemAssign for $ty<$t> + where + Self: Float, + { fn rem_assign(&mut self, rhs: Self) { *self = (*self % rhs).value; } } - } + }; } pub mod ieee; diff --git a/src/librustc_apfloat/ppc.rs b/src/librustc_apfloat/ppc.rs index 8e2e390568e48..e0b306ac47cc4 100644 --- a/src/librustc_apfloat/ppc.rs +++ b/src/librustc_apfloat/ppc.rs @@ -1,5 +1,5 @@ -use crate::{Category, ExpInt, Float, FloatConvert, Round, ParseError, Status, StatusAnd}; use crate::ieee; +use crate::{Category, ExpInt, Float, FloatConvert, ParseError, Round, Status, StatusAnd}; use core::cmp::Ordering; use core::fmt; @@ -165,10 +165,7 @@ where const SMALLEST: Self = DoubleFloat(F::SMALLEST, F::ZERO); fn smallest_normalized() -> Self { - DoubleFloat( - F::smallest_normalized().scalbn(F::PRECISION as ExpInt), - F::ZERO, - ) + DoubleFloat(F::smallest_normalized().scalbn(F::PRECISION as ExpInt), F::ZERO) } // Implement addition, subtraction, multiplication and division based on: @@ -185,13 +182,13 @@ where } } - (_, Category::Zero) | - (Category::NaN, _) | - (Category::Infinity, Category::Normal) => Status::OK.and(self), + (_, Category::Zero) | (Category::NaN, _) | (Category::Infinity, Category::Normal) => { + Status::OK.and(self) + } - (Category::Zero, _) | - (_, Category::NaN) | - (_, Category::Infinity) => Status::OK.and(rhs), + (Category::Zero, _) | (_, Category::NaN) | (_, Category::Infinity) => { + Status::OK.and(rhs) + } (Category::Normal, Category::Normal) => { let mut status = Status::OK; @@ -287,14 +284,13 @@ where (_, Category::NaN) => Status::OK.and(rhs), - (Category::Zero, Category::Infinity) | - (Category::Infinity, Category::Zero) => Status::OK.and(Self::NAN), + (Category::Zero, Category::Infinity) | (Category::Infinity, Category::Zero) => { + Status::OK.and(Self::NAN) + } - (Category::Zero, _) | - (Category::Infinity, _) => Status::OK.and(self), + (Category::Zero, _) | (Category::Infinity, _) => Status::OK.and(self), - (_, Category::Zero) | - (_, Category::Infinity) => Status::OK.and(rhs), + (_, Category::Zero) | (_, Category::Infinity) => Status::OK.and(rhs), (Category::Normal, Category::Normal) => { let mut status = Status::OK; @@ -343,21 +339,15 @@ where } fn div_r(self, rhs: Self, round: Round) -> StatusAnd { - Fallback::from(self).div_r(Fallback::from(rhs), round).map( - Self::from, - ) + Fallback::from(self).div_r(Fallback::from(rhs), round).map(Self::from) } fn c_fmod(self, rhs: Self) -> StatusAnd { - Fallback::from(self).c_fmod(Fallback::from(rhs)).map( - Self::from, - ) + Fallback::from(self).c_fmod(Fallback::from(rhs)).map(Self::from) } fn round_to_integral(self, round: Round) -> StatusAnd { - Fallback::from(self).round_to_integral(round).map( - Self::from, - ) + Fallback::from(self).round_to_integral(round).map(Self::from) } fn next_up(self) -> StatusAnd { @@ -366,10 +356,7 @@ where fn from_bits(input: u128) -> Self { let (a, b) = (input, input >> F::BITS); - DoubleFloat( - F::from_bits(a & ((1 << F::BITS) - 1)), - F::from_bits(b & ((1 << F::BITS) - 1)), - ) + DoubleFloat(F::from_bits(a & ((1 << F::BITS) - 1)), F::from_bits(b & ((1 << F::BITS) - 1))) } fn from_u128_r(input: u128, round: Round) -> StatusAnd { @@ -394,11 +381,9 @@ where if result != Ordering::Equal { let against = self.0.is_negative() ^ self.1.is_negative(); let rhs_against = rhs.0.is_negative() ^ rhs.1.is_negative(); - (!against).cmp(&!rhs_against).then_with(|| if against { - result.reverse() - } else { - result - }) + (!against) + .cmp(&!rhs_against) + .then_with(|| if against { result.reverse() } else { result }) } else { result } @@ -414,8 +399,8 @@ where } fn is_denormal(self) -> bool { - self.category() == Category::Normal && - (self.0.is_denormal() || self.0.is_denormal() || + self.category() == Category::Normal + && (self.0.is_denormal() || self.0.is_denormal() || // (double)(Hi + Lo) == Hi defines a normal number. !(self.0 + self.1).value.bitwise_eq(self.0)) } diff --git a/src/librustc_apfloat/tests/ieee.rs b/src/librustc_apfloat/tests/ieee.rs index 7158efae8f1ad..e5b06cf225d16 100644 --- a/src/librustc_apfloat/tests/ieee.rs +++ b/src/librustc_apfloat/tests/ieee.rs @@ -1,9 +1,9 @@ // ignore-tidy-filelength +use rustc_apfloat::ieee::{Double, Half, Quad, Single, X87DoubleExtended}; +use rustc_apfloat::unpack; use rustc_apfloat::{Category, ExpInt, IEK_INF, IEK_NAN, IEK_ZERO}; use rustc_apfloat::{Float, FloatConvert, ParseError, Round, Status}; -use rustc_apfloat::ieee::{Half, Single, Double, Quad, X87DoubleExtended}; -use rustc_apfloat::unpack; trait SingleExt { fn from_f32(input: f32) -> Self; @@ -108,18 +108,14 @@ fn next() { // = -(-largest + inc) // = largest - inc. let test = unpack!(status=, Quad::largest().next_down()); - let expected = "0x1.fffffffffffffffffffffffffffep+16383" - .parse::() - .unwrap(); + let expected = "0x1.fffffffffffffffffffffffffffep+16383".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(!test.is_infinite() && !test.is_negative()); assert!(test.bitwise_eq(expected)); // nextUp(-largest) = -largest + inc. let test = unpack!(status=, (-Quad::largest()).next_up()); - let expected = "-0x1.fffffffffffffffffffffffffffep+16383" - .parse::() - .unwrap(); + let expected = "-0x1.fffffffffffffffffffffffffffep+16383".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.bitwise_eq(expected)); @@ -135,9 +131,7 @@ fn next() { .parse::() .unwrap() .next_up()); - let expected = "0x0.0000000000000000000000000002p-16382" - .parse::() - .unwrap(); + let expected = "0x0.0000000000000000000000000002p-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.bitwise_eq(expected)); @@ -166,9 +160,7 @@ fn next() { .parse::() .unwrap() .next_down()); - let expected = "-0x0.0000000000000000000000000002p-16382" - .parse::() - .unwrap(); + let expected = "-0x0.0000000000000000000000000002p-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.bitwise_eq(expected)); @@ -233,9 +225,7 @@ fn next() { .parse::() .unwrap() .next_up()); - let expected = "0x1.0000000000000000000000000000p-16382" - .parse::() - .unwrap(); + let expected = "0x1.0000000000000000000000000000p-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(!test.is_denormal()); assert!(test.bitwise_eq(expected)); @@ -245,9 +235,7 @@ fn next() { .parse::() .unwrap() .next_down()); - let expected = "-0x1.0000000000000000000000000000p-16382" - .parse::() - .unwrap(); + let expected = "-0x1.0000000000000000000000000000p-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(!test.is_denormal()); assert!(test.bitwise_eq(expected)); @@ -257,9 +245,7 @@ fn next() { .parse::() .unwrap() .next_up()); - let expected = "-0x0.ffffffffffffffffffffffffffffp-16382" - .parse::() - .unwrap(); + let expected = "-0x0.ffffffffffffffffffffffffffffp-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.is_denormal()); assert!(test.bitwise_eq(expected)); @@ -269,9 +255,7 @@ fn next() { .parse::() .unwrap() .next_down()); - let expected = "+0x0.ffffffffffffffffffffffffffffp-16382" - .parse::() - .unwrap(); + let expected = "+0x0.ffffffffffffffffffffffffffffp-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.is_denormal()); assert!(test.bitwise_eq(expected)); @@ -284,17 +268,13 @@ fn next() { // nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1. let test = unpack!(status=, "-0x1p+1".parse::().unwrap().next_up()); - let expected = "-0x1.ffffffffffffffffffffffffffffp+0" - .parse::() - .unwrap(); + let expected = "-0x1.ffffffffffffffffffffffffffffp+0".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.bitwise_eq(expected)); // nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1. let test = unpack!(status=, "0x1p+1".parse::().unwrap().next_down()); - let expected = "0x1.ffffffffffffffffffffffffffffp+0" - .parse::() - .unwrap(); + let expected = "0x1.ffffffffffffffffffffffffffffp+0".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.bitwise_eq(expected)); @@ -332,9 +312,7 @@ fn next() { .parse::() .unwrap() .next_up()); - let expected = "-0x0.fffffffffffffffffffffffffffep-16382" - .parse::() - .unwrap(); + let expected = "-0x0.fffffffffffffffffffffffffffep-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.is_denormal()); assert!(test.is_negative()); @@ -345,9 +323,7 @@ fn next() { .parse::() .unwrap() .next_down()); - let expected = "0x0.fffffffffffffffffffffffffffep-16382" - .parse::() - .unwrap(); + let expected = "0x0.fffffffffffffffffffffffffffep-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.is_denormal()); assert!(!test.is_negative()); @@ -358,9 +334,7 @@ fn next() { .parse::() .unwrap() .next_up()); - let expected = "0x1.0000000000000000000000000001p-16382" - .parse::() - .unwrap(); + let expected = "0x1.0000000000000000000000000001p-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(!test.is_denormal()); assert!(!test.is_negative()); @@ -371,9 +345,7 @@ fn next() { .parse::() .unwrap() .next_down()); - let expected = "-0x1.0000000000000000000000000001p-16382" - .parse::() - .unwrap(); + let expected = "-0x1.0000000000000000000000000001p-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(!test.is_denormal()); assert!(test.is_negative()); @@ -390,9 +362,7 @@ fn next() { // nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382 let test = unpack!(status=, "-0x1p-16381".parse::().unwrap().next_up()); - let expected = "-0x1.ffffffffffffffffffffffffffffp-16382" - .parse::() - .unwrap(); + let expected = "-0x1.ffffffffffffffffffffffffffffp-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.bitwise_eq(expected)); @@ -417,9 +387,7 @@ fn next() { // nextDown(0x1p-16381) -> 0x1.ffffffffffffffffffffffffffffp-16382 let test = unpack!(status=, "0x1p-16381".parse::().unwrap().next_down()); - let expected = "0x1.ffffffffffffffffffffffffffffp-16382" - .parse::() - .unwrap(); + let expected = "0x1.ffffffffffffffffffffffffffffp-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.bitwise_eq(expected)); @@ -439,9 +407,7 @@ fn next() { .parse::() .unwrap() .next_up()); - let expected = "0x0.ffffffffffffffffffffffff000dp-16382" - .parse::() - .unwrap(); + let expected = "0x0.ffffffffffffffffffffffff000dp-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.is_denormal()); assert!(!test.is_negative()); @@ -452,9 +418,7 @@ fn next() { .parse::() .unwrap() .next_down()); - let expected = "0x0.ffffffffffffffffffffffff000bp-16382" - .parse::() - .unwrap(); + let expected = "0x0.ffffffffffffffffffffffff000bp-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.is_denormal()); assert!(!test.is_negative()); @@ -465,9 +429,7 @@ fn next() { .parse::() .unwrap() .next_up()); - let expected = "-0x0.ffffffffffffffffffffffff000bp-16382" - .parse::() - .unwrap(); + let expected = "-0x0.ffffffffffffffffffffffff000bp-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.is_denormal()); assert!(test.is_negative()); @@ -478,9 +440,7 @@ fn next() { .parse::() .unwrap() .next_down()); - let expected = "-0x0.ffffffffffffffffffffffff000dp-16382" - .parse::() - .unwrap(); + let expected = "-0x0.ffffffffffffffffffffffff000dp-16382".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(test.is_denormal()); assert!(test.is_negative()); @@ -491,9 +451,7 @@ fn next() { .parse::() .unwrap() .next_up()); - let expected = "0x1.ffffffffffffffffffffffff000dp-16000" - .parse::() - .unwrap(); + let expected = "0x1.ffffffffffffffffffffffff000dp-16000".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(!test.is_denormal()); assert!(!test.is_negative()); @@ -504,9 +462,7 @@ fn next() { .parse::() .unwrap() .next_down()); - let expected = "0x1.ffffffffffffffffffffffff000bp-16000" - .parse::() - .unwrap(); + let expected = "0x1.ffffffffffffffffffffffff000bp-16000".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(!test.is_denormal()); assert!(!test.is_negative()); @@ -517,9 +473,7 @@ fn next() { .parse::() .unwrap() .next_up()); - let expected = "-0x1.ffffffffffffffffffffffff000bp-16000" - .parse::() - .unwrap(); + let expected = "-0x1.ffffffffffffffffffffffff000bp-16000".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(!test.is_denormal()); assert!(test.is_negative()); @@ -530,9 +484,7 @@ fn next() { .parse::() .unwrap() .next_down()); - let expected = "-0x1.ffffffffffffffffffffffff000dp-16000" - .parse::() - .unwrap(); + let expected = "-0x1.ffffffffffffffffffffffff000dp-16000".parse::().unwrap(); assert_eq!(status, Status::OK); assert!(!test.is_denormal()); assert!(test.is_negative()); @@ -668,9 +620,7 @@ fn denormal() { { assert!(!X87DoubleExtended::from_u128(0).value.is_denormal()); - let mut t = "3.36210314311209350626e-4932" - .parse::() - .unwrap(); + let mut t = "3.36210314311209350626e-4932".parse::().unwrap(); assert!(!t.is_denormal()); t /= X87DoubleExtended::from_u128(2).value; @@ -681,9 +631,7 @@ fn denormal() { { assert!(!Quad::from_u128(0).value.is_denormal()); - let mut t = "3.36210314311209350626267781732175260e-4932" - .parse::() - .unwrap(); + let mut t = "3.36210314311209350626267781732175260e-4932".parse::().unwrap(); assert!(!t.is_denormal()); t /= Quad::from_u128(2).value; @@ -707,7 +655,6 @@ fn decimal_strings_without_null_terminators() { assert_eq!(val.to_f64(), 0.00); let val = "0e+3"[..4].parse::().unwrap(); assert_eq!(val.to_f64(), 0.00); - } #[test] @@ -755,7 +702,6 @@ fn from_zero_decimal_single_exponent_string() { assert_eq!(0.0, "+0e-1".parse::().unwrap().to_f64()); assert_eq!(-0.0, "-0e-1".parse::().unwrap().to_f64()); - assert_eq!(0.0, "0.e1".parse::().unwrap().to_f64()); assert_eq!(0.0, "+0.e1".parse::().unwrap().to_f64()); assert_eq!(-0.0, "-0.e1".parse::().unwrap().to_f64()); @@ -780,7 +726,6 @@ fn from_zero_decimal_single_exponent_string() { assert_eq!(0.0, "+.0e-1".parse::().unwrap().to_f64()); assert_eq!(-0.0, "-.0e-1".parse::().unwrap().to_f64()); - assert_eq!(0.0, "0.0e1".parse::().unwrap().to_f64()); assert_eq!(0.0, "+0.0e1".parse::().unwrap().to_f64()); assert_eq!(-0.0, "-0.0e1".parse::().unwrap().to_f64()); @@ -793,7 +738,6 @@ fn from_zero_decimal_single_exponent_string() { assert_eq!(0.0, "+0.0e-1".parse::().unwrap().to_f64()); assert_eq!(-0.0, "-0.0e-1".parse::().unwrap().to_f64()); - assert_eq!(0.0, "000.0000e1".parse::().unwrap().to_f64()); assert_eq!(0.0, "+000.0000e+1".parse::().unwrap().to_f64()); assert_eq!(-0.0, "-000.0000e+1".parse::().unwrap().to_f64()); @@ -831,7 +775,6 @@ fn from_zero_hexadecimal_string() { assert_eq!(0.0, "+0x0p-1".parse::().unwrap().to_f64()); assert_eq!(-0.0, "-0x0p-1".parse::().unwrap().to_f64()); - assert_eq!(0.0, "0x0.p1".parse::().unwrap().to_f64()); assert_eq!(0.0, "+0x0.p1".parse::().unwrap().to_f64()); assert_eq!(-0.0, "-0x0.p1".parse::().unwrap().to_f64()); @@ -844,7 +787,6 @@ fn from_zero_hexadecimal_string() { assert_eq!(0.0, "+0x0.p-1".parse::().unwrap().to_f64()); assert_eq!(-0.0, "-0x0.p-1".parse::().unwrap().to_f64()); - assert_eq!(0.0, "0x.0p1".parse::().unwrap().to_f64()); assert_eq!(0.0, "+0x.0p1".parse::().unwrap().to_f64()); assert_eq!(-0.0, "-0x.0p1".parse::().unwrap().to_f64()); @@ -857,7 +799,6 @@ fn from_zero_hexadecimal_string() { assert_eq!(0.0, "+0x.0p-1".parse::().unwrap().to_f64()); assert_eq!(-0.0, "-0x.0p-1".parse::().unwrap().to_f64()); - assert_eq!(0.0, "0x0.0p1".parse::().unwrap().to_f64()); assert_eq!(0.0, "+0x0.0p1".parse::().unwrap().to_f64()); assert_eq!(-0.0, "-0x0.0p1".parse::().unwrap().to_f64()); @@ -870,7 +811,6 @@ fn from_zero_hexadecimal_string() { assert_eq!(0.0, "+0x0.0p-1".parse::().unwrap().to_f64()); assert_eq!(-0.0, "-0x0.0p-1".parse::().unwrap().to_f64()); - assert_eq!(0.0, "0x00000.p1".parse::().unwrap().to_f64()); assert_eq!(0.0, "0x0000.00000p1".parse::().unwrap().to_f64()); assert_eq!(0.0, "0x.00000p1".parse::().unwrap().to_f64()); @@ -907,14 +847,8 @@ fn from_decimal_string() { assert_eq!(2.05e+2, "002.05000e+2".parse::().unwrap().to_f64()); assert_eq!(2.05e-2, "002.05000e-2".parse::().unwrap().to_f64()); assert_eq!(2.05e12, "002.05000e12".parse::().unwrap().to_f64()); - assert_eq!( - 2.05e+12, - "002.05000e+12".parse::().unwrap().to_f64() - ); - assert_eq!( - 2.05e-12, - "002.05000e-12".parse::().unwrap().to_f64() - ); + assert_eq!(2.05e+12, "002.05000e+12".parse::().unwrap().to_f64()); + assert_eq!(2.05e-12, "002.05000e-12".parse::().unwrap().to_f64()); // These are "carefully selected" to overflow the fast log-base // calculations in the implementation. @@ -940,7 +874,6 @@ fn from_hexadecimal_string() { assert_eq!(1.0, "+0x1p-0".parse::().unwrap().to_f64()); assert_eq!(-1.0, "-0x1p-0".parse::().unwrap().to_f64()); - assert_eq!(2.0, "0x1p1".parse::().unwrap().to_f64()); assert_eq!(2.0, "+0x1p1".parse::().unwrap().to_f64()); assert_eq!(-2.0, "-0x1p1".parse::().unwrap().to_f64()); @@ -953,7 +886,6 @@ fn from_hexadecimal_string() { assert_eq!(0.5, "+0x1p-1".parse::().unwrap().to_f64()); assert_eq!(-0.5, "-0x1p-1".parse::().unwrap().to_f64()); - assert_eq!(3.0, "0x1.8p1".parse::().unwrap().to_f64()); assert_eq!(3.0, "+0x1.8p1".parse::().unwrap().to_f64()); assert_eq!(-3.0, "-0x1.8p1".parse::().unwrap().to_f64()); @@ -966,25 +898,17 @@ fn from_hexadecimal_string() { assert_eq!(0.75, "+0x1.8p-1".parse::().unwrap().to_f64()); assert_eq!(-0.75, "-0x1.8p-1".parse::().unwrap().to_f64()); - assert_eq!(8192.0, "0x1000.000p1".parse::().unwrap().to_f64()); assert_eq!(8192.0, "+0x1000.000p1".parse::().unwrap().to_f64()); assert_eq!(-8192.0, "-0x1000.000p1".parse::().unwrap().to_f64()); assert_eq!(8192.0, "0x1000.000p+1".parse::().unwrap().to_f64()); assert_eq!(8192.0, "+0x1000.000p+1".parse::().unwrap().to_f64()); - assert_eq!( - -8192.0, - "-0x1000.000p+1".parse::().unwrap().to_f64() - ); + assert_eq!(-8192.0, "-0x1000.000p+1".parse::().unwrap().to_f64()); assert_eq!(2048.0, "0x1000.000p-1".parse::().unwrap().to_f64()); assert_eq!(2048.0, "+0x1000.000p-1".parse::().unwrap().to_f64()); - assert_eq!( - -2048.0, - "-0x1000.000p-1".parse::().unwrap().to_f64() - ); - + assert_eq!(-2048.0, "-0x1000.000p-1".parse::().unwrap().to_f64()); assert_eq!(8192.0, "0x1000p1".parse::().unwrap().to_f64()); assert_eq!(8192.0, "+0x1000p1".parse::().unwrap().to_f64()); @@ -998,7 +922,6 @@ fn from_hexadecimal_string() { assert_eq!(2048.0, "+0x1000p-1".parse::().unwrap().to_f64()); assert_eq!(-2048.0, "-0x1000p-1".parse::().unwrap().to_f64()); - assert_eq!(16384.0, "0x10p10".parse::().unwrap().to_f64()); assert_eq!(16384.0, "+0x10p10".parse::().unwrap().to_f64()); assert_eq!(-16384.0, "-0x10p10".parse::().unwrap().to_f64()); @@ -1016,17 +939,11 @@ fn from_hexadecimal_string() { assert_eq!( "0x1p-150".parse::().unwrap().to_f64(), - "+0x800000000000000001.p-221" - .parse::() - .unwrap() - .to_f64() + "+0x800000000000000001.p-221".parse::().unwrap().to_f64() ); assert_eq!( 2251799813685248.5, - "0x80000000000004000000.010p-28" - .parse::() - .unwrap() - .to_f64() + "0x80000000000004000000.010p-28".parse::().unwrap().to_f64() ); } @@ -1048,20 +965,11 @@ fn to_string() { assert_eq!("0.0101", to_string(1.01E-2, 5, 2)); assert_eq!("0.0101", to_string(1.01E-2, 4, 2)); assert_eq!("1.01E-2", to_string(1.01E-2, 5, 1)); - assert_eq!( - "0.78539816339744828", - to_string(0.78539816339744830961, 0, 3) - ); - assert_eq!( - "4.9406564584124654E-324", - to_string(4.9406564584124654e-324, 0, 3) - ); + assert_eq!("0.78539816339744828", to_string(0.78539816339744830961, 0, 3)); + assert_eq!("4.9406564584124654E-324", to_string(4.9406564584124654e-324, 0, 3)); assert_eq!("873.18340000000001", to_string(873.1834, 0, 1)); assert_eq!("8.7318340000000001E+2", to_string(873.1834, 0, 0)); - assert_eq!( - "1.7976931348623157E+308", - to_string(1.7976931348623157E+308, 0, 0) - ); + assert_eq!("1.7976931348623157E+308", to_string(1.7976931348623157E+308, 0, 0)); let to_string = |d: f64, precision: usize, width: usize| { let x = Double::from_f64(d); @@ -1079,20 +987,11 @@ fn to_string() { assert_eq!("0.0101", to_string(1.01E-2, 5, 2)); assert_eq!("0.0101", to_string(1.01E-2, 4, 2)); assert_eq!("1.01000e-02", to_string(1.01E-2, 5, 1)); - assert_eq!( - "0.78539816339744828", - to_string(0.78539816339744830961, 0, 3) - ); - assert_eq!( - "4.94065645841246540e-324", - to_string(4.9406564584124654e-324, 0, 3) - ); + assert_eq!("0.78539816339744828", to_string(0.78539816339744830961, 0, 3)); + assert_eq!("4.94065645841246540e-324", to_string(4.9406564584124654e-324, 0, 3)); assert_eq!("873.18340000000001", to_string(873.1834, 0, 1)); assert_eq!("8.73183400000000010e+02", to_string(873.1834, 0, 0)); - assert_eq!( - "1.79769313486231570e+308", - to_string(1.7976931348623157E+308, 0, 0) - ); + assert_eq!("1.79769313486231570e+308", to_string(1.7976931348623157E+308, 0, 0)); } #[test] @@ -1101,71 +1000,43 @@ fn to_integer() { assert_eq!( Status::OK.and(10), - "10".parse::().unwrap().to_u128_r( - 5, - Round::TowardZero, - &mut is_exact, - ) + "10".parse::().unwrap().to_u128_r(5, Round::TowardZero, &mut is_exact,) ); assert!(is_exact); assert_eq!( Status::INVALID_OP.and(0), - "-10".parse::().unwrap().to_u128_r( - 5, - Round::TowardZero, - &mut is_exact, - ) + "-10".parse::().unwrap().to_u128_r(5, Round::TowardZero, &mut is_exact,) ); assert!(!is_exact); assert_eq!( Status::INVALID_OP.and(31), - "32".parse::().unwrap().to_u128_r( - 5, - Round::TowardZero, - &mut is_exact, - ) + "32".parse::().unwrap().to_u128_r(5, Round::TowardZero, &mut is_exact,) ); assert!(!is_exact); assert_eq!( Status::INEXACT.and(7), - "7.9".parse::().unwrap().to_u128_r( - 5, - Round::TowardZero, - &mut is_exact, - ) + "7.9".parse::().unwrap().to_u128_r(5, Round::TowardZero, &mut is_exact,) ); assert!(!is_exact); assert_eq!( Status::OK.and(-10), - "-10".parse::().unwrap().to_i128_r( - 5, - Round::TowardZero, - &mut is_exact, - ) + "-10".parse::().unwrap().to_i128_r(5, Round::TowardZero, &mut is_exact,) ); assert!(is_exact); assert_eq!( Status::INVALID_OP.and(-16), - "-17".parse::().unwrap().to_i128_r( - 5, - Round::TowardZero, - &mut is_exact, - ) + "-17".parse::().unwrap().to_i128_r(5, Round::TowardZero, &mut is_exact,) ); assert!(!is_exact); assert_eq!( Status::INVALID_OP.and(15), - "16".parse::().unwrap().to_i128_r( - 5, - Round::TowardZero, - &mut is_exact, - ) + "16".parse::().unwrap().to_i128_r(5, Round::TowardZero, &mut is_exact,) ); assert!(!is_exact); } @@ -1173,16 +1044,8 @@ fn to_integer() { #[test] fn nan() { fn nanbits(signaling: bool, negative: bool, fill: u128) -> u128 { - let x = if signaling { - T::snan(Some(fill)) - } else { - T::qnan(Some(fill)) - }; - if negative { - (-x).to_bits() - } else { - x.to_bits() - } + let x = if signaling { T::snan(Some(fill)) } else { T::qnan(Some(fill)) }; + if negative { (-x).to_bits() } else { x.to_bits() } } assert_eq!(0x7fc00000, nanbits::(false, false, 0)); @@ -1197,241 +1060,85 @@ fn nan() { assert_eq!(0x7ff8000000000000, nanbits::(false, false, 0)); assert_eq!(0xfff8000000000000, nanbits::(false, true, 0)); assert_eq!(0x7ff800000000ae72, nanbits::(false, false, 0xae72)); - assert_eq!( - 0x7fffffffffffae72, - nanbits::(false, false, 0xffffffffffffae72) - ); + assert_eq!(0x7fffffffffffae72, nanbits::(false, false, 0xffffffffffffae72)); assert_eq!(0x7ff4000000000000, nanbits::(true, false, 0)); assert_eq!(0xfff4000000000000, nanbits::(true, true, 0)); assert_eq!(0x7ff000000000ae72, nanbits::(true, false, 0xae72)); - assert_eq!( - 0x7ff7ffffffffae72, - nanbits::(true, false, 0xffffffffffffae72) - ); + assert_eq!(0x7ff7ffffffffae72, nanbits::(true, false, 0xffffffffffffae72)); } #[test] fn string_decimal_death() { - assert_eq!( - "".parse::(), - Err(ParseError("Invalid string length")) - ); - assert_eq!( - "+".parse::(), - Err(ParseError("String has no digits")) - ); - assert_eq!( - "-".parse::(), - Err(ParseError("String has no digits")) - ); - - assert_eq!( - "\0".parse::(), - Err(ParseError("Invalid character in significand")) - ); - assert_eq!( - "1\0".parse::(), - Err(ParseError("Invalid character in significand")) - ); - assert_eq!( - "1\02".parse::(), - Err(ParseError("Invalid character in significand")) - ); - assert_eq!( - "1\02e1".parse::(), - Err(ParseError("Invalid character in significand")) - ); - assert_eq!( - "1e\0".parse::(), - Err(ParseError("Invalid character in exponent")) - ); - assert_eq!( - "1e1\0".parse::(), - Err(ParseError("Invalid character in exponent")) - ); - assert_eq!( - "1e1\02".parse::(), - Err(ParseError("Invalid character in exponent")) - ); - - assert_eq!( - "1.0f".parse::(), - Err(ParseError("Invalid character in significand")) - ); - - assert_eq!( - "..".parse::(), - Err(ParseError("String contains multiple dots")) - ); - assert_eq!( - "..0".parse::(), - Err(ParseError("String contains multiple dots")) - ); - assert_eq!( - "1.0.0".parse::(), - Err(ParseError("String contains multiple dots")) - ); + assert_eq!("".parse::(), Err(ParseError("Invalid string length"))); + assert_eq!("+".parse::(), Err(ParseError("String has no digits"))); + assert_eq!("-".parse::(), Err(ParseError("String has no digits"))); + + assert_eq!("\0".parse::(), Err(ParseError("Invalid character in significand"))); + assert_eq!("1\0".parse::(), Err(ParseError("Invalid character in significand"))); + assert_eq!("1\02".parse::(), Err(ParseError("Invalid character in significand"))); + assert_eq!("1\02e1".parse::(), Err(ParseError("Invalid character in significand"))); + assert_eq!("1e\0".parse::(), Err(ParseError("Invalid character in exponent"))); + assert_eq!("1e1\0".parse::(), Err(ParseError("Invalid character in exponent"))); + assert_eq!("1e1\02".parse::(), Err(ParseError("Invalid character in exponent"))); + + assert_eq!("1.0f".parse::(), Err(ParseError("Invalid character in significand"))); + + assert_eq!("..".parse::(), Err(ParseError("String contains multiple dots"))); + assert_eq!("..0".parse::(), Err(ParseError("String contains multiple dots"))); + assert_eq!("1.0.0".parse::(), Err(ParseError("String contains multiple dots"))); } #[test] fn string_decimal_significand_death() { - assert_eq!( - ".".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "+.".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "-.".parse::(), - Err(ParseError("Significand has no digits")) - ); - - - assert_eq!( - "e".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "+e".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "-e".parse::(), - Err(ParseError("Significand has no digits")) - ); + assert_eq!(".".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("+.".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("-.".parse::(), Err(ParseError("Significand has no digits"))); - assert_eq!( - "e1".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "+e1".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "-e1".parse::(), - Err(ParseError("Significand has no digits")) - ); + assert_eq!("e".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("+e".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("-e".parse::(), Err(ParseError("Significand has no digits"))); - assert_eq!( - ".e1".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "+.e1".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "-.e1".parse::(), - Err(ParseError("Significand has no digits")) - ); + assert_eq!("e1".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("+e1".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("-e1".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!(".e1".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("+.e1".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("-.e1".parse::(), Err(ParseError("Significand has no digits"))); - assert_eq!( - ".e".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "+.e".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "-.e".parse::(), - Err(ParseError("Significand has no digits")) - ); + assert_eq!(".e".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("+.e".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("-.e".parse::(), Err(ParseError("Significand has no digits"))); } #[test] fn string_decimal_exponent_death() { - assert_eq!( - "1e".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+1e".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-1e".parse::(), - Err(ParseError("Exponent has no digits")) - ); - - assert_eq!( - "1.e".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+1.e".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-1.e".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!("1e".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+1e".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-1e".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - ".1e".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+.1e".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-.1e".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!("1.e".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+1.e".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-1.e".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - "1.1e".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+1.1e".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-1.1e".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!(".1e".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+.1e".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-.1e".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("1.1e".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+1.1e".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-1.1e".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - "1e+".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "1e-".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!("1e+".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("1e-".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - ".1e".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - ".1e+".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - ".1e-".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!(".1e".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!(".1e+".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!(".1e-".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - "1.0e".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "1.0e+".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "1.0e-".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!("1.0e".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("1.0e+".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("1.0e-".parse::(), Err(ParseError("Exponent has no digits"))); } #[test] @@ -1440,378 +1147,124 @@ fn string_hexadecimal_death() { assert_eq!("+0x".parse::(), Err(ParseError("Invalid string"))); assert_eq!("-0x".parse::(), Err(ParseError("Invalid string"))); - assert_eq!( - "0x0".parse::(), - Err(ParseError("Hex strings require an exponent")) - ); - assert_eq!( - "+0x0".parse::(), - Err(ParseError("Hex strings require an exponent")) - ); - assert_eq!( - "-0x0".parse::(), - Err(ParseError("Hex strings require an exponent")) - ); + assert_eq!("0x0".parse::(), Err(ParseError("Hex strings require an exponent"))); + assert_eq!("+0x0".parse::(), Err(ParseError("Hex strings require an exponent"))); + assert_eq!("-0x0".parse::(), Err(ParseError("Hex strings require an exponent"))); - assert_eq!( - "0x0.".parse::(), - Err(ParseError("Hex strings require an exponent")) - ); - assert_eq!( - "+0x0.".parse::(), - Err(ParseError("Hex strings require an exponent")) - ); - assert_eq!( - "-0x0.".parse::(), - Err(ParseError("Hex strings require an exponent")) - ); + assert_eq!("0x0.".parse::(), Err(ParseError("Hex strings require an exponent"))); + assert_eq!("+0x0.".parse::(), Err(ParseError("Hex strings require an exponent"))); + assert_eq!("-0x0.".parse::(), Err(ParseError("Hex strings require an exponent"))); - assert_eq!( - "0x.0".parse::(), - Err(ParseError("Hex strings require an exponent")) - ); - assert_eq!( - "+0x.0".parse::(), - Err(ParseError("Hex strings require an exponent")) - ); - assert_eq!( - "-0x.0".parse::(), - Err(ParseError("Hex strings require an exponent")) - ); + assert_eq!("0x.0".parse::(), Err(ParseError("Hex strings require an exponent"))); + assert_eq!("+0x.0".parse::(), Err(ParseError("Hex strings require an exponent"))); + assert_eq!("-0x.0".parse::(), Err(ParseError("Hex strings require an exponent"))); - assert_eq!( - "0x0.0".parse::(), - Err(ParseError("Hex strings require an exponent")) - ); - assert_eq!( - "+0x0.0".parse::(), - Err(ParseError("Hex strings require an exponent")) - ); - assert_eq!( - "-0x0.0".parse::(), - Err(ParseError("Hex strings require an exponent")) - ); + assert_eq!("0x0.0".parse::(), Err(ParseError("Hex strings require an exponent"))); + assert_eq!("+0x0.0".parse::(), Err(ParseError("Hex strings require an exponent"))); + assert_eq!("-0x0.0".parse::(), Err(ParseError("Hex strings require an exponent"))); - assert_eq!( - "0x\0".parse::(), - Err(ParseError("Invalid character in significand")) - ); - assert_eq!( - "0x1\0".parse::(), - Err(ParseError("Invalid character in significand")) - ); - assert_eq!( - "0x1\02".parse::(), - Err(ParseError("Invalid character in significand")) - ); - assert_eq!( - "0x1\02p1".parse::(), - Err(ParseError("Invalid character in significand")) - ); - assert_eq!( - "0x1p\0".parse::(), - Err(ParseError("Invalid character in exponent")) - ); - assert_eq!( - "0x1p1\0".parse::(), - Err(ParseError("Invalid character in exponent")) - ); - assert_eq!( - "0x1p1\02".parse::(), - Err(ParseError("Invalid character in exponent")) - ); + assert_eq!("0x\0".parse::(), Err(ParseError("Invalid character in significand"))); + assert_eq!("0x1\0".parse::(), Err(ParseError("Invalid character in significand"))); + assert_eq!("0x1\02".parse::(), Err(ParseError("Invalid character in significand"))); + assert_eq!("0x1\02p1".parse::(), Err(ParseError("Invalid character in significand"))); + assert_eq!("0x1p\0".parse::(), Err(ParseError("Invalid character in exponent"))); + assert_eq!("0x1p1\0".parse::(), Err(ParseError("Invalid character in exponent"))); + assert_eq!("0x1p1\02".parse::(), Err(ParseError("Invalid character in exponent"))); - assert_eq!( - "0x1p0f".parse::(), - Err(ParseError("Invalid character in exponent")) - ); + assert_eq!("0x1p0f".parse::(), Err(ParseError("Invalid character in exponent"))); - assert_eq!( - "0x..p1".parse::(), - Err(ParseError("String contains multiple dots")) - ); - assert_eq!( - "0x..0p1".parse::(), - Err(ParseError("String contains multiple dots")) - ); - assert_eq!( - "0x1.0.0p1".parse::(), - Err(ParseError("String contains multiple dots")) - ); + assert_eq!("0x..p1".parse::(), Err(ParseError("String contains multiple dots"))); + assert_eq!("0x..0p1".parse::(), Err(ParseError("String contains multiple dots"))); + assert_eq!("0x1.0.0p1".parse::(), Err(ParseError("String contains multiple dots"))); } #[test] fn string_hexadecimal_significand_death() { - assert_eq!( - "0x.".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "+0x.".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "-0x.".parse::(), - Err(ParseError("Significand has no digits")) - ); + assert_eq!("0x.".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("+0x.".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("-0x.".parse::(), Err(ParseError("Significand has no digits"))); - assert_eq!( - "0xp".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "+0xp".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "-0xp".parse::(), - Err(ParseError("Significand has no digits")) - ); + assert_eq!("0xp".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("+0xp".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("-0xp".parse::(), Err(ParseError("Significand has no digits"))); - assert_eq!( - "0xp+".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "+0xp+".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "-0xp+".parse::(), - Err(ParseError("Significand has no digits")) - ); + assert_eq!("0xp+".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("+0xp+".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("-0xp+".parse::(), Err(ParseError("Significand has no digits"))); - assert_eq!( - "0xp-".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "+0xp-".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "-0xp-".parse::(), - Err(ParseError("Significand has no digits")) - ); + assert_eq!("0xp-".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("+0xp-".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("-0xp-".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("0x.p".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("+0x.p".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("-0x.p".parse::(), Err(ParseError("Significand has no digits"))); - assert_eq!( - "0x.p".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "+0x.p".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "-0x.p".parse::(), - Err(ParseError("Significand has no digits")) - ); + assert_eq!("0x.p+".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("+0x.p+".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("-0x.p+".parse::(), Err(ParseError("Significand has no digits"))); - assert_eq!( - "0x.p+".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "+0x.p+".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "-0x.p+".parse::(), - Err(ParseError("Significand has no digits")) - ); - - assert_eq!( - "0x.p-".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "+0x.p-".parse::(), - Err(ParseError("Significand has no digits")) - ); - assert_eq!( - "-0x.p-".parse::(), - Err(ParseError("Significand has no digits")) - ); + assert_eq!("0x.p-".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("+0x.p-".parse::(), Err(ParseError("Significand has no digits"))); + assert_eq!("-0x.p-".parse::(), Err(ParseError("Significand has no digits"))); } #[test] fn string_hexadecimal_exponent_death() { - assert_eq!( - "0x1p".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+0x1p".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-0x1p".parse::(), - Err(ParseError("Exponent has no digits")) - ); - - assert_eq!( - "0x1p+".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+0x1p+".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-0x1p+".parse::(), - Err(ParseError("Exponent has no digits")) - ); - - assert_eq!( - "0x1p-".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+0x1p-".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-0x1p-".parse::(), - Err(ParseError("Exponent has no digits")) - ); - + assert_eq!("0x1p".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+0x1p".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-0x1p".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - "0x1.p".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+0x1.p".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-0x1.p".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!("0x1p+".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+0x1p+".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-0x1p+".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - "0x1.p+".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+0x1.p+".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-0x1.p+".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!("0x1p-".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+0x1p-".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-0x1p-".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - "0x1.p-".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+0x1.p-".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-0x1.p-".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!("0x1.p".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+0x1.p".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-0x1.p".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("0x1.p+".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+0x1.p+".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-0x1.p+".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - "0x.1p".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+0x.1p".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-0x.1p".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!("0x1.p-".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+0x1.p-".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-0x1.p-".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - "0x.1p+".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+0x.1p+".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-0x.1p+".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!("0x.1p".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+0x.1p".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-0x.1p".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - "0x.1p-".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+0x.1p-".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-0x.1p-".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!("0x.1p+".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+0x.1p+".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-0x.1p+".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("0x.1p-".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+0x.1p-".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-0x.1p-".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - "0x1.1p".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+0x1.1p".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-0x1.1p".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!("0x1.1p".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+0x1.1p".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-0x1.1p".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - "0x1.1p+".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+0x1.1p+".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-0x1.1p+".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!("0x1.1p+".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+0x1.1p+".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-0x1.1p+".parse::(), Err(ParseError("Exponent has no digits"))); - assert_eq!( - "0x1.1p-".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "+0x1.1p-".parse::(), - Err(ParseError("Exponent has no digits")) - ); - assert_eq!( - "-0x1.1p-".parse::(), - Err(ParseError("Exponent has no digits")) - ); + assert_eq!("0x1.1p-".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("+0x1.1p-".parse::(), Err(ParseError("Exponent has no digits"))); + assert_eq!("-0x1.1p-".parse::(), Err(ParseError("Exponent has no digits"))); } #[test] fn exact_inverse() { // Trivial operation. - assert!( - Double::from_f64(2.0) - .get_exact_inverse() - .unwrap() - .bitwise_eq(Double::from_f64(0.5)) - ); - assert!( - Single::from_f32(2.0) - .get_exact_inverse() - .unwrap() - .bitwise_eq(Single::from_f32(0.5)) - ); + assert!(Double::from_f64(2.0).get_exact_inverse().unwrap().bitwise_eq(Double::from_f64(0.5))); + assert!(Single::from_f32(2.0).get_exact_inverse().unwrap().bitwise_eq(Single::from_f32(0.5))); assert!( "2.0" .parse::() @@ -1842,62 +1295,28 @@ fn exact_inverse() { // Zero assert!(Double::from_f64(0.0).get_exact_inverse().is_none()); // Denormalized float - assert!( - Single::from_f32(1.40129846e-45) - .get_exact_inverse() - .is_none() - ); + assert!(Single::from_f32(1.40129846e-45).get_exact_inverse().is_none()); } #[test] fn round_to_integral() { let t = Double::from_f64(-0.5); assert_eq!(-0.0, t.round_to_integral(Round::TowardZero).value.to_f64()); - assert_eq!( - -1.0, - t.round_to_integral(Round::TowardNegative).value.to_f64() - ); - assert_eq!( - -0.0, - t.round_to_integral(Round::TowardPositive).value.to_f64() - ); - assert_eq!( - -0.0, - t.round_to_integral(Round::NearestTiesToEven).value.to_f64() - ); + assert_eq!(-1.0, t.round_to_integral(Round::TowardNegative).value.to_f64()); + assert_eq!(-0.0, t.round_to_integral(Round::TowardPositive).value.to_f64()); + assert_eq!(-0.0, t.round_to_integral(Round::NearestTiesToEven).value.to_f64()); let s = Double::from_f64(3.14); assert_eq!(3.0, s.round_to_integral(Round::TowardZero).value.to_f64()); - assert_eq!( - 3.0, - s.round_to_integral(Round::TowardNegative).value.to_f64() - ); - assert_eq!( - 4.0, - s.round_to_integral(Round::TowardPositive).value.to_f64() - ); - assert_eq!( - 3.0, - s.round_to_integral(Round::NearestTiesToEven).value.to_f64() - ); + assert_eq!(3.0, s.round_to_integral(Round::TowardNegative).value.to_f64()); + assert_eq!(4.0, s.round_to_integral(Round::TowardPositive).value.to_f64()); + assert_eq!(3.0, s.round_to_integral(Round::NearestTiesToEven).value.to_f64()); let r = Double::largest(); - assert_eq!( - r.to_f64(), - r.round_to_integral(Round::TowardZero).value.to_f64() - ); - assert_eq!( - r.to_f64(), - r.round_to_integral(Round::TowardNegative).value.to_f64() - ); - assert_eq!( - r.to_f64(), - r.round_to_integral(Round::TowardPositive).value.to_f64() - ); - assert_eq!( - r.to_f64(), - r.round_to_integral(Round::NearestTiesToEven).value.to_f64() - ); + assert_eq!(r.to_f64(), r.round_to_integral(Round::TowardZero).value.to_f64()); + assert_eq!(r.to_f64(), r.round_to_integral(Round::TowardNegative).value.to_f64()); + assert_eq!(r.to_f64(), r.round_to_integral(Round::TowardPositive).value.to_f64()); + assert_eq!(r.to_f64(), r.round_to_integral(Round::NearestTiesToEven).value.to_f64()); let p = Double::ZERO.round_to_integral(Round::TowardZero).value; assert_eq!(0.0, p.to_f64()); @@ -1907,9 +1326,7 @@ fn round_to_integral() { assert!(p.to_f64().is_nan()); let p = Double::INFINITY.round_to_integral(Round::TowardZero).value; assert!(p.to_f64().is_infinite() && p.to_f64() > 0.0); - let p = (-Double::INFINITY) - .round_to_integral(Round::TowardZero) - .value; + let p = (-Double::INFINITY).round_to_integral(Round::TowardZero).value; assert!(p.to_f64().is_infinite() && p.to_f64() < 0.0); } @@ -1952,18 +1369,14 @@ fn smallest() { assert!(test.bitwise_eq(expected)); let test = Quad::SMALLEST; - let expected = "0x0.0000000000000000000000000001p-16382" - .parse::() - .unwrap(); + let expected = "0x0.0000000000000000000000000001p-16382".parse::().unwrap(); assert!(!test.is_negative()); assert!(test.is_finite_non_zero()); assert!(test.is_denormal()); assert!(test.bitwise_eq(expected)); let test = -Quad::SMALLEST; - let expected = "-0x0.0000000000000000000000000001p-16382" - .parse::() - .unwrap(); + let expected = "-0x0.0000000000000000000000000001p-16382".parse::().unwrap(); assert!(test.is_negative()); assert!(test.is_finite_non_zero()); assert!(test.is_denormal()); @@ -2034,26 +1447,22 @@ fn zero() { #[test] fn copy_sign() { - assert!(Double::from_f64(-42.0).bitwise_eq( - Double::from_f64(42.0).copy_sign( - Double::from_f64(-1.0), - ), - )); - assert!(Double::from_f64(42.0).bitwise_eq( - Double::from_f64(-42.0).copy_sign( - Double::from_f64(1.0), - ), - )); - assert!(Double::from_f64(-42.0).bitwise_eq( - Double::from_f64(-42.0).copy_sign( - Double::from_f64(-1.0), - ), - )); - assert!(Double::from_f64(42.0).bitwise_eq( - Double::from_f64(42.0).copy_sign( - Double::from_f64(1.0), - ), - )); + assert!( + Double::from_f64(-42.0) + .bitwise_eq(Double::from_f64(42.0).copy_sign(Double::from_f64(-1.0),),) + ); + assert!( + Double::from_f64(42.0) + .bitwise_eq(Double::from_f64(-42.0).copy_sign(Double::from_f64(1.0),),) + ); + assert!( + Double::from_f64(-42.0) + .bitwise_eq(Double::from_f64(-42.0).copy_sign(Double::from_f64(-1.0),),) + ); + assert!( + Double::from_f64(42.0) + .bitwise_eq(Double::from_f64(42.0).copy_sign(Double::from_f64(1.0),),) + ); } #[test] @@ -2232,535 +1641,474 @@ fn add() { (p_inf, m_zero, "inf", Status::OK, Category::Infinity), (p_inf, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(p_inf, snan, "nan", Status::INVALID_OP, Category::NaN), - */ + // See Note 1. + (p_inf, snan, "nan", Status::INVALID_OP, Category::NaN), + */ (p_inf, p_normal_value, "inf", Status::OK, Category::Infinity), (p_inf, m_normal_value, "inf", Status::OK, Category::Infinity), - ( - p_inf, - p_largest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - m_largest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - p_smallest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - m_smallest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - p_smallest_normalized, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - m_smallest_normalized, - "inf", - Status::OK, - Category::Infinity, - ), + (p_inf, p_largest_value, "inf", Status::OK, Category::Infinity), + (p_inf, m_largest_value, "inf", Status::OK, Category::Infinity), + (p_inf, p_smallest_value, "inf", Status::OK, Category::Infinity), + (p_inf, m_smallest_value, "inf", Status::OK, Category::Infinity), + (p_inf, p_smallest_normalized, "inf", Status::OK, Category::Infinity), + (p_inf, m_smallest_normalized, "inf", Status::OK, Category::Infinity), (m_inf, p_inf, "nan", Status::INVALID_OP, Category::NaN), (m_inf, m_inf, "-inf", Status::OK, Category::Infinity), (m_inf, p_zero, "-inf", Status::OK, Category::Infinity), (m_inf, m_zero, "-inf", Status::OK, Category::Infinity), (m_inf, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(m_inf, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_inf, - p_normal_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_normal_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - p_largest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_largest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - p_smallest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_smallest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - p_smallest_normalized, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_smallest_normalized, - "-inf", - Status::OK, - Category::Infinity, - ), + // See Note 1. + (m_inf, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_inf, p_normal_value, "-inf", Status::OK, Category::Infinity), + (m_inf, m_normal_value, "-inf", Status::OK, Category::Infinity), + (m_inf, p_largest_value, "-inf", Status::OK, Category::Infinity), + (m_inf, m_largest_value, "-inf", Status::OK, Category::Infinity), + (m_inf, p_smallest_value, "-inf", Status::OK, Category::Infinity), + (m_inf, m_smallest_value, "-inf", Status::OK, Category::Infinity), + (m_inf, p_smallest_normalized, "-inf", Status::OK, Category::Infinity), + (m_inf, m_smallest_normalized, "-inf", Status::OK, Category::Infinity), (p_zero, p_inf, "inf", Status::OK, Category::Infinity), (p_zero, m_inf, "-inf", Status::OK, Category::Infinity), (p_zero, p_zero, "0x0p+0", Status::OK, Category::Zero), (p_zero, m_zero, "0x0p+0", Status::OK, Category::Zero), (p_zero, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(p_zero, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_zero, - p_normal_value, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_zero, - m_normal_value, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_zero, - p_largest_value, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - p_zero, - m_largest_value, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - p_zero, - p_smallest_value, - "0x1p-149", - Status::OK, - Category::Normal, - ), - ( - p_zero, - m_smallest_value, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - ( - p_zero, - p_smallest_normalized, - "0x1p-126", - Status::OK, - Category::Normal, - ), - ( - p_zero, - m_smallest_normalized, - "-0x1p-126", - Status::OK, - Category::Normal, - ), + // See Note 1. + (p_zero, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_zero, p_normal_value, "0x1p+0", Status::OK, Category::Normal), + (p_zero, m_normal_value, "-0x1p+0", Status::OK, Category::Normal), + (p_zero, p_largest_value, "0x1.fffffep+127", Status::OK, Category::Normal), + (p_zero, m_largest_value, "-0x1.fffffep+127", Status::OK, Category::Normal), + (p_zero, p_smallest_value, "0x1p-149", Status::OK, Category::Normal), + (p_zero, m_smallest_value, "-0x1p-149", Status::OK, Category::Normal), + (p_zero, p_smallest_normalized, "0x1p-126", Status::OK, Category::Normal), + (p_zero, m_smallest_normalized, "-0x1p-126", Status::OK, Category::Normal), (m_zero, p_inf, "inf", Status::OK, Category::Infinity), (m_zero, m_inf, "-inf", Status::OK, Category::Infinity), (m_zero, p_zero, "0x0p+0", Status::OK, Category::Zero), (m_zero, m_zero, "-0x0p+0", Status::OK, Category::Zero), (m_zero, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(m_zero, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_zero, - p_normal_value, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_zero, - m_normal_value, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_zero, - p_largest_value, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - m_zero, - m_largest_value, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - m_zero, - p_smallest_value, - "0x1p-149", - Status::OK, - Category::Normal, - ), - ( - m_zero, - m_smallest_value, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - ( - m_zero, - p_smallest_normalized, - "0x1p-126", - Status::OK, - Category::Normal, - ), - ( - m_zero, - m_smallest_normalized, - "-0x1p-126", - Status::OK, - Category::Normal, - ), + // See Note 1. + (m_zero, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_zero, p_normal_value, "0x1p+0", Status::OK, Category::Normal), + (m_zero, m_normal_value, "-0x1p+0", Status::OK, Category::Normal), + (m_zero, p_largest_value, "0x1.fffffep+127", Status::OK, Category::Normal), + (m_zero, m_largest_value, "-0x1.fffffep+127", Status::OK, Category::Normal), + (m_zero, p_smallest_value, "0x1p-149", Status::OK, Category::Normal), + (m_zero, m_smallest_value, "-0x1p-149", Status::OK, Category::Normal), + (m_zero, p_smallest_normalized, "0x1p-126", Status::OK, Category::Normal), + (m_zero, m_smallest_normalized, "-0x1p-126", Status::OK, Category::Normal), (qnan, p_inf, "nan", Status::OK, Category::NaN), (qnan, m_inf, "nan", Status::OK, Category::NaN), (qnan, p_zero, "nan", Status::OK, Category::NaN), (qnan, m_zero, "nan", Status::OK, Category::NaN), (qnan, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(qnan, snan, "nan", Status::INVALID_OP, Category::NaN), - */ + // See Note 1. + (qnan, snan, "nan", Status::INVALID_OP, Category::NaN), + */ (qnan, p_normal_value, "nan", Status::OK, Category::NaN), (qnan, m_normal_value, "nan", Status::OK, Category::NaN), (qnan, p_largest_value, "nan", Status::OK, Category::NaN), (qnan, m_largest_value, "nan", Status::OK, Category::NaN), (qnan, p_smallest_value, "nan", Status::OK, Category::NaN), (qnan, m_smallest_value, "nan", Status::OK, Category::NaN), - ( - qnan, - p_smallest_normalized, - "nan", - Status::OK, - Category::NaN, - ), - ( - qnan, - m_smallest_normalized, - "nan", - Status::OK, - Category::NaN, - ), + (qnan, p_smallest_normalized, "nan", Status::OK, Category::NaN), + (qnan, m_smallest_normalized, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(snan, p_inf, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_inf, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_zero, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_zero, "nan", Status::INVALID_OP, Category::NaN), -(snan, qnan, "nan", Status::INVALID_OP, Category::NaN), -(snan, snan, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_normal_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_normal_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_largest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_largest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_smallest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_smallest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), - */ + // See Note 1. + (snan, p_inf, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_inf, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_zero, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_zero, "nan", Status::INVALID_OP, Category::NaN), + (snan, qnan, "nan", Status::INVALID_OP, Category::NaN), + (snan, snan, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_normal_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_normal_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_largest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_largest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_smallest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_smallest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), + */ (p_normal_value, p_inf, "inf", Status::OK, Category::Infinity), - ( - p_normal_value, - m_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_normal_value, - p_zero, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_normal_value, - m_zero, - "0x1p+0", - Status::OK, - Category::Normal, - ), + (p_normal_value, m_inf, "-inf", Status::OK, Category::Infinity), + (p_normal_value, p_zero, "0x1p+0", Status::OK, Category::Normal), + (p_normal_value, m_zero, "0x1p+0", Status::OK, Category::Normal), (p_normal_value, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(p_normal_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ + // See Note 1. + (p_normal_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_normal_value, p_normal_value, "0x1p+1", Status::OK, Category::Normal), + (p_normal_value, m_normal_value, "0x0p+0", Status::OK, Category::Zero), + (p_normal_value, p_largest_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_normal_value, m_largest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_normal_value, p_smallest_value, "0x1p+0", Status::INEXACT, Category::Normal), + (p_normal_value, m_smallest_value, "0x1p+0", Status::INEXACT, Category::Normal), + (p_normal_value, p_smallest_normalized, "0x1p+0", Status::INEXACT, Category::Normal), + (p_normal_value, m_smallest_normalized, "0x1p+0", Status::INEXACT, Category::Normal), + (m_normal_value, p_inf, "inf", Status::OK, Category::Infinity), + (m_normal_value, m_inf, "-inf", Status::OK, Category::Infinity), + (m_normal_value, p_zero, "-0x1p+0", Status::OK, Category::Normal), + (m_normal_value, m_zero, "-0x1p+0", Status::OK, Category::Normal), + (m_normal_value, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (m_normal_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_normal_value, p_normal_value, "0x0p+0", Status::OK, Category::Zero), + (m_normal_value, m_normal_value, "-0x1p+1", Status::OK, Category::Normal), + (m_normal_value, p_largest_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_normal_value, m_largest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_normal_value, p_smallest_value, "-0x1p+0", Status::INEXACT, Category::Normal), + (m_normal_value, m_smallest_value, "-0x1p+0", Status::INEXACT, Category::Normal), + (m_normal_value, p_smallest_normalized, "-0x1p+0", Status::INEXACT, Category::Normal), + (m_normal_value, m_smallest_normalized, "-0x1p+0", Status::INEXACT, Category::Normal), + (p_largest_value, p_inf, "inf", Status::OK, Category::Infinity), + (p_largest_value, m_inf, "-inf", Status::OK, Category::Infinity), + (p_largest_value, p_zero, "0x1.fffffep+127", Status::OK, Category::Normal), + (p_largest_value, m_zero, "0x1.fffffep+127", Status::OK, Category::Normal), + (p_largest_value, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_largest_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_largest_value, p_normal_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_largest_value, m_normal_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_largest_value, p_largest_value, "inf", overflow_status, Category::Infinity), + (p_largest_value, m_largest_value, "0x0p+0", Status::OK, Category::Zero), + (p_largest_value, p_smallest_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_largest_value, m_smallest_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), ( - p_normal_value, - p_normal_value, - "0x1p+1", - Status::OK, + p_largest_value, + p_smallest_normalized, + "0x1.fffffep+127", + Status::INEXACT, Category::Normal, ), ( - p_normal_value, - m_normal_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_normal_value, p_largest_value, + m_smallest_normalized, "0x1.fffffep+127", Status::INEXACT, Category::Normal, ), + (m_largest_value, p_inf, "inf", Status::OK, Category::Infinity), + (m_largest_value, m_inf, "-inf", Status::OK, Category::Infinity), + (m_largest_value, p_zero, "-0x1.fffffep+127", Status::OK, Category::Normal), + (m_largest_value, m_zero, "-0x1.fffffep+127", Status::OK, Category::Normal), + (m_largest_value, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (m_largest_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_largest_value, p_normal_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_largest_value, m_normal_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_largest_value, p_largest_value, "0x0p+0", Status::OK, Category::Zero), + (m_largest_value, m_largest_value, "-inf", overflow_status, Category::Infinity), + (m_largest_value, p_smallest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_largest_value, m_smallest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), ( - p_normal_value, m_largest_value, + p_smallest_normalized, "-0x1.fffffep+127", Status::INEXACT, Category::Normal, ), ( - p_normal_value, - p_smallest_value, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_normal_value, - m_smallest_value, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_normal_value, - p_smallest_normalized, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_normal_value, + m_largest_value, m_smallest_normalized, - "0x1p+0", + "-0x1.fffffep+127", Status::INEXACT, Category::Normal, ), - (m_normal_value, p_inf, "inf", Status::OK, Category::Infinity), - ( - m_normal_value, - m_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_normal_value, - p_zero, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - m_zero, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - (m_normal_value, qnan, "nan", Status::OK, Category::NaN), + (p_smallest_value, p_inf, "inf", Status::OK, Category::Infinity), + (p_smallest_value, m_inf, "-inf", Status::OK, Category::Infinity), + (p_smallest_value, p_zero, "0x1p-149", Status::OK, Category::Normal), + (p_smallest_value, m_zero, "0x1p-149", Status::OK, Category::Normal), + (p_smallest_value, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(m_normal_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_normal_value, - p_normal_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_normal_value, - m_normal_value, - "-0x1p+1", - Status::OK, - Category::Normal, - ), + // See Note 1. + (p_smallest_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_smallest_value, p_normal_value, "0x1p+0", Status::INEXACT, Category::Normal), + (p_smallest_value, m_normal_value, "-0x1p+0", Status::INEXACT, Category::Normal), + (p_smallest_value, p_largest_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_smallest_value, m_largest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_smallest_value, p_smallest_value, "0x1p-148", Status::OK, Category::Normal), + (p_smallest_value, m_smallest_value, "0x0p+0", Status::OK, Category::Zero), + (p_smallest_value, p_smallest_normalized, "0x1.000002p-126", Status::OK, Category::Normal), + (p_smallest_value, m_smallest_normalized, "-0x1.fffffcp-127", Status::OK, Category::Normal), + (m_smallest_value, p_inf, "inf", Status::OK, Category::Infinity), + (m_smallest_value, m_inf, "-inf", Status::OK, Category::Infinity), + (m_smallest_value, p_zero, "-0x1p-149", Status::OK, Category::Normal), + (m_smallest_value, m_zero, "-0x1p-149", Status::OK, Category::Normal), + (m_smallest_value, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (m_smallest_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_smallest_value, p_normal_value, "0x1p+0", Status::INEXACT, Category::Normal), + (m_smallest_value, m_normal_value, "-0x1p+0", Status::INEXACT, Category::Normal), + (m_smallest_value, p_largest_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_smallest_value, m_largest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_smallest_value, p_smallest_value, "0x0p+0", Status::OK, Category::Zero), + (m_smallest_value, m_smallest_value, "-0x1p-148", Status::OK, Category::Normal), + (m_smallest_value, p_smallest_normalized, "0x1.fffffcp-127", Status::OK, Category::Normal), + (m_smallest_value, m_smallest_normalized, "-0x1.000002p-126", Status::OK, Category::Normal), + (p_smallest_normalized, p_inf, "inf", Status::OK, Category::Infinity), + (p_smallest_normalized, m_inf, "-inf", Status::OK, Category::Infinity), + (p_smallest_normalized, p_zero, "0x1p-126", Status::OK, Category::Normal), + (p_smallest_normalized, m_zero, "0x1p-126", Status::OK, Category::Normal), + (p_smallest_normalized, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_smallest_normalized, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_smallest_normalized, p_normal_value, "0x1p+0", Status::INEXACT, Category::Normal), + (p_smallest_normalized, m_normal_value, "-0x1p+0", Status::INEXACT, Category::Normal), ( - m_normal_value, + p_smallest_normalized, p_largest_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal, ), ( - m_normal_value, + p_smallest_normalized, m_largest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal, ), - ( - m_normal_value, - p_smallest_value, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_normal_value, - m_smallest_value, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_normal_value, - p_smallest_normalized, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_normal_value, - m_smallest_normalized, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_largest_value, - p_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_largest_value, - m_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_largest_value, - p_zero, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - p_largest_value, - m_zero, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - (p_largest_value, qnan, "nan", Status::OK, Category::NaN), + (p_smallest_normalized, p_smallest_value, "0x1.000002p-126", Status::OK, Category::Normal), + (p_smallest_normalized, m_smallest_value, "0x1.fffffcp-127", Status::OK, Category::Normal), + (p_smallest_normalized, p_smallest_normalized, "0x1p-125", Status::OK, Category::Normal), + (p_smallest_normalized, m_smallest_normalized, "0x0p+0", Status::OK, Category::Zero), + (m_smallest_normalized, p_inf, "inf", Status::OK, Category::Infinity), + (m_smallest_normalized, m_inf, "-inf", Status::OK, Category::Infinity), + (m_smallest_normalized, p_zero, "-0x1p-126", Status::OK, Category::Normal), + (m_smallest_normalized, m_zero, "-0x1p-126", Status::OK, Category::Normal), + (m_smallest_normalized, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(p_largest_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_largest_value, - p_normal_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), + // See Note 1. + (m_smallest_normalized, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_smallest_normalized, p_normal_value, "0x1p+0", Status::INEXACT, Category::Normal), + (m_smallest_normalized, m_normal_value, "-0x1p+0", Status::INEXACT, Category::Normal), ( + m_smallest_normalized, p_largest_value, - m_normal_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal, ), ( - p_largest_value, - p_largest_value, - "inf", - overflow_status, - Category::Infinity, - ), - ( - p_largest_value, + m_smallest_normalized, m_largest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_largest_value, - p_smallest_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_largest_value, - m_smallest_value, - "0x1.fffffep+127", + "-0x1.fffffep+127", Status::INEXACT, Category::Normal, ), + (m_smallest_normalized, p_smallest_value, "-0x1.fffffcp-127", Status::OK, Category::Normal), + (m_smallest_normalized, m_smallest_value, "-0x1.000002p-126", Status::OK, Category::Normal), + (m_smallest_normalized, p_smallest_normalized, "0x0p+0", Status::OK, Category::Zero), + (m_smallest_normalized, m_smallest_normalized, "-0x1p-125", Status::OK, Category::Normal), + ]; + + for &(x, y, e_result, e_status, e_category) in &special_cases[..] { + let status; + let result = unpack!(status=, x + y); + assert_eq!(status, e_status); + assert_eq!(result.category(), e_category); + assert!(result.bitwise_eq(e_result.parse::().unwrap())); + } +} + +#[test] +fn subtract() { + // Test Special Cases against each other and normal values. + + // FIXMES/NOTES: + // 1. Since we perform only default exception handling all operations with + // signaling NaNs should have a result that is a quiet NaN. Currently they + // return sNaN. + + let p_inf = Single::INFINITY; + let m_inf = -Single::INFINITY; + let p_zero = Single::ZERO; + let m_zero = -Single::ZERO; + let qnan = Single::NAN; + let p_normal_value = "0x1p+0".parse::().unwrap(); + let m_normal_value = "-0x1p+0".parse::().unwrap(); + let p_largest_value = Single::largest(); + let m_largest_value = -Single::largest(); + let p_smallest_value = Single::SMALLEST; + let m_smallest_value = -Single::SMALLEST; + let p_smallest_normalized = Single::smallest_normalized(); + let m_smallest_normalized = -Single::smallest_normalized(); + + let overflow_status = Status::OVERFLOW | Status::INEXACT; + + let special_cases = [ + (p_inf, p_inf, "nan", Status::INVALID_OP, Category::NaN), + (p_inf, m_inf, "inf", Status::OK, Category::Infinity), + (p_inf, p_zero, "inf", Status::OK, Category::Infinity), + (p_inf, m_zero, "inf", Status::OK, Category::Infinity), + (p_inf, qnan, "-nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_inf, snan, "-nan", Status::INVALID_OP, Category::NaN), + */ + (p_inf, p_normal_value, "inf", Status::OK, Category::Infinity), + (p_inf, m_normal_value, "inf", Status::OK, Category::Infinity), + (p_inf, p_largest_value, "inf", Status::OK, Category::Infinity), + (p_inf, m_largest_value, "inf", Status::OK, Category::Infinity), + (p_inf, p_smallest_value, "inf", Status::OK, Category::Infinity), + (p_inf, m_smallest_value, "inf", Status::OK, Category::Infinity), + (p_inf, p_smallest_normalized, "inf", Status::OK, Category::Infinity), + (p_inf, m_smallest_normalized, "inf", Status::OK, Category::Infinity), + (m_inf, p_inf, "-inf", Status::OK, Category::Infinity), + (m_inf, m_inf, "nan", Status::INVALID_OP, Category::NaN), + (m_inf, p_zero, "-inf", Status::OK, Category::Infinity), + (m_inf, m_zero, "-inf", Status::OK, Category::Infinity), + (m_inf, qnan, "-nan", Status::OK, Category::NaN), + /* + // See Note 1. + (m_inf, snan, "-nan", Status::INVALID_OP, Category::NaN), + */ + (m_inf, p_normal_value, "-inf", Status::OK, Category::Infinity), + (m_inf, m_normal_value, "-inf", Status::OK, Category::Infinity), + (m_inf, p_largest_value, "-inf", Status::OK, Category::Infinity), + (m_inf, m_largest_value, "-inf", Status::OK, Category::Infinity), + (m_inf, p_smallest_value, "-inf", Status::OK, Category::Infinity), + (m_inf, m_smallest_value, "-inf", Status::OK, Category::Infinity), + (m_inf, p_smallest_normalized, "-inf", Status::OK, Category::Infinity), + (m_inf, m_smallest_normalized, "-inf", Status::OK, Category::Infinity), + (p_zero, p_inf, "-inf", Status::OK, Category::Infinity), + (p_zero, m_inf, "inf", Status::OK, Category::Infinity), + (p_zero, p_zero, "0x0p+0", Status::OK, Category::Zero), + (p_zero, m_zero, "0x0p+0", Status::OK, Category::Zero), + (p_zero, qnan, "-nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_zero, snan, "-nan", Status::INVALID_OP, Category::NaN), + */ + (p_zero, p_normal_value, "-0x1p+0", Status::OK, Category::Normal), + (p_zero, m_normal_value, "0x1p+0", Status::OK, Category::Normal), + (p_zero, p_largest_value, "-0x1.fffffep+127", Status::OK, Category::Normal), + (p_zero, m_largest_value, "0x1.fffffep+127", Status::OK, Category::Normal), + (p_zero, p_smallest_value, "-0x1p-149", Status::OK, Category::Normal), + (p_zero, m_smallest_value, "0x1p-149", Status::OK, Category::Normal), + (p_zero, p_smallest_normalized, "-0x1p-126", Status::OK, Category::Normal), + (p_zero, m_smallest_normalized, "0x1p-126", Status::OK, Category::Normal), + (m_zero, p_inf, "-inf", Status::OK, Category::Infinity), + (m_zero, m_inf, "inf", Status::OK, Category::Infinity), + (m_zero, p_zero, "-0x0p+0", Status::OK, Category::Zero), + (m_zero, m_zero, "0x0p+0", Status::OK, Category::Zero), + (m_zero, qnan, "-nan", Status::OK, Category::NaN), + /* + // See Note 1. + (m_zero, snan, "-nan", Status::INVALID_OP, Category::NaN), + */ + (m_zero, p_normal_value, "-0x1p+0", Status::OK, Category::Normal), + (m_zero, m_normal_value, "0x1p+0", Status::OK, Category::Normal), + (m_zero, p_largest_value, "-0x1.fffffep+127", Status::OK, Category::Normal), + (m_zero, m_largest_value, "0x1.fffffep+127", Status::OK, Category::Normal), + (m_zero, p_smallest_value, "-0x1p-149", Status::OK, Category::Normal), + (m_zero, m_smallest_value, "0x1p-149", Status::OK, Category::Normal), + (m_zero, p_smallest_normalized, "-0x1p-126", Status::OK, Category::Normal), + (m_zero, m_smallest_normalized, "0x1p-126", Status::OK, Category::Normal), + (qnan, p_inf, "nan", Status::OK, Category::NaN), + (qnan, m_inf, "nan", Status::OK, Category::NaN), + (qnan, p_zero, "nan", Status::OK, Category::NaN), + (qnan, m_zero, "nan", Status::OK, Category::NaN), + (qnan, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (qnan, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (qnan, p_normal_value, "nan", Status::OK, Category::NaN), + (qnan, m_normal_value, "nan", Status::OK, Category::NaN), + (qnan, p_largest_value, "nan", Status::OK, Category::NaN), + (qnan, m_largest_value, "nan", Status::OK, Category::NaN), + (qnan, p_smallest_value, "nan", Status::OK, Category::NaN), + (qnan, m_smallest_value, "nan", Status::OK, Category::NaN), + (qnan, p_smallest_normalized, "nan", Status::OK, Category::NaN), + (qnan, m_smallest_normalized, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (snan, p_inf, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_inf, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_zero, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_zero, "nan", Status::INVALID_OP, Category::NaN), + (snan, qnan, "nan", Status::INVALID_OP, Category::NaN), + (snan, snan, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_normal_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_normal_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_largest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_largest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_smallest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_smallest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_normal_value, p_inf, "-inf", Status::OK, Category::Infinity), + (p_normal_value, m_inf, "inf", Status::OK, Category::Infinity), + (p_normal_value, p_zero, "0x1p+0", Status::OK, Category::Normal), + (p_normal_value, m_zero, "0x1p+0", Status::OK, Category::Normal), + (p_normal_value, qnan, "-nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_normal_value, snan, "-nan", Status::INVALID_OP, Category::NaN), + */ + (p_normal_value, p_normal_value, "0x0p+0", Status::OK, Category::Zero), + (p_normal_value, m_normal_value, "0x1p+1", Status::OK, Category::Normal), + (p_normal_value, p_largest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_normal_value, m_largest_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_normal_value, p_smallest_value, "0x1p+0", Status::INEXACT, Category::Normal), + (p_normal_value, m_smallest_value, "0x1p+0", Status::INEXACT, Category::Normal), + (p_normal_value, p_smallest_normalized, "0x1p+0", Status::INEXACT, Category::Normal), + (p_normal_value, m_smallest_normalized, "0x1p+0", Status::INEXACT, Category::Normal), + (m_normal_value, p_inf, "-inf", Status::OK, Category::Infinity), + (m_normal_value, m_inf, "inf", Status::OK, Category::Infinity), + (m_normal_value, p_zero, "-0x1p+0", Status::OK, Category::Normal), + (m_normal_value, m_zero, "-0x1p+0", Status::OK, Category::Normal), + (m_normal_value, qnan, "-nan", Status::OK, Category::NaN), + /* + // See Note 1. + (m_normal_value, snan, "-nan", Status::INVALID_OP, Category::NaN), + */ + (m_normal_value, p_normal_value, "-0x1p+1", Status::OK, Category::Normal), + (m_normal_value, m_normal_value, "0x0p+0", Status::OK, Category::Zero), + (m_normal_value, p_largest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_normal_value, m_largest_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_normal_value, p_smallest_value, "-0x1p+0", Status::INEXACT, Category::Normal), + (m_normal_value, m_smallest_value, "-0x1p+0", Status::INEXACT, Category::Normal), + (m_normal_value, p_smallest_normalized, "-0x1p+0", Status::INEXACT, Category::Normal), + (m_normal_value, m_smallest_normalized, "-0x1p+0", Status::INEXACT, Category::Normal), + (p_largest_value, p_inf, "-inf", Status::OK, Category::Infinity), + (p_largest_value, m_inf, "inf", Status::OK, Category::Infinity), + (p_largest_value, p_zero, "0x1.fffffep+127", Status::OK, Category::Normal), + (p_largest_value, m_zero, "0x1.fffffep+127", Status::OK, Category::Normal), + (p_largest_value, qnan, "-nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_largest_value, snan, "-nan", Status::INVALID_OP, Category::NaN), + */ + (p_largest_value, p_normal_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_largest_value, m_normal_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_largest_value, p_largest_value, "0x0p+0", Status::OK, Category::Zero), + (p_largest_value, m_largest_value, "inf", overflow_status, Category::Infinity), + (p_largest_value, p_smallest_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_largest_value, m_smallest_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), ( p_largest_value, p_smallest_normalized, @@ -2775,468 +2123,132 @@ fn add() { Status::INEXACT, Category::Normal, ), - ( - m_largest_value, - p_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - m_largest_value, - m_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_largest_value, - p_zero, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - m_largest_value, - m_zero, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - (m_largest_value, qnan, "nan", Status::OK, Category::NaN), + (m_largest_value, p_inf, "-inf", Status::OK, Category::Infinity), + (m_largest_value, m_inf, "inf", Status::OK, Category::Infinity), + (m_largest_value, p_zero, "-0x1.fffffep+127", Status::OK, Category::Normal), + (m_largest_value, m_zero, "-0x1.fffffep+127", Status::OK, Category::Normal), + (m_largest_value, qnan, "-nan", Status::OK, Category::NaN), /* -// See Note 1. -(m_largest_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ + // See Note 1. + (m_largest_value, snan, "-nan", Status::INVALID_OP, Category::NaN), + */ + (m_largest_value, p_normal_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_largest_value, m_normal_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_largest_value, p_largest_value, "-inf", overflow_status, Category::Infinity), + (m_largest_value, m_largest_value, "0x0p+0", Status::OK, Category::Zero), + (m_largest_value, p_smallest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_largest_value, m_smallest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), ( m_largest_value, - p_normal_value, + p_smallest_normalized, "-0x1.fffffep+127", Status::INEXACT, Category::Normal, ), ( m_largest_value, - m_normal_value, + m_smallest_normalized, "-0x1.fffffep+127", Status::INEXACT, Category::Normal, ), + (p_smallest_value, p_inf, "-inf", Status::OK, Category::Infinity), + (p_smallest_value, m_inf, "inf", Status::OK, Category::Infinity), + (p_smallest_value, p_zero, "0x1p-149", Status::OK, Category::Normal), + (p_smallest_value, m_zero, "0x1p-149", Status::OK, Category::Normal), + (p_smallest_value, qnan, "-nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_smallest_value, snan, "-nan", Status::INVALID_OP, Category::NaN), + */ + (p_smallest_value, p_normal_value, "-0x1p+0", Status::INEXACT, Category::Normal), + (p_smallest_value, m_normal_value, "0x1p+0", Status::INEXACT, Category::Normal), + (p_smallest_value, p_largest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_smallest_value, m_largest_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (p_smallest_value, p_smallest_value, "0x0p+0", Status::OK, Category::Zero), + (p_smallest_value, m_smallest_value, "0x1p-148", Status::OK, Category::Normal), + (p_smallest_value, p_smallest_normalized, "-0x1.fffffcp-127", Status::OK, Category::Normal), + (p_smallest_value, m_smallest_normalized, "0x1.000002p-126", Status::OK, Category::Normal), + (m_smallest_value, p_inf, "-inf", Status::OK, Category::Infinity), + (m_smallest_value, m_inf, "inf", Status::OK, Category::Infinity), + (m_smallest_value, p_zero, "-0x1p-149", Status::OK, Category::Normal), + (m_smallest_value, m_zero, "-0x1p-149", Status::OK, Category::Normal), + (m_smallest_value, qnan, "-nan", Status::OK, Category::NaN), + /* + // See Note 1. + (m_smallest_value, snan, "-nan", Status::INVALID_OP, Category::NaN), + */ + (m_smallest_value, p_normal_value, "-0x1p+0", Status::INEXACT, Category::Normal), + (m_smallest_value, m_normal_value, "0x1p+0", Status::INEXACT, Category::Normal), + (m_smallest_value, p_largest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_smallest_value, m_largest_value, "0x1.fffffep+127", Status::INEXACT, Category::Normal), + (m_smallest_value, p_smallest_value, "-0x1p-148", Status::OK, Category::Normal), + (m_smallest_value, m_smallest_value, "0x0p+0", Status::OK, Category::Zero), + (m_smallest_value, p_smallest_normalized, "-0x1.000002p-126", Status::OK, Category::Normal), + (m_smallest_value, m_smallest_normalized, "0x1.fffffcp-127", Status::OK, Category::Normal), + (p_smallest_normalized, p_inf, "-inf", Status::OK, Category::Infinity), + (p_smallest_normalized, m_inf, "inf", Status::OK, Category::Infinity), + (p_smallest_normalized, p_zero, "0x1p-126", Status::OK, Category::Normal), + (p_smallest_normalized, m_zero, "0x1p-126", Status::OK, Category::Normal), + (p_smallest_normalized, qnan, "-nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_smallest_normalized, snan, "-nan", Status::INVALID_OP, Category::NaN), + */ + (p_smallest_normalized, p_normal_value, "-0x1p+0", Status::INEXACT, Category::Normal), + (p_smallest_normalized, m_normal_value, "0x1p+0", Status::INEXACT, Category::Normal), ( - m_largest_value, + p_smallest_normalized, p_largest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_largest_value, - m_largest_value, - "-inf", - overflow_status, - Category::Infinity, - ), - ( - m_largest_value, - p_smallest_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_largest_value, - m_smallest_value, "-0x1.fffffep+127", Status::INEXACT, Category::Normal, ), ( - m_largest_value, p_smallest_normalized, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( m_largest_value, - m_smallest_normalized, - "-0x1.fffffep+127", + "0x1.fffffep+127", Status::INEXACT, Category::Normal, ), - ( - p_smallest_value, - p_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_smallest_value, - m_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_smallest_value, - p_zero, - "0x1p-149", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - m_zero, - "0x1p-149", - Status::OK, - Category::Normal, - ), - (p_smallest_value, qnan, "nan", Status::OK, Category::NaN), + (p_smallest_normalized, p_smallest_value, "0x1.fffffcp-127", Status::OK, Category::Normal), + (p_smallest_normalized, m_smallest_value, "0x1.000002p-126", Status::OK, Category::Normal), + (p_smallest_normalized, p_smallest_normalized, "0x0p+0", Status::OK, Category::Zero), + (p_smallest_normalized, m_smallest_normalized, "0x1p-125", Status::OK, Category::Normal), + (m_smallest_normalized, p_inf, "-inf", Status::OK, Category::Infinity), + (m_smallest_normalized, m_inf, "inf", Status::OK, Category::Infinity), + (m_smallest_normalized, p_zero, "-0x1p-126", Status::OK, Category::Normal), + (m_smallest_normalized, m_zero, "-0x1p-126", Status::OK, Category::Normal), + (m_smallest_normalized, qnan, "-nan", Status::OK, Category::NaN), /* -// See Note 1. -(p_smallest_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_smallest_value, - p_normal_value, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_value, - m_normal_value, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), + // See Note 1. + (m_smallest_normalized, snan, "-nan", Status::INVALID_OP, Category::NaN), + */ + (m_smallest_normalized, p_normal_value, "-0x1p+0", Status::INEXACT, Category::Normal), + (m_smallest_normalized, m_normal_value, "0x1p+0", Status::INEXACT, Category::Normal), ( - p_smallest_value, + m_smallest_normalized, p_largest_value, - "0x1.fffffep+127", + "-0x1.fffffep+127", Status::INEXACT, Category::Normal, ), ( - p_smallest_value, + m_smallest_normalized, m_largest_value, - "-0x1.fffffep+127", + "0x1.fffffep+127", Status::INEXACT, Category::Normal, ), - ( - p_smallest_value, - p_smallest_value, - "0x1p-148", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - m_smallest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_smallest_value, - p_smallest_normalized, - "0x1.000002p-126", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - m_smallest_normalized, - "-0x1.fffffcp-127", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - p_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - m_smallest_value, - m_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_smallest_value, - p_zero, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - m_zero, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - (m_smallest_value, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(m_smallest_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_smallest_value, - p_normal_value, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_value, - m_normal_value, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_value, - p_largest_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_value, - m_largest_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_value, - p_smallest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_smallest_value, - m_smallest_value, - "-0x1p-148", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - p_smallest_normalized, - "0x1.fffffcp-127", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - m_smallest_normalized, - "-0x1.000002p-126", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - p_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_smallest_normalized, - m_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_smallest_normalized, - p_zero, - "0x1p-126", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - m_zero, - "0x1p-126", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - qnan, - "nan", - Status::OK, - Category::NaN, - ), - /* -// See Note 1. -(p_smallest_normalized, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_smallest_normalized, - p_normal_value, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_normalized, - m_normal_value, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_normalized, - p_largest_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_normalized, - m_largest_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_normalized, - p_smallest_value, - "0x1.000002p-126", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - m_smallest_value, - "0x1.fffffcp-127", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - p_smallest_normalized, - "0x1p-125", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - m_smallest_normalized, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_smallest_normalized, - p_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - m_smallest_normalized, - m_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_smallest_normalized, - p_zero, - "-0x1p-126", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - m_zero, - "-0x1p-126", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - qnan, - "nan", - Status::OK, - Category::NaN, - ), - /* -// See Note 1. -(m_smallest_normalized, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_smallest_normalized, - p_normal_value, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_normalized, - m_normal_value, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_normalized, - p_largest_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_normalized, - m_largest_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_normalized, - p_smallest_value, - "-0x1.fffffcp-127", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - m_smallest_value, - "-0x1.000002p-126", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - p_smallest_normalized, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_smallest_normalized, - m_smallest_normalized, - "-0x1p-125", - Status::OK, - Category::Normal, - ), + (m_smallest_normalized, p_smallest_value, "-0x1.000002p-126", Status::OK, Category::Normal), + (m_smallest_normalized, m_smallest_value, "-0x1.fffffcp-127", Status::OK, Category::Normal), + (m_smallest_normalized, p_smallest_normalized, "-0x1p-125", Status::OK, Category::Normal), + (m_smallest_normalized, m_smallest_normalized, "0x0p+0", Status::OK, Category::Zero), ]; for &(x, y, e_result, e_status, e_category) in &special_cases[..] { let status; - let result = unpack!(status=, x + y); + let result = unpack!(status=, x - y); assert_eq!(status, e_status); assert_eq!(result.category(), e_category); assert!(result.bitwise_eq(e_result.parse::().unwrap())); @@ -3244,7 +2256,7 @@ fn add() { } #[test] -fn subtract() { +fn multiply() { // Test Special Cases against each other and normal values. // FIXMES/NOTES: @@ -3267,3042 +2279,523 @@ fn subtract() { let m_smallest_normalized = -Single::smallest_normalized(); let overflow_status = Status::OVERFLOW | Status::INEXACT; + let underflow_status = Status::UNDERFLOW | Status::INEXACT; let special_cases = [ - (p_inf, p_inf, "nan", Status::INVALID_OP, Category::NaN), - (p_inf, m_inf, "inf", Status::OK, Category::Infinity), - (p_inf, p_zero, "inf", Status::OK, Category::Infinity), - (p_inf, m_zero, "inf", Status::OK, Category::Infinity), - (p_inf, qnan, "-nan", Status::OK, Category::NaN), + (p_inf, p_inf, "inf", Status::OK, Category::Infinity), + (p_inf, m_inf, "-inf", Status::OK, Category::Infinity), + (p_inf, p_zero, "nan", Status::INVALID_OP, Category::NaN), + (p_inf, m_zero, "nan", Status::INVALID_OP, Category::NaN), + (p_inf, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(p_inf, snan, "-nan", Status::INVALID_OP, Category::NaN), - */ + // See Note 1. + (p_inf, snan, "nan", Status::INVALID_OP, Category::NaN), + */ (p_inf, p_normal_value, "inf", Status::OK, Category::Infinity), - (p_inf, m_normal_value, "inf", Status::OK, Category::Infinity), - ( - p_inf, - p_largest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - m_largest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - p_smallest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - m_smallest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - p_smallest_normalized, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - m_smallest_normalized, - "inf", - Status::OK, - Category::Infinity, - ), + (p_inf, m_normal_value, "-inf", Status::OK, Category::Infinity), + (p_inf, p_largest_value, "inf", Status::OK, Category::Infinity), + (p_inf, m_largest_value, "-inf", Status::OK, Category::Infinity), + (p_inf, p_smallest_value, "inf", Status::OK, Category::Infinity), + (p_inf, m_smallest_value, "-inf", Status::OK, Category::Infinity), + (p_inf, p_smallest_normalized, "inf", Status::OK, Category::Infinity), + (p_inf, m_smallest_normalized, "-inf", Status::OK, Category::Infinity), (m_inf, p_inf, "-inf", Status::OK, Category::Infinity), - (m_inf, m_inf, "nan", Status::INVALID_OP, Category::NaN), - (m_inf, p_zero, "-inf", Status::OK, Category::Infinity), - (m_inf, m_zero, "-inf", Status::OK, Category::Infinity), - (m_inf, qnan, "-nan", Status::OK, Category::NaN), + (m_inf, m_inf, "inf", Status::OK, Category::Infinity), + (m_inf, p_zero, "nan", Status::INVALID_OP, Category::NaN), + (m_inf, m_zero, "nan", Status::INVALID_OP, Category::NaN), + (m_inf, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(m_inf, snan, "-nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_inf, - p_normal_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_normal_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - p_largest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_largest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - p_smallest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_smallest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - p_smallest_normalized, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_smallest_normalized, - "-inf", - Status::OK, - Category::Infinity, - ), - (p_zero, p_inf, "-inf", Status::OK, Category::Infinity), - (p_zero, m_inf, "inf", Status::OK, Category::Infinity), + // See Note 1. + (m_inf, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_inf, p_normal_value, "-inf", Status::OK, Category::Infinity), + (m_inf, m_normal_value, "inf", Status::OK, Category::Infinity), + (m_inf, p_largest_value, "-inf", Status::OK, Category::Infinity), + (m_inf, m_largest_value, "inf", Status::OK, Category::Infinity), + (m_inf, p_smallest_value, "-inf", Status::OK, Category::Infinity), + (m_inf, m_smallest_value, "inf", Status::OK, Category::Infinity), + (m_inf, p_smallest_normalized, "-inf", Status::OK, Category::Infinity), + (m_inf, m_smallest_normalized, "inf", Status::OK, Category::Infinity), + (p_zero, p_inf, "nan", Status::INVALID_OP, Category::NaN), + (p_zero, m_inf, "nan", Status::INVALID_OP, Category::NaN), (p_zero, p_zero, "0x0p+0", Status::OK, Category::Zero), - (p_zero, m_zero, "0x0p+0", Status::OK, Category::Zero), - (p_zero, qnan, "-nan", Status::OK, Category::NaN), + (p_zero, m_zero, "-0x0p+0", Status::OK, Category::Zero), + (p_zero, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(p_zero, snan, "-nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_zero, - p_normal_value, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_zero, - m_normal_value, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_zero, - p_largest_value, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - p_zero, - m_largest_value, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - p_zero, - p_smallest_value, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - ( - p_zero, - m_smallest_value, - "0x1p-149", - Status::OK, - Category::Normal, - ), - ( - p_zero, - p_smallest_normalized, - "-0x1p-126", - Status::OK, - Category::Normal, - ), - ( - p_zero, - m_smallest_normalized, - "0x1p-126", - Status::OK, - Category::Normal, - ), - (m_zero, p_inf, "-inf", Status::OK, Category::Infinity), - (m_zero, m_inf, "inf", Status::OK, Category::Infinity), - (m_zero, p_zero, "-0x0p+0", Status::OK, Category::Zero), - (m_zero, m_zero, "0x0p+0", Status::OK, Category::Zero), - (m_zero, qnan, "-nan", Status::OK, Category::NaN), - /* -// See Note 1. -(m_zero, snan, "-nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_zero, - p_normal_value, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_zero, - m_normal_value, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_zero, - p_largest_value, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - m_zero, - m_largest_value, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - m_zero, - p_smallest_value, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - ( - m_zero, - m_smallest_value, - "0x1p-149", - Status::OK, - Category::Normal, - ), - ( - m_zero, - p_smallest_normalized, - "-0x1p-126", - Status::OK, - Category::Normal, - ), - ( - m_zero, - m_smallest_normalized, - "0x1p-126", - Status::OK, - Category::Normal, - ), - (qnan, p_inf, "nan", Status::OK, Category::NaN), - (qnan, m_inf, "nan", Status::OK, Category::NaN), - (qnan, p_zero, "nan", Status::OK, Category::NaN), - (qnan, m_zero, "nan", Status::OK, Category::NaN), - (qnan, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(qnan, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - (qnan, p_normal_value, "nan", Status::OK, Category::NaN), - (qnan, m_normal_value, "nan", Status::OK, Category::NaN), - (qnan, p_largest_value, "nan", Status::OK, Category::NaN), - (qnan, m_largest_value, "nan", Status::OK, Category::NaN), - (qnan, p_smallest_value, "nan", Status::OK, Category::NaN), - (qnan, m_smallest_value, "nan", Status::OK, Category::NaN), - ( - qnan, - p_smallest_normalized, - "nan", - Status::OK, - Category::NaN, - ), - ( - qnan, - m_smallest_normalized, - "nan", - Status::OK, - Category::NaN, - ), - /* -// See Note 1. -(snan, p_inf, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_inf, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_zero, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_zero, "nan", Status::INVALID_OP, Category::NaN), -(snan, qnan, "nan", Status::INVALID_OP, Category::NaN), -(snan, snan, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_normal_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_normal_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_largest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_largest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_smallest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_smallest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_normal_value, - p_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - (p_normal_value, m_inf, "inf", Status::OK, Category::Infinity), - ( - p_normal_value, - p_zero, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_normal_value, - m_zero, - "0x1p+0", - Status::OK, - Category::Normal, - ), - (p_normal_value, qnan, "-nan", Status::OK, Category::NaN), - /* -// See Note 1. -(p_normal_value, snan, "-nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_normal_value, - p_normal_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_normal_value, - m_normal_value, - "0x1p+1", - Status::OK, - Category::Normal, - ), - ( - p_normal_value, - p_largest_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_normal_value, - m_largest_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_normal_value, - p_smallest_value, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_normal_value, - m_smallest_value, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_normal_value, - p_smallest_normalized, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_normal_value, - m_smallest_normalized, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_normal_value, - p_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - (m_normal_value, m_inf, "inf", Status::OK, Category::Infinity), - ( - m_normal_value, - p_zero, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - m_zero, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - (m_normal_value, qnan, "-nan", Status::OK, Category::NaN), - /* -// See Note 1. -(m_normal_value, snan, "-nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_normal_value, - p_normal_value, - "-0x1p+1", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - m_normal_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_normal_value, - p_largest_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_normal_value, - m_largest_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_normal_value, - p_smallest_value, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_normal_value, - m_smallest_value, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_normal_value, - p_smallest_normalized, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_normal_value, - m_smallest_normalized, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_largest_value, - p_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_largest_value, - m_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_largest_value, - p_zero, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - p_largest_value, - m_zero, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - (p_largest_value, qnan, "-nan", Status::OK, Category::NaN), - /* -// See Note 1. -(p_largest_value, snan, "-nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_largest_value, - p_normal_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_largest_value, - m_normal_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_largest_value, - p_largest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_largest_value, - m_largest_value, - "inf", - overflow_status, - Category::Infinity, - ), - ( - p_largest_value, - p_smallest_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_largest_value, - m_smallest_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_largest_value, - p_smallest_normalized, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_largest_value, - m_smallest_normalized, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_largest_value, - p_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_largest_value, - m_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - m_largest_value, - p_zero, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - m_largest_value, - m_zero, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - (m_largest_value, qnan, "-nan", Status::OK, Category::NaN), - /* -// See Note 1. -(m_largest_value, snan, "-nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_largest_value, - p_normal_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_largest_value, - m_normal_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_largest_value, - p_largest_value, - "-inf", - overflow_status, - Category::Infinity, - ), - ( - m_largest_value, - m_largest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_largest_value, - p_smallest_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_largest_value, - m_smallest_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_largest_value, - p_smallest_normalized, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_largest_value, - m_smallest_normalized, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_value, - p_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_smallest_value, - m_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_smallest_value, - p_zero, - "0x1p-149", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - m_zero, - "0x1p-149", - Status::OK, - Category::Normal, - ), - (p_smallest_value, qnan, "-nan", Status::OK, Category::NaN), - /* -// See Note 1. -(p_smallest_value, snan, "-nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_smallest_value, - p_normal_value, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_value, - m_normal_value, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_value, - p_largest_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_value, - m_largest_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_value, - p_smallest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_smallest_value, - m_smallest_value, - "0x1p-148", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - p_smallest_normalized, - "-0x1.fffffcp-127", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - m_smallest_normalized, - "0x1.000002p-126", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - p_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_smallest_value, - m_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - m_smallest_value, - p_zero, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - m_zero, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - (m_smallest_value, qnan, "-nan", Status::OK, Category::NaN), - /* -// See Note 1. -(m_smallest_value, snan, "-nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_smallest_value, - p_normal_value, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_value, - m_normal_value, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_value, - p_largest_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_value, - m_largest_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_value, - p_smallest_value, - "-0x1p-148", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - m_smallest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_smallest_value, - p_smallest_normalized, - "-0x1.000002p-126", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - m_smallest_normalized, - "0x1.fffffcp-127", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - p_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_smallest_normalized, - m_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_smallest_normalized, - p_zero, - "0x1p-126", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - m_zero, - "0x1p-126", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - qnan, - "-nan", - Status::OK, - Category::NaN, - ), - /* -// See Note 1. -(p_smallest_normalized, snan, "-nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_smallest_normalized, - p_normal_value, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_normalized, - m_normal_value, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_normalized, - p_largest_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_normalized, - m_largest_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - p_smallest_normalized, - p_smallest_value, - "0x1.fffffcp-127", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - m_smallest_value, - "0x1.000002p-126", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - p_smallest_normalized, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_smallest_normalized, - m_smallest_normalized, - "0x1p-125", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - p_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_smallest_normalized, - m_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - m_smallest_normalized, - p_zero, - "-0x1p-126", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - m_zero, - "-0x1p-126", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - qnan, - "-nan", - Status::OK, - Category::NaN, - ), - /* -// See Note 1. -(m_smallest_normalized, snan, "-nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_smallest_normalized, - p_normal_value, - "-0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_normalized, - m_normal_value, - "0x1p+0", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_normalized, - p_largest_value, - "-0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_normalized, - m_largest_value, - "0x1.fffffep+127", - Status::INEXACT, - Category::Normal, - ), - ( - m_smallest_normalized, - p_smallest_value, - "-0x1.000002p-126", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - m_smallest_value, - "-0x1.fffffcp-127", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - p_smallest_normalized, - "-0x1p-125", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - m_smallest_normalized, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ]; - - for &(x, y, e_result, e_status, e_category) in &special_cases[..] { - let status; - let result = unpack!(status=, x - y); - assert_eq!(status, e_status); - assert_eq!(result.category(), e_category); - assert!(result.bitwise_eq(e_result.parse::().unwrap())); - } -} - -#[test] -fn multiply() { - // Test Special Cases against each other and normal values. - - // FIXMES/NOTES: - // 1. Since we perform only default exception handling all operations with - // signaling NaNs should have a result that is a quiet NaN. Currently they - // return sNaN. - - let p_inf = Single::INFINITY; - let m_inf = -Single::INFINITY; - let p_zero = Single::ZERO; - let m_zero = -Single::ZERO; - let qnan = Single::NAN; - let p_normal_value = "0x1p+0".parse::().unwrap(); - let m_normal_value = "-0x1p+0".parse::().unwrap(); - let p_largest_value = Single::largest(); - let m_largest_value = -Single::largest(); - let p_smallest_value = Single::SMALLEST; - let m_smallest_value = -Single::SMALLEST; - let p_smallest_normalized = Single::smallest_normalized(); - let m_smallest_normalized = -Single::smallest_normalized(); - - let overflow_status = Status::OVERFLOW | Status::INEXACT; - let underflow_status = Status::UNDERFLOW | Status::INEXACT; - - let special_cases = [ - (p_inf, p_inf, "inf", Status::OK, Category::Infinity), - (p_inf, m_inf, "-inf", Status::OK, Category::Infinity), - (p_inf, p_zero, "nan", Status::INVALID_OP, Category::NaN), - (p_inf, m_zero, "nan", Status::INVALID_OP, Category::NaN), - (p_inf, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(p_inf, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - (p_inf, p_normal_value, "inf", Status::OK, Category::Infinity), - ( - p_inf, - m_normal_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - p_largest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - m_largest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - p_smallest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - m_smallest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - p_smallest_normalized, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - m_smallest_normalized, - "-inf", - Status::OK, - Category::Infinity, - ), - (m_inf, p_inf, "-inf", Status::OK, Category::Infinity), - (m_inf, m_inf, "inf", Status::OK, Category::Infinity), - (m_inf, p_zero, "nan", Status::INVALID_OP, Category::NaN), - (m_inf, m_zero, "nan", Status::INVALID_OP, Category::NaN), - (m_inf, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(m_inf, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_inf, - p_normal_value, - "-inf", - Status::OK, - Category::Infinity, - ), - (m_inf, m_normal_value, "inf", Status::OK, Category::Infinity), - ( - m_inf, - p_largest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_largest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - p_smallest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_smallest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - p_smallest_normalized, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_smallest_normalized, - "inf", - Status::OK, - Category::Infinity, - ), - (p_zero, p_inf, "nan", Status::INVALID_OP, Category::NaN), - (p_zero, m_inf, "nan", Status::INVALID_OP, Category::NaN), - (p_zero, p_zero, "0x0p+0", Status::OK, Category::Zero), - (p_zero, m_zero, "-0x0p+0", Status::OK, Category::Zero), - (p_zero, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(p_zero, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - (p_zero, p_normal_value, "0x0p+0", Status::OK, Category::Zero), - ( - p_zero, - m_normal_value, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_zero, - p_largest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_zero, - m_largest_value, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_zero, - p_smallest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_zero, - m_smallest_value, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_zero, - p_smallest_normalized, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_zero, - m_smallest_normalized, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - (m_zero, p_inf, "nan", Status::INVALID_OP, Category::NaN), - (m_zero, m_inf, "nan", Status::INVALID_OP, Category::NaN), - (m_zero, p_zero, "-0x0p+0", Status::OK, Category::Zero), - (m_zero, m_zero, "0x0p+0", Status::OK, Category::Zero), - (m_zero, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(m_zero, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_zero, - p_normal_value, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - (m_zero, m_normal_value, "0x0p+0", Status::OK, Category::Zero), - ( - m_zero, - p_largest_value, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_zero, - m_largest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_zero, - p_smallest_value, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_zero, - m_smallest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_zero, - p_smallest_normalized, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_zero, - m_smallest_normalized, - "0x0p+0", - Status::OK, - Category::Zero, - ), - (qnan, p_inf, "nan", Status::OK, Category::NaN), - (qnan, m_inf, "nan", Status::OK, Category::NaN), - (qnan, p_zero, "nan", Status::OK, Category::NaN), - (qnan, m_zero, "nan", Status::OK, Category::NaN), - (qnan, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(qnan, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - (qnan, p_normal_value, "nan", Status::OK, Category::NaN), - (qnan, m_normal_value, "nan", Status::OK, Category::NaN), - (qnan, p_largest_value, "nan", Status::OK, Category::NaN), - (qnan, m_largest_value, "nan", Status::OK, Category::NaN), - (qnan, p_smallest_value, "nan", Status::OK, Category::NaN), - (qnan, m_smallest_value, "nan", Status::OK, Category::NaN), - ( - qnan, - p_smallest_normalized, - "nan", - Status::OK, - Category::NaN, - ), - ( - qnan, - m_smallest_normalized, - "nan", - Status::OK, - Category::NaN, - ), - /* -// See Note 1. -(snan, p_inf, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_inf, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_zero, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_zero, "nan", Status::INVALID_OP, Category::NaN), -(snan, qnan, "nan", Status::INVALID_OP, Category::NaN), -(snan, snan, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_normal_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_normal_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_largest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_largest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_smallest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_smallest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), - */ - (p_normal_value, p_inf, "inf", Status::OK, Category::Infinity), - ( - p_normal_value, - m_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - (p_normal_value, p_zero, "0x0p+0", Status::OK, Category::Zero), - ( - p_normal_value, - m_zero, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - (p_normal_value, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(p_normal_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_normal_value, - p_normal_value, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_normal_value, - m_normal_value, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_normal_value, - p_largest_value, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - p_normal_value, - m_largest_value, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - p_normal_value, - p_smallest_value, - "0x1p-149", - Status::OK, - Category::Normal, - ), - ( - p_normal_value, - m_smallest_value, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - ( - p_normal_value, - p_smallest_normalized, - "0x1p-126", - Status::OK, - Category::Normal, - ), - ( - p_normal_value, - m_smallest_normalized, - "-0x1p-126", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - p_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - (m_normal_value, m_inf, "inf", Status::OK, Category::Infinity), - ( - m_normal_value, - p_zero, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - (m_normal_value, m_zero, "0x0p+0", Status::OK, Category::Zero), - (m_normal_value, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(m_normal_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_normal_value, - p_normal_value, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - m_normal_value, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - p_largest_value, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - m_largest_value, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - p_smallest_value, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - m_smallest_value, - "0x1p-149", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - p_smallest_normalized, - "-0x1p-126", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - m_smallest_normalized, - "0x1p-126", - Status::OK, - Category::Normal, - ), - ( - p_largest_value, - p_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_largest_value, - m_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_largest_value, - p_zero, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_largest_value, - m_zero, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - (p_largest_value, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(p_largest_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_largest_value, - p_normal_value, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - p_largest_value, - m_normal_value, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - p_largest_value, - p_largest_value, - "inf", - overflow_status, - Category::Infinity, - ), - ( - p_largest_value, - m_largest_value, - "-inf", - overflow_status, - Category::Infinity, - ), - ( - p_largest_value, - p_smallest_value, - "0x1.fffffep-22", - Status::OK, - Category::Normal, - ), - ( - p_largest_value, - m_smallest_value, - "-0x1.fffffep-22", - Status::OK, - Category::Normal, - ), - ( - p_largest_value, - p_smallest_normalized, - "0x1.fffffep+1", - Status::OK, - Category::Normal, - ), - ( - p_largest_value, - m_smallest_normalized, - "-0x1.fffffep+1", - Status::OK, - Category::Normal, - ), - ( - m_largest_value, - p_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_largest_value, - m_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - m_largest_value, - p_zero, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_largest_value, - m_zero, - "0x0p+0", - Status::OK, - Category::Zero, - ), - (m_largest_value, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(m_largest_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_largest_value, - p_normal_value, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - m_largest_value, - m_normal_value, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - m_largest_value, - p_largest_value, - "-inf", - overflow_status, - Category::Infinity, - ), - ( - m_largest_value, - m_largest_value, - "inf", - overflow_status, - Category::Infinity, - ), - ( - m_largest_value, - p_smallest_value, - "-0x1.fffffep-22", - Status::OK, - Category::Normal, - ), - ( - m_largest_value, - m_smallest_value, - "0x1.fffffep-22", - Status::OK, - Category::Normal, - ), - ( - m_largest_value, - p_smallest_normalized, - "-0x1.fffffep+1", - Status::OK, - Category::Normal, - ), - ( - m_largest_value, - m_smallest_normalized, - "0x1.fffffep+1", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - p_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_smallest_value, - m_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_smallest_value, - p_zero, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_smallest_value, - m_zero, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - (p_smallest_value, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(p_smallest_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_smallest_value, - p_normal_value, - "0x1p-149", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - m_normal_value, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - p_largest_value, - "0x1.fffffep-22", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - m_largest_value, - "-0x1.fffffep-22", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - p_smallest_value, - "0x0p+0", - underflow_status, - Category::Zero, - ), - ( - p_smallest_value, - m_smallest_value, - "-0x0p+0", - underflow_status, - Category::Zero, - ), - ( - p_smallest_value, - p_smallest_normalized, - "0x0p+0", - underflow_status, - Category::Zero, - ), - ( - p_smallest_value, - m_smallest_normalized, - "-0x0p+0", - underflow_status, - Category::Zero, - ), - ( - m_smallest_value, - p_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_smallest_value, - m_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - m_smallest_value, - p_zero, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_smallest_value, - m_zero, - "0x0p+0", - Status::OK, - Category::Zero, - ), - (m_smallest_value, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(m_smallest_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_smallest_value, - p_normal_value, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - m_normal_value, - "0x1p-149", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - p_largest_value, - "-0x1.fffffep-22", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - m_largest_value, - "0x1.fffffep-22", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - p_smallest_value, - "-0x0p+0", - underflow_status, - Category::Zero, - ), - ( - m_smallest_value, - m_smallest_value, - "0x0p+0", - underflow_status, - Category::Zero, - ), - ( - m_smallest_value, - p_smallest_normalized, - "-0x0p+0", - underflow_status, - Category::Zero, - ), - ( - m_smallest_value, - m_smallest_normalized, - "0x0p+0", - underflow_status, - Category::Zero, - ), - ( - p_smallest_normalized, - p_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_smallest_normalized, - m_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_smallest_normalized, - p_zero, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_smallest_normalized, - m_zero, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_smallest_normalized, - qnan, - "nan", - Status::OK, - Category::NaN, - ), - /* -// See Note 1. -(p_smallest_normalized, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_smallest_normalized, - p_normal_value, - "0x1p-126", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - m_normal_value, - "-0x1p-126", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - p_largest_value, - "0x1.fffffep+1", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - m_largest_value, - "-0x1.fffffep+1", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - p_smallest_value, - "0x0p+0", - underflow_status, - Category::Zero, - ), - ( - p_smallest_normalized, - m_smallest_value, - "-0x0p+0", - underflow_status, - Category::Zero, - ), - ( - p_smallest_normalized, - p_smallest_normalized, - "0x0p+0", - underflow_status, - Category::Zero, - ), - ( - p_smallest_normalized, - m_smallest_normalized, - "-0x0p+0", - underflow_status, - Category::Zero, - ), - ( - m_smallest_normalized, - p_inf, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_smallest_normalized, - m_inf, - "inf", - Status::OK, - Category::Infinity, - ), - ( - m_smallest_normalized, - p_zero, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_smallest_normalized, - m_zero, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_smallest_normalized, - qnan, - "nan", - Status::OK, - Category::NaN, - ), - /* -// See Note 1. -(m_smallest_normalized, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_smallest_normalized, - p_normal_value, - "-0x1p-126", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - m_normal_value, - "0x1p-126", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - p_largest_value, - "-0x1.fffffep+1", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - m_largest_value, - "0x1.fffffep+1", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - p_smallest_value, - "-0x0p+0", - underflow_status, - Category::Zero, - ), - ( - m_smallest_normalized, - m_smallest_value, - "0x0p+0", - underflow_status, - Category::Zero, - ), - ( - m_smallest_normalized, - p_smallest_normalized, - "-0x0p+0", - underflow_status, - Category::Zero, - ), - ( - m_smallest_normalized, - m_smallest_normalized, - "0x0p+0", - underflow_status, - Category::Zero, - ), - ]; - - for &(x, y, e_result, e_status, e_category) in &special_cases[..] { - let status; - let result = unpack!(status=, x * y); - assert_eq!(status, e_status); - assert_eq!(result.category(), e_category); - assert!(result.bitwise_eq(e_result.parse::().unwrap())); - } -} - -#[test] -fn divide() { - // Test Special Cases against each other and normal values. - - // FIXMES/NOTES: - // 1. Since we perform only default exception handling all operations with - // signaling NaNs should have a result that is a quiet NaN. Currently they - // return sNaN. - - let p_inf = Single::INFINITY; - let m_inf = -Single::INFINITY; - let p_zero = Single::ZERO; - let m_zero = -Single::ZERO; - let qnan = Single::NAN; - let p_normal_value = "0x1p+0".parse::().unwrap(); - let m_normal_value = "-0x1p+0".parse::().unwrap(); - let p_largest_value = Single::largest(); - let m_largest_value = -Single::largest(); - let p_smallest_value = Single::SMALLEST; - let m_smallest_value = -Single::SMALLEST; - let p_smallest_normalized = Single::smallest_normalized(); - let m_smallest_normalized = -Single::smallest_normalized(); - - let overflow_status = Status::OVERFLOW | Status::INEXACT; - let underflow_status = Status::UNDERFLOW | Status::INEXACT; - - let special_cases = [ - (p_inf, p_inf, "nan", Status::INVALID_OP, Category::NaN), - (p_inf, m_inf, "nan", Status::INVALID_OP, Category::NaN), - (p_inf, p_zero, "inf", Status::OK, Category::Infinity), - (p_inf, m_zero, "-inf", Status::OK, Category::Infinity), - (p_inf, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(p_inf, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - (p_inf, p_normal_value, "inf", Status::OK, Category::Infinity), - ( - p_inf, - m_normal_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - p_largest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - m_largest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - p_smallest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - m_smallest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - p_smallest_normalized, - "inf", - Status::OK, - Category::Infinity, - ), - ( - p_inf, - m_smallest_normalized, - "-inf", - Status::OK, - Category::Infinity, - ), - (m_inf, p_inf, "nan", Status::INVALID_OP, Category::NaN), - (m_inf, m_inf, "nan", Status::INVALID_OP, Category::NaN), - (m_inf, p_zero, "-inf", Status::OK, Category::Infinity), - (m_inf, m_zero, "inf", Status::OK, Category::Infinity), - (m_inf, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(m_inf, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_inf, - p_normal_value, - "-inf", - Status::OK, - Category::Infinity, - ), - (m_inf, m_normal_value, "inf", Status::OK, Category::Infinity), - ( - m_inf, - p_largest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_largest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - p_smallest_value, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_smallest_value, - "inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - p_smallest_normalized, - "-inf", - Status::OK, - Category::Infinity, - ), - ( - m_inf, - m_smallest_normalized, - "inf", - Status::OK, - Category::Infinity, - ), - (p_zero, p_inf, "0x0p+0", Status::OK, Category::Zero), - (p_zero, m_inf, "-0x0p+0", Status::OK, Category::Zero), - (p_zero, p_zero, "nan", Status::INVALID_OP, Category::NaN), - (p_zero, m_zero, "nan", Status::INVALID_OP, Category::NaN), - (p_zero, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(p_zero, snan, "nan", Status::INVALID_OP, Category::NaN), - */ + // See Note 1. + (p_zero, snan, "nan", Status::INVALID_OP, Category::NaN), + */ (p_zero, p_normal_value, "0x0p+0", Status::OK, Category::Zero), - ( - p_zero, - m_normal_value, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_zero, - p_largest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_zero, - m_largest_value, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_zero, - p_smallest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_zero, - m_smallest_value, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_zero, - p_smallest_normalized, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_zero, - m_smallest_normalized, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - (m_zero, p_inf, "-0x0p+0", Status::OK, Category::Zero), - (m_zero, m_inf, "0x0p+0", Status::OK, Category::Zero), - (m_zero, p_zero, "nan", Status::INVALID_OP, Category::NaN), - (m_zero, m_zero, "nan", Status::INVALID_OP, Category::NaN), + (p_zero, m_normal_value, "-0x0p+0", Status::OK, Category::Zero), + (p_zero, p_largest_value, "0x0p+0", Status::OK, Category::Zero), + (p_zero, m_largest_value, "-0x0p+0", Status::OK, Category::Zero), + (p_zero, p_smallest_value, "0x0p+0", Status::OK, Category::Zero), + (p_zero, m_smallest_value, "-0x0p+0", Status::OK, Category::Zero), + (p_zero, p_smallest_normalized, "0x0p+0", Status::OK, Category::Zero), + (p_zero, m_smallest_normalized, "-0x0p+0", Status::OK, Category::Zero), + (m_zero, p_inf, "nan", Status::INVALID_OP, Category::NaN), + (m_zero, m_inf, "nan", Status::INVALID_OP, Category::NaN), + (m_zero, p_zero, "-0x0p+0", Status::OK, Category::Zero), + (m_zero, m_zero, "0x0p+0", Status::OK, Category::Zero), (m_zero, qnan, "nan", Status::OK, Category::NaN), - /* -// See Note 1. -(m_zero, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_zero, - p_normal_value, - "-0x0p+0", - Status::OK, - Category::Zero, - ), + /* + // See Note 1. + (m_zero, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_zero, p_normal_value, "-0x0p+0", Status::OK, Category::Zero), (m_zero, m_normal_value, "0x0p+0", Status::OK, Category::Zero), - ( - m_zero, - p_largest_value, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_zero, - m_largest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_zero, - p_smallest_value, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_zero, - m_smallest_value, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_zero, - p_smallest_normalized, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_zero, - m_smallest_normalized, - "0x0p+0", - Status::OK, - Category::Zero, - ), + (m_zero, p_largest_value, "-0x0p+0", Status::OK, Category::Zero), + (m_zero, m_largest_value, "0x0p+0", Status::OK, Category::Zero), + (m_zero, p_smallest_value, "-0x0p+0", Status::OK, Category::Zero), + (m_zero, m_smallest_value, "0x0p+0", Status::OK, Category::Zero), + (m_zero, p_smallest_normalized, "-0x0p+0", Status::OK, Category::Zero), + (m_zero, m_smallest_normalized, "0x0p+0", Status::OK, Category::Zero), (qnan, p_inf, "nan", Status::OK, Category::NaN), (qnan, m_inf, "nan", Status::OK, Category::NaN), (qnan, p_zero, "nan", Status::OK, Category::NaN), (qnan, m_zero, "nan", Status::OK, Category::NaN), (qnan, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(qnan, snan, "nan", Status::INVALID_OP, Category::NaN), - */ + // See Note 1. + (qnan, snan, "nan", Status::INVALID_OP, Category::NaN), + */ (qnan, p_normal_value, "nan", Status::OK, Category::NaN), (qnan, m_normal_value, "nan", Status::OK, Category::NaN), (qnan, p_largest_value, "nan", Status::OK, Category::NaN), (qnan, m_largest_value, "nan", Status::OK, Category::NaN), (qnan, p_smallest_value, "nan", Status::OK, Category::NaN), (qnan, m_smallest_value, "nan", Status::OK, Category::NaN), - ( - qnan, - p_smallest_normalized, - "nan", - Status::OK, - Category::NaN, - ), - ( - qnan, - m_smallest_normalized, - "nan", - Status::OK, - Category::NaN, - ), + (qnan, p_smallest_normalized, "nan", Status::OK, Category::NaN), + (qnan, m_smallest_normalized, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(snan, p_inf, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_inf, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_zero, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_zero, "nan", Status::INVALID_OP, Category::NaN), -(snan, qnan, "nan", Status::INVALID_OP, Category::NaN), -(snan, snan, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_normal_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_normal_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_largest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_largest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_smallest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_smallest_value, "nan", Status::INVALID_OP, Category::NaN), -(snan, p_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), -(snan, m_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), - */ - (p_normal_value, p_inf, "0x0p+0", Status::OK, Category::Zero), - (p_normal_value, m_inf, "-0x0p+0", Status::OK, Category::Zero), - ( - p_normal_value, - p_zero, - "inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), - ( - p_normal_value, - m_zero, - "-inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), + // See Note 1. + (snan, p_inf, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_inf, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_zero, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_zero, "nan", Status::INVALID_OP, Category::NaN), + (snan, qnan, "nan", Status::INVALID_OP, Category::NaN), + (snan, snan, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_normal_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_normal_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_largest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_largest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_smallest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_smallest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_normal_value, p_inf, "inf", Status::OK, Category::Infinity), + (p_normal_value, m_inf, "-inf", Status::OK, Category::Infinity), + (p_normal_value, p_zero, "0x0p+0", Status::OK, Category::Zero), + (p_normal_value, m_zero, "-0x0p+0", Status::OK, Category::Zero), (p_normal_value, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(p_normal_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_normal_value, - p_normal_value, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_normal_value, - m_normal_value, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_normal_value, - p_largest_value, - "0x1p-128", - underflow_status, - Category::Normal, - ), - ( - p_normal_value, - m_largest_value, - "-0x1p-128", - underflow_status, - Category::Normal, - ), - ( - p_normal_value, - p_smallest_value, - "inf", - overflow_status, - Category::Infinity, - ), - ( - p_normal_value, - m_smallest_value, - "-inf", - overflow_status, - Category::Infinity, - ), - ( - p_normal_value, - p_smallest_normalized, - "0x1p+126", - Status::OK, - Category::Normal, - ), - ( - p_normal_value, - m_smallest_normalized, - "-0x1p+126", - Status::OK, - Category::Normal, - ), - (m_normal_value, p_inf, "-0x0p+0", Status::OK, Category::Zero), - (m_normal_value, m_inf, "0x0p+0", Status::OK, Category::Zero), - ( - m_normal_value, - p_zero, - "-inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), - ( - m_normal_value, - m_zero, - "inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), + // See Note 1. + (p_normal_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_normal_value, p_normal_value, "0x1p+0", Status::OK, Category::Normal), + (p_normal_value, m_normal_value, "-0x1p+0", Status::OK, Category::Normal), + (p_normal_value, p_largest_value, "0x1.fffffep+127", Status::OK, Category::Normal), + (p_normal_value, m_largest_value, "-0x1.fffffep+127", Status::OK, Category::Normal), + (p_normal_value, p_smallest_value, "0x1p-149", Status::OK, Category::Normal), + (p_normal_value, m_smallest_value, "-0x1p-149", Status::OK, Category::Normal), + (p_normal_value, p_smallest_normalized, "0x1p-126", Status::OK, Category::Normal), + (p_normal_value, m_smallest_normalized, "-0x1p-126", Status::OK, Category::Normal), + (m_normal_value, p_inf, "-inf", Status::OK, Category::Infinity), + (m_normal_value, m_inf, "inf", Status::OK, Category::Infinity), + (m_normal_value, p_zero, "-0x0p+0", Status::OK, Category::Zero), + (m_normal_value, m_zero, "0x0p+0", Status::OK, Category::Zero), (m_normal_value, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(m_normal_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_normal_value, - p_normal_value, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - m_normal_value, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - p_largest_value, - "-0x1p-128", - underflow_status, - Category::Normal, - ), - ( - m_normal_value, - m_largest_value, - "0x1p-128", - underflow_status, - Category::Normal, - ), - ( - m_normal_value, - p_smallest_value, - "-inf", - overflow_status, - Category::Infinity, - ), - ( - m_normal_value, - m_smallest_value, - "inf", - overflow_status, - Category::Infinity, - ), - ( - m_normal_value, - p_smallest_normalized, - "-0x1p+126", - Status::OK, - Category::Normal, - ), - ( - m_normal_value, - m_smallest_normalized, - "0x1p+126", - Status::OK, - Category::Normal, - ), - (p_largest_value, p_inf, "0x0p+0", Status::OK, Category::Zero), - ( - p_largest_value, - m_inf, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_largest_value, - p_zero, - "inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), - ( - p_largest_value, - m_zero, - "-inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), + // See Note 1. + (m_normal_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_normal_value, p_normal_value, "-0x1p+0", Status::OK, Category::Normal), + (m_normal_value, m_normal_value, "0x1p+0", Status::OK, Category::Normal), + (m_normal_value, p_largest_value, "-0x1.fffffep+127", Status::OK, Category::Normal), + (m_normal_value, m_largest_value, "0x1.fffffep+127", Status::OK, Category::Normal), + (m_normal_value, p_smallest_value, "-0x1p-149", Status::OK, Category::Normal), + (m_normal_value, m_smallest_value, "0x1p-149", Status::OK, Category::Normal), + (m_normal_value, p_smallest_normalized, "-0x1p-126", Status::OK, Category::Normal), + (m_normal_value, m_smallest_normalized, "0x1p-126", Status::OK, Category::Normal), + (p_largest_value, p_inf, "inf", Status::OK, Category::Infinity), + (p_largest_value, m_inf, "-inf", Status::OK, Category::Infinity), + (p_largest_value, p_zero, "0x0p+0", Status::OK, Category::Zero), + (p_largest_value, m_zero, "-0x0p+0", Status::OK, Category::Zero), (p_largest_value, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(p_largest_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_largest_value, - p_normal_value, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - p_largest_value, - m_normal_value, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - p_largest_value, - p_largest_value, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_largest_value, - m_largest_value, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_largest_value, - p_smallest_value, - "inf", - overflow_status, - Category::Infinity, - ), - ( - p_largest_value, - m_smallest_value, - "-inf", - overflow_status, - Category::Infinity, - ), - ( - p_largest_value, - p_smallest_normalized, - "inf", - overflow_status, - Category::Infinity, - ), - ( - p_largest_value, - m_smallest_normalized, - "-inf", - overflow_status, - Category::Infinity, - ), - ( - m_largest_value, - p_inf, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - (m_largest_value, m_inf, "0x0p+0", Status::OK, Category::Zero), - ( - m_largest_value, - p_zero, - "-inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), - ( - m_largest_value, - m_zero, - "inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), + // See Note 1. + (p_largest_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_largest_value, p_normal_value, "0x1.fffffep+127", Status::OK, Category::Normal), + (p_largest_value, m_normal_value, "-0x1.fffffep+127", Status::OK, Category::Normal), + (p_largest_value, p_largest_value, "inf", overflow_status, Category::Infinity), + (p_largest_value, m_largest_value, "-inf", overflow_status, Category::Infinity), + (p_largest_value, p_smallest_value, "0x1.fffffep-22", Status::OK, Category::Normal), + (p_largest_value, m_smallest_value, "-0x1.fffffep-22", Status::OK, Category::Normal), + (p_largest_value, p_smallest_normalized, "0x1.fffffep+1", Status::OK, Category::Normal), + (p_largest_value, m_smallest_normalized, "-0x1.fffffep+1", Status::OK, Category::Normal), + (m_largest_value, p_inf, "-inf", Status::OK, Category::Infinity), + (m_largest_value, m_inf, "inf", Status::OK, Category::Infinity), + (m_largest_value, p_zero, "-0x0p+0", Status::OK, Category::Zero), + (m_largest_value, m_zero, "0x0p+0", Status::OK, Category::Zero), (m_largest_value, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(m_largest_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_largest_value, - p_normal_value, - "-0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - m_largest_value, - m_normal_value, - "0x1.fffffep+127", - Status::OK, - Category::Normal, - ), - ( - m_largest_value, - p_largest_value, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_largest_value, - m_largest_value, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_largest_value, - p_smallest_value, - "-inf", - overflow_status, - Category::Infinity, - ), - ( - m_largest_value, - m_smallest_value, - "inf", - overflow_status, - Category::Infinity, - ), - ( - m_largest_value, - p_smallest_normalized, - "-inf", - overflow_status, - Category::Infinity, - ), - ( - m_largest_value, - m_smallest_normalized, - "inf", - overflow_status, - Category::Infinity, - ), - ( - p_smallest_value, - p_inf, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_smallest_value, - m_inf, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_smallest_value, - p_zero, - "inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), - ( - p_smallest_value, - m_zero, - "-inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), + // See Note 1. + (m_largest_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_largest_value, p_normal_value, "-0x1.fffffep+127", Status::OK, Category::Normal), + (m_largest_value, m_normal_value, "0x1.fffffep+127", Status::OK, Category::Normal), + (m_largest_value, p_largest_value, "-inf", overflow_status, Category::Infinity), + (m_largest_value, m_largest_value, "inf", overflow_status, Category::Infinity), + (m_largest_value, p_smallest_value, "-0x1.fffffep-22", Status::OK, Category::Normal), + (m_largest_value, m_smallest_value, "0x1.fffffep-22", Status::OK, Category::Normal), + (m_largest_value, p_smallest_normalized, "-0x1.fffffep+1", Status::OK, Category::Normal), + (m_largest_value, m_smallest_normalized, "0x1.fffffep+1", Status::OK, Category::Normal), + (p_smallest_value, p_inf, "inf", Status::OK, Category::Infinity), + (p_smallest_value, m_inf, "-inf", Status::OK, Category::Infinity), + (p_smallest_value, p_zero, "0x0p+0", Status::OK, Category::Zero), + (p_smallest_value, m_zero, "-0x0p+0", Status::OK, Category::Zero), + (p_smallest_value, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_smallest_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_smallest_value, p_normal_value, "0x1p-149", Status::OK, Category::Normal), + (p_smallest_value, m_normal_value, "-0x1p-149", Status::OK, Category::Normal), + (p_smallest_value, p_largest_value, "0x1.fffffep-22", Status::OK, Category::Normal), + (p_smallest_value, m_largest_value, "-0x1.fffffep-22", Status::OK, Category::Normal), + (p_smallest_value, p_smallest_value, "0x0p+0", underflow_status, Category::Zero), + (p_smallest_value, m_smallest_value, "-0x0p+0", underflow_status, Category::Zero), + (p_smallest_value, p_smallest_normalized, "0x0p+0", underflow_status, Category::Zero), + (p_smallest_value, m_smallest_normalized, "-0x0p+0", underflow_status, Category::Zero), + (m_smallest_value, p_inf, "-inf", Status::OK, Category::Infinity), + (m_smallest_value, m_inf, "inf", Status::OK, Category::Infinity), + (m_smallest_value, p_zero, "-0x0p+0", Status::OK, Category::Zero), + (m_smallest_value, m_zero, "0x0p+0", Status::OK, Category::Zero), + (m_smallest_value, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (m_smallest_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_smallest_value, p_normal_value, "-0x1p-149", Status::OK, Category::Normal), + (m_smallest_value, m_normal_value, "0x1p-149", Status::OK, Category::Normal), + (m_smallest_value, p_largest_value, "-0x1.fffffep-22", Status::OK, Category::Normal), + (m_smallest_value, m_largest_value, "0x1.fffffep-22", Status::OK, Category::Normal), + (m_smallest_value, p_smallest_value, "-0x0p+0", underflow_status, Category::Zero), + (m_smallest_value, m_smallest_value, "0x0p+0", underflow_status, Category::Zero), + (m_smallest_value, p_smallest_normalized, "-0x0p+0", underflow_status, Category::Zero), + (m_smallest_value, m_smallest_normalized, "0x0p+0", underflow_status, Category::Zero), + (p_smallest_normalized, p_inf, "inf", Status::OK, Category::Infinity), + (p_smallest_normalized, m_inf, "-inf", Status::OK, Category::Infinity), + (p_smallest_normalized, p_zero, "0x0p+0", Status::OK, Category::Zero), + (p_smallest_normalized, m_zero, "-0x0p+0", Status::OK, Category::Zero), + (p_smallest_normalized, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_smallest_normalized, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_smallest_normalized, p_normal_value, "0x1p-126", Status::OK, Category::Normal), + (p_smallest_normalized, m_normal_value, "-0x1p-126", Status::OK, Category::Normal), + (p_smallest_normalized, p_largest_value, "0x1.fffffep+1", Status::OK, Category::Normal), + (p_smallest_normalized, m_largest_value, "-0x1.fffffep+1", Status::OK, Category::Normal), + (p_smallest_normalized, p_smallest_value, "0x0p+0", underflow_status, Category::Zero), + (p_smallest_normalized, m_smallest_value, "-0x0p+0", underflow_status, Category::Zero), + (p_smallest_normalized, p_smallest_normalized, "0x0p+0", underflow_status, Category::Zero), + (p_smallest_normalized, m_smallest_normalized, "-0x0p+0", underflow_status, Category::Zero), + (m_smallest_normalized, p_inf, "-inf", Status::OK, Category::Infinity), + (m_smallest_normalized, m_inf, "inf", Status::OK, Category::Infinity), + (m_smallest_normalized, p_zero, "-0x0p+0", Status::OK, Category::Zero), + (m_smallest_normalized, m_zero, "0x0p+0", Status::OK, Category::Zero), + (m_smallest_normalized, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (m_smallest_normalized, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_smallest_normalized, p_normal_value, "-0x1p-126", Status::OK, Category::Normal), + (m_smallest_normalized, m_normal_value, "0x1p-126", Status::OK, Category::Normal), + (m_smallest_normalized, p_largest_value, "-0x1.fffffep+1", Status::OK, Category::Normal), + (m_smallest_normalized, m_largest_value, "0x1.fffffep+1", Status::OK, Category::Normal), + (m_smallest_normalized, p_smallest_value, "-0x0p+0", underflow_status, Category::Zero), + (m_smallest_normalized, m_smallest_value, "0x0p+0", underflow_status, Category::Zero), + (m_smallest_normalized, p_smallest_normalized, "-0x0p+0", underflow_status, Category::Zero), + (m_smallest_normalized, m_smallest_normalized, "0x0p+0", underflow_status, Category::Zero), + ]; + + for &(x, y, e_result, e_status, e_category) in &special_cases[..] { + let status; + let result = unpack!(status=, x * y); + assert_eq!(status, e_status); + assert_eq!(result.category(), e_category); + assert!(result.bitwise_eq(e_result.parse::().unwrap())); + } +} + +#[test] +fn divide() { + // Test Special Cases against each other and normal values. + + // FIXMES/NOTES: + // 1. Since we perform only default exception handling all operations with + // signaling NaNs should have a result that is a quiet NaN. Currently they + // return sNaN. + + let p_inf = Single::INFINITY; + let m_inf = -Single::INFINITY; + let p_zero = Single::ZERO; + let m_zero = -Single::ZERO; + let qnan = Single::NAN; + let p_normal_value = "0x1p+0".parse::().unwrap(); + let m_normal_value = "-0x1p+0".parse::().unwrap(); + let p_largest_value = Single::largest(); + let m_largest_value = -Single::largest(); + let p_smallest_value = Single::SMALLEST; + let m_smallest_value = -Single::SMALLEST; + let p_smallest_normalized = Single::smallest_normalized(); + let m_smallest_normalized = -Single::smallest_normalized(); + + let overflow_status = Status::OVERFLOW | Status::INEXACT; + let underflow_status = Status::UNDERFLOW | Status::INEXACT; + + let special_cases = [ + (p_inf, p_inf, "nan", Status::INVALID_OP, Category::NaN), + (p_inf, m_inf, "nan", Status::INVALID_OP, Category::NaN), + (p_inf, p_zero, "inf", Status::OK, Category::Infinity), + (p_inf, m_zero, "-inf", Status::OK, Category::Infinity), + (p_inf, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_inf, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_inf, p_normal_value, "inf", Status::OK, Category::Infinity), + (p_inf, m_normal_value, "-inf", Status::OK, Category::Infinity), + (p_inf, p_largest_value, "inf", Status::OK, Category::Infinity), + (p_inf, m_largest_value, "-inf", Status::OK, Category::Infinity), + (p_inf, p_smallest_value, "inf", Status::OK, Category::Infinity), + (p_inf, m_smallest_value, "-inf", Status::OK, Category::Infinity), + (p_inf, p_smallest_normalized, "inf", Status::OK, Category::Infinity), + (p_inf, m_smallest_normalized, "-inf", Status::OK, Category::Infinity), + (m_inf, p_inf, "nan", Status::INVALID_OP, Category::NaN), + (m_inf, m_inf, "nan", Status::INVALID_OP, Category::NaN), + (m_inf, p_zero, "-inf", Status::OK, Category::Infinity), + (m_inf, m_zero, "inf", Status::OK, Category::Infinity), + (m_inf, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (m_inf, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_inf, p_normal_value, "-inf", Status::OK, Category::Infinity), + (m_inf, m_normal_value, "inf", Status::OK, Category::Infinity), + (m_inf, p_largest_value, "-inf", Status::OK, Category::Infinity), + (m_inf, m_largest_value, "inf", Status::OK, Category::Infinity), + (m_inf, p_smallest_value, "-inf", Status::OK, Category::Infinity), + (m_inf, m_smallest_value, "inf", Status::OK, Category::Infinity), + (m_inf, p_smallest_normalized, "-inf", Status::OK, Category::Infinity), + (m_inf, m_smallest_normalized, "inf", Status::OK, Category::Infinity), + (p_zero, p_inf, "0x0p+0", Status::OK, Category::Zero), + (p_zero, m_inf, "-0x0p+0", Status::OK, Category::Zero), + (p_zero, p_zero, "nan", Status::INVALID_OP, Category::NaN), + (p_zero, m_zero, "nan", Status::INVALID_OP, Category::NaN), + (p_zero, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_zero, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_zero, p_normal_value, "0x0p+0", Status::OK, Category::Zero), + (p_zero, m_normal_value, "-0x0p+0", Status::OK, Category::Zero), + (p_zero, p_largest_value, "0x0p+0", Status::OK, Category::Zero), + (p_zero, m_largest_value, "-0x0p+0", Status::OK, Category::Zero), + (p_zero, p_smallest_value, "0x0p+0", Status::OK, Category::Zero), + (p_zero, m_smallest_value, "-0x0p+0", Status::OK, Category::Zero), + (p_zero, p_smallest_normalized, "0x0p+0", Status::OK, Category::Zero), + (p_zero, m_smallest_normalized, "-0x0p+0", Status::OK, Category::Zero), + (m_zero, p_inf, "-0x0p+0", Status::OK, Category::Zero), + (m_zero, m_inf, "0x0p+0", Status::OK, Category::Zero), + (m_zero, p_zero, "nan", Status::INVALID_OP, Category::NaN), + (m_zero, m_zero, "nan", Status::INVALID_OP, Category::NaN), + (m_zero, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (m_zero, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_zero, p_normal_value, "-0x0p+0", Status::OK, Category::Zero), + (m_zero, m_normal_value, "0x0p+0", Status::OK, Category::Zero), + (m_zero, p_largest_value, "-0x0p+0", Status::OK, Category::Zero), + (m_zero, m_largest_value, "0x0p+0", Status::OK, Category::Zero), + (m_zero, p_smallest_value, "-0x0p+0", Status::OK, Category::Zero), + (m_zero, m_smallest_value, "0x0p+0", Status::OK, Category::Zero), + (m_zero, p_smallest_normalized, "-0x0p+0", Status::OK, Category::Zero), + (m_zero, m_smallest_normalized, "0x0p+0", Status::OK, Category::Zero), + (qnan, p_inf, "nan", Status::OK, Category::NaN), + (qnan, m_inf, "nan", Status::OK, Category::NaN), + (qnan, p_zero, "nan", Status::OK, Category::NaN), + (qnan, m_zero, "nan", Status::OK, Category::NaN), + (qnan, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (qnan, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (qnan, p_normal_value, "nan", Status::OK, Category::NaN), + (qnan, m_normal_value, "nan", Status::OK, Category::NaN), + (qnan, p_largest_value, "nan", Status::OK, Category::NaN), + (qnan, m_largest_value, "nan", Status::OK, Category::NaN), + (qnan, p_smallest_value, "nan", Status::OK, Category::NaN), + (qnan, m_smallest_value, "nan", Status::OK, Category::NaN), + (qnan, p_smallest_normalized, "nan", Status::OK, Category::NaN), + (qnan, m_smallest_normalized, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (snan, p_inf, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_inf, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_zero, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_zero, "nan", Status::INVALID_OP, Category::NaN), + (snan, qnan, "nan", Status::INVALID_OP, Category::NaN), + (snan, snan, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_normal_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_normal_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_largest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_largest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_smallest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_smallest_value, "nan", Status::INVALID_OP, Category::NaN), + (snan, p_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), + (snan, m_smallest_normalized, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_normal_value, p_inf, "0x0p+0", Status::OK, Category::Zero), + (p_normal_value, m_inf, "-0x0p+0", Status::OK, Category::Zero), + (p_normal_value, p_zero, "inf", Status::DIV_BY_ZERO, Category::Infinity), + (p_normal_value, m_zero, "-inf", Status::DIV_BY_ZERO, Category::Infinity), + (p_normal_value, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_normal_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_normal_value, p_normal_value, "0x1p+0", Status::OK, Category::Normal), + (p_normal_value, m_normal_value, "-0x1p+0", Status::OK, Category::Normal), + (p_normal_value, p_largest_value, "0x1p-128", underflow_status, Category::Normal), + (p_normal_value, m_largest_value, "-0x1p-128", underflow_status, Category::Normal), + (p_normal_value, p_smallest_value, "inf", overflow_status, Category::Infinity), + (p_normal_value, m_smallest_value, "-inf", overflow_status, Category::Infinity), + (p_normal_value, p_smallest_normalized, "0x1p+126", Status::OK, Category::Normal), + (p_normal_value, m_smallest_normalized, "-0x1p+126", Status::OK, Category::Normal), + (m_normal_value, p_inf, "-0x0p+0", Status::OK, Category::Zero), + (m_normal_value, m_inf, "0x0p+0", Status::OK, Category::Zero), + (m_normal_value, p_zero, "-inf", Status::DIV_BY_ZERO, Category::Infinity), + (m_normal_value, m_zero, "inf", Status::DIV_BY_ZERO, Category::Infinity), + (m_normal_value, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (m_normal_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_normal_value, p_normal_value, "-0x1p+0", Status::OK, Category::Normal), + (m_normal_value, m_normal_value, "0x1p+0", Status::OK, Category::Normal), + (m_normal_value, p_largest_value, "-0x1p-128", underflow_status, Category::Normal), + (m_normal_value, m_largest_value, "0x1p-128", underflow_status, Category::Normal), + (m_normal_value, p_smallest_value, "-inf", overflow_status, Category::Infinity), + (m_normal_value, m_smallest_value, "inf", overflow_status, Category::Infinity), + (m_normal_value, p_smallest_normalized, "-0x1p+126", Status::OK, Category::Normal), + (m_normal_value, m_smallest_normalized, "0x1p+126", Status::OK, Category::Normal), + (p_largest_value, p_inf, "0x0p+0", Status::OK, Category::Zero), + (p_largest_value, m_inf, "-0x0p+0", Status::OK, Category::Zero), + (p_largest_value, p_zero, "inf", Status::DIV_BY_ZERO, Category::Infinity), + (p_largest_value, m_zero, "-inf", Status::DIV_BY_ZERO, Category::Infinity), + (p_largest_value, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (p_largest_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_largest_value, p_normal_value, "0x1.fffffep+127", Status::OK, Category::Normal), + (p_largest_value, m_normal_value, "-0x1.fffffep+127", Status::OK, Category::Normal), + (p_largest_value, p_largest_value, "0x1p+0", Status::OK, Category::Normal), + (p_largest_value, m_largest_value, "-0x1p+0", Status::OK, Category::Normal), + (p_largest_value, p_smallest_value, "inf", overflow_status, Category::Infinity), + (p_largest_value, m_smallest_value, "-inf", overflow_status, Category::Infinity), + (p_largest_value, p_smallest_normalized, "inf", overflow_status, Category::Infinity), + (p_largest_value, m_smallest_normalized, "-inf", overflow_status, Category::Infinity), + (m_largest_value, p_inf, "-0x0p+0", Status::OK, Category::Zero), + (m_largest_value, m_inf, "0x0p+0", Status::OK, Category::Zero), + (m_largest_value, p_zero, "-inf", Status::DIV_BY_ZERO, Category::Infinity), + (m_largest_value, m_zero, "inf", Status::DIV_BY_ZERO, Category::Infinity), + (m_largest_value, qnan, "nan", Status::OK, Category::NaN), + /* + // See Note 1. + (m_largest_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_largest_value, p_normal_value, "-0x1.fffffep+127", Status::OK, Category::Normal), + (m_largest_value, m_normal_value, "0x1.fffffep+127", Status::OK, Category::Normal), + (m_largest_value, p_largest_value, "-0x1p+0", Status::OK, Category::Normal), + (m_largest_value, m_largest_value, "0x1p+0", Status::OK, Category::Normal), + (m_largest_value, p_smallest_value, "-inf", overflow_status, Category::Infinity), + (m_largest_value, m_smallest_value, "inf", overflow_status, Category::Infinity), + (m_largest_value, p_smallest_normalized, "-inf", overflow_status, Category::Infinity), + (m_largest_value, m_smallest_normalized, "inf", overflow_status, Category::Infinity), + (p_smallest_value, p_inf, "0x0p+0", Status::OK, Category::Zero), + (p_smallest_value, m_inf, "-0x0p+0", Status::OK, Category::Zero), + (p_smallest_value, p_zero, "inf", Status::DIV_BY_ZERO, Category::Infinity), + (p_smallest_value, m_zero, "-inf", Status::DIV_BY_ZERO, Category::Infinity), (p_smallest_value, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(p_smallest_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_smallest_value, - p_normal_value, - "0x1p-149", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - m_normal_value, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - p_largest_value, - "0x0p+0", - underflow_status, - Category::Zero, - ), - ( - p_smallest_value, - m_largest_value, - "-0x0p+0", - underflow_status, - Category::Zero, - ), - ( - p_smallest_value, - p_smallest_value, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - m_smallest_value, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - p_smallest_normalized, - "0x1p-23", - Status::OK, - Category::Normal, - ), - ( - p_smallest_value, - m_smallest_normalized, - "-0x1p-23", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - p_inf, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_smallest_value, - m_inf, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_smallest_value, - p_zero, - "-inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), - ( - m_smallest_value, - m_zero, - "inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), + // See Note 1. + (p_smallest_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_smallest_value, p_normal_value, "0x1p-149", Status::OK, Category::Normal), + (p_smallest_value, m_normal_value, "-0x1p-149", Status::OK, Category::Normal), + (p_smallest_value, p_largest_value, "0x0p+0", underflow_status, Category::Zero), + (p_smallest_value, m_largest_value, "-0x0p+0", underflow_status, Category::Zero), + (p_smallest_value, p_smallest_value, "0x1p+0", Status::OK, Category::Normal), + (p_smallest_value, m_smallest_value, "-0x1p+0", Status::OK, Category::Normal), + (p_smallest_value, p_smallest_normalized, "0x1p-23", Status::OK, Category::Normal), + (p_smallest_value, m_smallest_normalized, "-0x1p-23", Status::OK, Category::Normal), + (m_smallest_value, p_inf, "-0x0p+0", Status::OK, Category::Zero), + (m_smallest_value, m_inf, "0x0p+0", Status::OK, Category::Zero), + (m_smallest_value, p_zero, "-inf", Status::DIV_BY_ZERO, Category::Infinity), + (m_smallest_value, m_zero, "inf", Status::DIV_BY_ZERO, Category::Infinity), (m_smallest_value, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(m_smallest_value, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_smallest_value, - p_normal_value, - "-0x1p-149", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - m_normal_value, - "0x1p-149", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - p_largest_value, - "-0x0p+0", - underflow_status, - Category::Zero, - ), - ( - m_smallest_value, - m_largest_value, - "0x0p+0", - underflow_status, - Category::Zero, - ), - ( - m_smallest_value, - p_smallest_value, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - m_smallest_value, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - p_smallest_normalized, - "-0x1p-23", - Status::OK, - Category::Normal, - ), - ( - m_smallest_value, - m_smallest_normalized, - "0x1p-23", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - p_inf, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_smallest_normalized, - m_inf, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - p_smallest_normalized, - p_zero, - "inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), - ( - p_smallest_normalized, - m_zero, - "-inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), - ( - p_smallest_normalized, - qnan, - "nan", - Status::OK, - Category::NaN, - ), + // See Note 1. + (m_smallest_value, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_smallest_value, p_normal_value, "-0x1p-149", Status::OK, Category::Normal), + (m_smallest_value, m_normal_value, "0x1p-149", Status::OK, Category::Normal), + (m_smallest_value, p_largest_value, "-0x0p+0", underflow_status, Category::Zero), + (m_smallest_value, m_largest_value, "0x0p+0", underflow_status, Category::Zero), + (m_smallest_value, p_smallest_value, "-0x1p+0", Status::OK, Category::Normal), + (m_smallest_value, m_smallest_value, "0x1p+0", Status::OK, Category::Normal), + (m_smallest_value, p_smallest_normalized, "-0x1p-23", Status::OK, Category::Normal), + (m_smallest_value, m_smallest_normalized, "0x1p-23", Status::OK, Category::Normal), + (p_smallest_normalized, p_inf, "0x0p+0", Status::OK, Category::Zero), + (p_smallest_normalized, m_inf, "-0x0p+0", Status::OK, Category::Zero), + (p_smallest_normalized, p_zero, "inf", Status::DIV_BY_ZERO, Category::Infinity), + (p_smallest_normalized, m_zero, "-inf", Status::DIV_BY_ZERO, Category::Infinity), + (p_smallest_normalized, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(p_smallest_normalized, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - p_smallest_normalized, - p_normal_value, - "0x1p-126", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - m_normal_value, - "-0x1p-126", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - p_largest_value, - "0x0p+0", - underflow_status, - Category::Zero, - ), - ( - p_smallest_normalized, - m_largest_value, - "-0x0p+0", - underflow_status, - Category::Zero, - ), - ( - p_smallest_normalized, - p_smallest_value, - "0x1p+23", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - m_smallest_value, - "-0x1p+23", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - p_smallest_normalized, - "0x1p+0", - Status::OK, - Category::Normal, - ), - ( - p_smallest_normalized, - m_smallest_normalized, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - p_inf, - "-0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_smallest_normalized, - m_inf, - "0x0p+0", - Status::OK, - Category::Zero, - ), - ( - m_smallest_normalized, - p_zero, - "-inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), - ( - m_smallest_normalized, - m_zero, - "inf", - Status::DIV_BY_ZERO, - Category::Infinity, - ), - ( - m_smallest_normalized, - qnan, - "nan", - Status::OK, - Category::NaN, - ), + // See Note 1. + (p_smallest_normalized, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (p_smallest_normalized, p_normal_value, "0x1p-126", Status::OK, Category::Normal), + (p_smallest_normalized, m_normal_value, "-0x1p-126", Status::OK, Category::Normal), + (p_smallest_normalized, p_largest_value, "0x0p+0", underflow_status, Category::Zero), + (p_smallest_normalized, m_largest_value, "-0x0p+0", underflow_status, Category::Zero), + (p_smallest_normalized, p_smallest_value, "0x1p+23", Status::OK, Category::Normal), + (p_smallest_normalized, m_smallest_value, "-0x1p+23", Status::OK, Category::Normal), + (p_smallest_normalized, p_smallest_normalized, "0x1p+0", Status::OK, Category::Normal), + (p_smallest_normalized, m_smallest_normalized, "-0x1p+0", Status::OK, Category::Normal), + (m_smallest_normalized, p_inf, "-0x0p+0", Status::OK, Category::Zero), + (m_smallest_normalized, m_inf, "0x0p+0", Status::OK, Category::Zero), + (m_smallest_normalized, p_zero, "-inf", Status::DIV_BY_ZERO, Category::Infinity), + (m_smallest_normalized, m_zero, "inf", Status::DIV_BY_ZERO, Category::Infinity), + (m_smallest_normalized, qnan, "nan", Status::OK, Category::NaN), /* -// See Note 1. -(m_smallest_normalized, snan, "nan", Status::INVALID_OP, Category::NaN), - */ - ( - m_smallest_normalized, - p_normal_value, - "-0x1p-126", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - m_normal_value, - "0x1p-126", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - p_largest_value, - "-0x0p+0", - underflow_status, - Category::Zero, - ), - ( - m_smallest_normalized, - m_largest_value, - "0x0p+0", - underflow_status, - Category::Zero, - ), - ( - m_smallest_normalized, - p_smallest_value, - "-0x1p+23", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - m_smallest_value, - "0x1p+23", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - p_smallest_normalized, - "-0x1p+0", - Status::OK, - Category::Normal, - ), - ( - m_smallest_normalized, - m_smallest_normalized, - "0x1p+0", - Status::OK, - Category::Normal, - ), + // See Note 1. + (m_smallest_normalized, snan, "nan", Status::INVALID_OP, Category::NaN), + */ + (m_smallest_normalized, p_normal_value, "-0x1p-126", Status::OK, Category::Normal), + (m_smallest_normalized, m_normal_value, "0x1p-126", Status::OK, Category::Normal), + (m_smallest_normalized, p_largest_value, "-0x0p+0", underflow_status, Category::Zero), + (m_smallest_normalized, m_largest_value, "0x0p+0", underflow_status, Category::Zero), + (m_smallest_normalized, p_smallest_value, "-0x1p+23", Status::OK, Category::Normal), + (m_smallest_normalized, m_smallest_value, "0x1p+23", Status::OK, Category::Normal), + (m_smallest_normalized, p_smallest_normalized, "-0x1p+0", Status::OK, Category::Normal), + (m_smallest_normalized, m_smallest_normalized, "0x1p+0", Status::OK, Category::Normal), ]; for &(x, y, e_result, e_status, e_category) in &special_cases[..] { @@ -6358,12 +2851,8 @@ fn abs() { assert!(p_largest_value.bitwise_eq(m_largest_value.abs())); assert!(p_smallest_value.bitwise_eq(p_smallest_value.abs())); assert!(p_smallest_value.bitwise_eq(m_smallest_value.abs())); - assert!(p_smallest_normalized.bitwise_eq( - p_smallest_normalized.abs(), - )); - assert!(p_smallest_normalized.bitwise_eq( - m_smallest_normalized.abs(), - )); + assert!(p_smallest_normalized.bitwise_eq(p_smallest_normalized.abs(),)); + assert!(p_smallest_normalized.bitwise_eq(m_smallest_normalized.abs(),)); } #[test] @@ -6393,32 +2882,16 @@ fn neg() { fn ilogb() { assert_eq!(-1074, Double::SMALLEST.ilogb()); assert_eq!(-1074, (-Double::SMALLEST).ilogb()); - assert_eq!( - -1023, - "0x1.ffffffffffffep-1024".parse::().unwrap().ilogb() - ); - assert_eq!( - -1023, - "0x1.ffffffffffffep-1023".parse::().unwrap().ilogb() - ); - assert_eq!( - -1023, - "-0x1.ffffffffffffep-1023" - .parse::() - .unwrap() - .ilogb() - ); + assert_eq!(-1023, "0x1.ffffffffffffep-1024".parse::().unwrap().ilogb()); + assert_eq!(-1023, "0x1.ffffffffffffep-1023".parse::().unwrap().ilogb()); + assert_eq!(-1023, "-0x1.ffffffffffffep-1023".parse::().unwrap().ilogb()); assert_eq!(-51, "0x1p-51".parse::().unwrap().ilogb()); - assert_eq!( - -1023, - "0x1.c60f120d9f87cp-1023".parse::().unwrap().ilogb() - ); + assert_eq!(-1023, "0x1.c60f120d9f87cp-1023".parse::().unwrap().ilogb()); assert_eq!(-2, "0x0.ffffp-1".parse::().unwrap().ilogb()); assert_eq!(-1023, "0x1.fffep-1023".parse::().unwrap().ilogb()); assert_eq!(1023, Double::largest().ilogb()); assert_eq!(1023, (-Double::largest()).ilogb()); - assert_eq!(0, "0x1p+0".parse::().unwrap().ilogb()); assert_eq!(0, "-0x1p+0".parse::().unwrap().ilogb()); assert_eq!(42, "0x1p+42".parse::().unwrap().ilogb()); @@ -6442,15 +2915,24 @@ fn ilogb() { #[test] fn scalbn() { - assert!("0x1p+0".parse::().unwrap().bitwise_eq( - "0x1p+0".parse::().unwrap().scalbn(0), - )); - assert!("0x1p+42".parse::().unwrap().bitwise_eq( - "0x1p+0".parse::().unwrap().scalbn(42), - )); - assert!("0x1p-42".parse::().unwrap().bitwise_eq( - "0x1p+0".parse::().unwrap().scalbn(-42), - )); + assert!( + "0x1p+0" + .parse::() + .unwrap() + .bitwise_eq("0x1p+0".parse::().unwrap().scalbn(0),) + ); + assert!( + "0x1p+42" + .parse::() + .unwrap() + .bitwise_eq("0x1p+0".parse::().unwrap().scalbn(42),) + ); + assert!( + "0x1p-42" + .parse::() + .unwrap() + .bitwise_eq("0x1p+0".parse::().unwrap().scalbn(-42),) + ); let p_inf = Single::INFINITY; let m_inf = -Single::INFINITY; @@ -6479,28 +2961,18 @@ fn scalbn() { assert!(quiet_payload.is_nan() && !quiet_payload.is_signaling()); assert_eq!(payload, quiet_payload.to_bits() & ((1 << 51) - 1)); - assert!(p_inf.bitwise_eq( - "0x1p+0".parse::().unwrap().scalbn(128), - )); - assert!(m_inf.bitwise_eq( - "-0x1p+0".parse::().unwrap().scalbn(128), - )); - assert!(p_inf.bitwise_eq( - "0x1p+127".parse::().unwrap().scalbn(1), - )); - assert!(p_zero.bitwise_eq( - "0x1p-127".parse::().unwrap().scalbn(-127), - )); - assert!(m_zero.bitwise_eq( - "-0x1p-127".parse::().unwrap().scalbn(-127), - )); - assert!("-0x1p-149".parse::().unwrap().bitwise_eq( - "-0x1p-127".parse::().unwrap().scalbn(-22), - )); - assert!(p_zero.bitwise_eq( - "0x1p-126".parse::().unwrap().scalbn(-24), - )); - + assert!(p_inf.bitwise_eq("0x1p+0".parse::().unwrap().scalbn(128),)); + assert!(m_inf.bitwise_eq("-0x1p+0".parse::().unwrap().scalbn(128),)); + assert!(p_inf.bitwise_eq("0x1p+127".parse::().unwrap().scalbn(1),)); + assert!(p_zero.bitwise_eq("0x1p-127".parse::().unwrap().scalbn(-127),)); + assert!(m_zero.bitwise_eq("-0x1p-127".parse::().unwrap().scalbn(-127),)); + assert!( + "-0x1p-149" + .parse::() + .unwrap() + .bitwise_eq("-0x1p-127".parse::().unwrap().scalbn(-22),) + ); + assert!(p_zero.bitwise_eq("0x1p-126".parse::().unwrap().scalbn(-24),)); let smallest_f64 = Double::SMALLEST; let neg_smallest_f64 = -Double::SMALLEST; @@ -6511,33 +2983,16 @@ fn scalbn() { let largest_denormal_f64 = "0x1.ffffffffffffep-1023".parse::().unwrap(); let neg_largest_denormal_f64 = "-0x1.ffffffffffffep-1023".parse::().unwrap(); + assert!(smallest_f64.bitwise_eq("0x1p-1074".parse::().unwrap().scalbn(0),)); + assert!(neg_smallest_f64.bitwise_eq("-0x1p-1074".parse::().unwrap().scalbn(0),)); - assert!(smallest_f64.bitwise_eq( - "0x1p-1074".parse::().unwrap().scalbn(0), - )); - assert!(neg_smallest_f64.bitwise_eq( - "-0x1p-1074".parse::().unwrap().scalbn(0), - )); - - assert!("0x1p+1023".parse::().unwrap().bitwise_eq( - smallest_f64.scalbn( - 2097, - ), - )); + assert!("0x1p+1023".parse::().unwrap().bitwise_eq(smallest_f64.scalbn(2097,),)); assert!(smallest_f64.scalbn(-2097).is_pos_zero()); assert!(smallest_f64.scalbn(-2098).is_pos_zero()); assert!(smallest_f64.scalbn(-2099).is_pos_zero()); - assert!("0x1p+1022".parse::().unwrap().bitwise_eq( - smallest_f64.scalbn( - 2096, - ), - )); - assert!("0x1p+1023".parse::().unwrap().bitwise_eq( - smallest_f64.scalbn( - 2097, - ), - )); + assert!("0x1p+1022".parse::().unwrap().bitwise_eq(smallest_f64.scalbn(2096,),)); + assert!("0x1p+1023".parse::().unwrap().bitwise_eq(smallest_f64.scalbn(2097,),)); assert!(smallest_f64.scalbn(2098).is_infinite()); assert!(smallest_f64.scalbn(2099).is_infinite()); @@ -6545,12 +3000,8 @@ fn scalbn() { assert!(smallest_f64.scalbn(-ExpInt::max_value()).is_pos_zero()); assert!(largest_f64.scalbn(ExpInt::max_value()).is_infinite()); - assert!(largest_denormal_f64.bitwise_eq( - largest_denormal_f64.scalbn(0), - )); - assert!(neg_largest_denormal_f64.bitwise_eq( - neg_largest_denormal_f64.scalbn(0), - )); + assert!(largest_denormal_f64.bitwise_eq(largest_denormal_f64.scalbn(0),)); + assert!(neg_largest_denormal_f64.bitwise_eq(neg_largest_denormal_f64.scalbn(0),)); assert!( "0x1.ffffffffffffep-1022" @@ -6602,11 +3053,7 @@ fn scalbn() { .unwrap() .bitwise_eq(largest_denormal_f64.scalbn(2046)) ); - assert!("0x1p+974".parse::().unwrap().bitwise_eq( - smallest_f64.scalbn( - 2048, - ), - )); + assert!("0x1p+974".parse::().unwrap().bitwise_eq(smallest_f64.scalbn(2048,),)); let random_denormal_f64 = "0x1.c60f120d9f87cp+51".parse::().unwrap(); assert!( @@ -6637,40 +3084,30 @@ fn scalbn() { assert!(random_denormal_f64.scalbn(-2097).is_pos_zero()); assert!(random_denormal_f64.scalbn(-2090).is_pos_zero()); + assert!("-0x1p-1073".parse::().unwrap().bitwise_eq(neg_largest_f64.scalbn(-2097),)); - assert!("-0x1p-1073".parse::().unwrap().bitwise_eq( - neg_largest_f64.scalbn(-2097), - )); - - assert!("-0x1p-1024".parse::().unwrap().bitwise_eq( - neg_largest_f64.scalbn(-2048), - )); + assert!("-0x1p-1024".parse::().unwrap().bitwise_eq(neg_largest_f64.scalbn(-2048),)); - assert!("0x1p-1073".parse::().unwrap().bitwise_eq( - largest_f64.scalbn( - -2097, - ), - )); + assert!("0x1p-1073".parse::().unwrap().bitwise_eq(largest_f64.scalbn(-2097,),)); - assert!("0x1p-1074".parse::().unwrap().bitwise_eq( - largest_f64.scalbn( - -2098, - ), - )); - assert!("-0x1p-1074".parse::().unwrap().bitwise_eq( - neg_largest_f64.scalbn(-2098), - )); + assert!("0x1p-1074".parse::().unwrap().bitwise_eq(largest_f64.scalbn(-2098,),)); + assert!("-0x1p-1074".parse::().unwrap().bitwise_eq(neg_largest_f64.scalbn(-2098),)); assert!(neg_largest_f64.scalbn(-2099).is_neg_zero()); assert!(largest_f64.scalbn(1).is_infinite()); + assert!( + "0x1p+0" + .parse::() + .unwrap() + .bitwise_eq("0x1p+52".parse::().unwrap().scalbn(-52),) + ); - assert!("0x1p+0".parse::().unwrap().bitwise_eq( - "0x1p+52".parse::().unwrap().scalbn(-52), - )); - - assert!("0x1p-103".parse::().unwrap().bitwise_eq( - "0x1p-51".parse::().unwrap().scalbn(-52), - )); + assert!( + "0x1p-103" + .parse::() + .unwrap() + .bitwise_eq("0x1p-51".parse::().unwrap().scalbn(-52),) + ); } #[test] @@ -6711,7 +3148,6 @@ fn frexp() { assert_eq!(0, exp); assert!(frac.is_neg_zero()); - let frac = one.frexp(&mut exp); assert_eq!(1, exp); assert!("0x1p-1".parse::().unwrap().bitwise_eq(frac)); @@ -6722,22 +3158,11 @@ fn frexp() { let frac = largest_denormal.frexp(&mut exp); assert_eq!(-1022, exp); - assert!( - "0x1.ffffffffffffep-1" - .parse::() - .unwrap() - .bitwise_eq(frac) - ); + assert!("0x1.ffffffffffffep-1".parse::().unwrap().bitwise_eq(frac)); let frac = neg_largest_denormal.frexp(&mut exp); assert_eq!(-1022, exp); - assert!( - "-0x1.ffffffffffffep-1" - .parse::() - .unwrap() - .bitwise_eq(frac) - ); - + assert!("-0x1.ffffffffffffep-1".parse::().unwrap().bitwise_eq(frac)); let frac = smallest.frexp(&mut exp); assert_eq!(-1073, exp); @@ -6747,25 +3172,13 @@ fn frexp() { assert_eq!(-1073, exp); assert!("-0x1p-1".parse::().unwrap().bitwise_eq(frac)); - let frac = largest.frexp(&mut exp); assert_eq!(1024, exp); - assert!( - "0x1.fffffffffffffp-1" - .parse::() - .unwrap() - .bitwise_eq(frac) - ); + assert!("0x1.fffffffffffffp-1".parse::().unwrap().bitwise_eq(frac)); let frac = neg_largest.frexp(&mut exp); assert_eq!(1024, exp); - assert!( - "-0x1.fffffffffffffp-1" - .parse::() - .unwrap() - .bitwise_eq(frac) - ); - + assert!("-0x1.fffffffffffffp-1".parse::().unwrap().bitwise_eq(frac)); let frac = p_inf.frexp(&mut exp); assert_eq!(IEK_INF, exp); @@ -6800,16 +3213,9 @@ fn frexp() { assert_eq!(-50, exp); assert!("0x1p-1".parse::().unwrap().bitwise_eq(frac)); - let frac = "0x1.c60f120d9f87cp+51".parse::().unwrap().frexp( - &mut exp, - ); + let frac = "0x1.c60f120d9f87cp+51".parse::().unwrap().frexp(&mut exp); assert_eq!(52, exp); - assert!( - "0x1.c60f120d9f87cp-1" - .parse::() - .unwrap() - .bitwise_eq(frac) - ); + assert!("0x1.c60f120d9f87cp-1".parse::().unwrap().bitwise_eq(frac)); } #[test] diff --git a/src/librustc_apfloat/tests/ppc.rs b/src/librustc_apfloat/tests/ppc.rs index 02cdeb90a12be..5a8de71cb3490 100644 --- a/src/librustc_apfloat/tests/ppc.rs +++ b/src/librustc_apfloat/tests/ppc.rs @@ -1,5 +1,5 @@ -use rustc_apfloat::{Category, Float, Round}; use rustc_apfloat::ppc::DoubleDouble; +use rustc_apfloat::{Category, Float, Round}; use std::cmp::Ordering; @@ -23,15 +23,11 @@ fn ppc_double_double() { assert_eq!(0x3ff0000000000000, test.to_bits()); // LDBL_MAX - let test = "1.79769313486231580793728971405301e+308" - .parse::() - .unwrap(); + let test = "1.79769313486231580793728971405301e+308".parse::().unwrap(); assert_eq!(0x7c8ffffffffffffe_7fefffffffffffff, test.to_bits()); // LDBL_MIN - let test = "2.00416836000897277799610805135016e-292" - .parse::() - .unwrap(); + let test = "2.00416836000897277799610805135016e-292".parse::().unwrap(); assert_eq!(0x0000000000000000_0360000000000000, test.to_bits()); } @@ -39,12 +35,7 @@ fn ppc_double_double() { fn ppc_double_double_add_special() { let data = [ // (1 + 0) + (-1 + 0) = Category::Zero - ( - 0x3ff0000000000000, - 0xbff0000000000000, - Category::Zero, - Round::NearestTiesToEven, - ), + (0x3ff0000000000000, 0xbff0000000000000, Category::Zero, Round::NearestTiesToEven), // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = Category::Infinity ( 0x7c8ffffffffffffe_7fefffffffffffff, @@ -70,12 +61,7 @@ fn ppc_double_double_add_special() { Round::NearestTiesToEven, ), // NaN + (1 + 0) = Category::NaN - ( - 0x7ff8000000000000, - 0x3ff0000000000000, - Category::NaN, - Round::NearestTiesToEven, - ), + (0x7ff8000000000000, 0x3ff0000000000000, Category::NaN, Round::NearestTiesToEven), ]; for &(op1, op2, expected, round) in &data { @@ -199,63 +185,23 @@ fn ppc_double_double_subtract() { fn ppc_double_double_multiply_special() { let data = [ // Category::NaN * Category::NaN = Category::NaN - ( - 0x7ff8000000000000, - 0x7ff8000000000000, - Category::NaN, - Round::NearestTiesToEven, - ), + (0x7ff8000000000000, 0x7ff8000000000000, Category::NaN, Round::NearestTiesToEven), // Category::NaN * Category::Zero = Category::NaN - ( - 0x7ff8000000000000, - 0, - Category::NaN, - Round::NearestTiesToEven, - ), + (0x7ff8000000000000, 0, Category::NaN, Round::NearestTiesToEven), // Category::NaN * Category::Infinity = Category::NaN - ( - 0x7ff8000000000000, - 0x7ff0000000000000, - Category::NaN, - Round::NearestTiesToEven, - ), + (0x7ff8000000000000, 0x7ff0000000000000, Category::NaN, Round::NearestTiesToEven), // Category::NaN * Category::Normal = Category::NaN - ( - 0x7ff8000000000000, - 0x3ff0000000000000, - Category::NaN, - Round::NearestTiesToEven, - ), + (0x7ff8000000000000, 0x3ff0000000000000, Category::NaN, Round::NearestTiesToEven), // Category::Infinity * Category::Infinity = Category::Infinity - ( - 0x7ff0000000000000, - 0x7ff0000000000000, - Category::Infinity, - Round::NearestTiesToEven, - ), + (0x7ff0000000000000, 0x7ff0000000000000, Category::Infinity, Round::NearestTiesToEven), // Category::Infinity * Category::Zero = Category::NaN - ( - 0x7ff0000000000000, - 0, - Category::NaN, - Round::NearestTiesToEven, - ), + (0x7ff0000000000000, 0, Category::NaN, Round::NearestTiesToEven), // Category::Infinity * Category::Normal = Category::Infinity - ( - 0x7ff0000000000000, - 0x3ff0000000000000, - Category::Infinity, - Round::NearestTiesToEven, - ), + (0x7ff0000000000000, 0x3ff0000000000000, Category::Infinity, Round::NearestTiesToEven), // Category::Zero * Category::Zero = Category::Zero (0, 0, Category::Zero, Round::NearestTiesToEven), // Category::Zero * Category::Normal = Category::Zero - ( - 0, - 0x3ff0000000000000, - Category::Zero, - Round::NearestTiesToEven, - ), + (0, 0x3ff0000000000000, Category::Zero, Round::NearestTiesToEven), ]; for &(op1, op2, expected, round) in &data { @@ -407,13 +353,7 @@ fn ppc_double_double_remainder() { let a2 = DoubleDouble::from_bits(op2); let result = a1.ieee_rem(a2).value; - assert_eq!( - expected, - result.to_bits(), - "ieee_rem({:#x}, {:#x})", - op1, - op2 - ); + assert_eq!(expected, result.to_bits(), "ieee_rem({:#x}, {:#x})", op1, op2); } } @@ -449,14 +389,8 @@ fn ppc_double_double_mod() { fn ppc_double_double_fma() { // Sanity check for now. let mut a = "2".parse::().unwrap(); - a = a.mul_add( - "3".parse::().unwrap(), - "4".parse::().unwrap(), - ).value; - assert_eq!( - Some(Ordering::Equal), - "10".parse::().unwrap().partial_cmp(&a) - ); + a = a.mul_add("3".parse::().unwrap(), "4".parse::().unwrap()).value; + assert_eq!(Some(Ordering::Equal), "10".parse::().unwrap().partial_cmp(&a)); } #[test] @@ -464,18 +398,12 @@ fn ppc_double_double_round_to_integral() { { let a = "1.5".parse::().unwrap(); let a = a.round_to_integral(Round::NearestTiesToEven).value; - assert_eq!( - Some(Ordering::Equal), - "2".parse::().unwrap().partial_cmp(&a) - ); + assert_eq!(Some(Ordering::Equal), "2".parse::().unwrap().partial_cmp(&a)); } { let a = "2.5".parse::().unwrap(); let a = a.round_to_integral(Round::NearestTiesToEven).value; - assert_eq!( - Some(Ordering::Equal), - "2".parse::().unwrap().partial_cmp(&a) - ); + assert_eq!(Some(Ordering::Equal), "2".parse::().unwrap().partial_cmp(&a)); } } @@ -483,47 +411,25 @@ fn ppc_double_double_round_to_integral() { fn ppc_double_double_compare() { let data = [ // (1 + 0) = (1 + 0) - ( - 0x3ff0000000000000, - 0x3ff0000000000000, - Some(Ordering::Equal), - ), + (0x3ff0000000000000, 0x3ff0000000000000, Some(Ordering::Equal)), // (1 + 0) < (1.00...1 + 0) (0x3ff0000000000000, 0x3ff0000000000001, Some(Ordering::Less)), // (1.00...1 + 0) > (1 + 0) - ( - 0x3ff0000000000001, - 0x3ff0000000000000, - Some(Ordering::Greater), - ), + (0x3ff0000000000001, 0x3ff0000000000000, Some(Ordering::Greater)), // (1 + 0) < (1 + epsilon) - ( - 0x3ff0000000000000, - 0x0000000000000001_3ff0000000000001, - Some(Ordering::Less), - ), + (0x3ff0000000000000, 0x0000000000000001_3ff0000000000001, Some(Ordering::Less)), // NaN != NaN (0x7ff8000000000000, 0x7ff8000000000000, None), // (1 + 0) != NaN (0x3ff0000000000000, 0x7ff8000000000000, None), // Inf = Inf - ( - 0x7ff0000000000000, - 0x7ff0000000000000, - Some(Ordering::Equal), - ), + (0x7ff0000000000000, 0x7ff0000000000000, Some(Ordering::Equal)), ]; for &(op1, op2, expected) in &data { let a1 = DoubleDouble::from_bits(op1); let a2 = DoubleDouble::from_bits(op2); - assert_eq!( - expected, - a1.partial_cmp(&a2), - "compare({:#x}, {:#x})", - op1, - op2, - ); + assert_eq!(expected, a1.partial_cmp(&a2), "compare({:#x}, {:#x})", op1, op2,); } } @@ -537,11 +443,7 @@ fn ppc_double_double_bitwise_eq() { // NaN = NaN (0x7ff8000000000000, 0x7ff8000000000000, true), // NaN != NaN with a different bit pattern - ( - 0x7ff8000000000000, - 0x3ff0000000000000_7ff8000000000000, - false, - ), + (0x7ff8000000000000, 0x3ff0000000000000_7ff8000000000000, false), // Inf = Inf (0x7ff0000000000000, 0x7ff0000000000000, true), ]; @@ -569,27 +471,12 @@ fn ppc_double_double_change_sign() { #[test] fn ppc_double_double_factories() { assert_eq!(0, DoubleDouble::ZERO.to_bits()); - assert_eq!( - 0x7c8ffffffffffffe_7fefffffffffffff, - DoubleDouble::largest().to_bits() - ); + assert_eq!(0x7c8ffffffffffffe_7fefffffffffffff, DoubleDouble::largest().to_bits()); assert_eq!(0x0000000000000001, DoubleDouble::SMALLEST.to_bits()); - assert_eq!( - 0x0360000000000000, - DoubleDouble::smallest_normalized().to_bits() - ); - assert_eq!( - 0x0000000000000000_8000000000000000, - (-DoubleDouble::ZERO).to_bits() - ); - assert_eq!( - 0xfc8ffffffffffffe_ffefffffffffffff, - (-DoubleDouble::largest()).to_bits() - ); - assert_eq!( - 0x0000000000000000_8000000000000001, - (-DoubleDouble::SMALLEST).to_bits() - ); + assert_eq!(0x0360000000000000, DoubleDouble::smallest_normalized().to_bits()); + assert_eq!(0x0000000000000000_8000000000000000, (-DoubleDouble::ZERO).to_bits()); + assert_eq!(0xfc8ffffffffffffe_ffefffffffffffff, (-DoubleDouble::largest()).to_bits()); + assert_eq!(0x0000000000000000_8000000000000001, (-DoubleDouble::SMALLEST).to_bits()); assert_eq!( 0x0000000000000000_8360000000000000, (-DoubleDouble::smallest_normalized()).to_bits() diff --git a/src/librustc_asan/build.rs b/src/librustc_asan/build.rs index 645707ccc0338..e276dc16c35ee 100644 --- a/src/librustc_asan/build.rs +++ b/src/librustc_asan/build.rs @@ -1,5 +1,5 @@ -use std::env; use build_helper::sanitizer_lib_boilerplate; +use std::env; use cmake::Config; diff --git a/src/librustc_asan/lib.rs b/src/librustc_asan/lib.rs index 4c8c9d15d5629..bdbc154f4e861 100644 --- a/src/librustc_asan/lib.rs +++ b/src/librustc_asan/lib.rs @@ -3,6 +3,8 @@ #![feature(sanitizer_runtime)] #![feature(staged_api)] #![no_std] -#![unstable(feature = "sanitizer_runtime_lib", - reason = "internal implementation detail of sanitizers", - issue = "none")] +#![unstable( + feature = "sanitizer_runtime_lib", + reason = "internal implementation detail of sanitizers", + issue = "none" +)] diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 2607a497326f9..c79d9f77e654e 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -5,21 +5,21 @@ use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use rustc_codegen_ssa::MemFlags; -use rustc_codegen_ssa::mir::place::PlaceRef; -use rustc_codegen_ssa::mir::operand::OperandValue; use rustc::bug; +use rustc::ty::layout::{self}; +use rustc::ty::Ty; +use rustc_codegen_ssa::mir::operand::OperandValue; +use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; +use rustc_codegen_ssa::MemFlags; use rustc_target::abi::call::ArgAbi; use rustc_target::abi::{HasDataLayout, LayoutOf}; -use rustc::ty::{Ty}; -use rustc::ty::layout::{self}; use libc::c_uint; -pub use rustc_target::spec::abi::Abi; pub use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA}; pub use rustc_target::abi::call::*; +pub use rustc_target::spec::abi::Abi; macro_rules! for_each_kind { ($flags: ident, $f: ident, $($kind: ident),+) => ({ @@ -28,13 +28,17 @@ macro_rules! for_each_kind { } trait ArgAttributeExt { - fn for_each_kind(&self, f: F) where F: FnMut(llvm::Attribute); + fn for_each_kind(&self, f: F) + where + F: FnMut(llvm::Attribute); } impl ArgAttributeExt for ArgAttribute { - fn for_each_kind(&self, mut f: F) where F: FnMut(llvm::Attribute) { - for_each_kind!(self, f, - NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg) + fn for_each_kind(&self, mut f: F) + where + F: FnMut(llvm::Attribute), + { + for_each_kind!(self, f, NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg) } } @@ -50,20 +54,14 @@ impl ArgAttributesExt for ArgAttributes { let deref = self.pointee_size.bytes(); if deref != 0 { if regular.contains(ArgAttribute::NonNull) { - llvm::LLVMRustAddDereferenceableAttr(llfn, - idx.as_uint(), - deref); + llvm::LLVMRustAddDereferenceableAttr(llfn, idx.as_uint(), deref); } else { - llvm::LLVMRustAddDereferenceableOrNullAttr(llfn, - idx.as_uint(), - deref); + llvm::LLVMRustAddDereferenceableOrNullAttr(llfn, idx.as_uint(), deref); } regular -= ArgAttribute::NonNull; } if let Some(align) = self.pointee_align { - llvm::LLVMRustAddAlignmentAttr(llfn, - idx.as_uint(), - align.bytes() as u32); + llvm::LLVMRustAddAlignmentAttr(llfn, idx.as_uint(), align.bytes() as u32); } if regular.contains(ArgAttribute::ByVal) { llvm::LLVMRustAddByValAttr(llfn, idx.as_uint(), ty.unwrap()); @@ -78,20 +76,22 @@ impl ArgAttributesExt for ArgAttributes { let deref = self.pointee_size.bytes(); if deref != 0 { if regular.contains(ArgAttribute::NonNull) { - llvm::LLVMRustAddDereferenceableCallSiteAttr(callsite, - idx.as_uint(), - deref); + llvm::LLVMRustAddDereferenceableCallSiteAttr(callsite, idx.as_uint(), deref); } else { - llvm::LLVMRustAddDereferenceableOrNullCallSiteAttr(callsite, - idx.as_uint(), - deref); + llvm::LLVMRustAddDereferenceableOrNullCallSiteAttr( + callsite, + idx.as_uint(), + deref, + ); } regular -= ArgAttribute::NonNull; } if let Some(align) = self.pointee_align { - llvm::LLVMRustAddAlignmentCallSiteAttr(callsite, - idx.as_uint(), - align.bytes() as u32); + llvm::LLVMRustAddAlignmentCallSiteAttr( + callsite, + idx.as_uint(), + align.bytes() as u32, + ); } if regular.contains(ArgAttribute::ByVal) { llvm::LLVMRustAddByValCallSiteAttr(callsite, idx.as_uint(), ty.unwrap()); @@ -109,16 +109,12 @@ impl LlvmType for Reg { fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type { match self.kind { RegKind::Integer => cx.type_ix(self.size.bits()), - RegKind::Float => { - match self.size.bits() { - 32 => cx.type_f32(), - 64 => cx.type_f64(), - _ => bug!("unsupported float: {:?}", self) - } - } - RegKind::Vector => { - cx.type_vector(cx.type_i8(), self.size.bytes()) - } + RegKind::Float => match self.size.bits() { + 32 => cx.type_f32(), + 64 => cx.type_f64(), + _ => bug!("unsupported float: {:?}", self), + }, + RegKind::Vector => cx.type_vector(cx.type_i8(), self.size.bytes()), } } } @@ -129,8 +125,10 @@ impl LlvmType for CastTarget { let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 { (0, 0) } else { - (self.rest.total.bytes() / self.rest.unit.size.bytes(), - self.rest.total.bytes() % self.rest.unit.size.bytes()) + ( + self.rest.total.bytes() / self.rest.unit.size.bytes(), + self.rest.total.bytes() % self.rest.unit.size.bytes(), + ) }; if self.prefix.iter().all(|x| x.is_none()) { @@ -146,9 +144,12 @@ impl LlvmType for CastTarget { } // Create list of fields in the main structure - let mut args: Vec<_> = - self.prefix.iter().flat_map(|option_kind| option_kind.map( - |kind| Reg { kind: kind, size: self.prefix_chunk }.llvm_type(cx))) + let mut args: Vec<_> = self + .prefix + .iter() + .flat_map(|option_kind| { + option_kind.map(|kind| Reg { kind: kind, size: self.prefix_chunk }.llvm_type(cx)) + }) .chain((0..rest_count).map(|_| rest_ll_unit)) .collect(); @@ -242,7 +243,7 @@ impl ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { llscratch, scratch_align, bx.const_usize(self.layout.size.bytes()), - MemFlags::empty() + MemFlags::empty(), ); bx.lifetime_end(llscratch, scratch_size); @@ -283,7 +284,8 @@ impl ArgAbiMethods<'tcx> for Builder<'a, 'll, 'tcx> { fn store_fn_arg( &mut self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, - idx: &mut usize, dst: PlaceRef<'tcx, Self::Value> + idx: &mut usize, + dst: PlaceRef<'tcx, Self::Value>, ) { arg_abi.store_fn_arg(self, idx, dst) } @@ -291,7 +293,7 @@ impl ArgAbiMethods<'tcx> for Builder<'a, 'll, 'tcx> { &mut self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, val: &'ll Value, - dst: PlaceRef<'tcx, &'ll Value> + dst: PlaceRef<'tcx, &'ll Value>, ) { arg_abi.store(self, val, dst) } @@ -315,14 +317,12 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> { if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 } ).sum(); let mut llargument_tys = Vec::with_capacity( - if let PassMode::Indirect(..) = self.ret.mode { 1 } else { 0 } + args_capacity + if let PassMode::Indirect(..) = self.ret.mode { 1 } else { 0 } + args_capacity, ); let llreturn_ty = match self.ret.mode { PassMode::Ignore => cx.type_void(), - PassMode::Direct(_) | PassMode::Pair(..) => { - self.ret.layout.immediate_llvm_type(cx) - } + PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_llvm_type(cx), PassMode::Cast(cast) => cast.llvm_type(cx), PassMode::Indirect(..) => { llargument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx))); @@ -366,8 +366,10 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> { fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type { unsafe { - llvm::LLVMPointerType(self.llvm_type(cx), - cx.data_layout().instruction_address_space as c_uint) + llvm::LLVMPointerType( + self.llvm_type(cx), + cx.data_layout().instruction_address_space as c_uint, + ) } } @@ -412,8 +414,9 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> { } match arg.mode { PassMode::Ignore => {} - PassMode::Direct(ref attrs) | - PassMode::Indirect(ref attrs, None) => apply(attrs, Some(arg.layout.llvm_type(cx))), + PassMode::Direct(ref attrs) | PassMode::Indirect(ref attrs, None) => { + apply(attrs, Some(arg.layout.llvm_type(cx))) + } PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => { apply(attrs, None); apply(extra_attrs, None); @@ -459,8 +462,9 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> { } match arg.mode { PassMode::Ignore => {} - PassMode::Direct(ref attrs) | - PassMode::Indirect(ref attrs, None) => apply(attrs, Some(arg.layout.llvm_type(bx))), + PassMode::Direct(ref attrs) | PassMode::Indirect(ref attrs, None) => { + apply(attrs, Some(arg.layout.llvm_type(bx))) + } PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => { apply(attrs, None); apply(extra_attrs, None); @@ -481,11 +485,7 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> { } impl AbiBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { - fn apply_attrs_callsite( - &mut self, - fn_abi: &FnAbi<'tcx, Ty<'tcx>>, - callsite: Self::Value - ) { + fn apply_attrs_callsite(&mut self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, callsite: Self::Value) { fn_abi.apply_attrs_callsite(self, callsite) } diff --git a/src/librustc_codegen_llvm/allocator.rs b/src/librustc_codegen_llvm/allocator.rs index e1d56b9be7a27..6dcf49f23fe9b 100644 --- a/src/librustc_codegen_llvm/allocator.rs +++ b/src/librustc_codegen_llvm/allocator.rs @@ -2,12 +2,12 @@ use std::ffi::CString; use crate::attributes; use libc::c_uint; +use rustc::bug; use rustc::ty::TyCtxt; use syntax::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS}; -use rustc::bug; -use crate::ModuleLlvm; use crate::llvm::{self, False, True}; +use crate::ModuleLlvm; pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut ModuleLlvm, kind: AllocatorKind) { let llcx = &*mods.llcx; @@ -33,26 +33,25 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut ModuleLlvm, kind: Alloc AllocatorTy::Ptr => args.push(i8p), AllocatorTy::Usize => args.push(usize), - AllocatorTy::ResultPtr | - AllocatorTy::Unit => panic!("invalid allocator arg"), + AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), } } let output = match method.output { AllocatorTy::ResultPtr => Some(i8p), AllocatorTy::Unit => None, - AllocatorTy::Layout | - AllocatorTy::Usize | - AllocatorTy::Ptr => panic!("invalid allocator output"), + AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { + panic!("invalid allocator output") + } }; - let ty = llvm::LLVMFunctionType(output.unwrap_or(void), - args.as_ptr(), - args.len() as c_uint, - False); + let ty = llvm::LLVMFunctionType( + output.unwrap_or(void), + args.as_ptr(), + args.len() as c_uint, + False, + ); let name = CString::new(format!("__rust_{}", method.name)).unwrap(); - let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, - name.as_ptr(), - ty); + let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr(), ty); if tcx.sess.target.target.options.default_hidden_visibility { llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); @@ -62,26 +61,26 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut ModuleLlvm, kind: Alloc } let callee = CString::new(kind.fn_name(method.name)).unwrap(); - let callee = llvm::LLVMRustGetOrInsertFunction(llmod, - callee.as_ptr(), - ty); + let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr(), ty); llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden); - let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, - llfn, - "entry\0".as_ptr().cast()); + let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast()); let llbuilder = llvm::LLVMCreateBuilderInContext(llcx); llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb); - let args = args.iter().enumerate().map(|(i, _)| { - llvm::LLVMGetParam(llfn, i as c_uint) - }).collect::>(); - let ret = llvm::LLVMRustBuildCall(llbuilder, - callee, - args.as_ptr(), - args.len() as c_uint, - None, - "\0".as_ptr().cast()); + let args = args + .iter() + .enumerate() + .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint)) + .collect::>(); + let ret = llvm::LLVMRustBuildCall( + llbuilder, + callee, + args.as_ptr(), + args.len() as c_uint, + None, + "\0".as_ptr().cast(), + ); llvm::LLVMSetTailCall(ret, True); if output.is_some() { llvm::LLVMBuildRet(llbuilder, ret); diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs index fa43e0829190b..9458d4a2697ed 100644 --- a/src/librustc_codegen_llvm/asm.rs +++ b/src/librustc_codegen_llvm/asm.rs @@ -1,18 +1,18 @@ -use crate::llvm; +use crate::builder::Builder; use crate::context::CodegenCx; +use crate::llvm; use crate::type_of::LayoutLlvmExt; -use crate::builder::Builder; use crate::value::Value; use rustc::hir; -use rustc_codegen_ssa::traits::*; -use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::mir::operand::OperandValue; +use rustc_codegen_ssa::mir::place::PlaceRef; +use rustc_codegen_ssa::traits::*; use syntax_pos::Span; -use std::ffi::{CStr, CString}; -use libc::{c_uint, c_char}; +use libc::{c_char, c_uint}; use log::debug; +use std::ffi::{CStr, CString}; impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { fn codegen_inline_asm( @@ -43,24 +43,26 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { inputs = indirect_outputs; } - let clobbers = ia.clobbers.iter() - .map(|s| format!("~{{{}}}", &s)); + let clobbers = ia.clobbers.iter().map(|s| format!("~{{{}}}", &s)); // Default per-arch clobbers // Basically what clang does let arch_clobbers = match &self.sess().target.target.arch[..] { - "x86" | "x86_64" => vec!["~{dirflag}", "~{fpsr}", "~{flags}"], + "x86" | "x86_64" => vec!["~{dirflag}", "~{fpsr}", "~{flags}"], "mips" | "mips64" => vec!["~{$1}"], - _ => Vec::new() + _ => Vec::new(), }; - let all_constraints = - ia.outputs.iter().map(|out| out.constraint.to_string()) - .chain(ia.inputs.iter().map(|s| s.to_string())) - .chain(ext_constraints) - .chain(clobbers) - .chain(arch_clobbers.iter().map(|s| s.to_string())) - .collect::>().join(","); + let all_constraints = ia + .outputs + .iter() + .map(|out| out.constraint.to_string()) + .chain(ia.inputs.iter().map(|s| s.to_string())) + .chain(ext_constraints) + .chain(clobbers) + .chain(arch_clobbers.iter().map(|s| s.to_string())) + .collect::>() + .join(","); debug!("Asm Constraints: {}", &all_constraints); @@ -69,7 +71,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { let output_type = match num_outputs { 0 => self.type_void(), 1 => output_types[0], - _ => self.type_struct(&output_types, false) + _ => self.type_struct(&output_types, false), }; let asm = CString::new(ia.asm.as_str().as_bytes()).unwrap(); @@ -82,7 +84,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { output_type, ia.volatile, ia.alignstack, - ia.dialect + ia.dialect, ); if r.is_none() { return false; @@ -100,13 +102,15 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { // back to source locations. See #17552. unsafe { let key = "srcloc"; - let kind = llvm::LLVMGetMDKindIDInContext(self.llcx, - key.as_ptr() as *const c_char, key.len() as c_uint); + let kind = llvm::LLVMGetMDKindIDInContext( + self.llcx, + key.as_ptr() as *const c_char, + key.len() as c_uint, + ); let val: &'ll Value = self.const_i32(span.ctxt().outer_expn().as_u32() as i32); - llvm::LLVMSetMetadata(r, kind, - llvm::LLVMMDNodeInContext(self.llcx, &val, 1)); + llvm::LLVMSetMetadata(r, kind, llvm::LLVMMDNodeInContext(self.llcx, &val, 1)); } true @@ -132,15 +136,16 @@ fn inline_asm_call( alignstack: bool, dia: ::syntax::ast::AsmDialect, ) -> Option<&'ll Value> { - let volatile = if volatile { llvm::True } - else { llvm::False }; - let alignstack = if alignstack { llvm::True } - else { llvm::False }; - - let argtys = inputs.iter().map(|v| { - debug!("Asm Input Type: {:?}", *v); - bx.cx.val_ty(*v) - }).collect::>(); + let volatile = if volatile { llvm::True } else { llvm::False }; + let alignstack = if alignstack { llvm::True } else { llvm::False }; + + let argtys = inputs + .iter() + .map(|v| { + debug!("Asm Input Type: {:?}", *v); + bx.cx.val_ty(*v) + }) + .collect::>(); debug!("Asm Output Type: {:?}", output); let fty = bx.cx.type_func(&argtys[..], output); diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 3f2a51b45bd06..816f5baddcbee 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -2,24 +2,24 @@ use std::ffi::CString; -use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::CodegenFnAttrFlags; +use rustc::session::config::{OptLevel, Sanitizer}; use rustc::session::Session; -use rustc::session::config::{Sanitizer, OptLevel}; -use rustc::ty::{self, TyCtxt, Ty}; use rustc::ty::layout::HasTyCtxt; use rustc::ty::query::Providers; -use rustc_data_structures::small_c_str::SmallCStr; +use rustc::ty::{self, Ty, TyCtxt}; +use rustc_codegen_ssa::traits::*; +use rustc_data_structures::const_cstr; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::small_c_str::SmallCStr; use rustc_target::abi::call::Conv; -use rustc_data_structures::const_cstr; use rustc_target::spec::PanicStrategy; -use rustc_codegen_ssa::traits::*; use crate::abi::FnAbi; use crate::attributes; -use crate::llvm::{self, Attribute}; use crate::llvm::AttributePlace::Function; +use crate::llvm::{self, Attribute}; use crate::llvm_util; pub use syntax::attr::{self, InlineAttr, OptimizeAttr}; @@ -31,18 +31,18 @@ use crate::value::Value; fn inline(cx: &CodegenCx<'ll, '_>, val: &'ll Value, inline: InlineAttr) { use self::InlineAttr::*; match inline { - Hint => Attribute::InlineHint.apply_llfn(Function, val), + Hint => Attribute::InlineHint.apply_llfn(Function, val), Always => Attribute::AlwaysInline.apply_llfn(Function, val), - Never => { + Never => { if cx.tcx().sess.target.target.arch != "amdgpu" { Attribute::NoInline.apply_llfn(Function, val); } - }, - None => { + } + None => { Attribute::InlineHint.unapply_llfn(Function, val); Attribute::AlwaysInline.unapply_llfn(Function, val); Attribute::NoInline.unapply_llfn(Function, val); - }, + } }; } @@ -67,8 +67,11 @@ fn naked(val: &'ll Value, is_naked: bool) { pub fn set_frame_pointer_elimination(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { if cx.sess().must_not_eliminate_frame_pointers() { llvm::AddFunctionAttrStringValue( - llfn, llvm::AttributePlace::Function, - const_cstr!("no-frame-pointer-elim"), const_cstr!("true")); + llfn, + llvm::AttributePlace::Function, + const_cstr!("no-frame-pointer-elim"), + const_cstr!("true"), + ); } } @@ -81,12 +84,16 @@ fn set_instrument_function(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { // The function name varies on platforms. // See test/CodeGen/mcount.c in clang. - let mcount_name = CString::new( - cx.sess().target.target.options.target_mcount.as_str().as_bytes()).unwrap(); + let mcount_name = + CString::new(cx.sess().target.target.options.target_mcount.as_str().as_bytes()) + .unwrap(); llvm::AddFunctionAttrStringValue( - llfn, llvm::AttributePlace::Function, - const_cstr!("instrument-function-entry-inlined"), &mcount_name); + llfn, + llvm::AttributePlace::Function, + const_cstr!("instrument-function-entry-inlined"), + &mcount_name, + ); } } @@ -94,16 +101,15 @@ fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { // Only use stack probes if the target specification indicates that we // should be using stack probes if !cx.sess().target.target.options.stack_probes { - return + return; } // Currently stack probes seem somewhat incompatible with the address // sanitizer and thread sanitizer. With asan we're already protected from // stack overflow anyway so we don't really need stack probes regardless. match cx.sess().opts.debugging_opts.sanitizer { - Some(Sanitizer::Address) | - Some(Sanitizer::Thread) => return, - _ => {}, + Some(Sanitizer::Address) | Some(Sanitizer::Thread) => return, + _ => {} } // probestack doesn't play nice either with `-C profile-generate`. @@ -119,17 +125,16 @@ fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { // Flag our internal `__rust_probestack` function as the stack probe symbol. // This is defined in the `compiler-builtins` crate for each architecture. llvm::AddFunctionAttrStringValue( - llfn, llvm::AttributePlace::Function, - const_cstr!("probe-stack"), const_cstr!("__rust_probestack")); + llfn, + llvm::AttributePlace::Function, + const_cstr!("probe-stack"), + const_cstr!("__rust_probestack"), + ); } fn translate_obsolete_target_features(feature: &str) -> &str { - const LLVM9_FEATURE_CHANGES: &[(&str, &str)] = &[ - ("+fp-only-sp", "-fp64"), - ("-fp-only-sp", "+fp64"), - ("+d16", "-d32"), - ("-d16", "+d32"), - ]; + const LLVM9_FEATURE_CHANGES: &[(&str, &str)] = + &[("+fp-only-sp", "-fp64"), ("-fp-only-sp", "+fp64"), ("+d16", "-d32"), ("-d16", "+d32")]; if llvm_util::get_major_version() >= 9 { for &(old, new) in LLVM9_FEATURE_CHANGES { if feature == old { @@ -147,13 +152,19 @@ fn translate_obsolete_target_features(feature: &str) -> &str { } pub fn llvm_target_features(sess: &Session) -> impl Iterator { - const RUSTC_SPECIFIC_FEATURES: &[&str] = &[ - "crt-static", - ]; + const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"]; - let cmdline = sess.opts.cg.target_feature.split(',') + let cmdline = sess + .opts + .cg + .target_feature + .split(',') .filter(|f| !RUSTC_SPECIFIC_FEATURES.iter().any(|s| f.contains(s))); - sess.target.target.options.features.split(',') + sess.target + .target + .options + .features + .split(',') .chain(cmdline) .filter(|l| !l.is_empty()) .map(translate_obsolete_target_features) @@ -162,10 +173,11 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator { pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { let target_cpu = SmallCStr::new(llvm_util::target_cpu(cx.tcx.sess)); llvm::AddFunctionAttrStringValue( - llfn, - llvm::AttributePlace::Function, - const_cstr!("target-cpu"), - target_cpu.as_c_str()); + llfn, + llvm::AttributePlace::Function, + const_cstr!("target-cpu"), + target_cpu.as_c_str(), + ); } /// Sets the `NonLazyBind` LLVM attribute on a given function, @@ -183,7 +195,7 @@ pub(crate) fn default_optimisation_attrs(sess: &Session, llfn: &'ll Value) { llvm::Attribute::MinSize.unapply_llfn(Function, llfn); llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn); - }, + } OptLevel::SizeMin => { llvm::Attribute::MinSize.apply_llfn(Function, llfn); llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); @@ -198,7 +210,6 @@ pub(crate) fn default_optimisation_attrs(sess: &Session, llfn: &'ll Value) { } } - /// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`) /// attributes. pub fn from_fn_attrs( @@ -248,8 +259,7 @@ pub fn from_fn_attrs( // // You can also find more info on why Windows is whitelisted here in: // https://bugzilla.mozilla.org/show_bug.cgi?id=1302078 - if !cx.sess().no_landing_pads() || - cx.sess().target.target.options.requires_uwtable { + if !cx.sess().no_landing_pads() || cx.sess().target.target.options.requires_uwtable { attributes::emit_uwtable(llfn, true); } @@ -267,46 +277,48 @@ pub fn from_fn_attrs( naked(llfn, true); } if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) { - Attribute::NoAlias.apply_llfn( - llvm::AttributePlace::ReturnValue, llfn); + Attribute::NoAlias.apply_llfn(llvm::AttributePlace::ReturnValue, llfn); } - unwind(llfn, if cx.tcx.sess.panic_strategy() != PanicStrategy::Unwind { - // In panic=abort mode we assume nothing can unwind anywhere, so - // optimize based on this! - false - } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) { - // If a specific #[unwind] attribute is present, use that. - true - } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) { - // Special attribute for allocator functions, which can't unwind. - false - } else { - if fn_abi.conv == Conv::Rust { - // Any Rust method (or `extern "Rust" fn` or `extern - // "rust-call" fn`) is explicitly allowed to unwind - // (unless it has no-unwind attribute, handled above). + unwind( + llfn, + if cx.tcx.sess.panic_strategy() != PanicStrategy::Unwind { + // In panic=abort mode we assume nothing can unwind anywhere, so + // optimize based on this! + false + } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) { + // If a specific #[unwind] attribute is present, use that. true - } else { - // Anything else is either: - // - // 1. A foreign item using a non-Rust ABI (like `extern "C" { fn foo(); }`), or - // - // 2. A Rust item using a non-Rust ABI (like `extern "C" fn foo() { ... }`). - // - // Foreign items (case 1) are assumed to not unwind; it is - // UB otherwise. (At least for now; see also - // rust-lang/rust#63909 and Rust RFC 2753.) - // - // Items defined in Rust with non-Rust ABIs (case 2) are also - // not supposed to unwind. Whether this should be enforced - // (versus stating it is UB) and *how* it would be enforced - // is currently under discussion; see rust-lang/rust#58794. - // - // In either case, we mark item as explicitly nounwind. + } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) { + // Special attribute for allocator functions, which can't unwind. false - } - }); + } else { + if fn_abi.conv == Conv::Rust { + // Any Rust method (or `extern "Rust" fn` or `extern + // "rust-call" fn`) is explicitly allowed to unwind + // (unless it has no-unwind attribute, handled above). + true + } else { + // Anything else is either: + // + // 1. A foreign item using a non-Rust ABI (like `extern "C" { fn foo(); }`), or + // + // 2. A Rust item using a non-Rust ABI (like `extern "C" fn foo() { ... }`). + // + // Foreign items (case 1) are assumed to not unwind; it is + // UB otherwise. (At least for now; see also + // rust-lang/rust#63909 and Rust RFC 2753.) + // + // Items defined in Rust with non-Rust ABIs (case 2) are also + // not supposed to unwind. Whether this should be enforced + // (versus stating it is UB) and *how* it would be enforced + // is currently under discussion; see rust-lang/rust#58794. + // + // In either case, we mark item as explicitly nounwind. + false + } + }, + ); // Always annotate functions with the target-cpu they are compiled for. // Without this, ThinLTO won't inline Rust functions into Clang generated @@ -315,22 +327,21 @@ pub fn from_fn_attrs( let features = llvm_target_features(cx.tcx.sess) .map(|s| s.to_string()) - .chain( - codegen_fn_attrs.target_features - .iter() - .map(|f| { - let feature = &f.as_str(); - format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature)) - }) - ) + .chain(codegen_fn_attrs.target_features.iter().map(|f| { + let feature = &f.as_str(); + format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature)) + })) .collect::>() .join(","); if !features.is_empty() { let val = CString::new(features).unwrap(); llvm::AddFunctionAttrStringValue( - llfn, llvm::AttributePlace::Function, - const_cstr!("target-features"), &val); + llfn, + llvm::AttributePlace::Function, + const_cstr!("target-features"), + &val, + ); } // Note that currently the `wasm-import-module` doesn't do anything, but @@ -345,9 +356,8 @@ pub fn from_fn_attrs( &module, ); - let name = codegen_fn_attrs.link_name.unwrap_or_else(|| { - cx.tcx.item_name(instance.def_id()) - }); + let name = + codegen_fn_attrs.link_name.unwrap_or_else(|| cx.tcx.item_name(instance.def_id())); let name = CString::new(&name.as_str()[..]).unwrap(); llvm::AddFunctionAttrStringValue( llfn, @@ -365,14 +375,15 @@ pub fn provide(providers: &mut Providers<'_>) { if tcx.sess.opts.actually_rustdoc { // rustdoc needs to be able to document functions that use all the features, so // whitelist them all - tcx.arena.alloc(llvm_util::all_known_features() - .map(|(a, b)| (a.to_string(), b)) - .collect()) + tcx.arena + .alloc(llvm_util::all_known_features().map(|(a, b)| (a.to_string(), b)).collect()) } else { - tcx.arena.alloc(llvm_util::target_feature_whitelist(tcx.sess) - .iter() - .map(|&(a, b)| (a.to_string(), b)) - .collect()) + tcx.arena.alloc( + llvm_util::target_feature_whitelist(tcx.sess) + .iter() + .map(|&(a, b)| (a.to_string(), b)) + .collect(), + ) } }; @@ -386,15 +397,14 @@ pub fn provide_extern(providers: &mut Providers<'_>) { // `#[link(wasm_import_module = "...")]` for example. let native_libs = tcx.native_libraries(cnum); - let def_id_to_native_lib = native_libs.iter().filter_map(|lib| - lib.foreign_module.map(|id| (id, lib)) - ).collect::>(); + let def_id_to_native_lib = native_libs + .iter() + .filter_map(|lib| lib.foreign_module.map(|id| (id, lib))) + .collect::>(); let mut ret = FxHashMap::default(); for lib in tcx.foreign_modules(cnum).iter() { - let module = def_id_to_native_lib - .get(&lib.def_id) - .and_then(|s| s.wasm_import_module); + let module = def_id_to_native_lib.get(&lib.def_id).and_then(|s| s.wasm_import_module); let module = match module { Some(s) => s, None => continue, @@ -410,7 +420,5 @@ pub fn provide_extern(providers: &mut Providers<'_>) { } fn wasm_import_module(tcx: TyCtxt<'_>, id: DefId) -> Option { - tcx.wasm_import_module_map(id.krate) - .get(&id) - .map(|s| CString::new(&s[..]).unwrap()) + tcx.wasm_import_module_map(id.krate).get(&id).map(|s| CString::new(&s[..]).unwrap()) } diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs index e169cfc4cc829..d4652070c7c6e 100644 --- a/src/librustc_codegen_llvm/back/archive.rs +++ b/src/librustc_codegen_llvm/back/archive.rs @@ -1,6 +1,6 @@ //! A helper class for dealing with static archives -use std::ffi::{CString, CStr}; +use std::ffi::{CStr, CString}; use std::io; use std::mem; use std::path::{Path, PathBuf}; @@ -9,11 +9,9 @@ use std::str; use crate::llvm::archive_ro::{ArchiveRO, Child}; use crate::llvm::{self, ArchiveKind}; -use rustc_codegen_ssa::{ - METADATA_FILENAME, RLIB_BYTECODE_EXTENSION, looks_like_rust_object_file -}; -use rustc_codegen_ssa::back::archive::{ArchiveBuilder, find_library}; use rustc::session::Session; +use rustc_codegen_ssa::back::archive::{find_library, ArchiveBuilder}; +use rustc_codegen_ssa::{looks_like_rust_object_file, METADATA_FILENAME, RLIB_BYTECODE_EXTENSION}; use syntax::symbol::Symbol; struct ArchiveConfig<'a> { @@ -34,15 +32,8 @@ pub struct LlvmArchiveBuilder<'a> { } enum Addition { - File { - path: PathBuf, - name_in_archive: String, - }, - Archive { - path: PathBuf, - archive: ArchiveRO, - skip: Box bool>, - }, + File { path: PathBuf, name_in_archive: String }, + Archive { path: PathBuf, archive: ArchiveRO, skip: Box bool> }, } impl Addition { @@ -60,9 +51,7 @@ fn is_relevant_child(c: &Child<'_>) -> bool { } } -fn archive_config<'a>(sess: &'a Session, - output: &Path, - input: Option<&Path>) -> ArchiveConfig<'a> { +fn archive_config<'a>(sess: &'a Session, output: &Path, input: Option<&Path>) -> ArchiveConfig<'a> { use rustc_codegen_ssa::back::link::archive_search_paths; ArchiveConfig { sess, @@ -75,9 +64,7 @@ fn archive_config<'a>(sess: &'a Session, impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { /// Creates a new static archive, ready for modifying the archive specified /// by `config`. - fn new(sess: &'a Session, - output: &Path, - input: Option<&Path>) -> LlvmArchiveBuilder<'a> { + fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> LlvmArchiveBuilder<'a> { let config = archive_config(sess, output, input); LlvmArchiveBuilder { config, @@ -96,28 +83,31 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { /// Lists all files in an archive fn src_files(&mut self) -> Vec { if self.src_archive().is_none() { - return Vec::new() + return Vec::new(); } let archive = self.src_archive.as_ref().unwrap().as_ref().unwrap(); - archive.iter() - .filter_map(|child| child.ok()) - .filter(is_relevant_child) - .filter_map(|child| child.name()) - .filter(|name| !self.removals.iter().any(|x| x == name)) - .map(|name| name.to_owned()) - .collect() + archive + .iter() + .filter_map(|child| child.ok()) + .filter(is_relevant_child) + .filter_map(|child| child.name()) + .filter(|name| !self.removals.iter().any(|x| x == name)) + .map(|name| name.to_owned()) + .collect() } /// Adds all of the contents of a native library to this archive. This will /// search in the relevant locations for a library named `name`. fn add_native_library(&mut self, name: Symbol) { - let location = find_library(name, &self.config.lib_search_paths, - self.config.sess); + let location = find_library(name, &self.config.lib_search_paths, self.config.sess); self.add_archive(&location, |_| false).unwrap_or_else(|e| { - self.config.sess.fatal(&format!("failed to add native library {}: {}", - location.to_string_lossy(), e)); + self.config.sess.fatal(&format!( + "failed to add native library {}: {}", + location.to_string_lossy(), + e + )); }); } @@ -126,11 +116,13 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { /// /// This ignores adding the bytecode from the rlib, and if LTO is enabled /// then the object file also isn't added. - fn add_rlib(&mut self, - rlib: &Path, - name: &str, - lto: bool, - skip_objects: bool) -> io::Result<()> { + fn add_rlib( + &mut self, + rlib: &Path, + name: &str, + lto: bool, + skip_objects: bool, + ) -> io::Result<()> { // Ignoring obj file starting with the crate name // as simple comparison is not enough - there // might be also an extra name suffix @@ -139,32 +131,30 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { self.add_archive(rlib, move |fname: &str| { // Ignore bytecode/metadata files, no matter the name. if fname.ends_with(RLIB_BYTECODE_EXTENSION) || fname == METADATA_FILENAME { - return true + return true; } // Don't include Rust objects if LTO is enabled if lto && looks_like_rust_object_file(fname) { - return true + return true; } // Otherwise if this is *not* a rust object and we're skipping // objects then skip this file if skip_objects && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) { - return true + return true; } // ok, don't skip this - return false + return false; }) } /// Adds an arbitrary file to this archive fn add_file(&mut self, file: &Path) { let name = file.file_name().unwrap().to_str().unwrap(); - self.additions.push(Addition::File { - path: file.to_path_buf(), - name_in_archive: name.to_owned(), - }); + self.additions + .push(Addition::File { path: file.to_path_buf(), name_in_archive: name.to_owned() }); } /// Indicate that the next call to `build` should update all symbols in @@ -176,36 +166,36 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { /// Combine the provided files, rlibs, and native libraries into a single /// `Archive`. fn build(mut self) { - let kind = self.llvm_archive_kind().unwrap_or_else(|kind| - self.config.sess.fatal(&format!("Don't know how to build archive of type: {}", kind))); + let kind = self.llvm_archive_kind().unwrap_or_else(|kind| { + self.config.sess.fatal(&format!("Don't know how to build archive of type: {}", kind)) + }); if let Err(e) = self.build_with_llvm(kind) { self.config.sess.fatal(&format!("failed to build archive: {}", e)); } - } } impl<'a> LlvmArchiveBuilder<'a> { fn src_archive(&mut self) -> Option<&ArchiveRO> { if let Some(ref a) = self.src_archive { - return a.as_ref() + return a.as_ref(); } let src = self.config.src.as_ref()?; self.src_archive = Some(ArchiveRO::open(src).ok()); self.src_archive.as_ref().unwrap().as_ref() } - fn add_archive(&mut self, archive: &Path, skip: F) - -> io::Result<()> - where F: FnMut(&str) -> bool + 'static + fn add_archive(&mut self, archive: &Path, skip: F) -> io::Result<()> + where + F: FnMut(&str) -> bool + 'static, { let archive_ro = match ArchiveRO::open(archive) { Ok(ar) => ar, Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)), }; if self.additions.iter().any(|ar| ar.path() == archive) { - return Ok(()) + return Ok(()); } self.additions.push(Addition::Archive { path: archive.to_path_buf(), @@ -238,13 +228,15 @@ impl<'a> LlvmArchiveBuilder<'a> { None => continue, }; if removals.iter().any(|r| r == child_name) { - continue + continue; } let name = CString::new(child_name)?; - members.push(llvm::LLVMRustArchiveMemberNew(ptr::null(), - name.as_ptr(), - Some(child.raw))); + members.push(llvm::LLVMRustArchiveMemberNew( + ptr::null(), + name.as_ptr(), + Some(child.raw), + )); strings.push(name); } } @@ -253,9 +245,11 @@ impl<'a> LlvmArchiveBuilder<'a> { Addition::File { path, name_in_archive } => { let path = CString::new(path.to_str().unwrap())?; let name = CString::new(name_in_archive.clone())?; - members.push(llvm::LLVMRustArchiveMemberNew(path.as_ptr(), - name.as_ptr(), - None)); + members.push(llvm::LLVMRustArchiveMemberNew( + path.as_ptr(), + name.as_ptr(), + None, + )); strings.push(path); strings.push(name); } @@ -263,11 +257,11 @@ impl<'a> LlvmArchiveBuilder<'a> { for child in archive.iter() { let child = child.map_err(string_to_io_error)?; if !is_relevant_child(&child) { - continue + continue; } let child_name = child.name().unwrap(); if skip(child_name) { - continue + continue; } // It appears that LLVM's archive writer is a little @@ -276,13 +270,14 @@ impl<'a> LlvmArchiveBuilder<'a> { // pass it in. // // See LLVM bug 25877 for more info. - let child_name = Path::new(child_name) - .file_name().unwrap() - .to_str().unwrap(); + let child_name = + Path::new(child_name).file_name().unwrap().to_str().unwrap(); let name = CString::new(child_name)?; - let m = llvm::LLVMRustArchiveMemberNew(ptr::null(), - name.as_ptr(), - Some(child.raw)); + let m = llvm::LLVMRustArchiveMemberNew( + ptr::null(), + name.as_ptr(), + Some(child.raw), + ); members.push(m); strings.push(name); } @@ -290,11 +285,13 @@ impl<'a> LlvmArchiveBuilder<'a> { } } - let r = llvm::LLVMRustWriteArchive(dst.as_ptr(), - members.len() as libc::size_t, - members.as_ptr() as *const &_, - should_update_symbols, - kind); + let r = llvm::LLVMRustWriteArchive( + dst.as_ptr(), + members.len() as libc::size_t, + members.as_ptr() as *const &_, + should_update_symbols, + kind, + ); let ret = if r.into_result().is_err() { let err = llvm::LLVMRustGetLastError(); let msg = if err.is_null() { diff --git a/src/librustc_codegen_llvm/back/bytecode.rs b/src/librustc_codegen_llvm/back/bytecode.rs index 397cdecbb6f77..db29556e70ccc 100644 --- a/src/librustc_codegen_llvm/back/bytecode.rs +++ b/src/librustc_codegen_llvm/back/bytecode.rs @@ -26,9 +26,9 @@ use std::io::{Read, Write}; use std::ptr; use std::str; -use flate2::Compression; use flate2::read::DeflateDecoder; use flate2::write::DeflateEncoder; +use flate2::Compression; // This is the "magic number" expected at the beginning of a LLVM bytecode // object in an rlib. @@ -49,8 +49,8 @@ pub fn encode(identifier: &str, bytecode: &[u8]) -> Vec { // Next is the LLVM module identifier length + contents let identifier_len = identifier.len(); encoded.extend_from_slice(&[ - (identifier_len >> 0) as u8, - (identifier_len >> 8) as u8, + (identifier_len >> 0) as u8, + (identifier_len >> 8) as u8, (identifier_len >> 16) as u8, (identifier_len >> 24) as u8, ]); @@ -62,15 +62,13 @@ pub fn encode(identifier: &str, bytecode: &[u8]) -> Vec { encoded.extend_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]); let before = encoded.len(); - DeflateEncoder::new(&mut encoded, Compression::fast()) - .write_all(bytecode) - .unwrap(); + DeflateEncoder::new(&mut encoded, Compression::fast()).write_all(bytecode).unwrap(); let after = encoded.len(); // Fill in the length we reserved space for before let bytecode_len = (after - before) as u64; - encoded[deflated_size_pos + 0] = (bytecode_len >> 0) as u8; - encoded[deflated_size_pos + 1] = (bytecode_len >> 8) as u8; + encoded[deflated_size_pos + 0] = (bytecode_len >> 0) as u8; + encoded[deflated_size_pos + 1] = (bytecode_len >> 8) as u8; encoded[deflated_size_pos + 2] = (bytecode_len >> 16) as u8; encoded[deflated_size_pos + 3] = (bytecode_len >> 24) as u8; encoded[deflated_size_pos + 4] = (bytecode_len >> 32) as u8; @@ -85,7 +83,7 @@ pub fn encode(identifier: &str, bytecode: &[u8]) -> Vec { encoded.push(0); } - return encoded + return encoded; } pub struct DecodedBytecode<'a> { @@ -96,50 +94,45 @@ pub struct DecodedBytecode<'a> { impl<'a> DecodedBytecode<'a> { pub fn new(data: &'a [u8]) -> Result, &'static str> { if !data.starts_with(RLIB_BYTECODE_OBJECT_MAGIC) { - return Err("magic bytecode prefix not found") + return Err("magic bytecode prefix not found"); } let data = &data[RLIB_BYTECODE_OBJECT_MAGIC.len()..]; if !data.starts_with(&[RLIB_BYTECODE_OBJECT_VERSION, 0, 0, 0]) { - return Err("wrong version prefix found in bytecode") + return Err("wrong version prefix found in bytecode"); } let data = &data[4..]; if data.len() < 4 { - return Err("bytecode corrupted") + return Err("bytecode corrupted"); } - let identifier_len = unsafe { - u32::from_le(ptr::read_unaligned(data.as_ptr() as *const u32)) as usize - }; + let identifier_len = + unsafe { u32::from_le(ptr::read_unaligned(data.as_ptr() as *const u32)) as usize }; let data = &data[4..]; if data.len() < identifier_len { - return Err("bytecode corrupted") + return Err("bytecode corrupted"); } let identifier = match str::from_utf8(&data[..identifier_len]) { Ok(s) => s, - Err(_) => return Err("bytecode corrupted") + Err(_) => return Err("bytecode corrupted"), }; let data = &data[identifier_len..]; if data.len() < 8 { - return Err("bytecode corrupted") + return Err("bytecode corrupted"); } - let bytecode_len = unsafe { - u64::from_le(ptr::read_unaligned(data.as_ptr() as *const u64)) as usize - }; + let bytecode_len = + unsafe { u64::from_le(ptr::read_unaligned(data.as_ptr() as *const u64)) as usize }; let data = &data[8..]; if data.len() < bytecode_len { - return Err("bytecode corrupted") + return Err("bytecode corrupted"); } let encoded_bytecode = &data[..bytecode_len]; - Ok(DecodedBytecode { - identifier, - encoded_bytecode, - }) + Ok(DecodedBytecode { identifier, encoded_bytecode }) } pub fn bytecode(&self) -> Vec { let mut data = Vec::new(); DeflateDecoder::new(self.encoded_bytecode).read_to_end(&mut data).unwrap(); - return data + return data; } pub fn identifier(&self) -> &'a str { diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 6481ef5c73ce0..629d303ffecf7 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -1,24 +1,25 @@ use crate::back::bytecode::DecodedBytecode; -use crate::back::write::{self, DiagnosticHandlers, with_llvm_pmb, save_temp_bitcode, - to_llvm_opt_settings}; +use crate::back::write::{ + self, save_temp_bitcode, to_llvm_opt_settings, with_llvm_pmb, DiagnosticHandlers, +}; use crate::llvm::archive_ro::ArchiveRO; -use crate::llvm::{self, True, False}; -use crate::{ModuleLlvm, LlvmCodegenBackend}; +use crate::llvm::{self, False, True}; +use crate::{LlvmCodegenBackend, ModuleLlvm}; +use log::{debug, info}; use rustc::bug; -use rustc_codegen_ssa::back::symbol_export; -use rustc_codegen_ssa::back::write::{ModuleConfig, CodegenContext, FatLTOInput}; -use rustc_codegen_ssa::back::lto::{SerializedModule, LtoModuleCodegen, ThinShared, ThinModule}; -use rustc_codegen_ssa::traits::*; -use rustc_errors::{FatalError, Handler}; use rustc::dep_graph::WorkProduct; -use rustc_session::cgu_reuse_tracker::CguReuse; use rustc::hir::def_id::LOCAL_CRATE; use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::session::config::{self, Lto}; use rustc::util::common::time_ext; -use rustc_data_structures::fx::{FxHashSet, FxHashMap}; -use rustc_codegen_ssa::{RLIB_BYTECODE_EXTENSION, ModuleCodegen, ModuleKind}; -use log::{info, debug}; +use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared}; +use rustc_codegen_ssa::back::symbol_export; +use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig}; +use rustc_codegen_ssa::traits::*; +use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, RLIB_BYTECODE_EXTENSION}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::{FatalError, Handler}; +use rustc_session::cgu_reuse_tracker::CguReuse; use std::ffi::{CStr, CString}; use std::fs::File; @@ -36,28 +37,24 @@ pub const THIN_LTO_IMPORTS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-imports.bi pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool { match crate_type { - config::CrateType::Executable | - config::CrateType::Staticlib | - config::CrateType::Cdylib => true, + config::CrateType::Executable + | config::CrateType::Staticlib + | config::CrateType::Cdylib => true, - config::CrateType::Dylib | - config::CrateType::Rlib | - config::CrateType::ProcMacro => false, + config::CrateType::Dylib | config::CrateType::Rlib | config::CrateType::ProcMacro => false, } } -fn prepare_lto(cgcx: &CodegenContext, - diag_handler: &Handler) - -> Result<(Vec, Vec<(SerializedModule, CString)>), FatalError> -{ +fn prepare_lto( + cgcx: &CodegenContext, + diag_handler: &Handler, +) -> Result<(Vec, Vec<(SerializedModule, CString)>), FatalError> { let export_threshold = match cgcx.lto { // We're just doing LTO for our one crate Lto::ThinLocal => SymbolExportLevel::Rust, // We're doing LTO for the entire crate graph - Lto::Fat | Lto::Thin => { - symbol_export::crates_export_threshold(&cgcx.crate_types) - } + Lto::Fat | Lto::Thin => symbol_export::crates_export_threshold(&cgcx.crate_types), Lto::No => panic!("didn't request LTO but we're doing LTO"), }; @@ -69,14 +66,10 @@ fn prepare_lto(cgcx: &CodegenContext, None } }; - let exported_symbols = cgcx.exported_symbols - .as_ref().expect("needs exported symbols for LTO"); + let exported_symbols = cgcx.exported_symbols.as_ref().expect("needs exported symbols for LTO"); let mut symbol_white_list = { let _timer = cgcx.prof.generic_activity("LLVM_lto_generate_symbol_white_list"); - exported_symbols[&LOCAL_CRATE] - .iter() - .filter_map(symbol_filter) - .collect::>() + exported_symbols[&LOCAL_CRATE].iter().filter_map(symbol_filter).collect::>() }; info!("{} symbols to preserve in this crate", symbol_white_list.len()); @@ -89,38 +82,41 @@ fn prepare_lto(cgcx: &CodegenContext, let mut upstream_modules = Vec::new(); if cgcx.lto != Lto::ThinLocal { if cgcx.opts.cg.prefer_dynamic { - diag_handler.struct_err("cannot prefer dynamic linking when performing LTO") - .note("only 'staticlib', 'bin', and 'cdylib' outputs are \ - supported with LTO") - .emit(); - return Err(FatalError) + diag_handler + .struct_err("cannot prefer dynamic linking when performing LTO") + .note( + "only 'staticlib', 'bin', and 'cdylib' outputs are \ + supported with LTO", + ) + .emit(); + return Err(FatalError); } // Make sure we actually can run LTO for crate_type in cgcx.crate_types.iter() { if !crate_type_allows_lto(*crate_type) { - let e = diag_handler.fatal("lto can only be run for executables, cdylibs and \ - static library outputs"); - return Err(e) + let e = diag_handler.fatal( + "lto can only be run for executables, cdylibs and \ + static library outputs", + ); + return Err(e); } } for &(cnum, ref path) in cgcx.each_linked_rlib_for_lto.iter() { - let exported_symbols = cgcx.exported_symbols - .as_ref().expect("needs exported symbols for LTO"); + let exported_symbols = + cgcx.exported_symbols.as_ref().expect("needs exported symbols for LTO"); { let _timer = cgcx.prof.generic_activity("LLVM_lto_generate_symbol_white_list"); - symbol_white_list.extend( - exported_symbols[&cnum] - .iter() - .filter_map(symbol_filter)); + symbol_white_list.extend(exported_symbols[&cnum].iter().filter_map(symbol_filter)); } let _timer = cgcx.prof.generic_activity("LLVM_lto_load_upstream_bitcode"); let archive = ArchiveRO::open(&path).expect("wanted an rlib"); - let bytecodes = archive.iter().filter_map(|child| { - child.ok().and_then(|c| c.name().map(|name| (name, c))) - }).filter(|&(name, _)| name.ends_with(RLIB_BYTECODE_EXTENSION)); + let bytecodes = archive + .iter() + .filter_map(|child| child.ok().and_then(|c| c.name().map(|name| (name, c)))) + .filter(|&(name, _)| name.ends_with(RLIB_BYTECODE_EXTENSION)); for (name, data) in bytecodes { info!("adding bytecode {}", name); let bc_encoded = data.data(); @@ -142,67 +138,51 @@ fn prepare_lto(cgcx: &CodegenContext, /// Performs fat LTO by merging all modules into a single one and returning it /// for further optimization. -pub(crate) fn run_fat(cgcx: &CodegenContext, - modules: Vec>, - cached_modules: Vec<(SerializedModule, WorkProduct)>) - -> Result, FatalError> -{ +pub(crate) fn run_fat( + cgcx: &CodegenContext, + modules: Vec>, + cached_modules: Vec<(SerializedModule, WorkProduct)>, +) -> Result, FatalError> { let diag_handler = cgcx.create_diag_handler(); let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, &diag_handler)?; - let symbol_white_list = symbol_white_list.iter() - .map(|c| c.as_ptr()) - .collect::>(); - fat_lto( - cgcx, - &diag_handler, - modules, - cached_modules, - upstream_modules, - &symbol_white_list, - ) + let symbol_white_list = symbol_white_list.iter().map(|c| c.as_ptr()).collect::>(); + fat_lto(cgcx, &diag_handler, modules, cached_modules, upstream_modules, &symbol_white_list) } /// Performs thin LTO by performing necessary global analysis and returning two /// lists, one of the modules that need optimization and another for modules that /// can simply be copied over from the incr. comp. cache. -pub(crate) fn run_thin(cgcx: &CodegenContext, - modules: Vec<(String, ThinBuffer)>, - cached_modules: Vec<(SerializedModule, WorkProduct)>) - -> Result<(Vec>, Vec), FatalError> -{ +pub(crate) fn run_thin( + cgcx: &CodegenContext, + modules: Vec<(String, ThinBuffer)>, + cached_modules: Vec<(SerializedModule, WorkProduct)>, +) -> Result<(Vec>, Vec), FatalError> { let diag_handler = cgcx.create_diag_handler(); let (symbol_white_list, upstream_modules) = prepare_lto(cgcx, &diag_handler)?; - let symbol_white_list = symbol_white_list.iter() - .map(|c| c.as_ptr()) - .collect::>(); + let symbol_white_list = symbol_white_list.iter().map(|c| c.as_ptr()).collect::>(); if cgcx.opts.cg.linker_plugin_lto.enabled() { - unreachable!("We should never reach this case if the LTO step \ - is deferred to the linker"); + unreachable!( + "We should never reach this case if the LTO step \ + is deferred to the linker" + ); } - thin_lto(cgcx, - &diag_handler, - modules, - upstream_modules, - cached_modules, - &symbol_white_list) + thin_lto(cgcx, &diag_handler, modules, upstream_modules, cached_modules, &symbol_white_list) } -pub(crate) fn prepare_thin( - module: ModuleCodegen -) -> (String, ThinBuffer) { +pub(crate) fn prepare_thin(module: ModuleCodegen) -> (String, ThinBuffer) { let name = module.name.clone(); let buffer = ThinBuffer::new(module.module_llvm.llmod()); (name, buffer) } -fn fat_lto(cgcx: &CodegenContext, - diag_handler: &Handler, - modules: Vec>, - cached_modules: Vec<(SerializedModule, WorkProduct)>, - mut serialized_modules: Vec<(SerializedModule, CString)>, - symbol_white_list: &[*const libc::c_char]) - -> Result, FatalError> -{ +fn fat_lto( + cgcx: &CodegenContext, + diag_handler: &Handler, + modules: Vec>, + cached_modules: Vec<(SerializedModule, WorkProduct)>, + mut serialized_modules: Vec<(SerializedModule, CString)>, + symbol_white_list: &[*const libc::c_char], +) -> Result, FatalError> { let _timer = cgcx.prof.generic_activity("LLVM_fat_lto_build_monolithic_module"); info!("going for a fat lto"); @@ -241,13 +221,12 @@ fn fat_lto(cgcx: &CodegenContext, // file copy operations in the backend work correctly. The only other kind // of module here should be an allocator one, and if your crate is smaller // than the allocator module then the size doesn't really matter anyway. - let costliest_module = in_memory.iter() + let costliest_module = in_memory + .iter() .enumerate() .filter(|&(_, module)| module.kind == ModuleKind::Regular) .map(|(i, module)| { - let cost = unsafe { - llvm::LLVMRustModuleCost(module.module_llvm.llmod()) - }; + let cost = unsafe { llvm::LLVMRustModuleCost(module.module_llvm.llmod()) }; (cost, i) }) .max(); @@ -320,9 +299,11 @@ fn fat_lto(cgcx: &CodegenContext, // more modules and such unsafe { let ptr = symbol_white_list.as_ptr(); - llvm::LLVMRustRunRestrictionPass(llmod, - ptr as *const *const libc::c_char, - symbol_white_list.len() as libc::size_t); + llvm::LLVMRustRunRestrictionPass( + llmod, + ptr as *const *const libc::c_char, + symbol_white_list.len() as libc::size_t, + ); save_temp_bitcode(&cgcx, &module, "lto.after-restriction"); } @@ -334,10 +315,7 @@ fn fat_lto(cgcx: &CodegenContext, } } - Ok(LtoModuleCodegen::Fat { - module: Some(module), - _serialized_bitcode: serialized_bitcode, - }) + Ok(LtoModuleCodegen::Fat { module: Some(module), _serialized_bitcode: serialized_bitcode }) } struct Linker<'a>(&'a mut llvm::Linker<'a>); @@ -349,9 +327,11 @@ impl Linker<'a> { fn add(&mut self, bytecode: &[u8]) -> Result<(), ()> { unsafe { - if llvm::LLVMRustLinkerAdd(self.0, - bytecode.as_ptr() as *const libc::c_char, - bytecode.len()) { + if llvm::LLVMRustLinkerAdd( + self.0, + bytecode.as_ptr() as *const libc::c_char, + bytecode.len(), + ) { Ok(()) } else { Err(()) @@ -362,7 +342,9 @@ impl Linker<'a> { impl Drop for Linker<'a> { fn drop(&mut self) { - unsafe { llvm::LLVMRustLinkerFree(&mut *(self.0 as *mut _)); } + unsafe { + llvm::LLVMRustLinkerFree(&mut *(self.0 as *mut _)); + } } } @@ -396,22 +378,20 @@ impl Drop for Linker<'a> { /// calculating the *index* for ThinLTO. This index will then be shared amongst /// all of the `LtoModuleCodegen` units returned below and destroyed once /// they all go out of scope. -fn thin_lto(cgcx: &CodegenContext, - diag_handler: &Handler, - modules: Vec<(String, ThinBuffer)>, - serialized_modules: Vec<(SerializedModule, CString)>, - cached_modules: Vec<(SerializedModule, WorkProduct)>, - symbol_white_list: &[*const libc::c_char]) - -> Result<(Vec>, Vec), FatalError> -{ +fn thin_lto( + cgcx: &CodegenContext, + diag_handler: &Handler, + modules: Vec<(String, ThinBuffer)>, + serialized_modules: Vec<(SerializedModule, CString)>, + cached_modules: Vec<(SerializedModule, WorkProduct)>, + symbol_white_list: &[*const libc::c_char], +) -> Result<(Vec>, Vec), FatalError> { let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_global_analysis"); unsafe { info!("going for that thin, thin LTO"); - let green_modules: FxHashMap<_, _> = cached_modules - .iter() - .map(|&(_, ref wp)| (wp.cgu_name.clone(), wp.clone())) - .collect(); + let green_modules: FxHashMap<_, _> = + cached_modules.iter().map(|&(_, ref wp)| (wp.cgu_name.clone(), wp.clone())).collect(); let full_scope_len = modules.len() + serialized_modules.len() + cached_modules.len(); let mut thin_buffers = Vec::with_capacity(modules.len()); @@ -448,9 +428,8 @@ fn thin_lto(cgcx: &CodegenContext, // we must always unconditionally look at the index). let mut serialized = Vec::with_capacity(serialized_modules.len() + cached_modules.len()); - let cached_modules = cached_modules.into_iter().map(|(sm, wp)| { - (sm, CString::new(wp.cgu_name).unwrap()) - }); + let cached_modules = + cached_modules.into_iter().map(|(sm, wp)| (sm, CString::new(wp.cgu_name).unwrap())); for (module, name) in serialized_modules.into_iter().chain(cached_modules) { info!("upstream or cached module {:?}", name); @@ -475,33 +454,28 @@ fn thin_lto(cgcx: &CodegenContext, thin_modules.len() as u32, symbol_white_list.as_ptr(), symbol_white_list.len() as u32, - ).ok_or_else(|| { - write::llvm_err(&diag_handler, "failed to prepare thin LTO context") - })?; + ) + .ok_or_else(|| write::llvm_err(&diag_handler, "failed to prepare thin LTO context"))?; info!("thin LTO data created"); let (import_map_path, prev_import_map, curr_import_map) = - if let Some(ref incr_comp_session_dir) = cgcx.incr_comp_session_dir - { - let path = incr_comp_session_dir.join(THIN_LTO_IMPORTS_INCR_COMP_FILE_NAME); - // If previous imports have been deleted, or we get an IO error - // reading the file storing them, then we'll just use `None` as the - // prev_import_map, which will force the code to be recompiled. - let prev = if path.exists() { - ThinLTOImports::load_from_file(&path).ok() + if let Some(ref incr_comp_session_dir) = cgcx.incr_comp_session_dir { + let path = incr_comp_session_dir.join(THIN_LTO_IMPORTS_INCR_COMP_FILE_NAME); + // If previous imports have been deleted, or we get an IO error + // reading the file storing them, then we'll just use `None` as the + // prev_import_map, which will force the code to be recompiled. + let prev = + if path.exists() { ThinLTOImports::load_from_file(&path).ok() } else { None }; + let curr = ThinLTOImports::from_thin_lto_data(data); + (Some(path), prev, curr) } else { - None + // If we don't compile incrementally, we don't need to load the + // import data from LLVM. + assert!(green_modules.is_empty()); + let curr = ThinLTOImports::default(); + (None, None, curr) }; - let curr = ThinLTOImports::from_thin_lto_data(data); - (Some(path), prev, curr) - } else { - // If we don't compile incrementally, we don't need to load the - // import data from LLVM. - assert!(green_modules.is_empty()); - let curr = ThinLTOImports::default(); - (None, None, curr) - }; info!("thin LTO import map loaded"); let data = ThinData(data); @@ -554,9 +528,8 @@ fn thin_lto(cgcx: &CodegenContext, copy_jobs.push(work_product); info!(" - {}: re-used", module_name); assert!(cgcx.incr_comp_session_dir.is_some()); - cgcx.cgu_reuse_tracker.set_actual_reuse(module_name, - CguReuse::PostLto); - continue + cgcx.cgu_reuse_tracker.set_actual_reuse(module_name, CguReuse::PostLto); + continue; } } @@ -585,19 +558,25 @@ fn thin_lto(cgcx: &CodegenContext, /// element order is disregarded). fn equivalent_as_sets(a: &[String], b: &[String]) -> bool { // cheap path: unequal lengths means cannot possibly be set equivalent. - if a.len() != b.len() { return false; } + if a.len() != b.len() { + return false; + } // fast path: before building new things, check if inputs are equivalent as is. - if a == b { return true; } + if a == b { + return true; + } // slow path: general set comparison. let a: FxHashSet<&str> = a.iter().map(|s| s.as_str()).collect(); let b: FxHashSet<&str> = b.iter().map(|s| s.as_str()).collect(); a == b } -pub(crate) fn run_pass_manager(cgcx: &CodegenContext, - module: &ModuleCodegen, - config: &ModuleConfig, - thin: bool) { +pub(crate) fn run_pass_manager( + cgcx: &CodegenContext, + module: &ModuleCodegen, + config: &ModuleConfig, + thin: bool, +) { // Now we have one massive module inside of llmod. Time to run the // LTO-specific optimization passes that LLVM provides. // @@ -625,7 +604,9 @@ pub(crate) fn run_pass_manager(cgcx: &CodegenContext, // Note that in general this shouldn't matter too much as you typically // only turn on ThinLTO when you're compiling with optimizations // otherwise. - let opt_level = config.opt_level.map(|x| to_llvm_opt_settings(x).0) + let opt_level = config + .opt_level + .map(|x| to_llvm_opt_settings(x).0) .unwrap_or(llvm::CodeGenOptLevel::None); let opt_level = match opt_level { llvm::CodeGenOptLevel::None => llvm::CodeGenOptLevel::Less, @@ -635,9 +616,9 @@ pub(crate) fn run_pass_manager(cgcx: &CodegenContext, if thin { llvm::LLVMRustPassManagerBuilderPopulateThinLTOPassManager(b, pm); } else { - llvm::LLVMPassManagerBuilderPopulateLTOPassManager(b, pm, - /* Internalize = */ False, - /* RunInliner = */ True); + llvm::LLVMPassManagerBuilderPopulateLTOPassManager( + b, pm, /* Internalize = */ False, /* RunInliner = */ True, + ); } }); @@ -653,8 +634,9 @@ pub(crate) fn run_pass_manager(cgcx: &CodegenContext, llvm::LLVMRustAddPass(pm, pass.unwrap()); } - time_ext(cgcx.time_passes, "LTO passes", || - llvm::LLVMRunPassManager(pm, module.module_llvm.llmod())); + time_ext(cgcx.time_passes, "LTO passes", || { + llvm::LLVMRunPassManager(pm, module.module_llvm.llmod()) + }); llvm::LLVMDisposePassManager(pm); } @@ -668,9 +650,7 @@ unsafe impl Sync for ModuleBuffer {} impl ModuleBuffer { pub fn new(m: &llvm::Module) -> ModuleBuffer { - ModuleBuffer(unsafe { - llvm::LLVMRustModuleBufferCreate(m) - }) + ModuleBuffer(unsafe { llvm::LLVMRustModuleBufferCreate(m) }) } } @@ -686,7 +666,9 @@ impl ModuleBufferMethods for ModuleBuffer { impl Drop for ModuleBuffer { fn drop(&mut self) { - unsafe { llvm::LLVMRustModuleBufferFree(&mut *(self.0 as *mut _)); } + unsafe { + llvm::LLVMRustModuleBufferFree(&mut *(self.0 as *mut _)); + } } } @@ -740,9 +722,7 @@ pub unsafe fn optimize_thin_module( cgcx: &CodegenContext, ) -> Result, FatalError> { let diag_handler = cgcx.create_diag_handler(); - let tm = (cgcx.tm_factory.0)().map_err(|e| { - write::llvm_err(&diag_handler, &e) - })?; + let tm = (cgcx.tm_factory.0)().map_err(|e| write::llvm_err(&diag_handler, &e))?; // Right now the implementation we've got only works over serialized // modules, so we create a fresh new LLVM context and parse the module @@ -757,11 +737,7 @@ pub unsafe fn optimize_thin_module( &diag_handler, )? as *const _; let module = ModuleCodegen { - module_llvm: ModuleLlvm { - llmod_raw, - llcx, - tm, - }, + module_llvm: ModuleLlvm { llmod_raw, llcx, tm }, name: thin_module.name().to_string(), kind: ModuleKind::Regular, }; @@ -778,7 +754,7 @@ pub unsafe fn optimize_thin_module( llvm::LLVMRustThinLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2); if !cu2.is_null() { let msg = "multiple source DICompileUnits found"; - return Err(write::llvm_err(&diag_handler, msg)) + return Err(write::llvm_err(&diag_handler, msg)); } // Like with "fat" LTO, get some better optimizations if landing pads @@ -801,7 +777,7 @@ pub unsafe fn optimize_thin_module( let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_rename"); if !llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod) { let msg = "failed to prepare thin LTO module"; - return Err(write::llvm_err(&diag_handler, msg)) + return Err(write::llvm_err(&diag_handler, msg)); } save_temp_bitcode(cgcx, &module, "thin-lto-after-rename"); } @@ -810,7 +786,7 @@ pub unsafe fn optimize_thin_module( let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_resolve_weak"); if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) { let msg = "failed to prepare thin LTO module"; - return Err(write::llvm_err(&diag_handler, msg)) + return Err(write::llvm_err(&diag_handler, msg)); } save_temp_bitcode(cgcx, &module, "thin-lto-after-resolve"); } @@ -819,7 +795,7 @@ pub unsafe fn optimize_thin_module( let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_internalize"); if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) { let msg = "failed to prepare thin LTO module"; - return Err(write::llvm_err(&diag_handler, msg)) + return Err(write::llvm_err(&diag_handler, msg)); } save_temp_bitcode(cgcx, &module, "thin-lto-after-internalize"); } @@ -828,7 +804,7 @@ pub unsafe fn optimize_thin_module( let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_import"); if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod) { let msg = "failed to prepare thin LTO module"; - return Err(write::llvm_err(&diag_handler, msg)) + return Err(write::llvm_err(&diag_handler, msg)); } save_temp_bitcode(cgcx, &module, "thin-lto-after-import"); } @@ -918,11 +894,8 @@ impl ThinLTOImports { for line in io::BufReader::new(file).lines() { let line = line?; if line.is_empty() { - let importing_module = current_module - .take() - .expect("Importing module not set"); - imports.insert(importing_module, - mem::replace(&mut current_imports, vec![])); + let importing_module = current_module.take().expect("Importing module not set"); + imports.insert(importing_module, mem::replace(&mut current_imports, vec![])); } else if line.starts_with(" ") { // Space marks an imported module assert_ne!(current_module, None); @@ -938,10 +911,12 @@ impl ThinLTOImports { /// Loads the ThinLTO import map from ThinLTOData. unsafe fn from_thin_lto_data(data: *const llvm::ThinLTOData) -> ThinLTOImports { - unsafe extern "C" fn imported_module_callback(payload: *mut libc::c_void, - importing_module_name: *const libc::c_char, - imported_module_name: *const libc::c_char) { - let map = &mut* (payload as *mut ThinLTOImports); + unsafe extern "C" fn imported_module_callback( + payload: *mut libc::c_void, + importing_module_name: *const libc::c_char, + imported_module_name: *const libc::c_char, + ) { + let map = &mut *(payload as *mut ThinLTOImports); let importing_module_name = CStr::from_ptr(importing_module_name); let importing_module_name = module_name_to_str(&importing_module_name); let imported_module_name = CStr::from_ptr(imported_module_name); @@ -952,21 +927,24 @@ impl ThinLTOImports { } map.imports - .get_mut(importing_module_name) - .unwrap() - .push(imported_module_name.to_owned()); + .get_mut(importing_module_name) + .unwrap() + .push(imported_module_name.to_owned()); } let mut map = ThinLTOImports::default(); - llvm::LLVMRustGetThinLTOModuleImports(data, - imported_module_callback, - &mut map as *mut _ as *mut libc::c_void); + llvm::LLVMRustGetThinLTOModuleImports( + data, + imported_module_callback, + &mut map as *mut _ as *mut libc::c_void, + ); map } } fn module_name_to_str(c_str: &CStr) -> &str { - c_str.to_str().unwrap_or_else(|e| - bug!("Encountered non-utf8 LLVM module name `{}`: {}", c_str.to_string_lossy(), e)) + c_str.to_str().unwrap_or_else(|e| { + bug!("Encountered non-utf8 LLVM module name `{}`: {}", c_str.to_string_lossy(), e) + }) } pub fn parse_module<'a>( @@ -976,14 +954,11 @@ pub fn parse_module<'a>( diag_handler: &Handler, ) -> Result<&'a llvm::Module, FatalError> { unsafe { - llvm::LLVMRustParseBitcodeForLTO( - cx, - data.as_ptr(), - data.len(), - name.as_ptr(), - ).ok_or_else(|| { - let msg = "failed to parse bitcode for LTO module"; - write::llvm_err(&diag_handler, msg) - }) + llvm::LLVMRustParseBitcodeForLTO(cx, data.as_ptr(), data.len(), name.as_ptr()).ok_or_else( + || { + let msg = "failed to parse bitcode for LTO module"; + write::llvm_err(&diag_handler, msg) + }, + ) } } diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index edd34b52eade7..4168d2b66e454 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -14,30 +14,30 @@ //! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`. use super::{LlvmCodegenBackend, ModuleLlvm}; -use rustc_codegen_ssa::{ModuleCodegen, ModuleKind}; use rustc_codegen_ssa::base::maybe_create_entry_wrapper; +use rustc_codegen_ssa::{ModuleCodegen, ModuleKind}; -use crate::llvm; -use crate::metadata; use crate::builder::Builder; use crate::common; use crate::context::CodegenCx; +use crate::llvm; +use crate::metadata; use rustc::dep_graph; -use rustc::mir::mono::{Linkage, Visibility}; -use rustc::middle::cstore::{EncodedMetadata}; -use rustc::ty::TyCtxt; +use rustc::middle::cstore::EncodedMetadata; use rustc::middle::exported_symbols; +use rustc::mir::mono::{Linkage, Visibility}; use rustc::session::config::DebugInfo; +use rustc::ty::TyCtxt; use rustc_codegen_ssa::mono_item::MonoItemExt; use rustc_data_structures::small_c_str::SmallCStr; -use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::back::write::submit_codegened_module_to_llvm; +use rustc_codegen_ssa::traits::*; +use rustc::hir::CodegenFnAttrs; use std::ffi::CString; use std::time::Instant; use syntax_pos::symbol::Symbol; -use rustc::hir::CodegenFnAttrs; use crate::value::Value; @@ -46,22 +46,22 @@ pub fn write_compressed_metadata<'tcx>( metadata: &EncodedMetadata, llvm_module: &mut ModuleLlvm, ) { - use std::io::Write; - use flate2::Compression; use flate2::write::DeflateEncoder; + use flate2::Compression; + use std::io::Write; let (metadata_llcx, metadata_llmod) = (&*llvm_module.llcx, llvm_module.llmod()); let mut compressed = tcx.metadata_encoding_version(); DeflateEncoder::new(&mut compressed, Compression::fast()) - .write_all(&metadata.raw_data).unwrap(); + .write_all(&metadata.raw_data) + .unwrap(); let llmeta = common::bytes_in_context(metadata_llcx, &compressed); let llconst = common::struct_in_context(metadata_llcx, &[llmeta], false); let name = exported_symbols::metadata_symbol_name(tcx); let buf = CString::new(name).unwrap(); - let llglobal = unsafe { - llvm::LLVMAddGlobal(metadata_llmod, common::val_ty(llconst), buf.as_ptr()) - }; + let llglobal = + unsafe { llvm::LLVMAddGlobal(metadata_llmod, common::val_ty(llconst), buf.as_ptr()) }; unsafe { llvm::LLVMSetInitializer(llglobal, llconst); let section_name = metadata::metadata_section_name(&tcx.sess.target.target); @@ -95,12 +95,7 @@ impl Iterator for ValueIter<'ll> { } pub fn iter_globals(llmod: &'ll llvm::Module) -> ValueIter<'ll> { - unsafe { - ValueIter { - cur: llvm::LLVMGetFirstGlobal(llmod), - step: llvm::LLVMGetNextGlobal, - } - } + unsafe { ValueIter { cur: llvm::LLVMGetFirstGlobal(llmod), step: llvm::LLVMGetNextGlobal } } } pub fn compile_codegen_unit( @@ -112,34 +107,24 @@ pub fn compile_codegen_unit( let start_time = Instant::now(); let dep_node = tcx.codegen_unit(cgu_name).codegen_dep_node(tcx); - let (module, _) = tcx.dep_graph.with_task( - dep_node, - tcx, - cgu_name, - module_codegen, - dep_graph::hash_result, - ); + let (module, _) = + tcx.dep_graph.with_task(dep_node, tcx, cgu_name, module_codegen, dep_graph::hash_result); let time_to_codegen = start_time.elapsed(); drop(prof_timer); // We assume that the cost to run LLVM on a CGU is proportional to // the time we needed for codegenning it. - let cost = time_to_codegen.as_secs() * 1_000_000_000 + - time_to_codegen.subsec_nanos() as u64; + let cost = time_to_codegen.as_secs() * 1_000_000_000 + time_to_codegen.subsec_nanos() as u64; submit_codegened_module_to_llvm(&LlvmCodegenBackend(()), tx_to_llvm_workers, module, cost); - fn module_codegen( - tcx: TyCtxt<'_>, - cgu_name: Symbol, - ) -> ModuleCodegen { + fn module_codegen(tcx: TyCtxt<'_>, cgu_name: Symbol) -> ModuleCodegen { let cgu = tcx.codegen_unit(cgu_name); // Instantiate monomorphizations without filling out definitions yet... let llvm_module = ModuleLlvm::new(tcx, &cgu_name.as_str()); { let cx = CodegenCx::new(tcx, cgu, &llvm_module); - let mono_items = cx.codegen_unit - .items_in_deterministic_order(cx.tcx); + let mono_items = cx.codegen_unit.items_in_deterministic_order(cx.tcx); for &(mono_item, (linkage, visibility)) in &mono_items { mono_item.predefine::>(&cx, linkage, visibility); } diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 7509584df277e..8bf238379dd5c 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -1,30 +1,30 @@ -use crate::llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope}; -use crate::llvm::{self, False, BasicBlock}; use crate::common::Funclet; use crate::context::CodegenCx; +use crate::llvm::{self, BasicBlock, False}; +use crate::llvm::{AtomicOrdering, AtomicRmwBinOp, SynchronizationScope}; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate}; -use rustc_codegen_ssa::MemFlags; -use libc::{c_uint, c_char}; -use rustc::ty::{self, Ty, TyCtxt}; -use rustc::ty::layout::{self, Align, Size, TyLayout}; +use libc::{c_char, c_uint}; +use log::debug; use rustc::hir::def_id::DefId; use rustc::session::config; -use rustc_data_structures::small_c_str::SmallCStr; -use rustc_codegen_ssa::traits::*; +use rustc::ty::layout::{self, Align, Size, TyLayout}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc_codegen_ssa::base::to_immediate; -use rustc_codegen_ssa::mir::operand::{OperandValue, OperandRef}; +use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, TypeKind}; +use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; +use rustc_codegen_ssa::traits::*; +use rustc_codegen_ssa::MemFlags; +use rustc_data_structures::const_cstr; +use rustc_data_structures::small_c_str::SmallCStr; use rustc_target::spec::{HasTargetSpec, Target}; use std::borrow::Cow; use std::ffi::CStr; +use std::iter::TrustedLen; use std::ops::{Deref, Range}; use std::ptr; -use std::iter::TrustedLen; -use rustc_data_structures::const_cstr; -use log::debug; // All Builders must have an llfn associated with them #[must_use] @@ -42,9 +42,7 @@ impl Drop for Builder<'a, 'll, 'tcx> { } // FIXME(eddyb) use a checked constructor when they become `const fn`. -const EMPTY_C_STR: &CStr = unsafe { - CStr::from_bytes_with_nul_unchecked(b"\0") -}; +const EMPTY_C_STR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"\0") }; /// Empty string, to be used where LLVM expects an instruction name, indicating /// that the instruction is to be left unnamed (i.e. numbered, in textual IR). @@ -117,19 +115,11 @@ macro_rules! builder_methods_for_value_instructions { } impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { - fn new_block<'b>( - cx: &'a CodegenCx<'ll, 'tcx>, - llfn: &'ll Value, - name: &'b str - ) -> Self { + fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &'b str) -> Self { let mut bx = Builder::with_cx(cx); let llbb = unsafe { let name = SmallCStr::new(name); - llvm::LLVMAppendBasicBlockInContext( - cx.llcx, - llfn, - name.as_ptr() - ) + llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, name.as_ptr()) }; bx.position_at_end(llbb); bx @@ -137,13 +127,8 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self { // Create a fresh builder from the crate context. - let llbuilder = unsafe { - llvm::LLVMCreateBuilderInContext(cx.llcx) - }; - Builder { - llbuilder, - cx, - } + let llbuilder = unsafe { llvm::LLVMCreateBuilderInContext(cx.llcx) }; + Builder { llbuilder, cx } } fn build_sibling_block(&self, name: &str) -> Self { @@ -151,9 +136,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } fn llbb(&self) -> &'ll BasicBlock { - unsafe { - llvm::LLVMGetInsertBlock(self.llbuilder) - } + unsafe { llvm::LLVMGetInsertBlock(self.llbuilder) } } fn position_at_end(&mut self, llbb: &'ll BasicBlock) { @@ -197,14 +180,11 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { else_llbb: &'ll BasicBlock, cases: impl ExactSizeIterator + TrustedLen, ) { - let switch = unsafe { - llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, cases.len() as c_uint) - }; + let switch = + unsafe { llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, cases.len() as c_uint) }; for (on_val, dest) in cases { let on_val = self.const_uint_big(self.val_ty(v), on_val); - unsafe { - llvm::LLVMAddCase(switch, on_val, dest) - } + unsafe { llvm::LLVMAddCase(switch, on_val, dest) } } } @@ -216,24 +196,23 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { catch: &'ll BasicBlock, funclet: Option<&Funclet<'ll>>, ) -> &'ll Value { - - debug!("invoke {:?} with args ({:?})", - llfn, - args); + debug!("invoke {:?} with args ({:?})", llfn, args); let args = self.check_call("invoke", llfn, args); let bundle = funclet.map(|funclet| funclet.bundle()); let bundle = bundle.as_ref().map(|b| &*b.raw); unsafe { - llvm::LLVMRustBuildInvoke(self.llbuilder, - llfn, - args.as_ptr(), - args.len() as c_uint, - then, - catch, - bundle, - UNNAMED) + llvm::LLVMRustBuildInvoke( + self.llbuilder, + llfn, + args.as_ptr(), + args.len() as c_uint, + then, + catch, + bundle, + UNNAMED, + ) } } @@ -322,15 +301,15 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { lhs: Self::Value, rhs: Self::Value, ) -> (Self::Value, Self::Value) { + use rustc::ty::{Int, Uint}; use syntax::ast::IntTy::*; use syntax::ast::UintTy::*; - use rustc::ty::{Int, Uint}; let new_kind = match ty.kind { Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.ptr_width)), Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.ptr_width)), ref t @ Uint(_) | ref t @ Int(_) => t.clone(), - _ => panic!("tried to get overflow intrinsic for op applied to non-int type") + _ => panic!("tried to get overflow intrinsic for op applied to non-int type"), }; let name = match oop { @@ -383,17 +362,12 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let intrinsic = self.get_intrinsic(&name); let res = self.call(intrinsic, &[lhs, rhs], None); - ( - self.extract_value(res, 0), - self.extract_value(res, 1), - ) + (self.extract_value(res, 0), self.extract_value(res, 1)) } 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()) - }); + bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) }); bx.dynamic_alloca(ty, align) } @@ -405,10 +379,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn array_alloca(&mut self, - ty: &'ll Type, - len: &'ll Value, - align: Align) -> &'ll Value { + fn array_alloca(&mut self, ty: &'ll Type, len: &'ll Value, align: Align) -> &'ll Value { unsafe { let alloca = llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, UNNAMED); llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); @@ -451,10 +422,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn load_operand( - &mut self, - place: PlaceRef<'tcx, &'ll Value> - ) -> OperandRef<'tcx, &'ll Value> { + fn load_operand(&mut self, place: PlaceRef<'tcx, &'ll Value>) -> OperandRef<'tcx, &'ll Value> { debug!("PlaceRef::load: {:?}", place); assert_eq!(place.llextra.is_some(), place.layout.is_unsized()); @@ -466,7 +434,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn scalar_load_metadata<'a, 'll, 'tcx>( bx: &mut Builder<'a, 'll, 'tcx>, load: &'ll Value, - scalar: &layout::Scalar + scalar: &layout::Scalar, ) { let vr = scalar.valid_range.clone(); match scalar.value { @@ -509,11 +477,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 - } + if scalar.is_bool() { self.trunc(load, self.type_i1()) } else { load } }; OperandValue::Pair( @@ -549,8 +513,9 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb()); let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size); - cg_elem.val.store(&mut body_bx, - PlaceRef::new_sized_aligned(current, cg_elem.layout, align)); + cg_elem + .val + .store(&mut body_bx, PlaceRef::new_sized_aligned(current, cg_elem.layout, align)); let next = body_bx.inbounds_gep(current, &[self.const_usize(1)]); body_bx.br(header_bx.llbb()); @@ -572,20 +537,24 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let llty = self.cx.val_ty(load); let v = [ self.cx.const_uint_big(llty, range.start), - self.cx.const_uint_big(llty, range.end) + self.cx.const_uint_big(llty, range.end), ]; - llvm::LLVMSetMetadata(load, llvm::MD_range as c_uint, - llvm::LLVMMDNodeInContext(self.cx.llcx, - v.as_ptr(), - v.len() as c_uint)); + llvm::LLVMSetMetadata( + load, + llvm::MD_range as c_uint, + llvm::LLVMMDNodeInContext(self.cx.llcx, v.as_ptr(), v.len() as c_uint), + ); } } fn nonnull_metadata(&mut self, load: &'ll Value) { unsafe { - llvm::LLVMSetMetadata(load, llvm::MD_nonnull as c_uint, - llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0)); + llvm::LLVMSetMetadata( + load, + llvm::MD_nonnull as c_uint, + llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0), + ); } } @@ -604,11 +573,8 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let ptr = self.check_store(val, ptr); unsafe { let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr); - let align = if flags.contains(MemFlags::UNALIGNED) { - 1 - } else { - align.bytes() as c_uint - }; + let align = + if flags.contains(MemFlags::UNALIGNED) { 1 } else { align.bytes() as c_uint }; llvm::LLVMSetAlignment(store, align); if flags.contains(MemFlags::VOLATILE) { llvm::LLVMSetVolatile(store, llvm::True); @@ -626,8 +592,13 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn atomic_store(&mut self, val: &'ll Value, ptr: &'ll Value, - order: rustc_codegen_ssa::common::AtomicOrdering, size: Size) { + fn atomic_store( + &mut self, + val: &'ll Value, + ptr: &'ll Value, + order: rustc_codegen_ssa::common::AtomicOrdering, + size: Size, + ) { debug!("Store {:?} -> {:?}", val, ptr); let ptr = self.check_store(val, ptr); unsafe { @@ -644,123 +615,106 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn gep(&mut self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value { unsafe { - llvm::LLVMBuildGEP(self.llbuilder, ptr, indices.as_ptr(), - indices.len() as c_uint, UNNAMED) + llvm::LLVMBuildGEP( + self.llbuilder, + ptr, + indices.as_ptr(), + indices.len() as c_uint, + UNNAMED, + ) } } fn inbounds_gep(&mut self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value { unsafe { llvm::LLVMBuildInBoundsGEP( - self.llbuilder, ptr, indices.as_ptr(), indices.len() as c_uint, UNNAMED) + self.llbuilder, + ptr, + indices.as_ptr(), + indices.len() as c_uint, + UNNAMED, + ) } } fn struct_gep(&mut self, ptr: &'ll Value, idx: u64) -> &'ll Value { assert_eq!(idx as c_uint as u64, idx); - unsafe { - llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, UNNAMED) - } + unsafe { llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, UNNAMED) } } /* Casts */ fn trunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, UNNAMED) - } + unsafe { llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, UNNAMED) } } fn sext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, UNNAMED) - } + unsafe { llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, UNNAMED) } } fn fptoui(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, UNNAMED) - } + unsafe { llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, UNNAMED) } } fn fptosi(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty,UNNAMED) - } + unsafe { llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty, UNNAMED) } } fn uitofp(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty, UNNAMED) - } + unsafe { llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty, UNNAMED) } } fn sitofp(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty, UNNAMED) - } + unsafe { llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty, UNNAMED) } } fn fptrunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty, UNNAMED) - } + unsafe { llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty, UNNAMED) } } fn fpext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty, UNNAMED) - } + unsafe { llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty, UNNAMED) } } fn ptrtoint(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty, UNNAMED) - } + unsafe { llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty, UNNAMED) } } fn inttoptr(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty, UNNAMED) - } + unsafe { llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty, UNNAMED) } } fn bitcast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED) - } + unsafe { llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED) } } - fn intcast(&mut self, val: &'ll Value, dest_ty: &'ll Type, is_signed: bool) -> &'ll Value { - unsafe { - llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty, is_signed) - } + unsafe { llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty, is_signed) } } fn pointercast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty, UNNAMED) - } + unsafe { llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty, UNNAMED) } } /* Comparisons */ fn icmp(&mut self, op: IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { let op = llvm::IntPredicate::from_generic(op); - unsafe { - llvm::LLVMBuildICmp(self.llbuilder, op as c_uint, lhs, rhs, UNNAMED) - } + unsafe { llvm::LLVMBuildICmp(self.llbuilder, op as c_uint, lhs, rhs, UNNAMED) } } fn fcmp(&mut self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - unsafe { - llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, UNNAMED) - } + unsafe { llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, UNNAMED) } } /* Miscellaneous instructions */ - fn memcpy(&mut self, dst: &'ll Value, dst_align: Align, - src: &'ll Value, src_align: Align, - size: &'ll Value, flags: MemFlags) { + fn memcpy( + &mut self, + dst: &'ll Value, + dst_align: Align, + src: &'ll Value, + src_align: Align, + size: &'ll Value, + flags: MemFlags, + ) { if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memcpy. let val = self.load(src, src_align); @@ -773,14 +727,27 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let dst = self.pointercast(dst, self.type_i8p()); let src = self.pointercast(src, self.type_i8p()); unsafe { - llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align.bytes() as c_uint, - src, src_align.bytes() as c_uint, size, is_volatile); + llvm::LLVMRustBuildMemCpy( + self.llbuilder, + dst, + dst_align.bytes() as c_uint, + src, + src_align.bytes() as c_uint, + size, + is_volatile, + ); } } - fn memmove(&mut self, dst: &'ll Value, dst_align: Align, - src: &'ll Value, src_align: Align, - size: &'ll Value, flags: MemFlags) { + fn memmove( + &mut self, + dst: &'ll Value, + dst_align: Align, + src: &'ll Value, + src_align: Align, + size: &'ll Value, + flags: MemFlags, + ) { if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memmove. let val = self.load(src, src_align); @@ -793,8 +760,15 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let dst = self.pointercast(dst, self.type_i8p()); let src = self.pointercast(src, self.type_i8p()); unsafe { - llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align.bytes() as c_uint, - src, src_align.bytes() as c_uint, size, is_volatile); + llvm::LLVMRustBuildMemMove( + self.llbuilder, + dst, + dst_align.bytes() as c_uint, + src, + src_align.bytes() as c_uint, + size, + is_volatile, + ); } } @@ -816,26 +790,21 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } fn select( - &mut self, cond: &'ll Value, + &mut self, + cond: &'ll Value, then_val: &'ll Value, else_val: &'ll Value, ) -> &'ll Value { - unsafe { - llvm::LLVMBuildSelect(self.llbuilder, cond, then_val, else_val, UNNAMED) - } + unsafe { llvm::LLVMBuildSelect(self.llbuilder, cond, then_val, else_val, UNNAMED) } } #[allow(dead_code)] fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) - } + unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) } } fn extract_element(&mut self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value { - unsafe { - llvm::LLVMBuildExtractElement(self.llbuilder, vec, idx, UNNAMED) - } + unsafe { llvm::LLVMBuildExtractElement(self.llbuilder, vec, idx, UNNAMED) } } fn vector_splat(&mut self, num_elts: usize, elt: &'ll Value) -> &'ll Value { @@ -850,25 +819,22 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn extract_value(&mut self, agg_val: &'ll Value, idx: u64) -> &'ll Value { assert_eq!(idx as c_uint as u64, idx); - unsafe { - llvm::LLVMBuildExtractValue(self.llbuilder, agg_val, idx as c_uint, UNNAMED) - } + unsafe { llvm::LLVMBuildExtractValue(self.llbuilder, agg_val, idx as c_uint, UNNAMED) } } - fn insert_value(&mut self, agg_val: &'ll Value, elt: &'ll Value, - idx: u64) -> &'ll Value { + fn insert_value(&mut self, agg_val: &'ll Value, elt: &'ll Value, idx: u64) -> &'ll Value { assert_eq!(idx as c_uint as u64, idx); - unsafe { - llvm::LLVMBuildInsertValue(self.llbuilder, agg_val, elt, idx as c_uint, - UNNAMED) - } + unsafe { llvm::LLVMBuildInsertValue(self.llbuilder, agg_val, elt, idx as c_uint, UNNAMED) } } - fn landing_pad(&mut self, ty: &'ll Type, pers_fn: &'ll Value, - num_clauses: usize) -> &'ll Value { + fn landing_pad( + &mut self, + ty: &'ll Type, + pers_fn: &'ll Value, + num_clauses: usize, + ) -> &'ll Value { unsafe { - llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn, - num_clauses as c_uint, UNNAMED) + llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn, num_clauses as c_uint, UNNAMED) } } @@ -879,43 +845,43 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } fn resume(&mut self, exn: &'ll Value) -> &'ll Value { - unsafe { - llvm::LLVMBuildResume(self.llbuilder, exn) - } + unsafe { llvm::LLVMBuildResume(self.llbuilder, exn) } } - fn cleanup_pad(&mut self, - parent: Option<&'ll Value>, - args: &[&'ll Value]) -> Funclet<'ll> { + fn cleanup_pad(&mut self, parent: Option<&'ll Value>, args: &[&'ll Value]) -> Funclet<'ll> { let name = const_cstr!("cleanuppad"); let ret = unsafe { - llvm::LLVMRustBuildCleanupPad(self.llbuilder, - parent, - args.len() as c_uint, - args.as_ptr(), - name.as_ptr()) + llvm::LLVMRustBuildCleanupPad( + self.llbuilder, + parent, + args.len() as c_uint, + args.as_ptr(), + name.as_ptr(), + ) }; Funclet::new(ret.expect("LLVM does not have support for cleanuppad")) } fn cleanup_ret( - &mut self, funclet: &Funclet<'ll>, + &mut self, + funclet: &Funclet<'ll>, unwind: Option<&'ll BasicBlock>, ) -> &'ll Value { - let ret = unsafe { - llvm::LLVMRustBuildCleanupRet(self.llbuilder, funclet.cleanuppad(), unwind) - }; + let ret = + unsafe { llvm::LLVMRustBuildCleanupRet(self.llbuilder, funclet.cleanuppad(), unwind) }; ret.expect("LLVM does not have support for cleanupret") } - fn catch_pad(&mut self, - parent: &'ll Value, - args: &[&'ll Value]) -> Funclet<'ll> { + fn catch_pad(&mut self, parent: &'ll Value, args: &[&'ll Value]) -> Funclet<'ll> { let name = const_cstr!("catchpad"); let ret = unsafe { - llvm::LLVMRustBuildCatchPad(self.llbuilder, parent, - args.len() as c_uint, args.as_ptr(), - name.as_ptr()) + llvm::LLVMRustBuildCatchPad( + self.llbuilder, + parent, + args.len() as c_uint, + args.as_ptr(), + name.as_ptr(), + ) }; Funclet::new(ret.expect("LLVM does not have support for catchpad")) } @@ -928,9 +894,13 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { ) -> &'ll Value { let name = const_cstr!("catchswitch"); let ret = unsafe { - llvm::LLVMRustBuildCatchSwitch(self.llbuilder, parent, unwind, - num_handlers as c_uint, - name.as_ptr()) + llvm::LLVMRustBuildCatchSwitch( + self.llbuilder, + parent, + unwind, + num_handlers as c_uint, + name.as_ptr(), + ) }; ret.expect("LLVM does not have support for catchswitch") } @@ -966,7 +936,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { src, AtomicOrdering::from_generic(order), AtomicOrdering::from_generic(failure_order), - weak + weak, ) } } @@ -984,28 +954,32 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { dst, src, AtomicOrdering::from_generic(order), - False) + False, + ) } } fn atomic_fence( &mut self, order: rustc_codegen_ssa::common::AtomicOrdering, - scope: rustc_codegen_ssa::common::SynchronizationScope + scope: rustc_codegen_ssa::common::SynchronizationScope, ) { unsafe { llvm::LLVMRustBuildAtomicFence( self.llbuilder, AtomicOrdering::from_generic(order), - SynchronizationScope::from_generic(scope) + SynchronizationScope::from_generic(scope), ); } } fn set_invariant_load(&mut self, load: &'ll Value) { unsafe { - llvm::LLVMSetMetadata(load, llvm::MD_invariant_load as c_uint, - llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0)); + llvm::LLVMSetMetadata( + load, + llvm::MD_invariant_load as c_uint, + llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0), + ); } } @@ -1023,10 +997,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { args: &[&'ll Value], funclet: Option<&Funclet<'ll>>, ) -> &'ll Value { - - debug!("call {:?} with args ({:?})", - llfn, - args); + debug!("call {:?} with args ({:?})", llfn, args); let args = self.check_call("call", llfn, args); let bundle = funclet.map(|funclet| funclet.bundle()); @@ -1038,18 +1009,16 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { llfn, args.as_ptr() as *const &llvm::Value, args.len() as c_uint, - bundle, UNNAMED + bundle, + UNNAMED, ) } } fn zext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) - } + unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) } } - fn cx(&self) -> &CodegenCx<'ll, 'tcx> { self.cx } @@ -1072,9 +1041,7 @@ impl StaticBuilderMethods for Builder<'a, 'll, 'tcx> { impl Builder<'a, 'll, 'tcx> { pub fn llfn(&self) -> &'ll Value { - unsafe { - llvm::LLVMGetBasicBlockParent(self.llbb()) - } + unsafe { llvm::LLVMGetBasicBlockParent(self.llbb()) } } fn position_at_start(&mut self, llbb: &'ll BasicBlock) { @@ -1092,13 +1059,12 @@ impl Builder<'a, 'll, 'tcx> { } pub fn insert_element( - &mut self, vec: &'ll Value, + &mut self, + vec: &'ll Value, elt: &'ll Value, idx: &'ll Value, ) -> &'ll Value { - unsafe { - llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, UNNAMED) - } + unsafe { llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, UNNAMED) } } pub fn shuffle_vector( @@ -1107,9 +1073,7 @@ impl Builder<'a, 'll, 'tcx> { v2: &'ll Value, mask: &'ll Value, ) -> &'ll Value { - unsafe { - llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, UNNAMED) - } + unsafe { llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, UNNAMED) } } pub fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { @@ -1148,21 +1112,27 @@ impl Builder<'a, 'll, 'tcx> { unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) } } pub fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value { - unsafe { llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false) } + unsafe { + llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false) + } } pub fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value { - unsafe { llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false) } + unsafe { + llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false) + } } pub fn vector_reduce_fmin_fast(&mut self, src: &'ll Value) -> &'ll Value { unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true); + let instr = + llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } } pub fn vector_reduce_fmax_fast(&mut self, src: &'ll Value) -> &'ll Value { unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true); + let instr = + llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } @@ -1181,9 +1151,8 @@ impl Builder<'a, 'll, 'tcx> { } pub fn catch_ret(&mut self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value { - let ret = unsafe { - llvm::LLVMRustBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) - }; + let ret = + unsafe { llvm::LLVMRustBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind) }; ret.expect("LLVM does not have support for catchret") } @@ -1197,29 +1166,38 @@ impl Builder<'a, 'll, 'tcx> { if dest_ptr_ty == stored_ptr_ty { ptr } else { - debug!("type mismatch in store. \ + debug!( + "type mismatch in store. \ Expected {:?}, got {:?}; inserting bitcast", - dest_ptr_ty, stored_ptr_ty); + dest_ptr_ty, stored_ptr_ty + ); self.bitcast(ptr, stored_ptr_ty) } } - fn check_call<'b>(&mut self, - typ: &str, - llfn: &'ll Value, - args: &'b [&'ll Value]) -> Cow<'b, [&'ll Value]> { + fn check_call<'b>( + &mut self, + typ: &str, + llfn: &'ll Value, + args: &'b [&'ll Value], + ) -> Cow<'b, [&'ll Value]> { let mut fn_ty = self.cx.val_ty(llfn); // Strip off pointers while self.cx.type_kind(fn_ty) == TypeKind::Pointer { fn_ty = self.cx.element_type(fn_ty); } - assert!(self.cx.type_kind(fn_ty) == TypeKind::Function, - "builder::{} not passed a function, but {:?}", typ, fn_ty); + assert!( + self.cx.type_kind(fn_ty) == TypeKind::Function, + "builder::{} not passed a function, but {:?}", + typ, + fn_ty + ); let param_tys = self.cx.func_params_types(fn_ty); - let all_args_match = param_tys.iter() + let all_args_match = param_tys + .iter() .zip(args.iter().map(|&v| self.val_ty(v))) .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty); @@ -1227,15 +1205,18 @@ impl Builder<'a, 'll, 'tcx> { return Cow::Borrowed(args); } - let casted_args: Vec<_> = param_tys.into_iter() + let casted_args: Vec<_> = param_tys + .into_iter() .zip(args.iter()) .enumerate() .map(|(i, (expected_ty, &actual_val))| { let actual_ty = self.val_ty(actual_val); if expected_ty != actual_ty { - debug!("type mismatch in function call of {:?}. \ + debug!( + "type mismatch in function call of {:?}. \ Expected {:?} for param {}, got {:?}; injecting bitcast", - llfn, expected_ty, i, actual_ty); + llfn, expected_ty, i, actual_ty + ); self.bitcast(actual_val, expected_ty) } else { actual_val @@ -1247,9 +1228,7 @@ impl Builder<'a, 'll, 'tcx> { } pub fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) - } + unsafe { llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED) } } fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) { @@ -1270,13 +1249,9 @@ impl Builder<'a, 'll, 'tcx> { fn phi(&mut self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value { assert_eq!(vals.len(), bbs.len()); - let phi = unsafe { - llvm::LLVMBuildPhi(self.llbuilder, ty, UNNAMED) - }; + let phi = unsafe { llvm::LLVMBuildPhi(self.llbuilder, ty, UNNAMED) }; unsafe { - llvm::LLVMAddIncoming(phi, vals.as_ptr(), - bbs.as_ptr(), - vals.len() as c_uint); + llvm::LLVMAddIncoming(phi, vals.as_ptr(), bbs.as_ptr(), vals.len() as c_uint); phi } } diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index c0be87b117d65..7be179a2098c1 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -6,14 +6,14 @@ use crate::abi::{FnAbi, FnAbiLlvmExt}; use crate::attributes; -use crate::llvm; use crate::context::CodegenCx; +use crate::llvm; use crate::value::Value; -use rustc_codegen_ssa::traits::*; use log::debug; +use rustc_codegen_ssa::traits::*; -use rustc::ty::{TypeFoldable, Instance}; use rustc::ty::layout::{FnAbiExt, HasTyCtxt}; +use rustc::ty::{Instance, TypeFoldable}; /// Codegens a reference to a fn/method item, monomorphizing and /// inlining as it goes. @@ -22,10 +22,7 @@ use rustc::ty::layout::{FnAbiExt, HasTyCtxt}; /// /// - `cx`: the crate context /// - `instance`: the instance to be instantiated -pub fn get_fn( - cx: &CodegenCx<'ll, 'tcx>, - instance: Instance<'tcx>, -) -> &'ll Value { +pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value { let tcx = cx.tcx(); debug!("get_fn(instance={:?})", instance); @@ -125,16 +122,20 @@ pub fn get_fn( // the current crate does not re-export generics, the // definition of the instance will have been declared // as `hidden`. - if cx.tcx.is_unreachable_local_definition(instance_def_id) || - !cx.tcx.local_crate_exports_generics() { + if cx.tcx.is_unreachable_local_definition(instance_def_id) + || !cx.tcx.local_crate_exports_generics() + { llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); } } else { // This is a monomorphization of a generic function // defined in an upstream crate. - if cx.tcx.upstream_monomorphizations_for(instance_def_id) - .map(|set| set.contains_key(instance.substs)) - .unwrap_or(false) { + if cx + .tcx + .upstream_monomorphizations_for(instance_def_id) + .map(|set| set.contains_key(instance.substs)) + .unwrap_or(false) + { // This is instantiated in another crate. It cannot // be `hidden`. } else { @@ -172,9 +173,7 @@ pub fn get_fn( } } - if cx.use_dll_storage_attrs && - tcx.is_dllimport_foreign_item(instance_def_id) - { + if cx.use_dll_storage_attrs && tcx.is_dllimport_foreign_item(instance_def_id) { unsafe { llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); } diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index cda8fbc3517a9..525b3af29f826 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -2,24 +2,24 @@ //! Code that is useful in various codegen modules. -use crate::llvm::{self, True, False, Bool, BasicBlock, OperandBundleDef, ConstantInt}; use crate::consts; +use crate::llvm::{self, BasicBlock, Bool, ConstantInt, False, OperandBundleDef, True}; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use rustc_codegen_ssa::traits::*; -use rustc::bug; use log::debug; +use rustc::bug; +use rustc_codegen_ssa::traits::*; use crate::consts::const_alloc_to_llvm; -use rustc::ty::layout::{HasDataLayout, LayoutOf, self, TyLayout, Size}; -use rustc::mir::interpret::{Scalar, GlobalAlloc, Allocation}; +use rustc::mir::interpret::{Allocation, GlobalAlloc, Scalar}; +use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Size, TyLayout}; use rustc_codegen_ssa::mir::place::PlaceRef; -use libc::{c_uint, c_char}; +use libc::{c_char, c_uint}; -use syntax::symbol::Symbol; use syntax::ast::Mutability; +use syntax::symbol::Symbol; pub use crate::context::CodegenCx; @@ -70,10 +70,7 @@ pub struct Funclet<'ll> { impl Funclet<'ll> { pub fn new(cleanuppad: &'ll Value) -> Self { - Funclet { - cleanuppad, - operand: OperandBundleDef::new("funclet", &[cleanuppad]), - } + Funclet { cleanuppad, operand: OperandBundleDef::new("funclet", &[cleanuppad]) } } pub fn cleanuppad(&self) -> &'ll Value { @@ -113,23 +110,21 @@ impl CodegenCx<'ll, 'tcx> { bytes_in_context(self.llcx, bytes) } - fn const_cstr( - &self, - s: Symbol, - null_terminated: bool, - ) -> &'ll Value { + fn const_cstr(&self, s: Symbol, null_terminated: bool) -> &'ll Value { unsafe { if let Some(&llval) = self.const_cstr_cache.borrow().get(&s) { return llval; } let s_str = s.as_str(); - let sc = llvm::LLVMConstStringInContext(self.llcx, - s_str.as_ptr() as *const c_char, - s_str.len() as c_uint, - !null_terminated as Bool); + let sc = llvm::LLVMConstStringInContext( + self.llcx, + s_str.as_ptr() as *const c_char, + s_str.len() as c_uint, + !null_terminated as Bool, + ); let sym = self.generate_local_symbol_name("str"); - let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{ + let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(|| { bug!("symbol `{}` is already defined", sym); }); llvm::LLVMSetInitializer(g, sc); @@ -147,8 +142,7 @@ impl CodegenCx<'ll, 'tcx> { let us = &[idx as c_uint]; let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint); - debug!("const_get_elt(v={:?}, idx={}, r={:?})", - v, idx, r); + debug!("const_get_elt(v={:?}, idx={}, r={:?})", v, idx, r); r } @@ -157,27 +151,19 @@ impl CodegenCx<'ll, 'tcx> { impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn const_null(&self, t: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMConstNull(t) - } + unsafe { llvm::LLVMConstNull(t) } } fn const_undef(&self, t: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMGetUndef(t) - } + unsafe { llvm::LLVMGetUndef(t) } } fn const_int(&self, t: &'ll Type, i: i64) -> &'ll Value { - unsafe { - llvm::LLVMConstInt(t, i as u64, True) - } + unsafe { llvm::LLVMConstInt(t, i as u64, True) } } fn const_uint(&self, t: &'ll Type, i: u64) -> &'ll Value { - unsafe { - llvm::LLVMConstInt(t, i, False) - } + unsafe { llvm::LLVMConstInt(t, i, False) } } fn const_uint_big(&self, t: &'ll Type, u: u128) -> &'ll Value { @@ -207,7 +193,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { let bit_size = self.data_layout().pointer_size.bits(); if bit_size < 64 { // make sure it doesn't overflow - assert!(i < (1< for CodegenCx<'ll, 'tcx> { fn const_str(&self, s: Symbol) -> (&'ll Value, &'ll Value) { let len = s.as_str().len(); - let cs = consts::ptrcast(self.const_cstr(s, false), - self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self))); + let cs = consts::ptrcast( + self.const_cstr(s, false), + self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self)), + ); (cs, self.const_usize(len as u64)) } - fn const_struct( - &self, - elts: &[&'ll Value], - packed: bool - ) -> &'ll Value { + fn const_struct(&self, elts: &[&'ll Value], packed: bool) -> &'ll Value { struct_in_context(self.llcx, elts, packed) } fn const_to_opt_uint(&self, v: &'ll Value) -> Option { - try_as_const_integral(v).map(|v| unsafe { - llvm::LLVMConstIntGetZExtValue(v) - }) + try_as_const_integral(v).map(|v| unsafe { llvm::LLVMConstIntGetZExtValue(v) }) } fn const_to_opt_u128(&self, v: &'ll Value, sign_ext: bool) -> Option { try_as_const_integral(v).and_then(|v| unsafe { let (mut lo, mut hi) = (0u64, 0u64); - let success = llvm::LLVMRustConstInt128Get(v, sign_ext, - &mut hi, &mut lo); + let success = llvm::LLVMRustConstInt128Get(v, sign_ext, &mut hi, &mut lo); success.then_some(hi_lo_to_u128(lo, hi)) }) } @@ -262,7 +243,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { Scalar::Raw { size: 0, .. } => { assert_eq!(0, layout.value.size(self).bytes()); self.const_undef(self.type_ix(0)) - }, + } Scalar::Raw { data, size } => { assert_eq!(size as u64, layout.value.size(self).bytes()); let llval = self.const_uint_big(self.type_ix(bitsize), data); @@ -271,7 +252,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { } else { self.const_bitcast(llval, llty) } - }, + } Scalar::Ptr(ptr) => { let alloc_kind = self.tcx.alloc_map.lock().get(ptr.alloc_id); let base_addr = match alloc_kind { @@ -283,20 +264,20 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { self.static_addr_of(init, alloc.align, None) } } - Some(GlobalAlloc::Function(fn_instance)) => { - self.get_fn_addr(fn_instance) - } + Some(GlobalAlloc::Function(fn_instance)) => self.get_fn_addr(fn_instance), Some(GlobalAlloc::Static(def_id)) => { assert!(self.tcx.is_static(def_id)); self.get_static(def_id) } None => bug!("missing allocation {:?}", ptr.alloc_id), }; - let llval = unsafe { llvm::LLVMConstInBoundsGEP( - self.const_bitcast(base_addr, self.type_i8p()), - &self.const_usize(ptr.offset.bytes()), - 1, - ) }; + let llval = unsafe { + llvm::LLVMConstInBoundsGEP( + self.const_bitcast(base_addr, self.type_i8p()), + &self.const_usize(ptr.offset.bytes()), + 1, + ) + }; if layout.value != layout::Pointer { unsafe { llvm::LLVMConstPtrToInt(llval, llty) } } else { @@ -321,11 +302,13 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { let init = const_alloc_to_llvm(self, alloc); let base_addr = self.static_addr_of(init, alloc.align, None); - let llval = unsafe { llvm::LLVMConstInBoundsGEP( - self.const_bitcast(base_addr, self.type_i8p()), - &self.const_usize(offset.bytes()), - 1, - )}; + let llval = unsafe { + llvm::LLVMConstInBoundsGEP( + self.const_bitcast(base_addr, self.type_i8p()), + &self.const_usize(offset.bytes()), + 1, + ) + }; self.const_bitcast(llval, llty) }; PlaceRef::new_sized(llval, layout) @@ -337,9 +320,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { } pub fn val_ty(v: &'ll Value) -> &'ll Type { - unsafe { - llvm::LLVMTypeOf(v) - } + unsafe { llvm::LLVMTypeOf(v) } } pub fn bytes_in_context(llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value { @@ -349,15 +330,9 @@ pub fn bytes_in_context(llcx: &'ll llvm::Context, bytes: &[u8]) -> &'ll Value { } } -pub fn struct_in_context( - llcx: &'a llvm::Context, - elts: &[&'a Value], - packed: bool, -) -> &'a Value { +pub fn struct_in_context(llcx: &'a llvm::Context, elts: &[&'a Value], packed: bool) -> &'a Value { unsafe { - llvm::LLVMConstStructInContext(llcx, - elts.as_ptr(), elts.len() as c_uint, - packed as Bool) + llvm::LLVMConstStructInContext(llcx, elts.as_ptr(), elts.len() as c_uint, packed as Bool) } } @@ -367,7 +342,5 @@ fn hi_lo_to_u128(lo: u64, hi: u64) -> u128 { } fn try_as_const_integral(v: &'ll Value) -> Option<&'ll ConstantInt> { - unsafe { - llvm::LLVMIsAConstantInt(v) - } + unsafe { llvm::LLVMIsAConstantInt(v) } } diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 2c894a5d7403c..827516f76a164 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -1,8 +1,8 @@ use crate::abi::FnAbi; use crate::attributes; +use crate::debuginfo; use crate::llvm; use crate::llvm_util; -use crate::debuginfo; use crate::value::Value; use rustc::dep_graph::DepGraphSafe; use rustc::hir; @@ -10,30 +10,30 @@ use rustc::hir; use crate::type_::Type; use rustc_codegen_ssa::traits::*; -use rustc_data_structures::base_n; -use rustc_data_structures::small_c_str::SmallCStr; +use crate::callee::get_fn; use rustc::bug; use rustc::mir::mono::CodegenUnit; use rustc::session::config::{self, DebugInfo}; use rustc::session::Session; use rustc::ty::layout::{ - FnAbiExt, LayoutError, LayoutOf, PointeeInfo, Size, TyLayout, VariantIdx, HasParamEnv + FnAbiExt, HasParamEnv, LayoutError, LayoutOf, PointeeInfo, Size, TyLayout, VariantIdx, }; -use rustc::ty::{self, Ty, TyCtxt, Instance}; +use rustc::ty::{self, Instance, Ty, TyCtxt}; use rustc::util::nodemap::FxHashMap; -use rustc_target::spec::{HasTargetSpec, Target}; use rustc_codegen_ssa::base::wants_msvc_seh; -use crate::callee::get_fn; +use rustc_data_structures::base_n; use rustc_data_structures::const_cstr; +use rustc_data_structures::small_c_str::SmallCStr; +use rustc_target::spec::{HasTargetSpec, Target}; -use std::ffi::CStr; +use crate::abi::Abi; use std::cell::{Cell, RefCell}; +use std::ffi::CStr; use std::iter; use std::str; use std::sync::Arc; +use syntax::source_map::{Span, DUMMY_SP}; use syntax::symbol::Symbol; -use syntax::source_map::{DUMMY_SP, Span}; -use crate::abi::Abi; /// There is one `CodegenCx` per compilation unit. Each one has its own LLVM /// `llvm::Context` so that several compilation units may be optimized in parallel. @@ -104,12 +104,10 @@ pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode { None => &sess.target.target.options.relocation_model[..], }; - match crate::back::write::RELOC_MODEL_ARGS.iter().find( - |&&arg| arg.0 == reloc_model_arg) { + match crate::back::write::RELOC_MODEL_ARGS.iter().find(|&&arg| arg.0 == reloc_model_arg) { Some(x) => x.1, _ => { - sess.err(&format!("{:?} is not a valid relocation mode", - reloc_model_arg)); + sess.err(&format!("{:?} is not a valid relocation mode", reloc_model_arg)); sess.abort_if_errors(); bug!(); } @@ -122,12 +120,10 @@ fn get_tls_model(sess: &Session) -> llvm::ThreadLocalMode { None => &sess.target.target.options.tls_model[..], }; - match crate::back::write::TLS_MODEL_ARGS.iter().find( - |&&arg| arg.0 == tls_model_arg) { + match crate::back::write::TLS_MODEL_ARGS.iter().find(|&&arg| arg.0 == tls_model_arg) { Some(x) => x.1, _ => { - sess.err(&format!("{:?} is not a valid TLS model", - tls_model_arg)); + sess.err(&format!("{:?} is not a valid TLS model", tls_model_arg)); sess.abort_if_errors(); bug!(); } @@ -135,9 +131,7 @@ fn get_tls_model(sess: &Session) -> llvm::ThreadLocalMode { } fn is_any_library(sess: &Session) -> bool { - sess.crate_types.borrow().iter().any(|ty| { - *ty != config::CrateType::Executable - }) + sess.crate_types.borrow().iter().any(|ty| *ty != config::CrateType::Executable) } pub fn is_pie_binary(sess: &Session) -> bool { @@ -171,7 +165,8 @@ pub unsafe fn create_module( let llvm_data_layout = llvm::LLVMGetDataLayout(llmod); let llvm_data_layout = str::from_utf8(CStr::from_ptr(llvm_data_layout).to_bytes()) - .ok().expect("got a non-UTF8 data-layout from LLVM"); + .ok() + .expect("got a non-UTF8 data-layout from LLVM"); // Unfortunately LLVM target specs change over time, and right now we // don't have proper support to work with any more than one @@ -192,11 +187,13 @@ pub unsafe fn create_module( let custom_llvm_used = cfg_llvm_root.trim() != ""; if !custom_llvm_used && target_data_layout != llvm_data_layout { - bug!("data-layout for builtin `{}` target, `{}`, \ + bug!( + "data-layout for builtin `{}` target, `{}`, \ differs from LLVM default, `{}`", - sess.target.target.llvm_target, - target_data_layout, - llvm_data_layout); + sess.target.target.llvm_target, + target_data_layout, + llvm_data_layout + ); } } @@ -283,9 +280,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { let dbg_cx = if tcx.sess.opts.debuginfo != DebugInfo::None { let dctx = debuginfo::CrateDebugContext::new(llmod); - debuginfo::metadata::compile_unit_metadata(tcx, - &codegen_unit.name().as_str(), - &dctx); + debuginfo::metadata::compile_unit_metadata(tcx, &codegen_unit.name().as_str(), &dctx); Some(dctx) } else { None @@ -327,8 +322,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { } impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { - fn vtables(&self) -> &RefCell, - Option>), &'ll Value>> + fn vtables( + &self, + ) -> &RefCell, Option>), &'ll Value>> { &self.vtables } @@ -363,20 +359,19 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { // CRT's custom personality function, which forces LLVM to consider // landing pads as "landing pads for SEH". if let Some(llpersonality) = self.eh_personality.get() { - return llpersonality + return llpersonality; } let tcx = self.tcx; let llfn = match tcx.lang_items().eh_personality() { - Some(def_id) if !wants_msvc_seh(self.sess()) => { - self.get_fn_addr( - ty::Instance::resolve( - tcx, - ty::ParamEnv::reveal_all(), - def_id, - tcx.intern_substs(&[]), - ).unwrap() + Some(def_id) if !wants_msvc_seh(self.sess()) => self.get_fn_addr( + ty::Instance::resolve( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + tcx.intern_substs(&[]), ) - } + .unwrap(), + ), _ => { let name = if wants_msvc_seh(self.sess()) { "__CxxFrameHandler3" @@ -409,7 +404,8 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { ty::ParamEnv::reveal_all(), def_id, tcx.intern_substs(&[]), - ).unwrap() + ) + .unwrap(), ); unwresume.set(Some(llfn)); return llfn; @@ -420,7 +416,7 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { tcx.types.never, false, hir::Unsafety::Unsafe, - Abi::C + Abi::C, )); let fn_abi = FnAbi::of_fn_ptr(self, sig, &[]); @@ -457,15 +453,11 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn create_used_variable(&self) { let name = const_cstr!("llvm.used"); let section = const_cstr!("llvm.metadata"); - let array = self.const_array( - &self.type_ptr_to(self.type_i8()), - &*self.used_statics.borrow() - ); + let array = + self.const_array(&self.type_ptr_to(self.type_i8()), &*self.used_statics.borrow()); unsafe { - let g = llvm::LLVMAddGlobal(self.llmod, - self.val_ty(array), - name.as_ptr()); + let g = llvm::LLVMAddGlobal(self.llmod, self.val_ty(array), name.as_ptr()); llvm::LLVMSetInitializer(g, array); llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage); llvm::LLVMSetSection(g, section.as_ptr()); @@ -483,7 +475,10 @@ impl CodegenCx<'b, 'tcx> { } fn insert_intrinsic( - &self, name: &'static str, args: Option<&[&'b llvm::Type]>, ret: &'b llvm::Type + &self, + name: &'static str, + args: Option<&[&'b llvm::Type]>, + ret: &'b llvm::Type, ) -> &'b llvm::Value { let fn_ty = if let Some(args) = args { self.type_func(args, ret) @@ -496,10 +491,7 @@ impl CodegenCx<'b, 'tcx> { f } - fn declare_intrinsic( - &self, - key: &str - ) -> Option<&'b Value> { + fn declare_intrinsic(&self, key: &str) -> Option<&'b Value> { macro_rules! ifn { ($name:expr, fn() -> $ret:expr) => ( if key == $name { @@ -724,13 +716,13 @@ impl CodegenCx<'b, 'tcx> { ifn!("llvm.ctpop.i64", fn(t_i64) -> t_i64); ifn!("llvm.ctpop.i128", fn(t_i128) -> t_i128); - ifn!("llvm.ctlz.i8", fn(t_i8 , i1) -> t_i8); + ifn!("llvm.ctlz.i8", fn(t_i8, i1) -> t_i8); ifn!("llvm.ctlz.i16", fn(t_i16, i1) -> t_i16); ifn!("llvm.ctlz.i32", fn(t_i32, i1) -> t_i32); ifn!("llvm.ctlz.i64", fn(t_i64, i1) -> t_i64); ifn!("llvm.ctlz.i128", fn(t_i128, i1) -> t_i128); - ifn!("llvm.cttz.i8", fn(t_i8 , i1) -> t_i8); + ifn!("llvm.cttz.i8", fn(t_i8, i1) -> t_i8); ifn!("llvm.cttz.i16", fn(t_i16, i1) -> t_i16); ifn!("llvm.cttz.i32", fn(t_i32, i1) -> t_i32); ifn!("llvm.cttz.i64", fn(t_i64, i1) -> t_i64); @@ -759,41 +751,41 @@ impl CodegenCx<'b, 'tcx> { ifn!("llvm.fshr.i64", fn(t_i64, t_i64, t_i64) -> t_i64); ifn!("llvm.fshr.i128", fn(t_i128, t_i128, t_i128) -> t_i128); - ifn!("llvm.sadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1}); - ifn!("llvm.sadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1}); - ifn!("llvm.sadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1}); - ifn!("llvm.sadd.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1}); - ifn!("llvm.sadd.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1}); - - ifn!("llvm.uadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1}); - ifn!("llvm.uadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1}); - ifn!("llvm.uadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1}); - ifn!("llvm.uadd.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1}); - ifn!("llvm.uadd.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1}); - - ifn!("llvm.ssub.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1}); - ifn!("llvm.ssub.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1}); - ifn!("llvm.ssub.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1}); - ifn!("llvm.ssub.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1}); - ifn!("llvm.ssub.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1}); - - ifn!("llvm.usub.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1}); - ifn!("llvm.usub.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1}); - ifn!("llvm.usub.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1}); - ifn!("llvm.usub.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1}); - ifn!("llvm.usub.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1}); - - ifn!("llvm.smul.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1}); - ifn!("llvm.smul.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1}); - ifn!("llvm.smul.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1}); - ifn!("llvm.smul.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1}); - ifn!("llvm.smul.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1}); - - ifn!("llvm.umul.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1}); - ifn!("llvm.umul.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1}); - ifn!("llvm.umul.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1}); - ifn!("llvm.umul.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1}); - ifn!("llvm.umul.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1}); + ifn!("llvm.sadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct! {t_i8, i1}); + ifn!("llvm.sadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct! {t_i16, i1}); + ifn!("llvm.sadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct! {t_i32, i1}); + ifn!("llvm.sadd.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct! {t_i64, i1}); + ifn!("llvm.sadd.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct! {t_i128, i1}); + + ifn!("llvm.uadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct! {t_i8, i1}); + ifn!("llvm.uadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct! {t_i16, i1}); + ifn!("llvm.uadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct! {t_i32, i1}); + ifn!("llvm.uadd.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct! {t_i64, i1}); + ifn!("llvm.uadd.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct! {t_i128, i1}); + + ifn!("llvm.ssub.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct! {t_i8, i1}); + ifn!("llvm.ssub.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct! {t_i16, i1}); + ifn!("llvm.ssub.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct! {t_i32, i1}); + ifn!("llvm.ssub.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct! {t_i64, i1}); + ifn!("llvm.ssub.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct! {t_i128, i1}); + + ifn!("llvm.usub.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct! {t_i8, i1}); + ifn!("llvm.usub.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct! {t_i16, i1}); + ifn!("llvm.usub.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct! {t_i32, i1}); + ifn!("llvm.usub.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct! {t_i64, i1}); + ifn!("llvm.usub.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct! {t_i128, i1}); + + ifn!("llvm.smul.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct! {t_i8, i1}); + ifn!("llvm.smul.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct! {t_i16, i1}); + ifn!("llvm.smul.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct! {t_i32, i1}); + ifn!("llvm.smul.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct! {t_i64, i1}); + ifn!("llvm.smul.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct! {t_i128, i1}); + + ifn!("llvm.umul.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct! {t_i8, i1}); + ifn!("llvm.umul.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct! {t_i16, i1}); + ifn!("llvm.umul.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct! {t_i32, i1}); + ifn!("llvm.umul.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct! {t_i64, i1}); + ifn!("llvm.umul.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct! {t_i128, i1}); ifn!("llvm.sadd.sat.i8", fn(t_i8, t_i8) -> t_i8); ifn!("llvm.sadd.sat.i16", fn(t_i16, t_i16) -> t_i16); @@ -819,7 +811,7 @@ impl CodegenCx<'b, 'tcx> { ifn!("llvm.usub.sat.i64", fn(t_i64, t_i64) -> t_i64); ifn!("llvm.usub.sat.i128", fn(t_i128, t_i128) -> t_i128); - ifn!("llvm.lifetime.start", fn(t_i64,i8p) -> void); + ifn!("llvm.lifetime.start", fn(t_i64, i8p) -> void); ifn!("llvm.lifetime.end", fn(t_i64, i8p) -> void); ifn!("llvm.expect.i1", fn(i1, i1) -> i1); @@ -887,12 +879,13 @@ impl LayoutOf for CodegenCx<'ll, 'tcx> { } fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Span) -> Self::TyLayout { - self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)) - .unwrap_or_else(|e| if let LayoutError::SizeOverflow(_) = e { + self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap_or_else(|e| { + if let LayoutError::SizeOverflow(_) = e { self.sess().span_fatal(span, &e.to_string()) } else { bug!("failed to get layout for `{}`: {}", ty, e) - }) + } + }) } } diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs index 91d5a22b0228d..206884d63c7d6 100644 --- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs +++ b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs @@ -1,10 +1,10 @@ -use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, DebugScope}; use super::metadata::file_metadata; -use super::utils::{DIB, span_start}; +use super::utils::{span_start, DIB}; +use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext}; +use crate::common::CodegenCx; use crate::llvm; use crate::llvm::debuginfo::{DIScope, DISubprogram}; -use crate::common::CodegenCx; use rustc::mir::{Body, SourceScope}; use libc::c_uint; @@ -36,12 +36,14 @@ pub fn compute_mir_scopes( } } -fn make_mir_scope(cx: &CodegenCx<'ll, '_>, - mir: &Body<'_>, - fn_metadata: &'ll DISubprogram, - has_variables: &BitSet, - debug_context: &mut FunctionDebugContext<&'ll DISubprogram>, - scope: SourceScope) { +fn make_mir_scope( + cx: &CodegenCx<'ll, '_>, + mir: &Body<'_>, + fn_metadata: &'ll DISubprogram, + has_variables: &BitSet, + debug_context: &mut FunctionDebugContext<&'ll DISubprogram>, + scope: SourceScope, +) { if debug_context.scopes[scope].is_valid() { return; } @@ -75,9 +77,7 @@ fn make_mir_scope(cx: &CodegenCx<'ll, '_>, } let loc = span_start(cx, scope_data.span); - let file_metadata = file_metadata(cx, - &loc.file.name, - debug_context.defining_crate); + let file_metadata = file_metadata(cx, &loc.file.name, debug_context.defining_crate); let scope_metadata = unsafe { Some(llvm::LLVMRustDIBuilderCreateLexicalBlock( @@ -85,7 +85,8 @@ fn make_mir_scope(cx: &CodegenCx<'ll, '_>, parent_scope.scope_metadata.unwrap(), file_metadata, loc.line as c_uint, - loc.col.to_usize() as c_uint)) + loc.col.to_usize() as c_uint, + )) }; debug_context.scopes[scope] = DebugScope { scope_metadata, diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/src/librustc_codegen_llvm/debuginfo/gdb.rs index 739437ac27b82..f68b7b2cfb954 100644 --- a/src/librustc_codegen_llvm/debuginfo/gdb.rs +++ b/src/librustc_codegen_llvm/debuginfo/gdb.rs @@ -2,17 +2,16 @@ use crate::llvm; -use crate::common::CodegenCx; use crate::builder::Builder; +use crate::common::CodegenCx; use crate::value::Value; +use rustc::bug; use rustc::session::config::DebugInfo; use rustc_codegen_ssa::traits::*; -use rustc::bug; use syntax::attr; use syntax::symbol::sym; - /// Inserts a side-effect free instruction sequence that makes sure that the /// .debug_gdb_scripts global is referenced, so it isn't removed by the linker. pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, '_, '_>) { @@ -31,28 +30,23 @@ pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, /// Allocates the global variable responsible for the .debug_gdb_scripts binary /// section. -pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx<'ll, '_>) - -> &'ll Value { +pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx<'ll, '_>) -> &'ll Value { let c_section_var_name = "__rustc_debug_gdb_scripts_section__\0"; - let section_var_name = &c_section_var_name[..c_section_var_name.len()-1]; + let section_var_name = &c_section_var_name[..c_section_var_name.len() - 1]; - let section_var = unsafe { - llvm::LLVMGetNamedGlobal(cx.llmod, - c_section_var_name.as_ptr().cast()) - }; + let section_var = + unsafe { llvm::LLVMGetNamedGlobal(cx.llmod, c_section_var_name.as_ptr().cast()) }; section_var.unwrap_or_else(|| { let section_name = b".debug_gdb_scripts\0"; let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0"; unsafe { - let llvm_type = cx.type_array(cx.type_i8(), - section_contents.len() as u64); + let llvm_type = cx.type_array(cx.type_i8(), section_contents.len() as u64); - let section_var = cx.define_global(section_var_name, - llvm_type).unwrap_or_else(||{ - bug!("symbol `{}` is already defined", section_var_name) - }); + let section_var = cx + .define_global(section_var_name, llvm_type) + .unwrap_or_else(|| bug!("symbol `{}` is already defined", section_var_name)); llvm::LLVMSetSection(section_var, section_name.as_ptr().cast()); llvm::LLVMSetInitializer(section_var, cx.const_bytes(section_contents)); llvm::LLVMSetGlobalConstant(section_var, llvm::True); @@ -70,7 +64,7 @@ pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { let omit_gdb_pretty_printer_section = attr::contains_name(&cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section); - !omit_gdb_pretty_printer_section && - cx.sess().opts.debuginfo != DebugInfo::None && - cx.sess().target.target.options.emit_debug_gdb_scripts + !omit_gdb_pretty_printer_section + && cx.sess().opts.debuginfo != DebugInfo::None + && cx.sess().target.target.options.emit_debug_gdb_scripts } diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 1de298de75f2e..8c6d1ce695b05 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -3,51 +3,51 @@ mod doc; use rustc_codegen_ssa::mir::debuginfo::VariableKind::*; -use self::utils::{DIB, span_start, create_DIArray, is_node_local_to_unit}; +use self::metadata::{file_metadata, type_metadata, TypeMap}; use self::namespace::mangled_name_of_instance; -use self::type_names::compute_debuginfo_type_name; -use self::metadata::{type_metadata, file_metadata, TypeMap}; use self::source_loc::InternalDebugLocation::{self, UnknownLocation}; +use self::type_names::compute_debuginfo_type_name; +use self::utils::{create_DIArray, is_node_local_to_unit, span_start, DIB}; use crate::llvm; -use crate::llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilder, DIArray, DIFlags, - DISPFlags, DILexicalBlock}; +use crate::llvm::debuginfo::{ + DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DISPFlags, DIScope, DIType, +}; +use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir::CodegenFnAttrFlags; -use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; -use rustc::ty::subst::{SubstsRef, GenericArgKind}; +use rustc::ty::subst::{GenericArgKind, SubstsRef}; use crate::abi::FnAbi; -use crate::common::CodegenCx; use crate::builder::Builder; +use crate::common::CodegenCx; use crate::value::Value; -use rustc::ty::{self, ParamEnv, Ty, InstanceDef, Instance}; use rustc::mir; use rustc::session::config::{self, DebugInfo}; +use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty}; use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet}; +use rustc_codegen_ssa::debuginfo::type_names; +use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind}; use rustc_data_structures::small_c_str::SmallCStr; use rustc_index::vec::IndexVec; -use rustc_codegen_ssa::debuginfo::type_names; -use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, DebugScope, - VariableKind}; use libc::c_uint; +use log::debug; use std::cell::RefCell; use std::ffi::CString; -use log::debug; +use rustc::ty::layout::{self, HasTyCtxt, LayoutOf, Size}; +use rustc_codegen_ssa::traits::*; use smallvec::SmallVec; -use syntax_pos::{self, BytePos, Span, Pos}; use syntax::ast; use syntax::symbol::Symbol; -use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, Size}; -use rustc_codegen_ssa::traits::*; +use syntax_pos::{self, BytePos, Pos, Span}; +mod create_scope_map; pub mod gdb; -mod utils; -mod namespace; pub mod metadata; -mod create_scope_map; +mod namespace; mod source_loc; +mod utils; pub use self::create_scope_map::compute_mir_scopes; pub use self::metadata::create_global_var_metadata; @@ -126,24 +126,20 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) { // for macOS to understand. For more info see #11352 // This can be overridden using --llvm-opts -dwarf-version,N. // Android has the same issue (#22398) - if cx.sess().target.target.options.is_like_osx || - cx.sess().target.target.options.is_like_android { - llvm::LLVMRustAddModuleFlag(cx.llmod, - "Dwarf Version\0".as_ptr().cast(), - 2) + if cx.sess().target.target.options.is_like_osx + || cx.sess().target.target.options.is_like_android + { + llvm::LLVMRustAddModuleFlag(cx.llmod, "Dwarf Version\0".as_ptr().cast(), 2) } // Indicate that we want CodeView debug information on MSVC if cx.sess().target.target.options.is_like_msvc { - llvm::LLVMRustAddModuleFlag(cx.llmod, - "CodeView\0".as_ptr().cast(), - 1) + llvm::LLVMRustAddModuleFlag(cx.llmod, "CodeView\0".as_ptr().cast(), 1) } // Prevent bitcode readers from deleting the debug info. let ptr = "Debug Info Version\0".as_ptr(); - llvm::LLVMRustAddModuleFlag(cx.llmod, ptr.cast(), - llvm::LLVMRustDebugMetadataVersion()); + llvm::LLVMRustAddModuleFlag(cx.llmod, ptr.cast(), llvm::LLVMRustDebugMetadataVersion()); }; } @@ -164,16 +160,14 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { let cx = self.cx(); let file = span_start(cx, span).file; - let file_metadata = file_metadata(cx, - &file.name, - dbg_context.defining_crate); + let file_metadata = file_metadata(cx, &file.name, dbg_context.defining_crate); let loc = span_start(cx, span); let type_metadata = type_metadata(cx, variable_type, span); let (argument_index, dwarf_tag) = match variable_kind { ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable), - LocalVariable => (0, DW_TAG_auto_variable) + LocalVariable => (0, DW_TAG_auto_variable), }; let align = cx.align_of(variable_type); @@ -210,8 +204,10 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { align.bytes() as u32, ) }; - source_loc::set_debug_location(self, - InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize())); + source_loc::set_debug_location( + self, + InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()), + ); unsafe { let debug_loc = llvm::LLVMGetCurrentDebugLocation(self.llbuilder); let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd( @@ -221,7 +217,8 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { addr_ops.as_ptr(), addr_ops.len() as c_uint, debug_loc, - self.llbb()); + self.llbb(), + ); llvm::LLVMSetInstDebugLocation(self.llbuilder, instr); } @@ -249,8 +246,7 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { // Only function parameters and instructions are local to a function, // don't change the name of anything else (e.g. globals). let param_or_inst = unsafe { - llvm::LLVMIsAArgument(value).is_some() || - llvm::LLVMIsAInstruction(value).is_some() + llvm::LLVMIsAArgument(value).is_some() || llvm::LLVMIsAInstruction(value).is_some() }; if !param_or_inst { return; @@ -311,11 +307,8 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { // name if necessary. let generics = self.tcx().generics_of(enclosing_fn_def_id); let substs = instance.substs.truncate_to(self.tcx(), generics); - let template_parameters = get_template_parameters(self, - &generics, - substs, - file_metadata, - &mut name); + let template_parameters = + get_template_parameters(self, &generics, substs, file_metadata, &mut name); // Get the linkage_name, which is just the symbol name let linkage_name = mangled_name_of_instance(self, instance); @@ -358,7 +351,8 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { spflags, llfn, template_parameters, - None) + None, + ) }; // Initialize fn debug context (including scopes). @@ -366,7 +360,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { let null_scope = DebugScope { scope_metadata: None, file_start_pos: BytePos(0), - file_end_pos: BytePos(0) + file_end_pos: BytePos(0), }; let mut fn_debug_context = FunctionDebugContext { scopes: IndexVec::from_elem(null_scope, &mir.source_scopes), @@ -412,17 +406,21 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { let t = arg.layout.ty; let t = match t.kind { ty::Array(ct, _) - if (ct == cx.tcx.types.u8) || cx.layout_of(ct).is_zst() => { + if (ct == cx.tcx.types.u8) || cx.layout_of(ct).is_zst() => + { cx.tcx.mk_imm_ptr(ct) } - _ => t + _ => t, }; Some(type_metadata(cx, t, syntax_pos::DUMMY_SP)) })); } else { - signature.extend(fn_abi.args.iter().map(|arg| { - Some(type_metadata(cx, arg.layout.ty, syntax_pos::DUMMY_SP)) - })); + signature.extend( + fn_abi + .args + .iter() + .map(|arg| Some(type_metadata(cx, arg.layout.ty, syntax_pos::DUMMY_SP))), + ); } create_DIArray(DIB(cx), &signature[..]) @@ -448,9 +446,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), actual_type); // Add actual type name to <...> clause of function name - let actual_type_name = compute_debuginfo_type_name(cx.tcx(), - actual_type, - true); + let actual_type_name = compute_debuginfo_type_name(cx.tcx(), actual_type, true); name_to_append_suffix_to.push_str(&actual_type_name[..]); } name_to_append_suffix_to.push('>'); @@ -458,28 +454,32 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { // Again, only create type information if full debuginfo is enabled let template_params: Vec<_> = if cx.sess().opts.debuginfo == DebugInfo::Full { let names = get_parameter_names(cx, generics); - substs.iter().zip(names).filter_map(|(kind, name)| { - if let GenericArgKind::Type(ty) = kind.unpack() { - let actual_type = - cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); - let actual_type_metadata = - type_metadata(cx, actual_type, syntax_pos::DUMMY_SP); - let name = SmallCStr::new(&name.as_str()); - Some(unsafe { - Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( - DIB(cx), - None, - name.as_ptr(), - actual_type_metadata, - file_metadata, - 0, - 0, - )) - }) - } else { - None - } - }).collect() + substs + .iter() + .zip(names) + .filter_map(|(kind, name)| { + if let GenericArgKind::Type(ty) = kind.unpack() { + let actual_type = + cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); + let actual_type_metadata = + type_metadata(cx, actual_type, syntax_pos::DUMMY_SP); + let name = SmallCStr::new(&name.as_str()); + Some(unsafe { + Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( + DIB(cx), + None, + name.as_ptr(), + actual_type_metadata, + file_metadata, + 0, + 0, + )) + }) + } else { + None + } + }) + .collect() } else { vec![] }; @@ -487,12 +487,10 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { return create_DIArray(DIB(cx), &template_params[..]); } - fn get_parameter_names(cx: &CodegenCx<'_, '_>, - generics: &ty::Generics) - -> Vec { - let mut names = generics.parent.map_or(vec![], |def_id| { - get_parameter_names(cx, cx.tcx.generics_of(def_id)) - }); + fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) -> Vec { + let mut names = generics + .parent + .map_or(vec![], |def_id| get_parameter_names(cx, cx.tcx.generics_of(def_id))); names.extend(generics.params.iter().map(|param| param.name)); names } @@ -519,7 +517,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { ty::Adt(def, ..) if !def.is_box() => { Some(type_metadata(cx, impl_self_ty, syntax_pos::DUMMY_SP)) } - _ => None + _ => None, } } else { // For trait method impls we still use the "parallel namespace" @@ -529,33 +527,33 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { }); self_type.unwrap_or_else(|| { - namespace::item_namespace(cx, DefId { - krate: instance.def_id().krate, - index: cx.tcx - .def_key(instance.def_id()) - .parent - .expect("get_containing_scope: missing parent?") - }) + namespace::item_namespace( + cx, + DefId { + krate: instance.def_id().krate, + index: cx + .tcx + .def_key(instance.def_id()) + .parent + .expect("get_containing_scope: missing parent?"), + }, + ) }) } } - fn create_vtable_metadata( - &self, - ty: Ty<'tcx>, - vtable: Self::Value, - ) { + fn create_vtable_metadata(&self, ty: Ty<'tcx>, vtable: Self::Value) { metadata::create_vtable_metadata(self, ty, vtable) } fn extend_scope_to_file( - &self, - scope_metadata: &'ll DIScope, - file: &syntax_pos::SourceFile, - defining_crate: CrateNum, - ) -> &'ll DILexicalBlock { - metadata::extend_scope_to_file(&self, scope_metadata, file, defining_crate) - } + &self, + scope_metadata: &'ll DIScope, + file: &syntax_pos::SourceFile, + defining_crate: CrateNum, + ) -> &'ll DILexicalBlock { + metadata::extend_scope_to_file(&self, scope_metadata, file, defining_crate) + } fn debuginfo_finalize(&self) { finalize(self) diff --git a/src/librustc_codegen_llvm/debuginfo/namespace.rs b/src/librustc_codegen_llvm/debuginfo/namespace.rs index 482bcf2aa5835..77b47efd3ddce 100644 --- a/src/librustc_codegen_llvm/debuginfo/namespace.rs +++ b/src/librustc_codegen_llvm/debuginfo/namespace.rs @@ -1,12 +1,12 @@ // Namespace Handling. use super::metadata::{unknown_file_metadata, UNKNOWN_LINE_NUMBER}; -use super::utils::{DIB, debug_context}; +use super::utils::{debug_context, DIB}; use rustc::ty::{self, Instance}; +use crate::common::CodegenCx; use crate::llvm; use crate::llvm::debuginfo::DIScope; -use crate::common::CodegenCx; use rustc::hir::def_id::DefId; use rustc::hir::map::DefPathData; @@ -16,8 +16,8 @@ pub fn mangled_name_of_instance<'a, 'tcx>( cx: &CodegenCx<'a, 'tcx>, instance: Instance<'tcx>, ) -> ty::SymbolName { - let tcx = cx.tcx; - tcx.symbol_name(instance) + let tcx = cx.tcx; + tcx.symbol_name(instance) } pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { @@ -26,16 +26,13 @@ pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { } let def_key = cx.tcx.def_key(def_id); - let parent_scope = def_key.parent.map(|parent| { - item_namespace(cx, DefId { - krate: def_id.krate, - index: parent - }) - }); + let parent_scope = def_key + .parent + .map(|parent| item_namespace(cx, DefId { krate: def_id.krate, index: parent })); let namespace_name = match def_key.disambiguated_data.data { DefPathData::CrateRoot => cx.tcx.crate_name(def_id.krate), - data => data.as_symbol() + data => data.as_symbol(), }; let namespace_name = SmallCStr::new(&namespace_name.as_str()); @@ -46,7 +43,8 @@ pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { parent_scope, namespace_name.as_ptr(), unknown_file_metadata(cx), - UNKNOWN_LINE_NUMBER) + UNKNOWN_LINE_NUMBER, + ) }; debug_context(cx).namespace_map.borrow_mut().insert(def_id, scope); diff --git a/src/librustc_codegen_llvm/debuginfo/source_loc.rs b/src/librustc_codegen_llvm/debuginfo/source_loc.rs index 82183fa9bd7bf..5fb50e1723649 100644 --- a/src/librustc_codegen_llvm/debuginfo/source_loc.rs +++ b/src/librustc_codegen_llvm/debuginfo/source_loc.rs @@ -1,17 +1,17 @@ use self::InternalDebugLocation::*; -use super::utils::{debug_context, span_start}; use super::metadata::UNKNOWN_COLUMN_NUMBER; +use super::utils::{debug_context, span_start}; use rustc_codegen_ssa::mir::debuginfo::FunctionDebugContext; +use crate::builder::Builder; use crate::llvm; use crate::llvm::debuginfo::DIScope; -use crate::builder::Builder; -use rustc_codegen_ssa::traits::*; use log::debug; +use rustc_codegen_ssa::traits::*; use libc::c_uint; -use syntax_pos::{Span, Pos}; +use syntax_pos::{Pos, Span}; /// Sets the current debug location at the beginning of the span. /// @@ -32,33 +32,25 @@ pub fn set_source_location( set_debug_location(bx, dbg_loc); } - #[derive(Copy, Clone, PartialEq)] pub enum InternalDebugLocation<'ll> { KnownLocation { scope: &'ll DIScope, line: usize, col: usize }, - UnknownLocation + UnknownLocation, } impl InternalDebugLocation<'ll> { pub fn new(scope: &'ll DIScope, line: usize, col: usize) -> Self { - KnownLocation { - scope, - line, - col, - } + KnownLocation { scope, line, col } } } -pub fn set_debug_location( - bx: &Builder<'_, 'll, '_>, - debug_location: InternalDebugLocation<'ll> -) { +pub fn set_debug_location(bx: &Builder<'_, 'll, '_>, debug_location: InternalDebugLocation<'ll>) { let metadata_node = match debug_location { KnownLocation { scope, line, col } => { // For MSVC, set the column number to zero. // Otherwise, emit it. This mimics clang behaviour. // See discussion in https://github.com/rust-lang/rust/issues/42921 - let col_used = if bx.sess().target.target.options.is_like_msvc { + let col_used = if bx.sess().target.target.options.is_like_msvc { UNKNOWN_COLUMN_NUMBER } else { col as c_uint @@ -71,7 +63,8 @@ pub fn set_debug_location( line as c_uint, col_used, scope, - None)) + None, + )) } } UnknownLocation => { diff --git a/src/librustc_codegen_llvm/debuginfo/utils.rs b/src/librustc_codegen_llvm/debuginfo/utils.rs index c64e0d9806b29..e77dab998d27d 100644 --- a/src/librustc_codegen_llvm/debuginfo/utils.rs +++ b/src/librustc_codegen_llvm/debuginfo/utils.rs @@ -1,20 +1,19 @@ // Utility Functions. -use super::{CrateDebugContext}; use super::namespace::item_namespace; +use super::CrateDebugContext; use rustc::hir::def_id::DefId; use rustc::ty::DefIdTree; +use crate::common::CodegenCx; use crate::llvm; -use crate::llvm::debuginfo::{DIScope, DIBuilder, DIDescriptor, DIArray}; -use crate::common::{CodegenCx}; +use crate::llvm::debuginfo::{DIArray, DIBuilder, DIDescriptor, DIScope}; use rustc_codegen_ssa::traits::*; use syntax_pos::Span; -pub fn is_node_local_to_unit(cx: &CodegenCx<'_, '_>, def_id: DefId) -> bool -{ +pub fn is_node_local_to_unit(cx: &CodegenCx<'_, '_>, def_id: DefId) -> bool { // The is_local_to_unit flag indicates whether a function is local to the // current compilation unit (i.e., if it is *static* in the C-sense). The // *reachable* set should provide a good approximation of this, as it @@ -27,10 +26,7 @@ pub fn is_node_local_to_unit(cx: &CodegenCx<'_, '_>, def_id: DefId) -> bool } #[allow(non_snake_case)] -pub fn create_DIArray( - builder: &DIBuilder<'ll>, - arr: &[Option<&'ll DIDescriptor>], -) -> &'ll DIArray { +pub fn create_DIArray(builder: &DIBuilder<'ll>, arr: &[Option<&'ll DIDescriptor>]) -> &'ll DIArray { return unsafe { llvm::LLVMRustDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32) }; @@ -53,6 +49,5 @@ pub fn DIB(cx: &'a CodegenCx<'ll, '_>) -> &'a DIBuilder<'ll> { } pub fn get_namespace_for_item(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { - item_namespace(cx, cx.tcx.parent(def_id) - .expect("get_namespace_for_item: missing parent?")) + item_namespace(cx, cx.tcx.parent(def_id).expect("get_namespace_for_item: missing parent?")) } diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index 5144b92ea101c..bb06b52162186 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -11,18 +11,18 @@ //! * Use define_* family of methods when you might be defining the Value. //! * When in doubt, define. -use crate::llvm; -use crate::llvm::AttributePlace::Function; use crate::abi::{FnAbi, FnAbiLlvmExt}; use crate::attributes; use crate::context::CodegenCx; +use crate::llvm; +use crate::llvm::AttributePlace::Function; use crate::type_::Type; use crate::value::Value; -use rustc::ty::Ty; +use log::debug; use rustc::session::config::Sanitizer; -use rustc_data_structures::small_c_str::SmallCStr; +use rustc::ty::Ty; use rustc_codegen_ssa::traits::*; -use log::debug; +use rustc_data_structures::small_c_str::SmallCStr; /// Declare a function. /// @@ -36,17 +36,14 @@ fn declare_raw_fn( ) -> &'ll Value { debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty); let namebuf = SmallCStr::new(name); - let llfn = unsafe { - llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty) - }; + let llfn = unsafe { llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty) }; llvm::SetFunctionCallConv(llfn, callconv); // Function addresses in Rust are never significant, allowing functions to // be merged. llvm::SetUnnamedAddr(llfn, true); - if cx.tcx.sess.opts.cg.no_redzone - .unwrap_or(cx.tcx.sess.target.target.options.disable_redzone) { + if cx.tcx.sess.opts.cg.no_redzone.unwrap_or(cx.tcx.sess.target.target.options.disable_redzone) { llvm::Attribute::NoRedZone.apply_llfn(Function, llfn); } @@ -54,13 +51,13 @@ fn declare_raw_fn( match *sanitizer { Sanitizer::Address => { llvm::Attribute::SanitizeAddress.apply_llfn(Function, llfn); - }, + } Sanitizer::Memory => { llvm::Attribute::SanitizeMemory.apply_llfn(Function, llfn); - }, + } Sanitizer::Thread => { llvm::Attribute::SanitizeThread.apply_llfn(Function, llfn); - }, + } _ => {} } } @@ -71,30 +68,16 @@ fn declare_raw_fn( } impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> { - - fn declare_global( - &self, - name: &str, ty: &'ll Type - ) -> &'ll Value { + fn declare_global(&self, name: &str, ty: &'ll Type) -> &'ll Value { debug!("declare_global(name={:?})", name); - unsafe { - llvm::LLVMRustGetOrInsertGlobal(self.llmod, name.as_ptr().cast(), name.len(), ty) - } + unsafe { llvm::LLVMRustGetOrInsertGlobal(self.llmod, name.as_ptr().cast(), name.len(), ty) } } - fn declare_cfn( - &self, - name: &str, - fn_type: &'ll Type - ) -> &'ll Value { + fn declare_cfn(&self, name: &str, fn_type: &'ll Type) -> &'ll Value { declare_raw_fn(self, name, llvm::CCallConv, fn_type) } - fn declare_fn( - &self, - name: &str, - fn_abi: &FnAbi<'tcx, Ty<'tcx>>, - ) -> &'ll Value { + fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> &'ll Value { debug!("declare_rust_fn(name={:?}, fn_abi={:?})", name, fn_abi); let llfn = declare_raw_fn(self, name, fn_abi.llvm_cconv(), fn_abi.llvm_type(self)); @@ -102,11 +85,7 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> { llfn } - fn define_global( - &self, - name: &str, - ty: &'ll Type - ) -> Option<&'ll Value> { + fn define_global(&self, name: &str, ty: &'ll Type) -> Option<&'ll Value> { if self.get_defined_value(name).is_some() { None } else { @@ -115,9 +94,7 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> { } fn define_private_global(&self, ty: &'ll Type) -> &'ll Value { - unsafe { - llvm::LLVMRustInsertPrivateGlobal(self.llmod, ty) - } + unsafe { llvm::LLVMRustInsertPrivateGlobal(self.llmod, ty) } } fn get_declared_value(&self, name: &str) -> Option<&'ll Value> { @@ -127,15 +104,9 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> { } fn get_defined_value(&self, name: &str) -> Option<&'ll Value> { - self.get_declared_value(name).and_then(|val|{ - let declaration = unsafe { - llvm::LLVMIsDeclaration(val) != 0 - }; - if !declaration { - Some(val) - } else { - None - } + self.get_declared_value(name).and_then(|val| { + let declaration = unsafe { llvm::LLVMIsDeclaration(val) != 0 }; + if !declaration { Some(val) } else { None } }) } } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index e5a7583a8cc70..abb17b3b0f116 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -1,24 +1,24 @@ -use crate::llvm; -use crate::llvm_util; use crate::abi::{Abi, FnAbi, LlvmType, PassMode}; +use crate::builder::Builder; use crate::context::CodegenCx; +use crate::llvm; +use crate::llvm_util; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; -use crate::builder::Builder; -use crate::value::Value; use crate::va_arg::emit_va_arg; -use rustc_codegen_ssa::MemFlags; -use rustc_codegen_ssa::mir::place::PlaceRef; -use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; -use rustc_codegen_ssa::glue; -use rustc_codegen_ssa::base::{to_immediate, wants_msvc_seh, compare_simd_types}; +use crate::value::Value; +use rustc::hir; +use rustc::ty::layout::{self, FnAbiExt, HasTyCtxt, LayoutOf, Primitive}; use rustc::ty::{self, Ty}; -use rustc::ty::layout::{self, FnAbiExt, LayoutOf, HasTyCtxt, Primitive}; +use rustc::{bug, span_bug}; +use rustc_codegen_ssa::base::{compare_simd_types, to_immediate, wants_msvc_seh}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; -use rustc::hir; +use rustc_codegen_ssa::glue; +use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; +use rustc_codegen_ssa::mir::place::PlaceRef; +use rustc_codegen_ssa::MemFlags; use rustc_target::abi::HasDataLayout; use syntax::ast; -use rustc::{bug, span_bug}; use rustc_codegen_ssa::common::span_invalid_monomorphization_error; use rustc_codegen_ssa::traits::*; @@ -26,7 +26,7 @@ use rustc_codegen_ssa::traits::*; use syntax_pos::Span; use std::cmp::Ordering; -use std::{iter, i128, u128}; +use std::{i128, iter, u128}; fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Value> { let llvm_name = match name { @@ -74,7 +74,7 @@ fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Valu "roundf64" => "llvm.round.f64", "assume" => "llvm.assume", "abort" => "llvm.trap", - _ => return None + _ => return None, }; Some(cx.get_intrinsic(&llvm_name)) } @@ -93,7 +93,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { let (def_id, substs) = match callee_ty.kind { ty::FnDef(def_id, substs) => (def_id, substs), - _ => bug!("expected fn item type, found {}", callee_ty) + _ => bug!("expected fn item type, found {}", callee_ty), }; let sig = callee_ty.fn_sig(tcx); @@ -107,14 +107,14 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { let simple = get_simple_intrinsic(self, name); let llval = match name { - _ if simple.is_some() => { - self.call(simple.unwrap(), - &args.iter().map(|arg| arg.immediate()).collect::>(), - None) - } + _ if simple.is_some() => self.call( + simple.unwrap(), + &args.iter().map(|arg| arg.immediate()).collect::>(), + None, + ), "unreachable" => { return; - }, + } "likely" => { let expect = self.get_intrinsic(&("llvm.expect.i1")); self.call(expect, &[args[0].immediate(), self.const_bool(true)], None) @@ -124,23 +124,21 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { self.call(expect, &[args[0].immediate(), self.const_bool(false)], None) } "try" => { - try_intrinsic(self, - args[0].immediate(), - args[1].immediate(), - args[2].immediate(), - llresult); + try_intrinsic( + self, + args[0].immediate(), + args[1].immediate(), + args[2].immediate(), + llresult, + ); return; } "breakpoint" => { let llfn = self.get_intrinsic(&("llvm.debugtrap")); self.call(llfn, &[], None) } - "va_start" => { - self.va_start(args[0].immediate()) - } - "va_end" => { - self.va_end(args[0].immediate()) - } + "va_start" => self.va_start(args[0].immediate()), + "va_end" => self.va_end(args[0].immediate()), "va_copy" => { let intrinsic = self.cx().get_intrinsic(&("llvm.va_copy")); self.call(intrinsic, &[args[0].immediate(), args[1].immediate()], None) @@ -155,26 +153,20 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { // less than 4 bytes in length. If it is, promote // the integer to a `i32` and truncate the result // back to the smaller type. - let promoted_result = emit_va_arg(self, args[0], - tcx.types.i32); + let promoted_result = emit_va_arg(self, args[0], tcx.types.i32); self.trunc(promoted_result, llret_ty) } else { emit_va_arg(self, args[0], ret_ty) } } - Primitive::F64 | - Primitive::Pointer => { + Primitive::F64 | Primitive::Pointer => { emit_va_arg(self, args[0], ret_ty) } // `va_arg` should never be used with the return type f32. - Primitive::F32 => { - bug!("the va_arg intrinsic does not work with `f32`") - } + Primitive::F32 => bug!("the va_arg intrinsic does not work with `f32`"), } } - _ => { - bug!("the va_arg intrinsic does not work with non-scalar types") - } + _ => bug!("the va_arg intrinsic does not work with non-scalar types"), } } "size_of_val" => { @@ -195,13 +187,10 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { self.const_usize(self.align_of(tp_ty).bytes()) } } - "size_of" | - "pref_align_of" | - "min_align_of" | - "needs_drop" | - "type_id" | - "type_name" => { - let ty_name = self.tcx + "size_of" | "pref_align_of" | "min_align_of" | "needs_drop" | "type_id" + | "type_name" => { + let ty_name = self + .tcx .const_eval_instance(ty::ParamEnv::reveal_all(), instance, None) .unwrap(); OperandRef::from_const(self, ty_name).immediate_or_packed_pair(self) @@ -219,7 +208,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { ty, llresult, self.const_u8(0), - self.const_usize(1) + self.const_usize(1), ); } return; @@ -240,34 +229,74 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { } "copy_nonoverlapping" => { - copy_intrinsic(self, false, false, substs.type_at(0), - args[1].immediate(), args[0].immediate(), args[2].immediate()); + copy_intrinsic( + self, + false, + false, + substs.type_at(0), + args[1].immediate(), + args[0].immediate(), + args[2].immediate(), + ); return; } "copy" => { - copy_intrinsic(self, true, false, substs.type_at(0), - args[1].immediate(), args[0].immediate(), args[2].immediate()); + copy_intrinsic( + self, + true, + false, + substs.type_at(0), + args[1].immediate(), + args[0].immediate(), + args[2].immediate(), + ); return; } "write_bytes" => { - memset_intrinsic(self, false, substs.type_at(0), - args[0].immediate(), args[1].immediate(), args[2].immediate()); + memset_intrinsic( + self, + false, + substs.type_at(0), + args[0].immediate(), + args[1].immediate(), + args[2].immediate(), + ); return; } "volatile_copy_nonoverlapping_memory" => { - copy_intrinsic(self, false, true, substs.type_at(0), - args[0].immediate(), args[1].immediate(), args[2].immediate()); + copy_intrinsic( + self, + false, + true, + substs.type_at(0), + args[0].immediate(), + args[1].immediate(), + args[2].immediate(), + ); return; } "volatile_copy_memory" => { - copy_intrinsic(self, true, true, substs.type_at(0), - args[0].immediate(), args[1].immediate(), args[2].immediate()); + copy_intrinsic( + self, + true, + true, + substs.type_at(0), + args[0].immediate(), + args[1].immediate(), + args[2].immediate(), + ); return; } "volatile_set_memory" => { - memset_intrinsic(self, true, substs.type_at(0), - args[0].immediate(), args[1].immediate(), args[2].immediate()); + memset_intrinsic( + self, + true, + substs.type_at(0), + args[0].immediate(), + args[1].immediate(), + args[2].immediate(), + ); return; } "volatile_load" | "unaligned_volatile_load" => { @@ -286,243 +315,265 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { llvm::LLVMSetAlignment(load, align); } to_immediate(self, load, self.layout_of(tp_ty)) - }, + } "volatile_store" => { let dst = args[0].deref(self.cx()); args[1].val.volatile_store(self, dst); return; - }, + } "unaligned_volatile_store" => { let dst = args[0].deref(self.cx()); args[1].val.unaligned_volatile_store(self, dst); return; - }, - "prefetch_read_data" | "prefetch_write_data" | - "prefetch_read_instruction" | "prefetch_write_instruction" => { + } + "prefetch_read_data" + | "prefetch_write_data" + | "prefetch_read_instruction" + | "prefetch_write_instruction" => { let expect = self.get_intrinsic(&("llvm.prefetch")); let (rw, cache_type) = match name { "prefetch_read_data" => (0, 1), "prefetch_write_data" => (1, 1), "prefetch_read_instruction" => (0, 0), "prefetch_write_instruction" => (1, 0), - _ => bug!() + _ => bug!(), }; - self.call(expect, &[ - args[0].immediate(), - self.const_i32(rw), - args[1].immediate(), - self.const_i32(cache_type) - ], None) - }, - "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" | - "bitreverse" | "add_with_overflow" | "sub_with_overflow" | - "mul_with_overflow" | "wrapping_add" | "wrapping_sub" | "wrapping_mul" | - "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" | - "unchecked_add" | "unchecked_sub" | "unchecked_mul" | "exact_div" | - "rotate_left" | "rotate_right" | "saturating_add" | "saturating_sub" => { + self.call( + expect, + &[ + args[0].immediate(), + self.const_i32(rw), + args[1].immediate(), + self.const_i32(cache_type), + ], + None, + ) + } + "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" + | "bitreverse" | "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" + | "wrapping_add" | "wrapping_sub" | "wrapping_mul" | "unchecked_div" + | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" | "unchecked_add" + | "unchecked_sub" | "unchecked_mul" | "exact_div" | "rotate_left" | "rotate_right" + | "saturating_add" | "saturating_sub" => { let ty = arg_tys[0]; match int_type_width_signed(ty, self) { - Some((width, signed)) => - match name { - "ctlz" | "cttz" => { - let y = self.const_bool(false); - let llfn = self.get_intrinsic( - &format!("llvm.{}.i{}", name, width), - ); - self.call(llfn, &[args[0].immediate(), y], None) - } - "ctlz_nonzero" | "cttz_nonzero" => { - let y = self.const_bool(true); - let llvm_name = &format!("llvm.{}.i{}", &name[..4], width); - let llfn = self.get_intrinsic(llvm_name); - self.call(llfn, &[args[0].immediate(), y], None) - } - "ctpop" => self.call( - self.get_intrinsic(&format!("llvm.ctpop.i{}", width)), - &[args[0].immediate()], - None - ), - "bswap" => { - if width == 8 { - args[0].immediate() // byte swap a u8/i8 is just a no-op - } else { - self.call( - self.get_intrinsic( - &format!("llvm.bswap.i{}", width), - ), - &[args[0].immediate()], - None, - ) - } - } - "bitreverse" => { + Some((width, signed)) => match name { + "ctlz" | "cttz" => { + let y = self.const_bool(false); + let llfn = self.get_intrinsic(&format!("llvm.{}.i{}", name, width)); + self.call(llfn, &[args[0].immediate(), y], None) + } + "ctlz_nonzero" | "cttz_nonzero" => { + let y = self.const_bool(true); + let llvm_name = &format!("llvm.{}.i{}", &name[..4], width); + let llfn = self.get_intrinsic(llvm_name); + self.call(llfn, &[args[0].immediate(), y], None) + } + "ctpop" => self.call( + self.get_intrinsic(&format!("llvm.ctpop.i{}", width)), + &[args[0].immediate()], + None, + ), + "bswap" => { + if width == 8 { + args[0].immediate() // byte swap a u8/i8 is just a no-op + } else { self.call( - self.get_intrinsic( - &format!("llvm.bitreverse.i{}", width), - ), + self.get_intrinsic(&format!("llvm.bswap.i{}", width)), &[args[0].immediate()], None, ) } - "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => { - let intrinsic = format!("llvm.{}{}.with.overflow.i{}", - if signed { 's' } else { 'u' }, - &name[..3], width); - let llfn = self.get_intrinsic(&intrinsic); - - // Convert `i1` to a `bool`, and write it to the out parameter - let pair = self.call(llfn, &[ - args[0].immediate(), - args[1].immediate() - ], None); + } + "bitreverse" => self.call( + self.get_intrinsic(&format!("llvm.bitreverse.i{}", width)), + &[args[0].immediate()], + None, + ), + "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => { + let intrinsic = format!( + "llvm.{}{}.with.overflow.i{}", + if signed { 's' } else { 'u' }, + &name[..3], + width + ); + let llfn = self.get_intrinsic(&intrinsic); + + // Convert `i1` to a `bool`, and write it to the out parameter + let pair = + self.call(llfn, &[args[0].immediate(), args[1].immediate()], None); + let val = self.extract_value(pair, 0); + let overflow = self.extract_value(pair, 1); + let overflow = self.zext(overflow, self.type_bool()); + + let dest = result.project_field(self, 0); + self.store(val, dest.llval, dest.align); + let dest = result.project_field(self, 1); + self.store(overflow, dest.llval, dest.align); + + return; + } + "wrapping_add" => self.add(args[0].immediate(), args[1].immediate()), + "wrapping_sub" => self.sub(args[0].immediate(), args[1].immediate()), + "wrapping_mul" => self.mul(args[0].immediate(), args[1].immediate()), + "exact_div" => { + if signed { + self.exactsdiv(args[0].immediate(), args[1].immediate()) + } else { + self.exactudiv(args[0].immediate(), args[1].immediate()) + } + } + "unchecked_div" => { + if signed { + self.sdiv(args[0].immediate(), args[1].immediate()) + } else { + self.udiv(args[0].immediate(), args[1].immediate()) + } + } + "unchecked_rem" => { + if signed { + self.srem(args[0].immediate(), args[1].immediate()) + } else { + self.urem(args[0].immediate(), args[1].immediate()) + } + } + "unchecked_shl" => self.shl(args[0].immediate(), args[1].immediate()), + "unchecked_shr" => { + if signed { + self.ashr(args[0].immediate(), args[1].immediate()) + } else { + self.lshr(args[0].immediate(), args[1].immediate()) + } + } + "unchecked_add" => { + if signed { + self.unchecked_sadd(args[0].immediate(), args[1].immediate()) + } else { + self.unchecked_uadd(args[0].immediate(), args[1].immediate()) + } + } + "unchecked_sub" => { + if signed { + self.unchecked_ssub(args[0].immediate(), args[1].immediate()) + } else { + self.unchecked_usub(args[0].immediate(), args[1].immediate()) + } + } + "unchecked_mul" => { + if signed { + self.unchecked_smul(args[0].immediate(), args[1].immediate()) + } else { + self.unchecked_umul(args[0].immediate(), args[1].immediate()) + } + } + "rotate_left" | "rotate_right" => { + let is_left = name == "rotate_left"; + let val = args[0].immediate(); + let raw_shift = args[1].immediate(); + // rotate = funnel shift with first two args the same + let llvm_name = + &format!("llvm.fsh{}.i{}", if is_left { 'l' } else { 'r' }, width); + let llfn = self.get_intrinsic(llvm_name); + self.call(llfn, &[val, val, raw_shift], None) + } + "saturating_add" | "saturating_sub" => { + let is_add = name == "saturating_add"; + let lhs = args[0].immediate(); + let rhs = args[1].immediate(); + if llvm_util::get_major_version() >= 8 { + let llvm_name = &format!( + "llvm.{}{}.sat.i{}", + if signed { 's' } else { 'u' }, + if is_add { "add" } else { "sub" }, + width + ); + let llfn = self.get_intrinsic(llvm_name); + self.call(llfn, &[lhs, rhs], None) + } else { + let llvm_name = &format!( + "llvm.{}{}.with.overflow.i{}", + if signed { 's' } else { 'u' }, + if is_add { "add" } else { "sub" }, + width + ); + let llfn = self.get_intrinsic(llvm_name); + let pair = self.call(llfn, &[lhs, rhs], None); let val = self.extract_value(pair, 0); let overflow = self.extract_value(pair, 1); - let overflow = self.zext(overflow, self.type_bool()); - - let dest = result.project_field(self, 0); - self.store(val, dest.llval, dest.align); - let dest = result.project_field(self, 1); - self.store(overflow, dest.llval, dest.align); - - return; - }, - "wrapping_add" => self.add(args[0].immediate(), args[1].immediate()), - "wrapping_sub" => self.sub(args[0].immediate(), args[1].immediate()), - "wrapping_mul" => self.mul(args[0].immediate(), args[1].immediate()), - "exact_div" => - if signed { - self.exactsdiv(args[0].immediate(), args[1].immediate()) - } else { - self.exactudiv(args[0].immediate(), args[1].immediate()) - }, - "unchecked_div" => - if signed { - self.sdiv(args[0].immediate(), args[1].immediate()) - } else { - self.udiv(args[0].immediate(), args[1].immediate()) - }, - "unchecked_rem" => - if signed { - self.srem(args[0].immediate(), args[1].immediate()) - } else { - self.urem(args[0].immediate(), args[1].immediate()) - }, - "unchecked_shl" => self.shl(args[0].immediate(), args[1].immediate()), - "unchecked_shr" => - if signed { - self.ashr(args[0].immediate(), args[1].immediate()) - } else { - self.lshr(args[0].immediate(), args[1].immediate()) - }, - "unchecked_add" => { - if signed { - self.unchecked_sadd(args[0].immediate(), args[1].immediate()) - } else { - self.unchecked_uadd(args[0].immediate(), args[1].immediate()) - } - }, - "unchecked_sub" => { - if signed { - self.unchecked_ssub(args[0].immediate(), args[1].immediate()) + let llty = self.type_ix(width); + + let limit = if signed { + let limit_lo = self + .const_uint_big(llty, (i128::MIN >> (128 - width)) as u128); + let limit_hi = self + .const_uint_big(llty, (i128::MAX >> (128 - width)) as u128); + let neg = self.icmp( + IntPredicate::IntSLT, + val, + self.const_uint(llty, 0), + ); + self.select(neg, limit_hi, limit_lo) + } else if is_add { + self.const_uint_big(llty, u128::MAX >> (128 - width)) } else { - self.unchecked_usub(args[0].immediate(), args[1].immediate()) - } - }, - "unchecked_mul" => { - if signed { - self.unchecked_smul(args[0].immediate(), args[1].immediate()) - } else { - self.unchecked_umul(args[0].immediate(), args[1].immediate()) - } - }, - "rotate_left" | "rotate_right" => { - let is_left = name == "rotate_left"; - let val = args[0].immediate(); - let raw_shift = args[1].immediate(); - // rotate = funnel shift with first two args the same - let llvm_name = &format!("llvm.fsh{}.i{}", - if is_left { 'l' } else { 'r' }, width); - let llfn = self.get_intrinsic(llvm_name); - self.call(llfn, &[val, val, raw_shift], None) - }, - "saturating_add" | "saturating_sub" => { - let is_add = name == "saturating_add"; - let lhs = args[0].immediate(); - let rhs = args[1].immediate(); - if llvm_util::get_major_version() >= 8 { - let llvm_name = &format!("llvm.{}{}.sat.i{}", - if signed { 's' } else { 'u' }, - if is_add { "add" } else { "sub" }, - width); - let llfn = self.get_intrinsic(llvm_name); - self.call(llfn, &[lhs, rhs], None) - } else { - let llvm_name = &format!("llvm.{}{}.with.overflow.i{}", - if signed { 's' } else { 'u' }, - if is_add { "add" } else { "sub" }, - width); - let llfn = self.get_intrinsic(llvm_name); - let pair = self.call(llfn, &[lhs, rhs], None); - let val = self.extract_value(pair, 0); - let overflow = self.extract_value(pair, 1); - let llty = self.type_ix(width); - - let limit = if signed { - let limit_lo = self.const_uint_big( - llty, (i128::MIN >> (128 - width)) as u128); - let limit_hi = self.const_uint_big( - llty, (i128::MAX >> (128 - width)) as u128); - let neg = self.icmp( - IntPredicate::IntSLT, val, self.const_uint(llty, 0)); - self.select(neg, limit_hi, limit_lo) - } else if is_add { - self.const_uint_big(llty, u128::MAX >> (128 - width)) - } else { - self.const_uint(llty, 0) - }; - self.select(overflow, limit, val) - } - }, - _ => bug!(), - }, + self.const_uint(llty, 0) + }; + self.select(overflow, limit, val) + } + } + _ => bug!(), + }, None => { span_invalid_monomorphization_error( - tcx.sess, span, - &format!("invalid monomorphization of `{}` intrinsic: \ - expected basic integer type, found `{}`", name, ty)); + tcx.sess, + span, + &format!( + "invalid monomorphization of `{}` intrinsic: \ + expected basic integer type, found `{}`", + name, ty + ), + ); return; } } - - }, + } "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => { match float_type_width(arg_tys[0]) { - Some(_width) => - match name { - "fadd_fast" => self.fadd_fast(args[0].immediate(), args[1].immediate()), - "fsub_fast" => self.fsub_fast(args[0].immediate(), args[1].immediate()), - "fmul_fast" => self.fmul_fast(args[0].immediate(), args[1].immediate()), - "fdiv_fast" => self.fdiv_fast(args[0].immediate(), args[1].immediate()), - "frem_fast" => self.frem_fast(args[0].immediate(), args[1].immediate()), - _ => bug!(), - }, + Some(_width) => match name { + "fadd_fast" => self.fadd_fast(args[0].immediate(), args[1].immediate()), + "fsub_fast" => self.fsub_fast(args[0].immediate(), args[1].immediate()), + "fmul_fast" => self.fmul_fast(args[0].immediate(), args[1].immediate()), + "fdiv_fast" => self.fdiv_fast(args[0].immediate(), args[1].immediate()), + "frem_fast" => self.frem_fast(args[0].immediate(), args[1].immediate()), + _ => bug!(), + }, None => { span_invalid_monomorphization_error( - tcx.sess, span, - &format!("invalid monomorphization of `{}` intrinsic: \ - expected basic float type, found `{}`", name, arg_tys[0])); + tcx.sess, + span, + &format!( + "invalid monomorphization of `{}` intrinsic: \ + expected basic float type, found `{}`", + name, arg_tys[0] + ), + ); return; } } - }, + } "float_to_int_approx_unchecked" => { if float_type_width(arg_tys[0]).is_none() { span_invalid_monomorphization_error( - tcx.sess, span, - &format!("invalid monomorphization of `float_to_int_approx_unchecked` \ + tcx.sess, + span, + &format!( + "invalid monomorphization of `float_to_int_approx_unchecked` \ intrinsic: expected basic float type, \ - found `{}`", arg_tys[0])); + found `{}`", + arg_tys[0] + ), + ); return; } match int_type_width_signed(ret_ty, self.cx) { @@ -535,35 +586,33 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { } None => { span_invalid_monomorphization_error( - tcx.sess, span, - &format!("invalid monomorphization of `float_to_int_approx_unchecked` \ + tcx.sess, + span, + &format!( + "invalid monomorphization of `float_to_int_approx_unchecked` \ intrinsic: expected basic integer type, \ - found `{}`", ret_ty)); + found `{}`", + ret_ty + ), + ); return; } } } - "discriminant_value" => { - args[0].deref(self.cx()).codegen_get_discr(self, ret_ty) - } + "discriminant_value" => args[0].deref(self.cx()).codegen_get_discr(self, ret_ty), name if name.starts_with("simd_") => { - match generic_simd_intrinsic(self, name, - callee_ty, - args, - ret_ty, llret_ty, - span) { + match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) { Ok(llval) => llval, - Err(()) => return + Err(()) => return, } } // This requires that atomic intrinsics follow a specific naming pattern: // "atomic_[_]", and no ordering means SeqCst name if name.starts_with("atomic_") => { use rustc_codegen_ssa::common::AtomicOrdering::*; - use rustc_codegen_ssa::common:: - {SynchronizationScope, AtomicRmwBinOp}; + use rustc_codegen_ssa::common::{AtomicRmwBinOp, SynchronizationScope}; let split: Vec<&str> = name.split('_').collect(); @@ -573,29 +622,31 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { 3 => match split[2] { "unordered" => (Unordered, Unordered), "relaxed" => (Monotonic, Monotonic), - "acq" => (Acquire, Acquire), - "rel" => (Release, Monotonic), - "acqrel" => (AcquireRelease, Acquire), - "failrelaxed" if is_cxchg => - (SequentiallyConsistent, Monotonic), - "failacq" if is_cxchg => - (SequentiallyConsistent, Acquire), - _ => self.sess().fatal("unknown ordering in atomic intrinsic") + "acq" => (Acquire, Acquire), + "rel" => (Release, Monotonic), + "acqrel" => (AcquireRelease, Acquire), + "failrelaxed" if is_cxchg => (SequentiallyConsistent, Monotonic), + "failacq" if is_cxchg => (SequentiallyConsistent, Acquire), + _ => self.sess().fatal("unknown ordering in atomic intrinsic"), }, 4 => match (split[2], split[3]) { - ("acq", "failrelaxed") if is_cxchg => - (Acquire, Monotonic), - ("acqrel", "failrelaxed") if is_cxchg => - (AcquireRelease, Monotonic), - _ => self.sess().fatal("unknown ordering in atomic intrinsic") + ("acq", "failrelaxed") if is_cxchg => (Acquire, Monotonic), + ("acqrel", "failrelaxed") if is_cxchg => (AcquireRelease, Monotonic), + _ => self.sess().fatal("unknown ordering in atomic intrinsic"), }, _ => self.sess().fatal("Atomic intrinsic not in correct format"), }; let invalid_monomorphization = |ty| { - span_invalid_monomorphization_error(tcx.sess, span, - &format!("invalid monomorphization of `{}` intrinsic: \ - expected basic integer type, found `{}`", name, ty)); + span_invalid_monomorphization_error( + tcx.sess, + span, + &format!( + "invalid monomorphization of `{}` intrinsic: \ + expected basic integer type, found `{}`", + name, ty + ), + ); }; match split[1] { @@ -609,7 +660,8 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { args[2].immediate(), order, failorder, - weak); + weak, + ); let val = self.extract_value(pair, 0); let success = self.extract_value(pair, 1); let success = self.zext(success, self.type_bool()); @@ -642,7 +694,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { args[1].immediate(), args[0].immediate(), order, - size + size, ); return; } else { @@ -663,18 +715,18 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { // These are all AtomicRMW ops op => { let atom_op = match op { - "xchg" => AtomicRmwBinOp::AtomicXchg, - "xadd" => AtomicRmwBinOp::AtomicAdd, - "xsub" => AtomicRmwBinOp::AtomicSub, - "and" => AtomicRmwBinOp::AtomicAnd, - "nand" => AtomicRmwBinOp::AtomicNand, - "or" => AtomicRmwBinOp::AtomicOr, - "xor" => AtomicRmwBinOp::AtomicXor, - "max" => AtomicRmwBinOp::AtomicMax, - "min" => AtomicRmwBinOp::AtomicMin, - "umax" => AtomicRmwBinOp::AtomicUMax, - "umin" => AtomicRmwBinOp::AtomicUMin, - _ => self.sess().fatal("unknown atomic operation") + "xchg" => AtomicRmwBinOp::AtomicXchg, + "xadd" => AtomicRmwBinOp::AtomicAdd, + "xsub" => AtomicRmwBinOp::AtomicSub, + "and" => AtomicRmwBinOp::AtomicAnd, + "nand" => AtomicRmwBinOp::AtomicNand, + "or" => AtomicRmwBinOp::AtomicOr, + "xor" => AtomicRmwBinOp::AtomicXor, + "max" => AtomicRmwBinOp::AtomicMax, + "min" => AtomicRmwBinOp::AtomicMin, + "umax" => AtomicRmwBinOp::AtomicUMax, + "umin" => AtomicRmwBinOp::AtomicUMin, + _ => self.sess().fatal("unknown atomic operation"), }; let ty = substs.type_at(0); @@ -683,7 +735,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { atom_op, args[0].immediate(), args[1].immediate(), - order + order, ) } else { return invalid_monomorphization(ty); @@ -725,7 +777,8 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { self.store(llval, ptr, result.align); } else { OperandRef::from_immediate_or_packed_pair(self, llval, result.layout) - .val.store(self, result); + .val + .store(self, result); } } } @@ -774,11 +827,7 @@ fn copy_intrinsic( ) { let (size, align) = bx.size_and_align_of(ty); let size = bx.mul(bx.const_usize(size.bytes()), count); - let flags = if volatile { - MemFlags::VOLATILE - } else { - MemFlags::empty() - }; + let flags = if volatile { MemFlags::VOLATILE } else { MemFlags::empty() }; if allow_overlap { bx.memmove(dst, align, src, align, size, flags); } else { @@ -792,15 +841,11 @@ fn memset_intrinsic( ty: Ty<'tcx>, dst: &'ll Value, val: &'ll Value, - count: &'ll Value + count: &'ll Value, ) { let (size, align) = bx.size_and_align_of(ty); let size = bx.mul(bx.const_usize(size.bytes()), count); - let flags = if volatile { - MemFlags::VOLATILE - } else { - MemFlags::empty() - }; + let flags = if volatile { MemFlags::VOLATILE } else { MemFlags::empty() }; bx.memset(dst, val, size, align, flags); } @@ -1014,7 +1059,7 @@ fn gen_fn<'ll, 'tcx>( output, false, hir::Unsafety::Unsafe, - Abi::Rust + Abi::Rust, )); let fn_abi = FnAbi::of_fn_ptr(cx, rust_fn_sig, &[]); let llfn = cx.declare_fn(name, &fn_abi); @@ -1045,7 +1090,7 @@ fn get_rust_try_fn<'ll, 'tcx>( tcx.mk_unit(), false, hir::Unsafety::Unsafe, - Abi::Rust + Abi::Rust, ))); let output = tcx.types.i32; let rust_try = gen_fn(cx, "__rust_try", vec![fn_ty, i8p, i8p], output, codegen); @@ -1060,7 +1105,7 @@ fn generic_simd_intrinsic( args: &[OperandRef<'tcx, &'ll Value>], ret_ty: Ty<'tcx>, llret_ty: &'ll Type, - span: Span + span: Span, ) -> Result<&'ll Value, ()> { // macros for error handling: macro_rules! emit_error { @@ -1095,14 +1140,12 @@ fn generic_simd_intrinsic( macro_rules! require_simd { ($ty: expr, $position: expr) => { require!($ty.is_simd(), "expected SIMD {} type, found non-SIMD `{}`", $position, $ty) - } + }; } let tcx = bx.tcx(); - let sig = tcx.normalize_erasing_late_bound_regions( - ty::ParamEnv::reveal_all(), - &callee_ty.fn_sig(tcx), - ); + let sig = tcx + .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &callee_ty.fn_sig(tcx)); let arg_tys = sig.inputs(); if name == "simd_select_bitmask" { @@ -1116,9 +1159,11 @@ fn generic_simd_intrinsic( }; require_simd!(arg_tys[1], "argument"); let v_len = arg_tys[1].simd_size(tcx); - require!(m_len == v_len, - "mismatched lengths: mask length `{}` != other vector length `{}`", - m_len, v_len + require!( + m_len == v_len, + "mismatched lengths: mask length `{}` != other vector length `{}`", + m_len, + v_len ); let i1 = bx.type_i1(); let i1xn = bx.type_vector(i1, m_len); @@ -1139,46 +1184,63 @@ fn generic_simd_intrinsic( "simd_le" => Some(hir::BinOpKind::Le), "simd_gt" => Some(hir::BinOpKind::Gt), "simd_ge" => Some(hir::BinOpKind::Ge), - _ => None + _ => None, }; if let Some(cmp_op) = comparison { require_simd!(ret_ty, "return"); let out_len = ret_ty.simd_size(tcx); - require!(in_len == out_len, - "expected return type with length {} (same as input type `{}`), \ + require!( + in_len == out_len, + "expected return type with length {} (same as input type `{}`), \ found `{}` with length {}", - in_len, in_ty, - ret_ty, out_len); - require!(bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer, - "expected return type with integer elements, found `{}` with non-integer `{}`", - ret_ty, - ret_ty.simd_type(tcx)); - - return Ok(compare_simd_types(bx, - args[0].immediate(), - args[1].immediate(), - in_elem, - llret_ty, - cmp_op)) + in_len, + in_ty, + ret_ty, + out_len + ); + require!( + bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer, + "expected return type with integer elements, found `{}` with non-integer `{}`", + ret_ty, + ret_ty.simd_type(tcx) + ); + + return Ok(compare_simd_types( + bx, + args[0].immediate(), + args[1].immediate(), + in_elem, + llret_ty, + cmp_op, + )); } if name.starts_with("simd_shuffle") { - let n: u64 = name["simd_shuffle".len()..].parse().unwrap_or_else(|_| - span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?")); + let n: u64 = name["simd_shuffle".len()..].parse().unwrap_or_else(|_| { + span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?") + }); require_simd!(ret_ty, "return"); let out_len = ret_ty.simd_size(tcx); - require!(out_len == n, - "expected return type of length {}, found `{}` with length {}", - n, ret_ty, out_len); - require!(in_elem == ret_ty.simd_type(tcx), - "expected return element type `{}` (element of input `{}`), \ + require!( + out_len == n, + "expected return type of length {}, found `{}` with length {}", + n, + ret_ty, + out_len + ); + require!( + in_elem == ret_ty.simd_type(tcx), + "expected return element type `{}` (element of input `{}`), \ found `{}` with element type `{}`", - in_elem, in_ty, - ret_ty, ret_ty.simd_type(tcx)); + in_elem, + in_ty, + ret_ty, + ret_ty.simd_type(tcx) + ); let total_len = u128::from(in_len) * 2; @@ -1194,8 +1256,11 @@ fn generic_simd_intrinsic( None } Some(idx) if idx >= total_len => { - emit_error!("shuffle index #{} is out of bounds (limit {})", - arg_idx, total_len); + emit_error!( + "shuffle index #{} is out of bounds (limit {})", + arg_idx, + total_len + ); None } Some(idx) => Some(bx.const_i32(idx as i32)), @@ -1204,27 +1269,39 @@ fn generic_simd_intrinsic( .collect(); let indices = match indices { Some(i) => i, - None => return Ok(bx.const_null(llret_ty)) + None => return Ok(bx.const_null(llret_ty)), }; - return Ok(bx.shuffle_vector(args[0].immediate(), - args[1].immediate(), - bx.const_vector(&indices))) + return Ok(bx.shuffle_vector( + args[0].immediate(), + args[1].immediate(), + bx.const_vector(&indices), + )); } if name == "simd_insert" { - require!(in_elem == arg_tys[2], - "expected inserted type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, arg_tys[2]); - return Ok(bx.insert_element(args[0].immediate(), - args[2].immediate(), - args[1].immediate())) + require!( + in_elem == arg_tys[2], + "expected inserted type `{}` (element of input `{}`), found `{}`", + in_elem, + in_ty, + arg_tys[2] + ); + return Ok(bx.insert_element( + args[0].immediate(), + args[2].immediate(), + args[1].immediate(), + )); } if name == "simd_extract" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return Ok(bx.extract_element(args[0].immediate(), args[1].immediate())) + require!( + ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, + in_ty, + ret_ty + ); + return Ok(bx.extract_element(args[0].immediate(), args[1].immediate())); } if name == "simd_select" { @@ -1232,13 +1309,15 @@ fn generic_simd_intrinsic( let m_len = in_len; require_simd!(arg_tys[1], "argument"); let v_len = arg_tys[1].simd_size(tcx); - require!(m_len == v_len, - "mismatched lengths: mask length `{}` != other vector length `{}`", - m_len, v_len + require!( + m_len == v_len, + "mismatched lengths: mask length `{}` != other vector length `{}`", + m_len, + v_len ); match m_elem_ty.kind { - ty::Int(_) => {}, - _ => return_error!("mask element type is `{}`, expected `i_`", m_elem_ty) + ty::Int(_) => {} + _ => return_error!("mask element type is `{}`, expected `i_`", m_elem_ty), } // truncate the mask to a vector of i1s let i1 = bx.type_i1(); @@ -1256,34 +1335,33 @@ fn generic_simd_intrinsic( // trailing bits. let expected_int_bits = in_len.max(8); match ret_ty.kind { - ty::Uint(i) if i.bit_width() == Some(expected_int_bits as usize) => (), - _ => return_error!( - "bitmask `{}`, expected `u{}`", - ret_ty, expected_int_bits - ), + ty::Uint(i) if i.bit_width() == Some(expected_int_bits as usize) => (), + _ => return_error!("bitmask `{}`, expected `u{}`", ret_ty, expected_int_bits), } // Integer vector : let (i_xn, in_elem_bitwidth) = match in_elem.kind { ty::Int(i) => ( args[0].immediate(), - i.bit_width().unwrap_or(bx.data_layout().pointer_size.bits() as _) + i.bit_width().unwrap_or(bx.data_layout().pointer_size.bits() as _), ), ty::Uint(i) => ( args[0].immediate(), - i.bit_width().unwrap_or(bx.data_layout().pointer_size.bits() as _) + i.bit_width().unwrap_or(bx.data_layout().pointer_size.bits() as _), ), _ => return_error!( "vector argument `{}`'s element type `{}`, expected integer element type", - in_ty, in_elem + in_ty, + in_elem ), }; // Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position. - let shift_indices = vec![ - bx.cx.const_int(bx.type_ix(in_elem_bitwidth as _), (in_elem_bitwidth - 1) as _); - in_len as _ - ]; + let shift_indices = + vec![ + bx.cx.const_int(bx.type_ix(in_elem_bitwidth as _), (in_elem_bitwidth - 1) as _); + in_len as _ + ]; let i_xn_msb = bx.lshr(i_xn, bx.const_vector(shift_indices.as_slice())); // Truncate vector to an let i1xn = bx.trunc(i_xn_msb, bx.type_vector(bx.type_i1(), in_len as _)); @@ -1327,22 +1405,30 @@ fn generic_simd_intrinsic( return_error!( "unsupported floating-point vector `{}` with length `{}` \ out-of-range [2, 16]", - in_ty, in_len); + in_ty, + in_len + ); } "f32" - }, + } ty::Float(f) if f.bit_width() == 64 => { if in_len < 2 || in_len > 8 { - return_error!("unsupported floating-point vector `{}` with length `{}` \ + return_error!( + "unsupported floating-point vector `{}` with length `{}` \ out-of-range [2, 8]", - in_ty, in_len); + in_ty, + in_len + ); } "f64" - }, + } ty::Float(f) => { - return_error!("unsupported element type `{}` of floating-point vector `{}`", - f.name_str(), in_ty); - }, + return_error!( + "unsupported element type `{}` of floating-point vector `{}`", + f.name_str(), + in_ty + ); + } _ => { return_error!("`{}` is not a floating-point type", in_ty); } @@ -1350,9 +1436,8 @@ fn generic_simd_intrinsic( let llvm_name = &format!("llvm.{0}.v{1}{2}", name, in_len, ety); let intrinsic = bx.get_intrinsic(&llvm_name); - let c = bx.call(intrinsic, - &args.iter().map(|arg| arg.immediate()).collect::>(), - None); + let c = + bx.call(intrinsic, &args.iter().map(|arg| arg.immediate()).collect::>(), None); unsafe { llvm::LLVMRustSetHasUnsafeAlgebra(c) }; Ok(c) } @@ -1416,13 +1501,17 @@ fn generic_simd_intrinsic( } } - fn llvm_vector_ty(cx: &CodegenCx<'ll, '_>, elem_ty: Ty<'_>, vec_len: u64, - mut no_pointers: usize) -> &'ll Type { + fn llvm_vector_ty( + cx: &CodegenCx<'ll, '_>, + elem_ty: Ty<'_>, + vec_len: u64, + mut no_pointers: usize, + ) -> &'ll Type { // FIXME: use cx.layout_of(ty).llvm_type() ? let mut elem_ty = match elem_ty.kind { - ty::Int(v) => cx.type_int_from_ty( v), - ty::Uint(v) => cx.type_uint_from_ty( v), - ty::Float(v) => cx.type_float_from_ty( v), + ty::Int(v) => cx.type_int_from_ty(v), + ty::Uint(v) => cx.type_uint_from_ty(v), + ty::Float(v) => cx.type_float_from_ty(v), _ => unreachable!(), }; while no_pointers > 0 { @@ -1432,7 +1521,6 @@ fn generic_simd_intrinsic( cx.type_vector(elem_ty, vec_len) } - if name == "simd_gather" { // simd_gather(values: , pointers: , // mask: ) -> @@ -1447,19 +1535,29 @@ fn generic_simd_intrinsic( require_simd!(ret_ty, "return"); // Of the same length: - require!(in_len == arg_tys[1].simd_size(tcx), - "expected {} argument with length {} (same as input type `{}`), \ - found `{}` with length {}", "second", in_len, in_ty, arg_tys[1], - arg_tys[1].simd_size(tcx)); - require!(in_len == arg_tys[2].simd_size(tcx), - "expected {} argument with length {} (same as input type `{}`), \ - found `{}` with length {}", "third", in_len, in_ty, arg_tys[2], - arg_tys[2].simd_size(tcx)); + require!( + in_len == arg_tys[1].simd_size(tcx), + "expected {} argument with length {} (same as input type `{}`), \ + found `{}` with length {}", + "second", + in_len, + in_ty, + arg_tys[1], + arg_tys[1].simd_size(tcx) + ); + require!( + in_len == arg_tys[2].simd_size(tcx), + "expected {} argument with length {} (same as input type `{}`), \ + found `{}` with length {}", + "third", + in_len, + in_ty, + arg_tys[2], + arg_tys[2].simd_size(tcx) + ); // The return type must match the first argument type - require!(ret_ty == in_ty, - "expected return type `{}`, found `{}`", - in_ty, ret_ty); + require!(ret_ty == in_ty, "expected return type `{}`, found `{}`", in_ty, ret_ty); // This counts how many pointers fn ptr_count(t: Ty<'_>) -> usize { @@ -1480,14 +1578,22 @@ fn generic_simd_intrinsic( // The second argument must be a simd vector with an element type that's a pointer // to the element type of the first argument let (pointer_count, underlying_ty) = match arg_tys[1].simd_type(tcx).kind { - ty::RawPtr(p) if p.ty == in_elem => (ptr_count(arg_tys[1].simd_type(tcx)), - non_ptr(arg_tys[1].simd_type(tcx))), + ty::RawPtr(p) if p.ty == in_elem => { + (ptr_count(arg_tys[1].simd_type(tcx)), non_ptr(arg_tys[1].simd_type(tcx))) + } _ => { - require!(false, "expected element type `{}` of second argument `{}` \ + require!( + false, + "expected element type `{}` of second argument `{}` \ to be a pointer to the element type `{}` of the first \ argument `{}`, found `{}` != `*_ {}`", - arg_tys[1].simd_type(tcx), arg_tys[1], in_elem, in_ty, - arg_tys[1].simd_type(tcx), in_elem); + arg_tys[1].simd_type(tcx), + arg_tys[1], + in_elem, + in_ty, + arg_tys[1].simd_type(tcx), + in_elem + ); unreachable!(); } }; @@ -1499,9 +1605,13 @@ fn generic_simd_intrinsic( match arg_tys[2].simd_type(tcx).kind { ty::Int(_) => (), _ => { - require!(false, "expected element type `{}` of third argument `{}` \ + require!( + false, + "expected element type `{}` of third argument `{}` \ to be a signed integer type", - arg_tys[2].simd_type(tcx), arg_tys[2]); + arg_tys[2].simd_type(tcx), + arg_tys[2] + ); } } @@ -1524,17 +1634,17 @@ fn generic_simd_intrinsic( let llvm_elem_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count - 1); let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1); - let llvm_intrinsic = format!("llvm.masked.gather.{}.{}", - llvm_elem_vec_str, llvm_pointer_vec_str); - let f = bx.declare_cfn(&llvm_intrinsic, - bx.type_func(&[ - llvm_pointer_vec_ty, - alignment_ty, - mask_ty, - llvm_elem_vec_ty], llvm_elem_vec_ty)); + let llvm_intrinsic = + format!("llvm.masked.gather.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str); + let f = bx.declare_cfn( + &llvm_intrinsic, + bx.type_func( + &[llvm_pointer_vec_ty, alignment_ty, mask_ty, llvm_elem_vec_ty], + llvm_elem_vec_ty, + ), + ); llvm::SetUnnamedAddr(f, false); - let v = bx.call(f, &[args[1].immediate(), alignment, mask, args[0].immediate()], - None); + let v = bx.call(f, &[args[1].immediate(), alignment, mask, args[0].immediate()], None); return Ok(v); } @@ -1551,14 +1661,26 @@ fn generic_simd_intrinsic( require_simd!(arg_tys[2], "third"); // Of the same length: - require!(in_len == arg_tys[1].simd_size(tcx), - "expected {} argument with length {} (same as input type `{}`), \ - found `{}` with length {}", "second", in_len, in_ty, arg_tys[1], - arg_tys[1].simd_size(tcx)); - require!(in_len == arg_tys[2].simd_size(tcx), - "expected {} argument with length {} (same as input type `{}`), \ - found `{}` with length {}", "third", in_len, in_ty, arg_tys[2], - arg_tys[2].simd_size(tcx)); + require!( + in_len == arg_tys[1].simd_size(tcx), + "expected {} argument with length {} (same as input type `{}`), \ + found `{}` with length {}", + "second", + in_len, + in_ty, + arg_tys[1], + arg_tys[1].simd_size(tcx) + ); + require!( + in_len == arg_tys[2].simd_size(tcx), + "expected {} argument with length {} (same as input type `{}`), \ + found `{}` with length {}", + "third", + in_len, + in_ty, + arg_tys[2], + arg_tys[2].simd_size(tcx) + ); // This counts how many pointers fn ptr_count(t: Ty<'_>) -> usize { @@ -1579,15 +1701,22 @@ fn generic_simd_intrinsic( // The second argument must be a simd vector with an element type that's a pointer // to the element type of the first argument let (pointer_count, underlying_ty) = match arg_tys[1].simd_type(tcx).kind { - ty::RawPtr(p) if p.ty == in_elem && p.mutbl == hir::Mutability::Mut - => (ptr_count(arg_tys[1].simd_type(tcx)), - non_ptr(arg_tys[1].simd_type(tcx))), + ty::RawPtr(p) if p.ty == in_elem && p.mutbl == hir::Mutability::Mut => { + (ptr_count(arg_tys[1].simd_type(tcx)), non_ptr(arg_tys[1].simd_type(tcx))) + } _ => { - require!(false, "expected element type `{}` of second argument `{}` \ + require!( + false, + "expected element type `{}` of second argument `{}` \ to be a pointer to the element type `{}` of the first \ argument `{}`, found `{}` != `*mut {}`", - arg_tys[1].simd_type(tcx), arg_tys[1], in_elem, in_ty, - arg_tys[1].simd_type(tcx), in_elem); + arg_tys[1].simd_type(tcx), + arg_tys[1], + in_elem, + in_ty, + arg_tys[1].simd_type(tcx), + in_elem + ); unreachable!(); } }; @@ -1599,9 +1728,13 @@ fn generic_simd_intrinsic( match arg_tys[2].simd_type(tcx).kind { ty::Int(_) => (), _ => { - require!(false, "expected element type `{}` of third argument `{}` \ + require!( + false, + "expected element type `{}` of third argument `{}` \ to be a signed integer type", - arg_tys[2].simd_type(tcx), arg_tys[2]); + arg_tys[2].simd_type(tcx), + arg_tys[2] + ); } } @@ -1626,25 +1759,27 @@ fn generic_simd_intrinsic( let llvm_elem_vec_ty = llvm_vector_ty(bx, underlying_ty, in_len, pointer_count - 1); let llvm_elem_vec_str = llvm_vector_str(underlying_ty, in_len, pointer_count - 1); - let llvm_intrinsic = format!("llvm.masked.scatter.{}.{}", - llvm_elem_vec_str, llvm_pointer_vec_str); - let f = bx.declare_cfn(&llvm_intrinsic, - bx.type_func(&[llvm_elem_vec_ty, - llvm_pointer_vec_ty, - alignment_ty, - mask_ty], ret_t)); + let llvm_intrinsic = + format!("llvm.masked.scatter.{}.{}", llvm_elem_vec_str, llvm_pointer_vec_str); + let f = bx.declare_cfn( + &llvm_intrinsic, + bx.type_func(&[llvm_elem_vec_ty, llvm_pointer_vec_ty, alignment_ty, mask_ty], ret_t), + ); llvm::SetUnnamedAddr(f, false); - let v = bx.call(f, &[args[0].immediate(), args[1].immediate(), alignment, mask], - None); + let v = bx.call(f, &[args[0].immediate(), args[1].immediate(), alignment, mask], None); return Ok(v); } macro_rules! arith_red { ($name:tt : $integer_reduce:ident, $float_reduce:ident, $ordered:expr) => { if name == $name { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); + require!( + ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, + in_ty, + ret_ty + ); return match in_elem.kind { ty::Int(_) | ty::Uint(_) => { let r = bx.$integer_reduce(args[0].immediate()); @@ -1659,7 +1794,7 @@ fn generic_simd_intrinsic( } else { Ok(bx.$integer_reduce(args[0].immediate())) } - }, + } ty::Float(f) => { let acc = if $ordered { // ordered arithmetic reductions take an accumulator @@ -1670,25 +1805,29 @@ fn generic_simd_intrinsic( match f.bit_width() { 32 => bx.const_real(bx.type_f32(), identity_acc), 64 => bx.const_real(bx.type_f64(), identity_acc), - v => { - return_error!(r#" + v => return_error!( + r#" unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, - $name, in_ty, in_elem, v, ret_ty - ) - } + $name, + in_ty, + in_elem, + v, + ret_ty + ), } }; Ok(bx.$float_reduce(acc, args[0].immediate())) } - _ => { - return_error!( - "unsupported {} from `{}` with element `{}` to `{}`", - $name, in_ty, in_elem, ret_ty - ) - }, - } + _ => return_error!( + "unsupported {} from `{}` with element `{}` to `{}`", + $name, + in_ty, + in_elem, + ret_ty + ), + }; } - } + }; } arith_red!("simd_reduce_add_ordered": vector_reduce_add, vector_reduce_fadd, true); @@ -1699,27 +1838,27 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, macro_rules! minmax_red { ($name:tt: $int_red:ident, $float_red:ident) => { if name == $name { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); + require!( + ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, + in_ty, + ret_ty + ); return match in_elem.kind { - ty::Int(_i) => { - Ok(bx.$int_red(args[0].immediate(), true)) - }, - ty::Uint(_u) => { - Ok(bx.$int_red(args[0].immediate(), false)) - }, - ty::Float(_f) => { - Ok(bx.$float_red(args[0].immediate())) - } - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - $name, in_ty, in_elem, ret_ty) - }, - } + ty::Int(_i) => Ok(bx.$int_red(args[0].immediate(), true)), + ty::Uint(_u) => Ok(bx.$int_red(args[0].immediate(), false)), + ty::Float(_f) => Ok(bx.$float_red(args[0].immediate())), + _ => return_error!( + "unsupported {} from `{}` with element `{}` to `{}`", + $name, + in_ty, + in_elem, + ret_ty + ), + }; } - - } + }; } minmax_red!("simd_reduce_min": vector_reduce_min, vector_reduce_fmin); @@ -1732,17 +1871,24 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, ($name:tt : $red:ident, $boolean:expr) => { if name == $name { let input = if !$boolean { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); + require!( + ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, + in_ty, + ret_ty + ); args[0].immediate() } else { match in_elem.kind { - ty::Int(_) | ty::Uint(_) => {}, - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - $name, in_ty, in_elem, ret_ty) - } + ty::Int(_) | ty::Uint(_) => {} + _ => return_error!( + "unsupported {} from `{}` with element `{}` to `{}`", + $name, + in_ty, + in_elem, + ret_ty + ), } // boolean reductions operate on vectors of i1s: @@ -1753,21 +1899,18 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, return match in_elem.kind { ty::Int(_) | ty::Uint(_) => { let r = bx.$red(input); - Ok( - if !$boolean { - r - } else { - bx.zext(r, bx.type_bool()) - } - ) - }, - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - $name, in_ty, in_elem, ret_ty) - }, - } + Ok(if !$boolean { r } else { bx.zext(r, bx.type_bool()) }) + } + _ => return_error!( + "unsupported {} from `{}` with element `{}` to `{}`", + $name, + in_ty, + in_elem, + ret_ty + ), + }; } - } + }; } bitwise_red!("simd_reduce_and": vector_reduce_and, false); @@ -1779,17 +1922,27 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, if name == "simd_cast" { require_simd!(ret_ty, "return"); let out_len = ret_ty.simd_size(tcx); - require!(in_len == out_len, - "expected return type with length {} (same as input type `{}`), \ + require!( + in_len == out_len, + "expected return type with length {} (same as input type `{}`), \ found `{}` with length {}", - in_len, in_ty, - ret_ty, out_len); + in_len, + in_ty, + ret_ty, + out_len + ); // casting cares about nominal type, not just structural type let out_elem = ret_ty.simd_type(tcx); - if in_elem == out_elem { return Ok(args[0].immediate()); } + if in_elem == out_elem { + return Ok(args[0].immediate()); + } - enum Style { Float, Int(/* is signed? */ bool), Unsupported } + enum Style { + Float, + Int(/* is signed? */ bool), + Unsupported, + } let (in_style, in_width) = match in_elem.kind { // vectors of pointer-sized integers should've been @@ -1797,13 +1950,13 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, ty::Int(i) => (Style::Int(true), i.bit_width().unwrap()), ty::Uint(u) => (Style::Int(false), u.bit_width().unwrap()), ty::Float(f) => (Style::Float, f.bit_width()), - _ => (Style::Unsupported, 0) + _ => (Style::Unsupported, 0), }; let (out_style, out_width) = match out_elem.kind { ty::Int(i) => (Style::Int(true), i.bit_width().unwrap()), ty::Uint(u) => (Style::Int(false), u.bit_width().unwrap()), ty::Float(f) => (Style::Float, f.bit_width()), - _ => (Style::Unsupported, 0) + _ => (Style::Unsupported, 0), }; match (in_style, out_style) { @@ -1811,40 +1964,46 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, return Ok(match in_width.cmp(&out_width) { Ordering::Greater => bx.trunc(args[0].immediate(), llret_ty), Ordering::Equal => args[0].immediate(), - Ordering::Less => if in_is_signed { - bx.sext(args[0].immediate(), llret_ty) - } else { - bx.zext(args[0].immediate(), llret_ty) + Ordering::Less => { + if in_is_signed { + bx.sext(args[0].immediate(), llret_ty) + } else { + bx.zext(args[0].immediate(), llret_ty) + } } - }) + }); } (Style::Int(in_is_signed), Style::Float) => { return Ok(if in_is_signed { bx.sitofp(args[0].immediate(), llret_ty) } else { bx.uitofp(args[0].immediate(), llret_ty) - }) + }); } (Style::Float, Style::Int(out_is_signed)) => { return Ok(if out_is_signed { bx.fptosi(args[0].immediate(), llret_ty) } else { bx.fptoui(args[0].immediate(), llret_ty) - }) + }); } (Style::Float, Style::Float) => { return Ok(match in_width.cmp(&out_width) { Ordering::Greater => bx.fptrunc(args[0].immediate(), llret_ty), Ordering::Equal => args[0].immediate(), - Ordering::Less => bx.fpext(args[0].immediate(), llret_ty) - }) + Ordering::Less => bx.fpext(args[0].immediate(), llret_ty), + }); } - _ => {/* Unsupported. Fallthrough. */} + _ => { /* Unsupported. Fallthrough. */ } } - require!(false, - "unsupported cast from `{}` with element `{}` to `{}` with element `{}`", - in_ty, in_elem, - ret_ty, out_elem); + require!( + false, + "unsupported cast from `{}` with element `{}` to `{}` with element `{}`", + in_ty, + in_elem, + ret_ty, + out_elem + ); } macro_rules! arith { ($($name: ident: $($($p: ident),* => $call: ident),*;)*) => { @@ -1884,23 +2043,14 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, let is_add = name == "simd_saturating_add"; let ptr_bits = bx.tcx().data_layout.pointer_size.bits() as _; let (signed, elem_width, elem_ty) = match in_elem.kind { - ty::Int(i) => - ( - true, - i.bit_width().unwrap_or(ptr_bits), - bx.cx.type_int_from_ty(i) - ), - ty::Uint(i) => - ( - false, - i.bit_width().unwrap_or(ptr_bits), - bx.cx.type_uint_from_ty(i) - ), + ty::Int(i) => (true, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_int_from_ty(i)), + ty::Uint(i) => (false, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_uint_from_ty(i)), _ => { return_error!( "expected element type `{}` of vector type `{}` \ to be a signed or unsigned integer type", - arg_tys[0].simd_type(tcx), arg_tys[0] + arg_tys[0].simd_type(tcx), + arg_tys[0] ); } }; @@ -1908,14 +2058,12 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, "llvm.{}{}.sat.v{}i{}", if signed { 's' } else { 'u' }, if is_add { "add" } else { "sub" }, - in_len, elem_width + in_len, + elem_width ); let vec_ty = bx.cx.type_vector(elem_ty, in_len as u64); - let f = bx.declare_cfn( - &llvm_intrinsic, - bx.type_func(&[vec_ty, vec_ty], vec_ty) - ); + let f = bx.declare_cfn(&llvm_intrinsic, bx.type_func(&[vec_ty, vec_ty], vec_ty)); llvm::SetUnnamedAddr(f, false); let v = bx.call(f, &[lhs, rhs], None); return Ok(v); @@ -1930,22 +2078,28 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, // stuffs. fn int_type_width_signed(ty: Ty<'_>, cx: &CodegenCx<'_, '_>) -> Option<(u64, bool)> { match ty.kind { - ty::Int(t) => Some((match t { - ast::IntTy::Isize => cx.tcx.sess.target.ptr_width as u64, - ast::IntTy::I8 => 8, - ast::IntTy::I16 => 16, - ast::IntTy::I32 => 32, - ast::IntTy::I64 => 64, - ast::IntTy::I128 => 128, - }, true)), - ty::Uint(t) => Some((match t { - ast::UintTy::Usize => cx.tcx.sess.target.ptr_width as u64, - ast::UintTy::U8 => 8, - ast::UintTy::U16 => 16, - ast::UintTy::U32 => 32, - ast::UintTy::U64 => 64, - ast::UintTy::U128 => 128, - }, false)), + ty::Int(t) => Some(( + match t { + ast::IntTy::Isize => cx.tcx.sess.target.ptr_width as u64, + ast::IntTy::I8 => 8, + ast::IntTy::I16 => 16, + ast::IntTy::I32 => 32, + ast::IntTy::I64 => 64, + ast::IntTy::I128 => 128, + }, + true, + )), + ty::Uint(t) => Some(( + match t { + ast::UintTy::Usize => cx.tcx.sess.target.ptr_width as u64, + ast::UintTy::U8 => 8, + ast::UintTy::U16 => 16, + ast::UintTy::U32 => 32, + ast::UintTy::U64 => 64, + ast::UintTy::U128 => 128, + }, + false, + )), _ => None, } } diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 1e1d74cfa9a40..2c1c9427e8c36 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -5,7 +5,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] - #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] @@ -21,25 +20,25 @@ #![feature(static_nobundle)] #![feature(trusted_len)] -use back::write::{create_target_machine, create_informational_target_machine}; +use back::write::{create_informational_target_machine, create_target_machine}; use syntax_pos::symbol::Symbol; +pub use llvm_util::target_features; +use rustc::dep_graph::WorkProduct; +use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; +use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig}; use rustc_codegen_ssa::traits::*; -use rustc_codegen_ssa::back::write::{CodegenContext, ModuleConfig, FatLTOInput}; -use rustc_codegen_ssa::back::lto::{SerializedModule, LtoModuleCodegen, ThinModule}; use rustc_codegen_ssa::CompiledModule; use rustc_errors::{FatalError, Handler}; -use rustc::dep_graph::WorkProduct; -use syntax::expand::allocator::AllocatorKind; -pub use llvm_util::target_features; use std::any::Any; -use std::sync::Arc; use std::ffi::CStr; +use std::sync::Arc; +use syntax::expand::allocator::AllocatorKind; use rustc::dep_graph::DepGraph; use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; +use rustc::session::config::{OptLevel, OutputFilenames, OutputType, PrintRequest}; use rustc::session::Session; -use rustc::session::config::{OutputFilenames, OutputType, PrintRequest, OptLevel}; use rustc::ty::{self, TyCtxt}; use rustc::util::common::ErrorReported; use rustc_codegen_ssa::ModuleCodegen; @@ -67,15 +66,19 @@ mod declare; mod intrinsic; // The following is a work around that replaces `pub mod llvm;` and that fixes issue 53912. -#[path = "llvm/mod.rs"] mod llvm_; pub mod llvm { pub use super::llvm_::*; } +#[path = "llvm/mod.rs"] +mod llvm_; +pub mod llvm { + pub use super::llvm_::*; +} mod llvm_util; mod metadata; mod mono_item; mod type_; mod type_of; -mod value; mod va_arg; +mod value; #[derive(Clone)] pub struct LlvmCodegenBackend(()); @@ -102,7 +105,8 @@ impl ExtraBackendMethods for LlvmCodegenBackend { unsafe { allocator::codegen(tcx, mods, kind) } } fn compile_codegen_unit( - &self, tcx: TyCtxt<'_>, + &self, + tcx: TyCtxt<'_>, cgu_name: Symbol, tx: &std::sync::mpsc::Sender>, ) { @@ -112,9 +116,8 @@ impl ExtraBackendMethods for LlvmCodegenBackend { &self, sess: &Session, optlvl: OptLevel, - find_features: bool - ) -> Arc - Result<&'static mut llvm::TargetMachine, String> + Send + Sync> { + find_features: bool, + ) -> Arc Result<&'static mut llvm::TargetMachine, String> + Send + Sync> { back::write::target_machine_factory(sess, optlvl, find_features) } fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str { @@ -130,7 +133,9 @@ impl WriteBackendMethods for LlvmCodegenBackend { type ThinData = back::lto::ThinData; type ThinBuffer = back::lto::ThinBuffer; fn print_pass_timings(&self) { - unsafe { llvm::LLVMRustPrintPassTimings(); } + unsafe { + llvm::LLVMRustPrintPassTimings(); + } } fn run_fat_lto( cgcx: &CodegenContext, @@ -168,21 +173,17 @@ impl WriteBackendMethods for LlvmCodegenBackend { ) -> Result { back::write::codegen(cgcx, diag_handler, module, config) } - fn prepare_thin( - module: ModuleCodegen - ) -> (String, Self::ThinBuffer) { + fn prepare_thin(module: ModuleCodegen) -> (String, Self::ThinBuffer) { back::lto::prepare_thin(module) } - fn serialize_module( - module: ModuleCodegen - ) -> (String, Self::ModuleBuffer) { + fn serialize_module(module: ModuleCodegen) -> (String, Self::ModuleBuffer) { (module.name, back::lto::ModuleBuffer::new(module.module_llvm.llmod())) } fn run_lto_pass_manager( cgcx: &CodegenContext, module: &ModuleCodegen, config: &ModuleConfig, - thin: bool + thin: bool, ) { back::lto::run_pass_manager(cgcx, module, config, thin) } @@ -213,14 +214,14 @@ impl CodegenBackend for LlvmCodegenBackend { } PrintRequest::CodeModels => { println!("Available code models:"); - for &(name, _) in back::write::CODE_GEN_MODEL_ARGS.iter(){ + for &(name, _) in back::write::CODE_GEN_MODEL_ARGS.iter() { println!(" {}", name); } println!(); } PrintRequest::TlsModels => { println!("Available TLS models:"); - for &(name, _) in back::write::TLS_MODEL_ARGS.iter(){ + for &(name, _) in back::write::TLS_MODEL_ARGS.iter() { println!(" {}", name); } println!(); @@ -260,7 +261,11 @@ impl CodegenBackend for LlvmCodegenBackend { need_metadata_module: bool, ) -> Box { box rustc_codegen_ssa::base::codegen_crate( - LlvmCodegenBackend(()), tcx, metadata, need_metadata_module) + LlvmCodegenBackend(()), + tcx, + metadata, + need_metadata_module, + ) } fn join_codegen_and_link( @@ -271,23 +276,26 @@ impl CodegenBackend for LlvmCodegenBackend { outputs: &OutputFilenames, ) -> Result<(), ErrorReported> { use rustc::util::common::time; - let (codegen_results, work_products) = - ongoing_codegen.downcast:: - >() - .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") - .join(sess); + let (codegen_results, work_products) = ongoing_codegen + .downcast::>() + .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") + .join(sess); if sess.opts.debugging_opts.incremental_info { rustc_codegen_ssa::back::write::dump_incremental_data(&codegen_results); } - time(sess, - "serialize work products", - move || rustc_incremental::save_work_product_index(sess, &dep_graph, work_products)); + time(sess, "serialize work products", move || { + rustc_incremental::save_work_product_index(sess, &dep_graph, work_products) + }); sess.compile_status()?; - if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe || - i == OutputType::Metadata) { + if !sess + .opts + .output_types + .keys() + .any(|&i| i == OutputType::Exe || i == OutputType::Metadata) + { return Ok(()); } @@ -296,8 +304,8 @@ impl CodegenBackend for LlvmCodegenBackend { time(sess, "linking", || { let _prof_timer = sess.prof.generic_activity("link_crate"); - use rustc_codegen_ssa::back::link::link_binary; use crate::back::archive::LlvmArchiveBuilder; + use rustc_codegen_ssa::back::link::link_binary; let target_cpu = crate::llvm_util::target_cpu(sess); link_binary::>( @@ -323,19 +331,15 @@ pub struct ModuleLlvm { tm: &'static mut llvm::TargetMachine, } -unsafe impl Send for ModuleLlvm { } -unsafe impl Sync for ModuleLlvm { } +unsafe impl Send for ModuleLlvm {} +unsafe impl Sync for ModuleLlvm {} impl ModuleLlvm { fn new(tcx: TyCtxt<'_>, mod_name: &str) -> Self { unsafe { let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names()); let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _; - ModuleLlvm { - llmod_raw, - llcx, - tm: create_target_machine(tcx, false), - } + ModuleLlvm { llmod_raw, llcx, tm: create_target_machine(tcx, false) } } } @@ -364,22 +368,16 @@ impl ModuleLlvm { Ok(m) => m, Err(e) => { handler.struct_err(&e).emit(); - return Err(FatalError) + return Err(FatalError); } }; - Ok(ModuleLlvm { - llmod_raw, - llcx, - tm, - }) + Ok(ModuleLlvm { llmod_raw, llcx, tm }) } } fn llmod(&self) -> &llvm::Module { - unsafe { - &*self.llmod_raw - } + unsafe { &*self.llmod_raw } } } diff --git a/src/librustc_codegen_llvm/llvm/archive_ro.rs b/src/librustc_codegen_llvm/llvm/archive_ro.rs index 0a8bb3250c5d5..ab9df4162472c 100644 --- a/src/librustc_codegen_llvm/llvm/archive_ro.rs +++ b/src/librustc_codegen_llvm/llvm/archive_ro.rs @@ -1,9 +1,9 @@ //! A wrapper around LLVM's archive (.a) code +use rustc_fs_util::path_to_c_string; use std::path::Path; use std::slice; use std::str; -use rustc_fs_util::path_to_c_string; pub struct ArchiveRO { pub raw: &'static mut super::Archive, @@ -37,11 +37,7 @@ impl ArchiveRO { } pub fn iter(&self) -> Iter<'_> { - unsafe { - Iter { - raw: super::LLVMRustArchiveIteratorNew(self.raw), - } - } + unsafe { Iter { raw: super::LLVMRustArchiveIteratorNew(self.raw) } } } } diff --git a/src/librustc_codegen_llvm/llvm/diagnostic.rs b/src/librustc_codegen_llvm/llvm/diagnostic.rs index 04e65ac423300..4347cd06532da 100644 --- a/src/librustc_codegen_llvm/llvm/diagnostic.rs +++ b/src/librustc_codegen_llvm/llvm/diagnostic.rs @@ -1,10 +1,10 @@ //! LLVM diagnostic reports. -pub use self::OptimizationDiagnosticKind::*; pub use self::Diagnostic::*; +pub use self::OptimizationDiagnosticKind::*; -use libc::c_uint; use crate::value::Value; +use libc::c_uint; use super::{DiagnosticInfo, Twine}; @@ -43,29 +43,31 @@ pub struct OptimizationDiagnostic<'ll> { } impl OptimizationDiagnostic<'ll> { - unsafe fn unpack( - kind: OptimizationDiagnosticKind, - di: &'ll DiagnosticInfo, - ) -> Self { + unsafe fn unpack(kind: OptimizationDiagnosticKind, di: &'ll DiagnosticInfo) -> Self { let mut function = None; let mut line = 0; let mut column = 0; let mut message = None; let mut filename = None; - let pass_name = super::build_string(|pass_name| - message = super::build_string(|message| - filename = super::build_string(|filename| - super::LLVMRustUnpackOptimizationDiagnostic(di, - pass_name, - &mut function, - &mut line, - &mut column, - filename, - message) - ).ok() - ).ok() - ).ok(); + let pass_name = super::build_string(|pass_name| { + message = super::build_string(|message| { + filename = super::build_string(|filename| { + super::LLVMRustUnpackOptimizationDiagnostic( + di, + pass_name, + &mut function, + &mut line, + &mut column, + filename, + message, + ) + }) + .ok() + }) + .ok() + }) + .ok(); let mut filename = filename.unwrap_or_default(); if filename.is_empty() { @@ -79,7 +81,7 @@ impl OptimizationDiagnostic<'ll> { line, column, filename, - message: message.expect("got a non-UTF8 OptimizationDiagnostic message from LLVM") + message: message.expect("got a non-UTF8 OptimizationDiagnostic message from LLVM"), } } } @@ -97,18 +99,9 @@ impl InlineAsmDiagnostic<'ll> { let mut message = None; let mut instruction = None; - super::LLVMRustUnpackInlineAsmDiagnostic( - di, - &mut cookie, - &mut message, - &mut instruction, - ); - - InlineAsmDiagnostic { - cookie, - message: message.unwrap(), - instruction, - } + super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut cookie, &mut message, &mut instruction); + + InlineAsmDiagnostic { cookie, message: message.unwrap(), instruction } } } @@ -156,12 +149,8 @@ impl Diagnostic<'ll> { Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di)) } - Dk::PGOProfile => { - PGO(di) - } - Dk::Linker => { - Linker(di) - } + Dk::PGOProfile => PGO(di), + Dk::Linker => Linker(di), _ => UnknownDiagnostic(di), } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index b8a1003b11866..875b2c47b3b36 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -2,13 +2,12 @@ #![allow(non_upper_case_globals)] use super::debuginfo::{ - DIBuilder, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType, - DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable, - DIGlobalVariableExpression, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator, - DINameSpace, DIFlags, DISPFlags, DebugEmissionKind, + DIArray, DIBasicType, DIBuilder, DICompositeType, DIDerivedType, DIDescriptor, DIEnumerator, + DIFile, DIFlags, DIGlobalVariableExpression, DILexicalBlock, DINameSpace, DISPFlags, DIScope, + DISubprogram, DISubrange, DITemplateTypeParameter, DIType, DIVariable, DebugEmissionKind, }; -use libc::{c_uint, c_int, size_t, c_char}; +use libc::{c_char, c_int, c_uint, size_t}; use libc::{c_ulonglong, c_void}; use std::marker::PhantomData; @@ -91,32 +90,32 @@ pub enum DLLStorageClass { #[repr(C)] #[derive(Copy, Clone, Debug)] pub enum Attribute { - AlwaysInline = 0, - ByVal = 1, - Cold = 2, - InlineHint = 3, - MinSize = 4, - Naked = 5, - NoAlias = 6, - NoCapture = 7, - NoInline = 8, - NonNull = 9, - NoRedZone = 10, - NoReturn = 11, - NoUnwind = 12, + AlwaysInline = 0, + ByVal = 1, + Cold = 2, + InlineHint = 3, + MinSize = 4, + Naked = 5, + NoAlias = 6, + NoCapture = 7, + NoInline = 8, + NonNull = 9, + NoRedZone = 10, + NoReturn = 11, + NoUnwind = 12, OptimizeForSize = 13, - ReadOnly = 14, - SExt = 15, - StructRet = 16, - UWTable = 17, - ZExt = 18, - InReg = 19, - SanitizeThread = 20, + ReadOnly = 14, + SExt = 15, + StructRet = 16, + UWTable = 17, + ZExt = 18, + InReg = 19, + SanitizeThread = 20, SanitizeAddress = 21, - SanitizeMemory = 22, - NonLazyBind = 23, - OptimizeNone = 24, - ReturnsTwice = 25, + SanitizeMemory = 22, + NonLazyBind = 23, + OptimizeNone = 24, + ReturnsTwice = 25, } /// LLVMIntPredicate @@ -177,8 +176,9 @@ pub enum RealPredicate { impl RealPredicate { pub fn from_generic(realpred: rustc_codegen_ssa::common::RealPredicate) -> Self { match realpred { - rustc_codegen_ssa::common::RealPredicate::RealPredicateFalse => - RealPredicate::RealPredicateFalse, + rustc_codegen_ssa::common::RealPredicate::RealPredicateFalse => { + RealPredicate::RealPredicateFalse + } rustc_codegen_ssa::common::RealPredicate::RealOEQ => RealPredicate::RealOEQ, rustc_codegen_ssa::common::RealPredicate::RealOGT => RealPredicate::RealOGT, rustc_codegen_ssa::common::RealPredicate::RealOGE => RealPredicate::RealOGE, @@ -193,8 +193,9 @@ impl RealPredicate { rustc_codegen_ssa::common::RealPredicate::RealULT => RealPredicate::RealULT, rustc_codegen_ssa::common::RealPredicate::RealULE => RealPredicate::RealULE, rustc_codegen_ssa::common::RealPredicate::RealUNE => RealPredicate::RealUNE, - rustc_codegen_ssa::common::RealPredicate::RealPredicateTrue => + rustc_codegen_ssa::common::RealPredicate::RealPredicateTrue => { RealPredicate::RealPredicateTrue + } } } } @@ -276,7 +277,7 @@ impl AtomicRmwBinOp { rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicMax => AtomicRmwBinOp::AtomicMax, rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicMin => AtomicRmwBinOp::AtomicMin, rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicUMax => AtomicRmwBinOp::AtomicUMax, - rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicUMin => AtomicRmwBinOp::AtomicUMin + rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicUMin => AtomicRmwBinOp::AtomicUMin, } } } @@ -304,15 +305,16 @@ impl AtomicOrdering { rustc_codegen_ssa::common::AtomicOrdering::Monotonic => AtomicOrdering::Monotonic, rustc_codegen_ssa::common::AtomicOrdering::Acquire => AtomicOrdering::Acquire, rustc_codegen_ssa::common::AtomicOrdering::Release => AtomicOrdering::Release, - rustc_codegen_ssa::common::AtomicOrdering::AcquireRelease => - AtomicOrdering::AcquireRelease, - rustc_codegen_ssa::common::AtomicOrdering::SequentiallyConsistent => + rustc_codegen_ssa::common::AtomicOrdering::AcquireRelease => { + AtomicOrdering::AcquireRelease + } + rustc_codegen_ssa::common::AtomicOrdering::SequentiallyConsistent => { AtomicOrdering::SequentiallyConsistent + } } } } - /// LLVMRustSynchronizationScope #[derive(Copy, Clone)] #[repr(C)] @@ -328,10 +330,12 @@ impl SynchronizationScope { pub fn from_generic(sc: rustc_codegen_ssa::common::SynchronizationScope) -> Self { match sc { rustc_codegen_ssa::common::SynchronizationScope::Other => SynchronizationScope::Other, - rustc_codegen_ssa::common::SynchronizationScope::SingleThread => - SynchronizationScope::SingleThread, - rustc_codegen_ssa::common::SynchronizationScope::CrossThread => - SynchronizationScope::CrossThread, + rustc_codegen_ssa::common::SynchronizationScope::SingleThread => { + SynchronizationScope::SingleThread + } + rustc_codegen_ssa::common::SynchronizationScope::CrossThread => { + SynchronizationScope::CrossThread + } } } } @@ -380,7 +384,7 @@ impl AsmDialect { pub fn from_generic(asm: syntax::ast::AsmDialect) -> Self { match asm { syntax::ast::AsmDialect::Att => AsmDialect::Att, - syntax::ast::AsmDialect::Intel => AsmDialect::Intel + syntax::ast::AsmDialect::Intel => AsmDialect::Intel, } } } @@ -469,10 +473,14 @@ pub enum PassKind { } /// LLVMRustThinLTOData -extern { pub type ThinLTOData; } +extern "C" { + pub type ThinLTOData; +} /// LLVMRustThinLTOBuffer -extern { pub type ThinLTOBuffer; } +extern "C" { + pub type ThinLTOBuffer; +} // LLVMRustModuleNameCallback pub type ThinLTOModuleNameCallback = @@ -490,14 +498,16 @@ pub struct ThinLTOModule { #[derive(Copy, Clone)] #[repr(C)] pub enum ThreadLocalMode { - NotThreadLocal, - GeneralDynamic, - LocalDynamic, - InitialExec, - LocalExec + NotThreadLocal, + GeneralDynamic, + LocalDynamic, + InitialExec, + LocalExec, } -extern { type Opaque; } +extern "C" { + type Opaque; +} #[repr(C)] struct InvariantOpaque<'a> { _marker: PhantomData<&'a mut &'a ()>, @@ -505,32 +515,64 @@ struct InvariantOpaque<'a> { } // Opaque pointer types -extern { pub type Module; } -extern { pub type Context; } -extern { pub type Type; } -extern { pub type Value; } -extern { pub type ConstantInt; } -extern { pub type Metadata; } -extern { pub type BasicBlock; } +extern "C" { + pub type Module; +} +extern "C" { + pub type Context; +} +extern "C" { + pub type Type; +} +extern "C" { + pub type Value; +} +extern "C" { + pub type ConstantInt; +} +extern "C" { + pub type Metadata; +} +extern "C" { + pub type BasicBlock; +} #[repr(C)] pub struct Builder<'a>(InvariantOpaque<'a>); -extern { pub type MemoryBuffer; } +extern "C" { + pub type MemoryBuffer; +} #[repr(C)] pub struct PassManager<'a>(InvariantOpaque<'a>); -extern { pub type PassManagerBuilder; } -extern { pub type ObjectFile; } +extern "C" { + pub type PassManagerBuilder; +} +extern "C" { + pub type ObjectFile; +} #[repr(C)] pub struct SectionIterator<'a>(InvariantOpaque<'a>); -extern { pub type Pass; } -extern { pub type TargetMachine; } -extern { pub type Archive; } +extern "C" { + pub type Pass; +} +extern "C" { + pub type TargetMachine; +} +extern "C" { + pub type Archive; +} #[repr(C)] pub struct ArchiveIterator<'a>(InvariantOpaque<'a>); #[repr(C)] pub struct ArchiveChild<'a>(InvariantOpaque<'a>); -extern { pub type Twine; } -extern { pub type DiagnosticInfo; } -extern { pub type SMDiagnostic; } +extern "C" { + pub type Twine; +} +extern "C" { + pub type DiagnosticInfo; +} +extern "C" { + pub type SMDiagnostic; +} #[repr(C)] pub struct RustArchiveMember<'a>(InvariantOpaque<'a>); #[repr(C)] @@ -541,7 +583,6 @@ pub struct Linker<'a>(InvariantOpaque<'a>); pub type DiagnosticHandler = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void); pub type InlineAsmDiagHandler = unsafe extern "C" fn(&SMDiagnostic, *const c_void, c_uint); - pub mod debuginfo { use super::{InvariantOpaque, Metadata}; use bitflags::bitflags; @@ -631,7 +672,9 @@ pub mod debuginfo { } } -extern { pub type ModuleBuffer; } +extern "C" { + pub type ModuleBuffer; +} extern "C" { pub fn LLVMRustInstallFatalErrorHandler(); @@ -672,20 +715,22 @@ extern "C" { pub fn LLVMDoubleTypeInContext(C: &Context) -> &Type; // Operations on function types - pub fn LLVMFunctionType(ReturnType: &'a Type, - ParamTypes: *const &'a Type, - ParamCount: c_uint, - IsVarArg: Bool) - -> &'a Type; + pub fn LLVMFunctionType( + ReturnType: &'a Type, + ParamTypes: *const &'a Type, + ParamCount: c_uint, + IsVarArg: Bool, + ) -> &'a Type; pub fn LLVMCountParamTypes(FunctionTy: &Type) -> c_uint; pub fn LLVMGetParamTypes(FunctionTy: &'a Type, Dest: *mut &'a Type); // Operations on struct types - pub fn LLVMStructTypeInContext(C: &'a Context, - ElementTypes: *const &'a Type, - ElementCount: c_uint, - Packed: Bool) - -> &'a Type; + pub fn LLVMStructTypeInContext( + C: &'a Context, + ElementTypes: *const &'a Type, + ElementCount: c_uint, + Packed: Bool, + ) -> &'a Type; // Operations on array, pointer, and vector types (sequence types) pub fn LLVMRustArrayType(ElementType: &Type, ElementCount: u64) -> &Type; @@ -721,26 +766,32 @@ extern "C" { pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value; pub fn LLVMConstReal(RealTy: &Type, N: f64) -> &Value; pub fn LLVMConstIntGetZExtValue(ConstantVal: &ConstantInt) -> c_ulonglong; - pub fn LLVMRustConstInt128Get(ConstantVal: &ConstantInt, SExt: bool, - high: &mut u64, low: &mut u64) -> bool; - + pub fn LLVMRustConstInt128Get( + ConstantVal: &ConstantInt, + SExt: bool, + high: &mut u64, + low: &mut u64, + ) -> bool; // Operations on composite constants - pub fn LLVMConstStringInContext(C: &Context, - Str: *const c_char, - Length: c_uint, - DontNullTerminate: Bool) - -> &Value; - pub fn LLVMConstStructInContext(C: &'a Context, - ConstantVals: *const &'a Value, - Count: c_uint, - Packed: Bool) - -> &'a Value; - - pub fn LLVMConstArray(ElementTy: &'a Type, - ConstantVals: *const &'a Value, - Length: c_uint) - -> &'a Value; + pub fn LLVMConstStringInContext( + C: &Context, + Str: *const c_char, + Length: c_uint, + DontNullTerminate: Bool, + ) -> &Value; + pub fn LLVMConstStructInContext( + C: &'a Context, + ConstantVals: *const &'a Value, + Count: c_uint, + Packed: Bool, + ) -> &'a Value; + + pub fn LLVMConstArray( + ElementTy: &'a Type, + ConstantVals: *const &'a Value, + Length: c_uint, + ) -> &'a Value; pub fn LLVMConstVector(ScalarConstantVals: *const &Value, Size: c_uint) -> &Value; // Constant expressions @@ -754,10 +805,11 @@ extern "C" { pub fn LLVMConstIntToPtr(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstBitCast(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; pub fn LLVMConstPointerCast(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value; - pub fn LLVMConstExtractValue(AggConstant: &Value, - IdxList: *const c_uint, - NumIdx: c_uint) - -> &Value; + pub fn LLVMConstExtractValue( + AggConstant: &Value, + IdxList: *const c_uint, + NumIdx: c_uint, + ) -> &Value; // Operations on global variables, functions, and aliases (globals) pub fn LLVMIsDeclaration(Global: &Value) -> Bool; @@ -770,13 +822,16 @@ extern "C" { pub fn LLVMSetAlignment(Global: &Value, Bytes: c_uint); pub fn LLVMSetDLLStorageClass(V: &Value, C: DLLStorageClass); - // Operations on global variables pub fn LLVMIsAGlobalVariable(GlobalVar: &Value) -> Option<&Value>; pub fn LLVMAddGlobal(M: &'a Module, Ty: &'a Type, Name: *const c_char) -> &'a Value; pub fn LLVMGetNamedGlobal(M: &Module, Name: *const c_char) -> Option<&Value>; - pub fn LLVMRustGetOrInsertGlobal(M: &'a Module, Name: *const c_char, NameLen: size_t, - T: &'a Type) -> &'a Value; + pub fn LLVMRustGetOrInsertGlobal( + M: &'a Module, + Name: *const c_char, + NameLen: size_t, + T: &'a Type, + ) -> &'a Value; pub fn LLVMRustInsertPrivateGlobal(M: &'a Module, T: &'a Type) -> &'a Value; pub fn LLVMGetFirstGlobal(M: &Module) -> Option<&Value>; pub fn LLVMGetNextGlobal(GlobalVar: &Value) -> Option<&Value>; @@ -791,20 +846,23 @@ extern "C" { pub fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool); // Operations on functions - pub fn LLVMRustGetOrInsertFunction(M: &'a Module, - Name: *const c_char, - FunctionTy: &'a Type) - -> &'a Value; + pub fn LLVMRustGetOrInsertFunction( + M: &'a Module, + Name: *const c_char, + FunctionTy: &'a Type, + ) -> &'a Value; pub fn LLVMSetFunctionCallConv(Fn: &Value, CC: c_uint); pub fn LLVMRustAddAlignmentAttr(Fn: &Value, index: c_uint, bytes: u32); pub fn LLVMRustAddDereferenceableAttr(Fn: &Value, index: c_uint, bytes: u64); pub fn LLVMRustAddDereferenceableOrNullAttr(Fn: &Value, index: c_uint, bytes: u64); pub fn LLVMRustAddByValAttr(Fn: &Value, index: c_uint, ty: &Type); pub fn LLVMRustAddFunctionAttribute(Fn: &Value, index: c_uint, attr: Attribute); - pub fn LLVMRustAddFunctionAttrStringValue(Fn: &Value, - index: c_uint, - Name: *const c_char, - Value: *const c_char); + pub fn LLVMRustAddFunctionAttrStringValue( + Fn: &Value, + index: c_uint, + Name: *const c_char, + Value: *const c_char, + ); pub fn LLVMRustRemoveFunctionAttributes(Fn: &Value, index: c_uint, attr: Attribute); // Operations on parameters @@ -814,10 +872,11 @@ extern "C" { // Operations on basic blocks pub fn LLVMGetBasicBlockParent(BB: &BasicBlock) -> &Value; - pub fn LLVMAppendBasicBlockInContext(C: &'a Context, - Fn: &'a Value, - Name: *const c_char) - -> &'a BasicBlock; + pub fn LLVMAppendBasicBlockInContext( + C: &'a Context, + Fn: &'a Value, + Name: *const c_char, + ) -> &'a BasicBlock; pub fn LLVMDeleteBasicBlock(BB: &BasicBlock); // Operations on instructions @@ -829,19 +888,19 @@ extern "C" { pub fn LLVMRustAddCallSiteAttribute(Instr: &Value, index: c_uint, attr: Attribute); pub fn LLVMRustAddAlignmentCallSiteAttr(Instr: &Value, index: c_uint, bytes: u32); pub fn LLVMRustAddDereferenceableCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64); - pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, - index: c_uint, - bytes: u64); + pub fn LLVMRustAddDereferenceableOrNullCallSiteAttr(Instr: &Value, index: c_uint, bytes: u64); pub fn LLVMRustAddByValCallSiteAttr(Instr: &Value, index: c_uint, ty: &Type); // Operations on load/store instructions (only) pub fn LLVMSetVolatile(MemoryAccessInst: &Value, volatile: Bool); // Operations on phi nodes - pub fn LLVMAddIncoming(PhiNode: &'a Value, - IncomingValues: *const &'a Value, - IncomingBlocks: *const &'a BasicBlock, - Count: c_uint); + pub fn LLVMAddIncoming( + PhiNode: &'a Value, + IncomingValues: *const &'a Value, + IncomingBlocks: *const &'a BasicBlock, + Count: c_uint, + ); // Instruction builders pub fn LLVMCreateBuilderInContext(C: &'a Context) -> &'a mut Builder<'a>; @@ -858,61 +917,69 @@ extern "C" { pub fn LLVMBuildRetVoid(B: &Builder<'a>) -> &'a Value; pub fn LLVMBuildRet(B: &Builder<'a>, V: &'a Value) -> &'a Value; pub fn LLVMBuildBr(B: &Builder<'a>, Dest: &'a BasicBlock) -> &'a Value; - pub fn LLVMBuildCondBr(B: &Builder<'a>, - If: &'a Value, - Then: &'a BasicBlock, - Else: &'a BasicBlock) - -> &'a Value; - pub fn LLVMBuildSwitch(B: &Builder<'a>, - V: &'a Value, - Else: &'a BasicBlock, - NumCases: c_uint) - -> &'a Value; - pub fn LLVMRustBuildInvoke(B: &Builder<'a>, - Fn: &'a Value, - Args: *const &'a Value, - NumArgs: c_uint, - Then: &'a BasicBlock, - Catch: &'a BasicBlock, - Bundle: Option<&OperandBundleDef<'a>>, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildLandingPad(B: &Builder<'a>, - Ty: &'a Type, - PersFn: &'a Value, - NumClauses: c_uint, - Name: *const c_char) - -> &'a Value; + pub fn LLVMBuildCondBr( + B: &Builder<'a>, + If: &'a Value, + Then: &'a BasicBlock, + Else: &'a BasicBlock, + ) -> &'a Value; + pub fn LLVMBuildSwitch( + B: &Builder<'a>, + V: &'a Value, + Else: &'a BasicBlock, + NumCases: c_uint, + ) -> &'a Value; + pub fn LLVMRustBuildInvoke( + B: &Builder<'a>, + Fn: &'a Value, + Args: *const &'a Value, + NumArgs: c_uint, + Then: &'a BasicBlock, + Catch: &'a BasicBlock, + Bundle: Option<&OperandBundleDef<'a>>, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildLandingPad( + B: &Builder<'a>, + Ty: &'a Type, + PersFn: &'a Value, + NumClauses: c_uint, + Name: *const c_char, + ) -> &'a Value; pub fn LLVMBuildResume(B: &Builder<'a>, Exn: &'a Value) -> &'a Value; pub fn LLVMBuildUnreachable(B: &Builder<'a>) -> &'a Value; - pub fn LLVMRustBuildCleanupPad(B: &Builder<'a>, - ParentPad: Option<&'a Value>, - ArgCnt: c_uint, - Args: *const &'a Value, - Name: *const c_char) - -> Option<&'a Value>; - pub fn LLVMRustBuildCleanupRet(B: &Builder<'a>, - CleanupPad: &'a Value, - UnwindBB: Option<&'a BasicBlock>) - -> Option<&'a Value>; - pub fn LLVMRustBuildCatchPad(B: &Builder<'a>, - ParentPad: &'a Value, - ArgCnt: c_uint, - Args: *const &'a Value, - Name: *const c_char) - -> Option<&'a Value>; + pub fn LLVMRustBuildCleanupPad( + B: &Builder<'a>, + ParentPad: Option<&'a Value>, + ArgCnt: c_uint, + Args: *const &'a Value, + Name: *const c_char, + ) -> Option<&'a Value>; + pub fn LLVMRustBuildCleanupRet( + B: &Builder<'a>, + CleanupPad: &'a Value, + UnwindBB: Option<&'a BasicBlock>, + ) -> Option<&'a Value>; + pub fn LLVMRustBuildCatchPad( + B: &Builder<'a>, + ParentPad: &'a Value, + ArgCnt: c_uint, + Args: *const &'a Value, + Name: *const c_char, + ) -> Option<&'a Value>; pub fn LLVMRustBuildCatchRet( B: &Builder<'a>, Pad: &'a Value, BB: &'a BasicBlock, ) -> Option<&'a Value>; - pub fn LLVMRustBuildCatchSwitch(Builder: &Builder<'a>, - ParentPad: Option<&'a Value>, - BB: Option<&'a BasicBlock>, - NumHandlers: c_uint, - Name: *const c_char) - -> Option<&'a Value>; + pub fn LLVMRustBuildCatchSwitch( + Builder: &Builder<'a>, + ParentPad: Option<&'a Value>, + BB: Option<&'a BasicBlock>, + NumHandlers: c_uint, + Name: *const c_char, + ) -> Option<&'a Value>; pub fn LLVMRustAddHandler(CatchSwitch: &'a Value, Handler: &'a BasicBlock); pub fn LLVMSetPersonalityFn(Func: &'a Value, Pers: &'a Value); @@ -926,136 +993,162 @@ extern "C" { pub fn LLVMSetCleanup(LandingPad: &Value, Val: Bool); // Arithmetic - pub fn LLVMBuildAdd(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildFAdd(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildSub(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildFSub(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildMul(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildFMul(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildUDiv(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildExactUDiv(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildSDiv(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildExactSDiv(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildFDiv(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildURem(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildSRem(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildFRem(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildShl(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildLShr(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildAShr(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildNSWAdd(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildNUWAdd(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildNSWSub(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildNUWSub(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildNSWMul(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildNUWMul(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildAnd(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildOr(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildXor(B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; + pub fn LLVMBuildAdd( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildFAdd( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildSub( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildFSub( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildMul( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildFMul( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildUDiv( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildExactUDiv( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildSDiv( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildExactSDiv( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildFDiv( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildURem( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildSRem( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildFRem( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildShl( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildLShr( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildAShr( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildNSWAdd( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildNUWAdd( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildNSWSub( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildNUWSub( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildNSWMul( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildNUWMul( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildAnd( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildOr( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildXor( + B: &Builder<'a>, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; pub fn LLVMBuildNeg(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value; pub fn LLVMBuildFNeg(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value; pub fn LLVMBuildNot(B: &Builder<'a>, V: &'a Value, Name: *const c_char) -> &'a Value; @@ -1063,268 +1156,286 @@ extern "C" { // Memory pub fn LLVMBuildAlloca(B: &Builder<'a>, Ty: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMBuildArrayAlloca(B: &Builder<'a>, - Ty: &'a Type, - Val: &'a Value, - Name: *const c_char) - -> &'a Value; + pub fn LLVMBuildArrayAlloca( + B: &Builder<'a>, + Ty: &'a Type, + Val: &'a Value, + Name: *const c_char, + ) -> &'a Value; pub fn LLVMBuildLoad(B: &Builder<'a>, PointerVal: &'a Value, Name: *const c_char) -> &'a Value; pub fn LLVMBuildStore(B: &Builder<'a>, Val: &'a Value, Ptr: &'a Value) -> &'a Value; - pub fn LLVMBuildGEP(B: &Builder<'a>, - Pointer: &'a Value, - Indices: *const &'a Value, - NumIndices: c_uint, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildInBoundsGEP(B: &Builder<'a>, - Pointer: &'a Value, - Indices: *const &'a Value, - NumIndices: c_uint, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildStructGEP(B: &Builder<'a>, - Pointer: &'a Value, - Idx: c_uint, - Name: *const c_char) - -> &'a Value; + pub fn LLVMBuildGEP( + B: &Builder<'a>, + Pointer: &'a Value, + Indices: *const &'a Value, + NumIndices: c_uint, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildInBoundsGEP( + B: &Builder<'a>, + Pointer: &'a Value, + Indices: *const &'a Value, + NumIndices: c_uint, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildStructGEP( + B: &Builder<'a>, + Pointer: &'a Value, + Idx: c_uint, + Name: *const c_char, + ) -> &'a Value; // Casts - pub fn LLVMBuildTrunc(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildZExt(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildSExt(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildFPToUI(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildFPToSI(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildUIToFP(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildSIToFP(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildFPTrunc(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildFPExt(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildPtrToInt(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildIntToPtr(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildBitCast(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildPointerCast(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMRustBuildIntCast(B: &Builder<'a>, - Val: &'a Value, - DestTy: &'a Type, - IsSized: bool) - -> &'a Value; + pub fn LLVMBuildTrunc( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildZExt( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildSExt( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildFPToUI( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildFPToSI( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildUIToFP( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildSIToFP( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildFPTrunc( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildFPExt( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildPtrToInt( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildIntToPtr( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildBitCast( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildPointerCast( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMRustBuildIntCast( + B: &Builder<'a>, + Val: &'a Value, + DestTy: &'a Type, + IsSized: bool, + ) -> &'a Value; // Comparisons - pub fn LLVMBuildICmp(B: &Builder<'a>, - Op: c_uint, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildFCmp(B: &Builder<'a>, - Op: c_uint, - LHS: &'a Value, - RHS: &'a Value, - Name: *const c_char) - -> &'a Value; + pub fn LLVMBuildICmp( + B: &Builder<'a>, + Op: c_uint, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildFCmp( + B: &Builder<'a>, + Op: c_uint, + LHS: &'a Value, + RHS: &'a Value, + Name: *const c_char, + ) -> &'a Value; // Miscellaneous instructions pub fn LLVMBuildPhi(B: &Builder<'a>, Ty: &'a Type, Name: *const c_char) -> &'a Value; - pub fn LLVMRustBuildCall(B: &Builder<'a>, - Fn: &'a Value, - Args: *const &'a Value, - NumArgs: c_uint, - Bundle: Option<&OperandBundleDef<'a>>, - Name: *const c_char) - -> &'a Value; - pub fn LLVMRustBuildMemCpy(B: &Builder<'a>, - Dst: &'a Value, - DstAlign: c_uint, - Src: &'a Value, - SrcAlign: c_uint, - Size: &'a Value, - IsVolatile: bool) - -> &'a Value; - pub fn LLVMRustBuildMemMove(B: &Builder<'a>, - Dst: &'a Value, - DstAlign: c_uint, - Src: &'a Value, - SrcAlign: c_uint, - Size: &'a Value, - IsVolatile: bool) - -> &'a Value; - pub fn LLVMBuildSelect(B: &Builder<'a>, - If: &'a Value, - Then: &'a Value, - Else: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildVAArg(B: &Builder<'a>, - list: &'a Value, - Ty: &'a Type, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildExtractElement(B: &Builder<'a>, - VecVal: &'a Value, - Index: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildInsertElement(B: &Builder<'a>, - VecVal: &'a Value, - EltVal: &'a Value, - Index: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildShuffleVector(B: &Builder<'a>, - V1: &'a Value, - V2: &'a Value, - Mask: &'a Value, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildExtractValue(B: &Builder<'a>, - AggVal: &'a Value, - Index: c_uint, - Name: *const c_char) - -> &'a Value; - pub fn LLVMBuildInsertValue(B: &Builder<'a>, - AggVal: &'a Value, - EltVal: &'a Value, - Index: c_uint, - Name: *const c_char) - -> &'a Value; - - pub fn LLVMRustBuildVectorReduceFAdd(B: &Builder<'a>, - Acc: &'a Value, - Src: &'a Value) - -> &'a Value; - pub fn LLVMRustBuildVectorReduceFMul(B: &Builder<'a>, - Acc: &'a Value, - Src: &'a Value) - -> &'a Value; - pub fn LLVMRustBuildVectorReduceAdd(B: &Builder<'a>, - Src: &'a Value) - -> &'a Value; - pub fn LLVMRustBuildVectorReduceMul(B: &Builder<'a>, - Src: &'a Value) - -> &'a Value; - pub fn LLVMRustBuildVectorReduceAnd(B: &Builder<'a>, - Src: &'a Value) - -> &'a Value; - pub fn LLVMRustBuildVectorReduceOr(B: &Builder<'a>, - Src: &'a Value) - -> &'a Value; - pub fn LLVMRustBuildVectorReduceXor(B: &Builder<'a>, - Src: &'a Value) - -> &'a Value; - pub fn LLVMRustBuildVectorReduceMin(B: &Builder<'a>, - Src: &'a Value, - IsSigned: bool) - -> &'a Value; - pub fn LLVMRustBuildVectorReduceMax(B: &Builder<'a>, - Src: &'a Value, - IsSigned: bool) - -> &'a Value; - pub fn LLVMRustBuildVectorReduceFMin(B: &Builder<'a>, - Src: &'a Value, - IsNaN: bool) - -> &'a Value; - pub fn LLVMRustBuildVectorReduceFMax(B: &Builder<'a>, - Src: &'a Value, - IsNaN: bool) - -> &'a Value; - - pub fn LLVMRustBuildMinNum( + pub fn LLVMRustBuildCall( B: &Builder<'a>, - LHS: &'a Value, - LHS: &'a Value, + Fn: &'a Value, + Args: *const &'a Value, + NumArgs: c_uint, + Bundle: Option<&OperandBundleDef<'a>>, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMRustBuildMemCpy( + B: &Builder<'a>, + Dst: &'a Value, + DstAlign: c_uint, + Src: &'a Value, + SrcAlign: c_uint, + Size: &'a Value, + IsVolatile: bool, + ) -> &'a Value; + pub fn LLVMRustBuildMemMove( + B: &Builder<'a>, + Dst: &'a Value, + DstAlign: c_uint, + Src: &'a Value, + SrcAlign: c_uint, + Size: &'a Value, + IsVolatile: bool, + ) -> &'a Value; + pub fn LLVMBuildSelect( + B: &Builder<'a>, + If: &'a Value, + Then: &'a Value, + Else: &'a Value, + Name: *const c_char, ) -> &'a Value; - pub fn LLVMRustBuildMaxNum( + pub fn LLVMBuildVAArg( + B: &Builder<'a>, + list: &'a Value, + Ty: &'a Type, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildExtractElement( + B: &Builder<'a>, + VecVal: &'a Value, + Index: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildInsertElement( + B: &Builder<'a>, + VecVal: &'a Value, + EltVal: &'a Value, + Index: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildShuffleVector( + B: &Builder<'a>, + V1: &'a Value, + V2: &'a Value, + Mask: &'a Value, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildExtractValue( + B: &Builder<'a>, + AggVal: &'a Value, + Index: c_uint, + Name: *const c_char, + ) -> &'a Value; + pub fn LLVMBuildInsertValue( + B: &Builder<'a>, + AggVal: &'a Value, + EltVal: &'a Value, + Index: c_uint, + Name: *const c_char, + ) -> &'a Value; + + pub fn LLVMRustBuildVectorReduceFAdd( + B: &Builder<'a>, + Acc: &'a Value, + Src: &'a Value, + ) -> &'a Value; + pub fn LLVMRustBuildVectorReduceFMul( + B: &Builder<'a>, + Acc: &'a Value, + Src: &'a Value, + ) -> &'a Value; + pub fn LLVMRustBuildVectorReduceAdd(B: &Builder<'a>, Src: &'a Value) -> &'a Value; + pub fn LLVMRustBuildVectorReduceMul(B: &Builder<'a>, Src: &'a Value) -> &'a Value; + pub fn LLVMRustBuildVectorReduceAnd(B: &Builder<'a>, Src: &'a Value) -> &'a Value; + pub fn LLVMRustBuildVectorReduceOr(B: &Builder<'a>, Src: &'a Value) -> &'a Value; + pub fn LLVMRustBuildVectorReduceXor(B: &Builder<'a>, Src: &'a Value) -> &'a Value; + pub fn LLVMRustBuildVectorReduceMin( + B: &Builder<'a>, + Src: &'a Value, + IsSigned: bool, + ) -> &'a Value; + pub fn LLVMRustBuildVectorReduceMax( + B: &Builder<'a>, + Src: &'a Value, + IsSigned: bool, + ) -> &'a Value; + pub fn LLVMRustBuildVectorReduceFMin(B: &Builder<'a>, Src: &'a Value, IsNaN: bool) + -> &'a Value; + pub fn LLVMRustBuildVectorReduceFMax(B: &Builder<'a>, Src: &'a Value, IsNaN: bool) + -> &'a Value; + + pub fn LLVMRustBuildMinNum(B: &Builder<'a>, LHS: &'a Value, LHS: &'a Value) -> &'a Value; + pub fn LLVMRustBuildMaxNum(B: &Builder<'a>, LHS: &'a Value, LHS: &'a Value) -> &'a Value; + + // Atomic Operations + pub fn LLVMRustBuildAtomicLoad( + B: &Builder<'a>, + PointerVal: &'a Value, + Name: *const c_char, + Order: AtomicOrdering, + ) -> &'a Value; + + pub fn LLVMRustBuildAtomicStore( + B: &Builder<'a>, + Val: &'a Value, + Ptr: &'a Value, + Order: AtomicOrdering, + ) -> &'a Value; + + pub fn LLVMRustBuildAtomicCmpXchg( B: &Builder<'a>, LHS: &'a Value, + CMP: &'a Value, + RHS: &'a Value, + Order: AtomicOrdering, + FailureOrder: AtomicOrdering, + Weak: Bool, + ) -> &'a Value; + + pub fn LLVMBuildAtomicRMW( + B: &Builder<'a>, + Op: AtomicRmwBinOp, LHS: &'a Value, + RHS: &'a Value, + Order: AtomicOrdering, + SingleThreaded: Bool, ) -> &'a Value; - // Atomic Operations - pub fn LLVMRustBuildAtomicLoad(B: &Builder<'a>, - PointerVal: &'a Value, - Name: *const c_char, - Order: AtomicOrdering) - -> &'a Value; - - pub fn LLVMRustBuildAtomicStore(B: &Builder<'a>, - Val: &'a Value, - Ptr: &'a Value, - Order: AtomicOrdering) - -> &'a Value; - - pub fn LLVMRustBuildAtomicCmpXchg(B: &Builder<'a>, - LHS: &'a Value, - CMP: &'a Value, - RHS: &'a Value, - Order: AtomicOrdering, - FailureOrder: AtomicOrdering, - Weak: Bool) - -> &'a Value; - - pub fn LLVMBuildAtomicRMW(B: &Builder<'a>, - Op: AtomicRmwBinOp, - LHS: &'a Value, - RHS: &'a Value, - Order: AtomicOrdering, - SingleThreaded: Bool) - -> &'a Value; - - pub fn LLVMRustBuildAtomicFence(B: &Builder<'_>, - Order: AtomicOrdering, - Scope: SynchronizationScope); + pub fn LLVMRustBuildAtomicFence( + B: &Builder<'_>, + Order: AtomicOrdering, + Scope: SynchronizationScope, + ); /// Writes a module to the specified path. Returns 0 on success. pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int; @@ -1349,20 +1460,29 @@ extern "C" { pub fn LLVMPassManagerBuilderDispose(PMB: &'static mut PassManagerBuilder); pub fn LLVMPassManagerBuilderSetSizeLevel(PMB: &PassManagerBuilder, Value: Bool); pub fn LLVMPassManagerBuilderSetDisableUnrollLoops(PMB: &PassManagerBuilder, Value: Bool); - pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(PMB: &PassManagerBuilder, - threshold: c_uint); - pub fn LLVMPassManagerBuilderPopulateModulePassManager(PMB: &PassManagerBuilder, - PM: &PassManager<'_>); - - pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(PMB: &PassManagerBuilder, - PM: &PassManager<'_>); - pub fn LLVMPassManagerBuilderPopulateLTOPassManager(PMB: &PassManagerBuilder, - PM: &PassManager<'_>, - Internalize: Bool, - RunInliner: Bool); + pub fn LLVMPassManagerBuilderUseInlinerWithThreshold( + PMB: &PassManagerBuilder, + threshold: c_uint, + ); + pub fn LLVMPassManagerBuilderPopulateModulePassManager( + PMB: &PassManagerBuilder, + PM: &PassManager<'_>, + ); + + pub fn LLVMPassManagerBuilderPopulateFunctionPassManager( + PMB: &PassManagerBuilder, + PM: &PassManager<'_>, + ); + pub fn LLVMPassManagerBuilderPopulateLTOPassManager( + PMB: &PassManagerBuilder, + PM: &PassManager<'_>, + Internalize: Bool, + RunInliner: Bool, + ); pub fn LLVMRustPassManagerBuilderPopulateThinLTOPassManager( PMB: &PassManagerBuilder, - PM: &PassManager<'_>); + PM: &PassManager<'_>, + ); // Stuff that's in rustllvm/ because it's not upstream yet. @@ -1403,22 +1523,23 @@ extern "C" { pub fn LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> &Type; - pub fn LLVMStructSetBody(StructTy: &'a Type, - ElementTypes: *const &'a Type, - ElementCount: c_uint, - Packed: Bool); + pub fn LLVMStructSetBody( + StructTy: &'a Type, + ElementTypes: *const &'a Type, + ElementCount: c_uint, + Packed: Bool, + ); /// Prepares inline assembly. - pub fn LLVMRustInlineAsm(Ty: &Type, - AsmString: *const c_char, - Constraints: *const c_char, - SideEffects: Bool, - AlignStack: Bool, - Dialect: AsmDialect) - -> &Value; - pub fn LLVMRustInlineAsmVerify(Ty: &Type, - Constraints: *const c_char) - -> bool; + pub fn LLVMRustInlineAsm( + Ty: &Type, + AsmString: *const c_char, + Constraints: *const c_char, + SideEffects: Bool, + AlignStack: Bool, + Dialect: AsmDialect, + ) -> &Value; + pub fn LLVMRustInlineAsmVerify(Ty: &Type, Constraints: *const c_char) -> bool; pub fn LLVMRustDebugMetadataVersion() -> u32; pub fn LLVMRustVersionMajor() -> u32; @@ -1434,234 +1555,258 @@ extern "C" { pub fn LLVMRustDIBuilderFinalize(Builder: &DIBuilder<'_>); - pub fn LLVMRustDIBuilderCreateCompileUnit(Builder: &DIBuilder<'a>, - Lang: c_uint, - File: &'a DIFile, - Producer: *const c_char, - isOptimized: bool, - Flags: *const c_char, - RuntimeVer: c_uint, - SplitName: *const c_char, - kind: DebugEmissionKind) - -> &'a DIDescriptor; - - pub fn LLVMRustDIBuilderCreateFile(Builder: &DIBuilder<'a>, - Filename: *const c_char, - Directory: *const c_char) - -> &'a DIFile; - - pub fn LLVMRustDIBuilderCreateSubroutineType(Builder: &DIBuilder<'a>, - File: &'a DIFile, - ParameterTypes: &'a DIArray) - -> &'a DICompositeType; - - pub fn LLVMRustDIBuilderCreateFunction(Builder: &DIBuilder<'a>, - Scope: &'a DIDescriptor, - Name: *const c_char, - LinkageName: *const c_char, - File: &'a DIFile, - LineNo: c_uint, - Ty: &'a DIType, - ScopeLine: c_uint, - Flags: DIFlags, - SPFlags: DISPFlags, - Fn: &'a Value, - TParam: &'a DIArray, - Decl: Option<&'a DIDescriptor>) - -> &'a DISubprogram; - - pub fn LLVMRustDIBuilderCreateBasicType(Builder: &DIBuilder<'a>, - Name: *const c_char, - SizeInBits: u64, - AlignInBits: u32, - Encoding: c_uint) - -> &'a DIBasicType; - - pub fn LLVMRustDIBuilderCreatePointerType(Builder: &DIBuilder<'a>, - PointeeTy: &'a DIType, - SizeInBits: u64, - AlignInBits: u32, - Name: *const c_char) - -> &'a DIDerivedType; - - pub fn LLVMRustDIBuilderCreateStructType(Builder: &DIBuilder<'a>, - Scope: Option<&'a DIDescriptor>, - Name: *const c_char, - File: &'a DIFile, - LineNumber: c_uint, - SizeInBits: u64, - AlignInBits: u32, - Flags: DIFlags, - DerivedFrom: Option<&'a DIType>, - Elements: &'a DIArray, - RunTimeLang: c_uint, - VTableHolder: Option<&'a DIType>, - UniqueId: *const c_char) - -> &'a DICompositeType; - - pub fn LLVMRustDIBuilderCreateMemberType(Builder: &DIBuilder<'a>, - Scope: &'a DIDescriptor, - Name: *const c_char, - File: &'a DIFile, - LineNo: c_uint, - SizeInBits: u64, - AlignInBits: u32, - OffsetInBits: u64, - Flags: DIFlags, - Ty: &'a DIType) - -> &'a DIDerivedType; - - pub fn LLVMRustDIBuilderCreateVariantMemberType(Builder: &DIBuilder<'a>, - Scope: &'a DIScope, - Name: *const c_char, - File: &'a DIFile, - LineNumber: c_uint, - SizeInBits: u64, - AlignInBits: u32, - OffsetInBits: u64, - Discriminant: Option<&'a Value>, - Flags: DIFlags, - Ty: &'a DIType) - -> &'a DIType; - - pub fn LLVMRustDIBuilderCreateLexicalBlock(Builder: &DIBuilder<'a>, - Scope: &'a DIScope, - File: &'a DIFile, - Line: c_uint, - Col: c_uint) - -> &'a DILexicalBlock; - - pub fn LLVMRustDIBuilderCreateLexicalBlockFile(Builder: &DIBuilder<'a>, - Scope: &'a DIScope, - File: &'a DIFile) - -> &'a DILexicalBlock; - - pub fn LLVMRustDIBuilderCreateStaticVariable(Builder: &DIBuilder<'a>, - Context: Option<&'a DIScope>, - Name: *const c_char, - LinkageName: *const c_char, - File: &'a DIFile, - LineNo: c_uint, - Ty: &'a DIType, - isLocalToUnit: bool, - Val: &'a Value, - Decl: Option<&'a DIDescriptor>, - AlignInBits: u32) - -> &'a DIGlobalVariableExpression; - - pub fn LLVMRustDIBuilderCreateVariable(Builder: &DIBuilder<'a>, - Tag: c_uint, - Scope: &'a DIDescriptor, - Name: *const c_char, - File: &'a DIFile, - LineNo: c_uint, - Ty: &'a DIType, - AlwaysPreserve: bool, - Flags: DIFlags, - ArgNo: c_uint, - AlignInBits: u32) - -> &'a DIVariable; - - pub fn LLVMRustDIBuilderCreateArrayType(Builder: &DIBuilder<'a>, - Size: u64, - AlignInBits: u32, - Ty: &'a DIType, - Subscripts: &'a DIArray) - -> &'a DIType; - - pub fn LLVMRustDIBuilderGetOrCreateSubrange(Builder: &DIBuilder<'a>, - Lo: i64, - Count: i64) - -> &'a DISubrange; - - pub fn LLVMRustDIBuilderGetOrCreateArray(Builder: &DIBuilder<'a>, - Ptr: *const Option<&'a DIDescriptor>, - Count: c_uint) - -> &'a DIArray; - - pub fn LLVMRustDIBuilderInsertDeclareAtEnd(Builder: &DIBuilder<'a>, - Val: &'a Value, - VarInfo: &'a DIVariable, - AddrOps: *const i64, - AddrOpsCount: c_uint, - DL: &'a Value, - InsertAtEnd: &'a BasicBlock) - -> &'a Value; - - pub fn LLVMRustDIBuilderCreateEnumerator(Builder: &DIBuilder<'a>, - Name: *const c_char, - Val: u64) - -> &'a DIEnumerator; - - pub fn LLVMRustDIBuilderCreateEnumerationType(Builder: &DIBuilder<'a>, - Scope: &'a DIScope, - Name: *const c_char, - File: &'a DIFile, - LineNumber: c_uint, - SizeInBits: u64, - AlignInBits: u32, - Elements: &'a DIArray, - ClassType: &'a DIType, - IsScoped: bool) - -> &'a DIType; - - pub fn LLVMRustDIBuilderCreateUnionType(Builder: &DIBuilder<'a>, - Scope: &'a DIScope, - Name: *const c_char, - File: &'a DIFile, - LineNumber: c_uint, - SizeInBits: u64, - AlignInBits: u32, - Flags: DIFlags, - Elements: Option<&'a DIArray>, - RunTimeLang: c_uint, - UniqueId: *const c_char) - -> &'a DIType; - - pub fn LLVMRustDIBuilderCreateVariantPart(Builder: &DIBuilder<'a>, - Scope: &'a DIScope, - Name: *const c_char, - File: &'a DIFile, - LineNo: c_uint, - SizeInBits: u64, - AlignInBits: u32, - Flags: DIFlags, - Discriminator: Option<&'a DIDerivedType>, - Elements: &'a DIArray, - UniqueId: *const c_char) - -> &'a DIDerivedType; + pub fn LLVMRustDIBuilderCreateCompileUnit( + Builder: &DIBuilder<'a>, + Lang: c_uint, + File: &'a DIFile, + Producer: *const c_char, + isOptimized: bool, + Flags: *const c_char, + RuntimeVer: c_uint, + SplitName: *const c_char, + kind: DebugEmissionKind, + ) -> &'a DIDescriptor; + + pub fn LLVMRustDIBuilderCreateFile( + Builder: &DIBuilder<'a>, + Filename: *const c_char, + Directory: *const c_char, + ) -> &'a DIFile; + + pub fn LLVMRustDIBuilderCreateSubroutineType( + Builder: &DIBuilder<'a>, + File: &'a DIFile, + ParameterTypes: &'a DIArray, + ) -> &'a DICompositeType; + + pub fn LLVMRustDIBuilderCreateFunction( + Builder: &DIBuilder<'a>, + Scope: &'a DIDescriptor, + Name: *const c_char, + LinkageName: *const c_char, + File: &'a DIFile, + LineNo: c_uint, + Ty: &'a DIType, + ScopeLine: c_uint, + Flags: DIFlags, + SPFlags: DISPFlags, + Fn: &'a Value, + TParam: &'a DIArray, + Decl: Option<&'a DIDescriptor>, + ) -> &'a DISubprogram; + + pub fn LLVMRustDIBuilderCreateBasicType( + Builder: &DIBuilder<'a>, + Name: *const c_char, + SizeInBits: u64, + AlignInBits: u32, + Encoding: c_uint, + ) -> &'a DIBasicType; + + pub fn LLVMRustDIBuilderCreatePointerType( + Builder: &DIBuilder<'a>, + PointeeTy: &'a DIType, + SizeInBits: u64, + AlignInBits: u32, + Name: *const c_char, + ) -> &'a DIDerivedType; + + pub fn LLVMRustDIBuilderCreateStructType( + Builder: &DIBuilder<'a>, + Scope: Option<&'a DIDescriptor>, + Name: *const c_char, + File: &'a DIFile, + LineNumber: c_uint, + SizeInBits: u64, + AlignInBits: u32, + Flags: DIFlags, + DerivedFrom: Option<&'a DIType>, + Elements: &'a DIArray, + RunTimeLang: c_uint, + VTableHolder: Option<&'a DIType>, + UniqueId: *const c_char, + ) -> &'a DICompositeType; + + pub fn LLVMRustDIBuilderCreateMemberType( + Builder: &DIBuilder<'a>, + Scope: &'a DIDescriptor, + Name: *const c_char, + File: &'a DIFile, + LineNo: c_uint, + SizeInBits: u64, + AlignInBits: u32, + OffsetInBits: u64, + Flags: DIFlags, + Ty: &'a DIType, + ) -> &'a DIDerivedType; + + pub fn LLVMRustDIBuilderCreateVariantMemberType( + Builder: &DIBuilder<'a>, + Scope: &'a DIScope, + Name: *const c_char, + File: &'a DIFile, + LineNumber: c_uint, + SizeInBits: u64, + AlignInBits: u32, + OffsetInBits: u64, + Discriminant: Option<&'a Value>, + Flags: DIFlags, + Ty: &'a DIType, + ) -> &'a DIType; + + pub fn LLVMRustDIBuilderCreateLexicalBlock( + Builder: &DIBuilder<'a>, + Scope: &'a DIScope, + File: &'a DIFile, + Line: c_uint, + Col: c_uint, + ) -> &'a DILexicalBlock; + + pub fn LLVMRustDIBuilderCreateLexicalBlockFile( + Builder: &DIBuilder<'a>, + Scope: &'a DIScope, + File: &'a DIFile, + ) -> &'a DILexicalBlock; + + pub fn LLVMRustDIBuilderCreateStaticVariable( + Builder: &DIBuilder<'a>, + Context: Option<&'a DIScope>, + Name: *const c_char, + LinkageName: *const c_char, + File: &'a DIFile, + LineNo: c_uint, + Ty: &'a DIType, + isLocalToUnit: bool, + Val: &'a Value, + Decl: Option<&'a DIDescriptor>, + AlignInBits: u32, + ) -> &'a DIGlobalVariableExpression; + + pub fn LLVMRustDIBuilderCreateVariable( + Builder: &DIBuilder<'a>, + Tag: c_uint, + Scope: &'a DIDescriptor, + Name: *const c_char, + File: &'a DIFile, + LineNo: c_uint, + Ty: &'a DIType, + AlwaysPreserve: bool, + Flags: DIFlags, + ArgNo: c_uint, + AlignInBits: u32, + ) -> &'a DIVariable; + + pub fn LLVMRustDIBuilderCreateArrayType( + Builder: &DIBuilder<'a>, + Size: u64, + AlignInBits: u32, + Ty: &'a DIType, + Subscripts: &'a DIArray, + ) -> &'a DIType; + + pub fn LLVMRustDIBuilderGetOrCreateSubrange( + Builder: &DIBuilder<'a>, + Lo: i64, + Count: i64, + ) -> &'a DISubrange; + + pub fn LLVMRustDIBuilderGetOrCreateArray( + Builder: &DIBuilder<'a>, + Ptr: *const Option<&'a DIDescriptor>, + Count: c_uint, + ) -> &'a DIArray; + + pub fn LLVMRustDIBuilderInsertDeclareAtEnd( + Builder: &DIBuilder<'a>, + Val: &'a Value, + VarInfo: &'a DIVariable, + AddrOps: *const i64, + AddrOpsCount: c_uint, + DL: &'a Value, + InsertAtEnd: &'a BasicBlock, + ) -> &'a Value; + + pub fn LLVMRustDIBuilderCreateEnumerator( + Builder: &DIBuilder<'a>, + Name: *const c_char, + Val: u64, + ) -> &'a DIEnumerator; + + pub fn LLVMRustDIBuilderCreateEnumerationType( + Builder: &DIBuilder<'a>, + Scope: &'a DIScope, + Name: *const c_char, + File: &'a DIFile, + LineNumber: c_uint, + SizeInBits: u64, + AlignInBits: u32, + Elements: &'a DIArray, + ClassType: &'a DIType, + IsScoped: bool, + ) -> &'a DIType; + + pub fn LLVMRustDIBuilderCreateUnionType( + Builder: &DIBuilder<'a>, + Scope: &'a DIScope, + Name: *const c_char, + File: &'a DIFile, + LineNumber: c_uint, + SizeInBits: u64, + AlignInBits: u32, + Flags: DIFlags, + Elements: Option<&'a DIArray>, + RunTimeLang: c_uint, + UniqueId: *const c_char, + ) -> &'a DIType; + + pub fn LLVMRustDIBuilderCreateVariantPart( + Builder: &DIBuilder<'a>, + Scope: &'a DIScope, + Name: *const c_char, + File: &'a DIFile, + LineNo: c_uint, + SizeInBits: u64, + AlignInBits: u32, + Flags: DIFlags, + Discriminator: Option<&'a DIDerivedType>, + Elements: &'a DIArray, + UniqueId: *const c_char, + ) -> &'a DIDerivedType; pub fn LLVMSetUnnamedAddr(GlobalVar: &Value, UnnamedAddr: Bool); - pub fn LLVMRustDIBuilderCreateTemplateTypeParameter(Builder: &DIBuilder<'a>, - Scope: Option<&'a DIScope>, - Name: *const c_char, - Ty: &'a DIType, - File: &'a DIFile, - LineNo: c_uint, - ColumnNo: c_uint) - -> &'a DITemplateTypeParameter; - - - pub fn LLVMRustDIBuilderCreateNameSpace(Builder: &DIBuilder<'a>, - Scope: Option<&'a DIScope>, - Name: *const c_char, - File: &'a DIFile, - LineNo: c_uint) - -> &'a DINameSpace; - - pub fn LLVMRustDICompositeTypeReplaceArrays(Builder: &DIBuilder<'a>, - CompositeType: &'a DIType, - Elements: Option<&'a DIArray>, - Params: Option<&'a DIArray>); - - - pub fn LLVMRustDIBuilderCreateDebugLocation(Context: &'a Context, - Line: c_uint, - Column: c_uint, - Scope: &'a DIScope, - InlinedAt: Option<&'a Metadata>) - -> &'a Value; + pub fn LLVMRustDIBuilderCreateTemplateTypeParameter( + Builder: &DIBuilder<'a>, + Scope: Option<&'a DIScope>, + Name: *const c_char, + Ty: &'a DIType, + File: &'a DIFile, + LineNo: c_uint, + ColumnNo: c_uint, + ) -> &'a DITemplateTypeParameter; + + pub fn LLVMRustDIBuilderCreateNameSpace( + Builder: &DIBuilder<'a>, + Scope: Option<&'a DIScope>, + Name: *const c_char, + File: &'a DIFile, + LineNo: c_uint, + ) -> &'a DINameSpace; + + pub fn LLVMRustDICompositeTypeReplaceArrays( + Builder: &DIBuilder<'a>, + CompositeType: &'a DIType, + Elements: Option<&'a DIArray>, + Params: Option<&'a DIArray>, + ); + + pub fn LLVMRustDIBuilderCreateDebugLocation( + Context: &'a Context, + Line: c_uint, + Column: c_uint, + Scope: &'a DIScope, + InlinedAt: Option<&'a Metadata>, + ) -> &'a Value; pub fn LLVMRustDIBuilderCreateOpDeref() -> i64; pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64; @@ -1676,13 +1821,17 @@ extern "C" { pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>; pub fn LLVMRustCreateAddressSanitizerFunctionPass(Recover: bool) -> &'static mut Pass; pub fn LLVMRustCreateModuleAddressSanitizerPass(Recover: bool) -> &'static mut Pass; - pub fn LLVMRustCreateMemorySanitizerPass(TrackOrigins: c_int, - Recover: bool) -> &'static mut Pass; + pub fn LLVMRustCreateMemorySanitizerPass( + TrackOrigins: c_int, + Recover: bool, + ) -> &'static mut Pass; pub fn LLVMRustCreateThreadSanitizerPass() -> &'static mut Pass; pub fn LLVMRustAddPass(PM: &PassManager<'_>, Pass: &'static mut Pass); - pub fn LLVMRustAddLastExtensionPasses(PMB: &PassManagerBuilder, - Passes: *const &'static mut Pass, - NumPasses: size_t); + pub fn LLVMRustAddLastExtensionPasses( + PMB: &PassManagerBuilder, + Passes: *const &'static mut Pass, + NumPasses: size_t, + ); pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool; @@ -1690,52 +1839,58 @@ extern "C" { pub fn LLVMRustPrintTargetFeatures(T: &TargetMachine); pub fn LLVMRustGetHostCPUName(len: *mut usize) -> *const c_char; - pub fn LLVMRustCreateTargetMachine(Triple: *const c_char, - CPU: *const c_char, - Features: *const c_char, - Abi: *const c_char, - Model: CodeModel, - Reloc: RelocMode, - Level: CodeGenOptLevel, - UseSoftFP: bool, - PositionIndependentExecutable: bool, - FunctionSections: bool, - DataSections: bool, - TrapUnreachable: bool, - Singlethread: bool, - AsmComments: bool, - EmitStackSizeSection: bool, - RelaxELFRelocations: bool) - -> Option<&'static mut TargetMachine>; + pub fn LLVMRustCreateTargetMachine( + Triple: *const c_char, + CPU: *const c_char, + Features: *const c_char, + Abi: *const c_char, + Model: CodeModel, + Reloc: RelocMode, + Level: CodeGenOptLevel, + UseSoftFP: bool, + PositionIndependentExecutable: bool, + FunctionSections: bool, + DataSections: bool, + TrapUnreachable: bool, + Singlethread: bool, + AsmComments: bool, + EmitStackSizeSection: bool, + RelaxELFRelocations: bool, + ) -> Option<&'static mut TargetMachine>; pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine); - pub fn LLVMRustAddBuilderLibraryInfo(PMB: &'a PassManagerBuilder, - M: &'a Module, - DisableSimplifyLibCalls: bool); - pub fn LLVMRustConfigurePassManagerBuilder(PMB: &PassManagerBuilder, - OptLevel: CodeGenOptLevel, - MergeFunctions: bool, - SLPVectorize: bool, - LoopVectorize: bool, - PrepareForThinLTO: bool, - PGOGenPath: *const c_char, - PGOUsePath: *const c_char); - pub fn LLVMRustAddLibraryInfo(PM: &PassManager<'a>, - M: &'a Module, - DisableSimplifyLibCalls: bool); + pub fn LLVMRustAddBuilderLibraryInfo( + PMB: &'a PassManagerBuilder, + M: &'a Module, + DisableSimplifyLibCalls: bool, + ); + pub fn LLVMRustConfigurePassManagerBuilder( + PMB: &PassManagerBuilder, + OptLevel: CodeGenOptLevel, + MergeFunctions: bool, + SLPVectorize: bool, + LoopVectorize: bool, + PrepareForThinLTO: bool, + PGOGenPath: *const c_char, + PGOUsePath: *const c_char, + ); + pub fn LLVMRustAddLibraryInfo( + PM: &PassManager<'a>, + M: &'a Module, + DisableSimplifyLibCalls: bool, + ); pub fn LLVMRustRunFunctionPassManager(PM: &PassManager<'a>, M: &'a Module); - pub fn LLVMRustWriteOutputFile(T: &'a TargetMachine, - PM: &PassManager<'a>, - M: &'a Module, - Output: *const c_char, - FileType: FileType) - -> LLVMRustResult; - pub fn LLVMRustPrintModule(M: &'a Module, - Output: *const c_char, - Demangle: extern fn(*const c_char, - size_t, - *mut c_char, - size_t) -> size_t, - ) -> LLVMRustResult; + pub fn LLVMRustWriteOutputFile( + T: &'a TargetMachine, + PM: &PassManager<'a>, + M: &'a Module, + Output: *const c_char, + FileType: FileType, + ) -> LLVMRustResult; + pub fn LLVMRustPrintModule( + M: &'a Module, + Output: *const c_char, + Demangle: extern "C" fn(*const c_char, size_t, *mut c_char, size_t) -> size_t, + ) -> LLVMRustResult; pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char); pub fn LLVMRustPrintPasses(); pub fn LLVMRustGetInstructionCount(M: &Module) -> u32; @@ -1756,59 +1911,72 @@ extern "C" { pub fn LLVMRustDestroyArchive(AR: &'static mut Archive); #[allow(improper_ctypes)] - pub fn LLVMRustGetSectionName(SI: &SectionIterator<'_>, - data: &mut Option>) -> size_t; + pub fn LLVMRustGetSectionName( + SI: &SectionIterator<'_>, + data: &mut Option>, + ) -> size_t; #[allow(improper_ctypes)] pub fn LLVMRustWriteTwineToString(T: &Twine, s: &RustString); - pub fn LLVMContextSetDiagnosticHandler(C: &Context, - Handler: DiagnosticHandler, - DiagnosticContext: *mut c_void); + pub fn LLVMContextSetDiagnosticHandler( + C: &Context, + Handler: DiagnosticHandler, + DiagnosticContext: *mut c_void, + ); #[allow(improper_ctypes)] - pub fn LLVMRustUnpackOptimizationDiagnostic(DI: &'a DiagnosticInfo, - pass_name_out: &RustString, - function_out: &mut Option<&'a Value>, - loc_line_out: &mut c_uint, - loc_column_out: &mut c_uint, - loc_filename_out: &RustString, - message_out: &RustString); - - pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: &'a DiagnosticInfo, - cookie_out: &mut c_uint, - message_out: &mut Option<&'a Twine>, - instruction_out: &mut Option<&'a Value>); + pub fn LLVMRustUnpackOptimizationDiagnostic( + DI: &'a DiagnosticInfo, + pass_name_out: &RustString, + function_out: &mut Option<&'a Value>, + loc_line_out: &mut c_uint, + loc_column_out: &mut c_uint, + loc_filename_out: &RustString, + message_out: &RustString, + ); + + pub fn LLVMRustUnpackInlineAsmDiagnostic( + DI: &'a DiagnosticInfo, + cookie_out: &mut c_uint, + message_out: &mut Option<&'a Twine>, + instruction_out: &mut Option<&'a Value>, + ); #[allow(improper_ctypes)] pub fn LLVMRustWriteDiagnosticInfoToString(DI: &DiagnosticInfo, s: &RustString); pub fn LLVMRustGetDiagInfoKind(DI: &DiagnosticInfo) -> DiagnosticKind; - pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: &Context, - H: InlineAsmDiagHandler, - CX: *mut c_void); + pub fn LLVMRustSetInlineAsmDiagnosticHandler( + C: &Context, + H: InlineAsmDiagHandler, + CX: *mut c_void, + ); #[allow(improper_ctypes)] pub fn LLVMRustWriteSMDiagnosticToString(d: &SMDiagnostic, s: &RustString); - pub fn LLVMRustWriteArchive(Dst: *const c_char, - NumMembers: size_t, - Members: *const &RustArchiveMember<'_>, - WriteSymbtab: bool, - Kind: ArchiveKind) - -> LLVMRustResult; - pub fn LLVMRustArchiveMemberNew(Filename: *const c_char, - Name: *const c_char, - Child: Option<&ArchiveChild<'a>>) - -> &'a mut RustArchiveMember<'a>; + pub fn LLVMRustWriteArchive( + Dst: *const c_char, + NumMembers: size_t, + Members: *const &RustArchiveMember<'_>, + WriteSymbtab: bool, + Kind: ArchiveKind, + ) -> LLVMRustResult; + pub fn LLVMRustArchiveMemberNew( + Filename: *const c_char, + Name: *const c_char, + Child: Option<&ArchiveChild<'a>>, + ) -> &'a mut RustArchiveMember<'a>; pub fn LLVMRustArchiveMemberFree(Member: &'a mut RustArchiveMember<'a>); pub fn LLVMRustSetDataLayoutFromTargetMachine(M: &'a Module, TM: &'a TargetMachine); - pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char, - Inputs: *const &'a Value, - NumInputs: c_uint) - -> &'a mut OperandBundleDef<'a>; + pub fn LLVMRustBuildOperandBundleDef( + Name: *const c_char, + Inputs: *const &'a Value, + NumInputs: c_uint, + ) -> &'a mut OperandBundleDef<'a>; pub fn LLVMRustFreeOperandBundleDef(Bundle: &'a mut OperandBundleDef<'a>); pub fn LLVMRustPositionBuilderAtStart(B: &Builder<'a>, BB: &'a BasicBlock); @@ -1833,22 +2001,10 @@ extern "C" { PreservedSymbols: *const *const c_char, PreservedSymbolsLen: c_uint, ) -> Option<&'static mut ThinLTOData>; - pub fn LLVMRustPrepareThinLTORename( - Data: &ThinLTOData, - Module: &Module, - ) -> bool; - pub fn LLVMRustPrepareThinLTOResolveWeak( - Data: &ThinLTOData, - Module: &Module, - ) -> bool; - pub fn LLVMRustPrepareThinLTOInternalize( - Data: &ThinLTOData, - Module: &Module, - ) -> bool; - pub fn LLVMRustPrepareThinLTOImport( - Data: &ThinLTOData, - Module: &Module, - ) -> bool; + pub fn LLVMRustPrepareThinLTORename(Data: &ThinLTOData, Module: &Module) -> bool; + pub fn LLVMRustPrepareThinLTOResolveWeak(Data: &ThinLTOData, Module: &Module) -> bool; + pub fn LLVMRustPrepareThinLTOInternalize(Data: &ThinLTOData, Module: &Module) -> bool; + pub fn LLVMRustPrepareThinLTOImport(Data: &ThinLTOData, Module: &Module) -> bool; pub fn LLVMRustGetThinLTOModuleImports( Data: *const ThinLTOData, ModuleNameCallback: ThinLTOModuleNameCallback, @@ -1861,14 +2017,18 @@ extern "C" { len: usize, Identifier: *const c_char, ) -> Option<&Module>; - pub fn LLVMRustThinLTOGetDICompileUnit(M: &Module, - CU1: &mut *mut c_void, - CU2: &mut *mut c_void); + pub fn LLVMRustThinLTOGetDICompileUnit( + M: &Module, + CU1: &mut *mut c_void, + CU2: &mut *mut c_void, + ); pub fn LLVMRustThinLTOPatchDICompileUnit(M: &Module, CU: *mut c_void); pub fn LLVMRustLinkerNew(M: &'a Module) -> &'a mut Linker<'a>; - pub fn LLVMRustLinkerAdd(linker: &Linker<'_>, - bytecode: *const c_char, - bytecode_len: usize) -> bool; + pub fn LLVMRustLinkerAdd( + linker: &Linker<'_>, + bytecode: *const c_char, + bytecode_len: usize, + ) -> bool; pub fn LLVMRustLinkerFree(linker: &'a mut Linker<'a>); } diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs index 975756753d6ad..eb13d6a575fe8 100644 --- a/src/librustc_codegen_llvm/llvm/mod.rs +++ b/src/librustc_codegen_llvm/llvm/mod.rs @@ -1,20 +1,20 @@ #![allow(non_snake_case)] -pub use self::IntPredicate::*; -pub use self::RealPredicate::*; pub use self::AtomicRmwBinOp::*; -pub use self::MetadataType::*; -pub use self::CodeGenOptSize::*; pub use self::CallConv::*; +pub use self::CodeGenOptSize::*; +pub use self::IntPredicate::*; pub use self::Linkage::*; +pub use self::MetadataType::*; +pub use self::RealPredicate::*; -use std::str::FromStr; -use std::string::FromUtf8Error; -use std::ffi::CStr; -use std::cell::RefCell; use libc::c_uint; use rustc_data_structures::small_c_str::SmallCStr; use rustc_llvm::RustString; +use std::cell::RefCell; +use std::ffi::CStr; +use std::str::FromStr; +use std::string::FromUtf8Error; pub mod archive_ro; pub mod diagnostic; @@ -31,15 +31,9 @@ impl LLVMRustResult { } } -pub fn AddFunctionAttrStringValue(llfn: &'a Value, - idx: AttributePlace, - attr: &CStr, - value: &CStr) { +pub fn AddFunctionAttrStringValue(llfn: &'a Value, idx: AttributePlace, attr: &CStr, value: &CStr) { unsafe { - LLVMRustAddFunctionAttrStringValue(llfn, - idx.as_uint(), - attr.as_ptr(), - value.as_ptr()) + LLVMRustAddFunctionAttrStringValue(llfn, idx.as_uint(), attr.as_ptr(), value.as_ptr()) } } @@ -197,8 +191,12 @@ pub fn mk_section_iter(llof: &'a ffi::ObjectFile) -> SectionIter<'a> { /// Safe wrapper around `LLVMGetParam`, because segfaults are no fun. pub fn get_param(llfn: &'a Value, index: c_uint) -> &'a Value { unsafe { - assert!(index < LLVMCountParams(llfn), - "out of bounds argument access: {} out of {} arguments", index, LLVMCountParams(llfn)); + assert!( + index < LLVMCountParams(llfn), + "out of bounds argument access: {} out of {} arguments", + index, + LLVMCountParams(llfn) + ); LLVMGetParam(llfn, index) } } @@ -221,17 +219,14 @@ pub fn set_value_name(value: &Value, name: &[u8]) { } pub fn build_string(f: impl FnOnce(&RustString)) -> Result { - let sr = RustString { - bytes: RefCell::new(Vec::new()), - }; + let sr = RustString { bytes: RefCell::new(Vec::new()) }; f(&sr); String::from_utf8(sr.bytes.into_inner()) } pub fn twine_to_string(tr: &Twine) -> String { unsafe { - build_string(|s| LLVMRustWriteTwineToString(tr, s)) - .expect("got a non-UTF8 Twine from LLVM") + build_string(|s| LLVMRustWriteTwineToString(tr, s)).expect("got a non-UTF8 Twine from LLVM") } } diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index 3145b0df63b8a..c4e0baeb04707 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -1,18 +1,18 @@ use crate::back::write::create_informational_target_machine; use crate::llvm; -use syntax_pos::symbol::Symbol; -use rustc::session::Session; +use libc::c_int; +use rustc::bug; use rustc::session::config::PrintRequest; +use rustc::session::Session; use rustc_data_structures::fx::FxHashSet; +use rustc_feature::UnstableFeatures; use rustc_target::spec::{MergeFunctions, PanicStrategy}; -use libc::c_int; use std::ffi::CString; -use rustc_feature::UnstableFeatures; use syntax::symbol::sym; -use rustc::bug; +use syntax_pos::symbol::Symbol; -use std::str; use std::slice; +use std::str; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Once; @@ -53,9 +53,7 @@ unsafe fn configure_llvm(sess: &Session) { llvm::LLVMRustInstallFatalErrorHandler(); fn llvm_arg_to_arg_name(full_arg: &str) -> &str { - full_arg.trim().split(|c: char| { - c == '=' || c.is_whitespace() - }).next().unwrap_or("") + full_arg.trim().split(|c: char| c == '=' || c.is_whitespace()).next().unwrap_or("") } let user_specified_args: FxHashSet<_> = sess @@ -78,25 +76,33 @@ unsafe fn configure_llvm(sess: &Session) { } }; add("rustc", true); // fake program name - if sess.time_llvm_passes() { add("-time-passes", false); } - if sess.print_llvm_passes() { add("-debug-pass=Structure", false); } + if sess.time_llvm_passes() { + add("-time-passes", false); + } + if sess.print_llvm_passes() { + add("-debug-pass=Structure", false); + } if sess.opts.debugging_opts.generate_arange_section { add("-generate-arange-section", false); } if get_major_version() >= 8 { - match sess.opts.debugging_opts.merge_functions - .unwrap_or(sess.target.target.options.merge_functions) { - MergeFunctions::Disabled | - MergeFunctions::Trampolines => {} + match sess + .opts + .debugging_opts + .merge_functions + .unwrap_or(sess.target.target.options.merge_functions) + { + MergeFunctions::Disabled | MergeFunctions::Trampolines => {} MergeFunctions::Aliases => { add("-mergefunc-use-aliases", false); } } } - if sess.target.target.target_os == "emscripten" && - sess.panic_strategy() == PanicStrategy::Unwind { + if sess.target.target.target_os == "emscripten" + && sess.panic_strategy() == PanicStrategy::Unwind + { add("-enable-emscripten-cxx-exceptions", false); } @@ -113,8 +119,7 @@ unsafe fn configure_llvm(sess: &Session) { ::rustc_llvm::initialize_available_targets(); - llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, - llvm_args.as_ptr()); + llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr()); } // WARNING: the features after applying `to_llvm_feature` must be known @@ -215,23 +220,21 @@ const POWERPC_WHITELIST: &[(&str, Option)] = &[ ("vsx", Some(sym::powerpc_target_feature)), ]; -const MIPS_WHITELIST: &[(&str, Option)] = &[ - ("fp64", Some(sym::mips_target_feature)), - ("msa", Some(sym::mips_target_feature)), -]; +const MIPS_WHITELIST: &[(&str, Option)] = + &[("fp64", Some(sym::mips_target_feature)), ("msa", Some(sym::mips_target_feature))]; -const WASM_WHITELIST: &[(&str, Option)] = &[ - ("simd128", Some(sym::wasm_target_feature)), - ("atomics", Some(sym::wasm_target_feature)), -]; +const WASM_WHITELIST: &[(&str, Option)] = + &[("simd128", Some(sym::wasm_target_feature)), ("atomics", Some(sym::wasm_target_feature))]; /// When rustdoc is running, provide a list of all known features so that all their respective /// primitives may be documented. /// /// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this /// iterator! -pub fn all_known_features() -> impl Iterator)> { - ARM_WHITELIST.iter().cloned() +pub fn all_known_features() -> impl Iterator)> { + ARM_WHITELIST + .iter() + .cloned() .chain(AARCH64_WHITELIST.iter().cloned()) .chain(X86_WHITELIST.iter().cloned()) .chain(HEXAGON_WHITELIST.iter().cloned()) @@ -241,11 +244,7 @@ pub fn all_known_features() -> impl Iterator) } pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str { - let arch = if sess.target.target.arch == "x86_64" { - "x86" - } else { - &*sess.target.target.arch - }; + let arch = if sess.target.target.arch == "x86_64" { "x86" } else { &*sess.target.target.arch }; match (arch, s) { ("x86", "pclmulqdq") => "pclmul", ("x86", "rdrand") => "rdrnd", @@ -273,12 +272,11 @@ pub fn target_features(sess: &Session) -> Vec { let cstr = CString::new(llvm_feature).unwrap(); unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } }) - .map(|feature| Symbol::intern(feature)).collect() + .map(|feature| Symbol::intern(feature)) + .collect() } -pub fn target_feature_whitelist(sess: &Session) - -> &'static [(&'static str, Option)] -{ +pub fn target_feature_whitelist(sess: &Session) -> &'static [(&'static str, Option)] { match &*sess.target.target.arch { "arm" => ARM_WHITELIST, "aarch64" => AARCH64_WHITELIST, @@ -294,8 +292,7 @@ pub fn target_feature_whitelist(sess: &Session) pub fn print_version() { // Can be called without initializing LLVM unsafe { - println!("LLVM version: {}.{}", - llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor()); + println!("LLVM version: {}.{}", llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor()); } } @@ -305,7 +302,9 @@ pub fn get_major_version() -> u32 { pub fn print_passes() { // Can be called without initializing LLVM - unsafe { llvm::LLVMRustPrintPasses(); } + unsafe { + llvm::LLVMRustPrintPasses(); + } } pub(crate) fn print(req: PrintRequest, sess: &Session) { @@ -323,10 +322,10 @@ pub(crate) fn print(req: PrintRequest, sess: &Session) { pub fn target_cpu(sess: &Session) -> &str { let name = match sess.opts.cg.target_cpu { Some(ref s) => &**s, - None => &*sess.target.target.options.cpu + None => &*sess.target.target.options.cpu, }; if name != "native" { - return name + return name; } unsafe { diff --git a/src/librustc_codegen_llvm/metadata.rs b/src/librustc_codegen_llvm/metadata.rs index bbe42e3b50a2c..d328144a15e12 100644 --- a/src/librustc_codegen_llvm/metadata.rs +++ b/src/librustc_codegen_llvm/metadata.rs @@ -1,17 +1,17 @@ use crate::llvm; -use crate::llvm::{False, ObjectFile, mk_section_iter}; use crate::llvm::archive_ro::ArchiveRO; +use crate::llvm::{mk_section_iter, False, ObjectFile}; use rustc::middle::cstore::MetadataLoader; use rustc_target::spec::Target; -use rustc_data_structures::owning_ref::OwningRef; -use rustc_codegen_ssa::METADATA_FILENAME; use log::debug; +use rustc_codegen_ssa::METADATA_FILENAME; +use rustc_data_structures::owning_ref::OwningRef; use rustc_data_structures::rustc_erase_owner; +use rustc_fs_util::path_to_c_string; use std::path::Path; use std::slice; -use rustc_fs_util::path_to_c_string; pub use rustc_data_structures::sync::MetadataRef; @@ -22,49 +22,42 @@ impl MetadataLoader for LlvmMetadataLoader { // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap // internally to read the file. We also avoid even using a memcpy by // just keeping the archive along while the metadata is in use. - let archive = ArchiveRO::open(filename) - .map(|ar| OwningRef::new(box ar)) - .map_err(|e| { - debug!("llvm didn't like `{}`: {}", filename.display(), e); - format!("failed to read rlib metadata in '{}': {}", filename.display(), e) - })?; - let buf: OwningRef<_, [u8]> = archive - .try_map(|ar| { - ar.iter() - .filter_map(|s| s.ok()) - .find(|sect| sect.name() == Some(METADATA_FILENAME)) - .map(|s| s.data()) - .ok_or_else(|| { - debug!("didn't find '{}' in the archive", METADATA_FILENAME); - format!("failed to read rlib metadata: '{}'", - filename.display()) - }) - })?; + let archive = ArchiveRO::open(filename).map(|ar| OwningRef::new(box ar)).map_err(|e| { + debug!("llvm didn't like `{}`: {}", filename.display(), e); + format!("failed to read rlib metadata in '{}': {}", filename.display(), e) + })?; + let buf: OwningRef<_, [u8]> = archive.try_map(|ar| { + ar.iter() + .filter_map(|s| s.ok()) + .find(|sect| sect.name() == Some(METADATA_FILENAME)) + .map(|s| s.data()) + .ok_or_else(|| { + debug!("didn't find '{}' in the archive", METADATA_FILENAME); + format!("failed to read rlib metadata: '{}'", filename.display()) + }) + })?; Ok(rustc_erase_owner!(buf)) } - fn get_dylib_metadata(&self, - target: &Target, - filename: &Path) - -> Result { + fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result { unsafe { let buf = path_to_c_string(filename); let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()) .ok_or_else(|| format!("error reading library: '{}'", filename.display()))?; - let of = ObjectFile::new(mb) - .map(|of| OwningRef::new(box of)) - .ok_or_else(|| format!("provided path not an object file: '{}'", - filename.display()))?; + let of = ObjectFile::new(mb).map(|of| OwningRef::new(box of)).ok_or_else(|| { + format!("provided path not an object file: '{}'", filename.display()) + })?; let buf = of.try_map(|of| search_meta_section(of, target, filename))?; Ok(rustc_erase_owner!(buf)) } } } -fn search_meta_section<'a>(of: &'a ObjectFile, - target: &Target, - filename: &Path) - -> Result<&'a [u8], String> { +fn search_meta_section<'a>( + of: &'a ObjectFile, + target: &Target, + filename: &Path, +) -> Result<&'a [u8], String> { unsafe { let si = mk_section_iter(of.llof); while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { @@ -72,11 +65,13 @@ fn search_meta_section<'a>(of: &'a ObjectFile, let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf); let name = name_buf.map_or( String::new(), // We got a NULL ptr, ignore `name_len`. - |buf| String::from_utf8( - slice::from_raw_parts(buf.as_ptr() as *const u8, - name_len as usize) - .to_vec() - ).unwrap() + |buf| { + String::from_utf8( + slice::from_raw_parts(buf.as_ptr() as *const u8, name_len as usize) + .to_vec(), + ) + .unwrap() + }, ); debug!("get_metadata_section: name {}", name); if read_metadata_section_name(target) == name { @@ -107,11 +102,7 @@ pub fn metadata_section_name(target: &Target) -> &'static str { // As a result, we choose a slightly shorter name! As to why // `.note.rustc` works on MinGW, that's another good question... - if target.options.is_like_osx { - "__DATA,.rustc" - } else { - ".rustc" - } + if target.options.is_like_osx { "__DATA,.rustc" } else { ".rustc" } } fn read_metadata_section_name(_target: &Target) -> &'static str { diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs index 9f6bdd2390082..e0a946a38e4d0 100644 --- a/src/librustc_codegen_llvm/mono_item.rs +++ b/src/librustc_codegen_llvm/mono_item.rs @@ -4,28 +4,32 @@ use crate::base; use crate::context::CodegenCx; use crate::llvm; use crate::type_of::LayoutLlvmExt; +use log::debug; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::mir::mono::{Linkage, Visibility}; -use rustc::ty::{TypeFoldable, Instance}; use rustc::ty::layout::{FnAbiExt, LayoutOf}; +use rustc::ty::{Instance, TypeFoldable}; use rustc_codegen_ssa::traits::*; -use log::debug; pub use rustc::mir::mono::MonoItem; impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> { - fn predefine_static(&self, - def_id: DefId, - linkage: Linkage, - visibility: Visibility, - symbol_name: &str) { + fn predefine_static( + &self, + def_id: DefId, + linkage: Linkage, + visibility: Visibility, + symbol_name: &str, + ) { let instance = Instance::mono(self.tcx, def_id); let ty = instance.ty(self.tcx); let llty = self.layout_of(ty).llvm_type(self); let g = self.define_global(symbol_name, llty).unwrap_or_else(|| { - self.sess().span_fatal(self.tcx.def_span(def_id), - &format!("symbol `{}` is already defined", symbol_name)) + self.sess().span_fatal( + self.tcx.def_span(def_id), + &format!("symbol `{}` is already defined", symbol_name), + ) }); unsafe { @@ -36,21 +40,21 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> { self.instances.borrow_mut().insert(instance, g); } - fn predefine_fn(&self, - instance: Instance<'tcx>, - linkage: Linkage, - visibility: Visibility, - symbol_name: &str) { - assert!(!instance.substs.needs_infer() && - !instance.substs.has_param_types()); + fn predefine_fn( + &self, + instance: Instance<'tcx>, + linkage: Linkage, + visibility: Visibility, + symbol_name: &str, + ) { + assert!(!instance.substs.needs_infer() && !instance.substs.has_param_types()); let fn_abi = FnAbi::of_instance(self, instance, &[]); let lldecl = self.declare_fn(symbol_name, &fn_abi); unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) }; let attrs = self.tcx.codegen_fn_attrs(instance.def_id()); base::set_link_section(lldecl, &attrs); - if linkage == Linkage::LinkOnceODR || - linkage == Linkage::WeakODR { + if linkage == Linkage::LinkOnceODR || linkage == Linkage::WeakODR { llvm::SetUniqueComdat(self.llmod, lldecl); } @@ -58,8 +62,10 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> { // compiler-rt, then we want to implicitly compile everything with hidden // visibility as we're going to link this object all over the place but // don't want the symbols to get exported. - if linkage != Linkage::Internal && linkage != Linkage::Private && - self.tcx.is_compiler_builtins(LOCAL_CRATE) { + if linkage != Linkage::Internal + && linkage != Linkage::Private + && self.tcx.is_compiler_builtins(LOCAL_CRATE) + { unsafe { llvm::LLVMRustSetVisibility(lldecl, llvm::Visibility::Hidden); } diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index e6677f3d25b9c..628b6fe39e6bf 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -1,21 +1,21 @@ pub use crate::llvm::Type; +use crate::context::CodegenCx; use crate::llvm; use crate::llvm::{Bool, False, True}; -use crate::context::CodegenCx; use crate::value::Value; -use rustc_codegen_ssa::traits::*; use rustc::bug; +use rustc_codegen_ssa::traits::*; +use crate::abi::{FnAbiLlvmExt, LlvmType}; use crate::common; use crate::type_of::LayoutLlvmExt; -use crate::abi::{LlvmType, FnAbiLlvmExt}; -use syntax::ast; -use rustc::ty::Ty; use rustc::ty::layout::{self, Align, Size, TyLayout}; -use rustc_target::abi::call::{CastTarget, FnAbi, Reg}; -use rustc_data_structures::small_c_str::SmallCStr; +use rustc::ty::Ty; use rustc_codegen_ssa::common::TypeKind; +use rustc_data_structures::small_c_str::SmallCStr; +use rustc_target::abi::call::{CastTarget, FnAbi, Reg}; +use syntax::ast; use std::fmt; use std::ptr; @@ -30,56 +30,44 @@ impl PartialEq for Type { impl fmt::Debug for Type { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&llvm::build_string(|s| unsafe { - llvm::LLVMRustWriteTypeToString(self, s); - }).expect("non-UTF8 type description from LLVM")) + f.write_str( + &llvm::build_string(|s| unsafe { + llvm::LLVMRustWriteTypeToString(self, s); + }) + .expect("non-UTF8 type description from LLVM"), + ) } } impl CodegenCx<'ll, 'tcx> { crate fn type_named_struct(&self, name: &str) -> &'ll Type { let name = SmallCStr::new(name); - unsafe { - llvm::LLVMStructCreateNamed(self.llcx, name.as_ptr()) - } + unsafe { llvm::LLVMStructCreateNamed(self.llcx, name.as_ptr()) } } crate fn set_struct_body(&self, ty: &'ll Type, els: &[&'ll Type], packed: bool) { - unsafe { - llvm::LLVMStructSetBody(ty, els.as_ptr(), - els.len() as c_uint, packed as Bool) - } + unsafe { llvm::LLVMStructSetBody(ty, els.as_ptr(), els.len() as c_uint, packed as Bool) } } crate fn type_void(&self) -> &'ll Type { - unsafe { - llvm::LLVMVoidTypeInContext(self.llcx) - } + unsafe { llvm::LLVMVoidTypeInContext(self.llcx) } } crate fn type_metadata(&self) -> &'ll Type { - unsafe { - llvm::LLVMRustMetadataTypeInContext(self.llcx) - } + unsafe { llvm::LLVMRustMetadataTypeInContext(self.llcx) } } ///x Creates an integer type with the given number of bits, e.g., i24 crate fn type_ix(&self, num_bits: u64) -> &'ll Type { - unsafe { - llvm::LLVMIntTypeInContext(self.llcx, num_bits as c_uint) - } + unsafe { llvm::LLVMIntTypeInContext(self.llcx, num_bits as c_uint) } } crate fn type_x86_mmx(&self) -> &'ll Type { - unsafe { - llvm::LLVMX86MMXTypeInContext(self.llcx) - } + unsafe { llvm::LLVMX86MMXTypeInContext(self.llcx) } } crate fn type_vector(&self, ty: &'ll Type, len: u64) -> &'ll Type { - unsafe { - llvm::LLVMVectorType(ty, len as c_uint) - } + unsafe { llvm::LLVMVectorType(ty, len as c_uint) } } crate fn func_params_types(&self, ty: &'ll Type) -> Vec<&'ll Type> { @@ -141,60 +129,38 @@ impl CodegenCx<'ll, 'tcx> { self.type_array(self.type_from_integer(unit), size / unit_size) } - crate fn type_variadic_func( - &self, - args: &[&'ll Type], - ret: &'ll Type - ) -> &'ll Type { - unsafe { - llvm::LLVMFunctionType(ret, args.as_ptr(), - args.len() as c_uint, True) - } + crate fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { + unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) } } crate fn type_array(&self, ty: &'ll Type, len: u64) -> &'ll Type { - unsafe { - llvm::LLVMRustArrayType(ty, len) - } + unsafe { llvm::LLVMRustArrayType(ty, len) } } } impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn type_i1(&self) -> &'ll Type { - unsafe { - llvm::LLVMInt1TypeInContext(self.llcx) - } + unsafe { llvm::LLVMInt1TypeInContext(self.llcx) } } fn type_i8(&self) -> &'ll Type { - unsafe { - llvm::LLVMInt8TypeInContext(self.llcx) - } + unsafe { llvm::LLVMInt8TypeInContext(self.llcx) } } - fn type_i16(&self) -> &'ll Type { - unsafe { - llvm::LLVMInt16TypeInContext(self.llcx) - } + unsafe { llvm::LLVMInt16TypeInContext(self.llcx) } } fn type_i32(&self) -> &'ll Type { - unsafe { - llvm::LLVMInt32TypeInContext(self.llcx) - } + unsafe { llvm::LLVMInt32TypeInContext(self.llcx) } } fn type_i64(&self) -> &'ll Type { - unsafe { - llvm::LLVMInt64TypeInContext(self.llcx) - } + unsafe { llvm::LLVMInt64TypeInContext(self.llcx) } } fn type_i128(&self) -> &'ll Type { - unsafe { - llvm::LLVMIntTypeInContext(self.llcx, 128) - } + unsafe { llvm::LLVMIntTypeInContext(self.llcx, 128) } } fn type_isize(&self) -> &'ll Type { @@ -202,62 +168,47 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { } fn type_f32(&self) -> &'ll Type { - unsafe { - llvm::LLVMFloatTypeInContext(self.llcx) - } + unsafe { llvm::LLVMFloatTypeInContext(self.llcx) } } fn type_f64(&self) -> &'ll Type { - unsafe { - llvm::LLVMDoubleTypeInContext(self.llcx) - } + unsafe { llvm::LLVMDoubleTypeInContext(self.llcx) } } - fn type_func( - &self, - args: &[&'ll Type], - ret: &'ll Type - ) -> &'ll Type { - unsafe { - llvm::LLVMFunctionType(ret, args.as_ptr(), - args.len() as c_uint, False) - } + fn type_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { + unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, False) } } - fn type_struct( - &self, - els: &[&'ll Type], - packed: bool - ) -> &'ll Type { + fn type_struct(&self, els: &[&'ll Type], packed: bool) -> &'ll Type { unsafe { - llvm::LLVMStructTypeInContext(self.llcx, els.as_ptr(), - els.len() as c_uint, - packed as Bool) + llvm::LLVMStructTypeInContext( + self.llcx, + els.as_ptr(), + els.len() as c_uint, + packed as Bool, + ) } } fn type_kind(&self, ty: &'ll Type) -> TypeKind { - unsafe { - llvm::LLVMRustGetTypeKind(ty).to_generic() - } + unsafe { llvm::LLVMRustGetTypeKind(ty).to_generic() } } fn type_ptr_to(&self, ty: &'ll Type) -> &'ll Type { - assert_ne!(self.type_kind(ty), TypeKind::Function, - "don't call ptr_to on function types, use ptr_to_llvm_type on FnAbi instead"); + assert_ne!( + self.type_kind(ty), + TypeKind::Function, + "don't call ptr_to on function types, use ptr_to_llvm_type on FnAbi instead" + ); ty.ptr_to() } fn element_type(&self, ty: &'ll Type) -> &'ll Type { - unsafe { - llvm::LLVMGetElementType(ty) - } + unsafe { llvm::LLVMGetElementType(ty) } } fn vector_length(&self, ty: &'ll Type) -> usize { - unsafe { - llvm::LLVMGetVectorSize(ty) as usize - } + unsafe { llvm::LLVMGetVectorSize(ty) as usize } } fn float_width(&self, ty: &'ll Type) -> usize { @@ -266,14 +217,12 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { TypeKind::Double => 64, TypeKind::X86_FP80 => 80, TypeKind::FP128 | TypeKind::PPC_FP128 => 128, - _ => bug!("llvm_float_width called on a non-float type") + _ => bug!("llvm_float_width called on a non-float type"), } } fn int_width(&self, ty: &'ll Type) -> u64 { - unsafe { - llvm::LLVMGetIntTypeWidth(ty) as u64 - } + unsafe { llvm::LLVMGetIntTypeWidth(ty) as u64 } } fn val_ty(&self, v: &'ll Value) -> &'ll Type { @@ -283,19 +232,12 @@ impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { impl Type { pub fn i8_llcx(llcx: &llvm::Context) -> &Type { - unsafe { - llvm::LLVMInt8TypeInContext(llcx) - } + unsafe { llvm::LLVMInt8TypeInContext(llcx) } } // Creates an integer type with the given number of bits, e.g., i24 - pub fn ix_llcx( - llcx: &llvm::Context, - num_bits: u64 - ) -> &Type { - unsafe { - llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint) - } + pub fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> &Type { + unsafe { llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint) } } pub fn i8p_llcx(llcx: &'ll llvm::Context) -> &'ll Type { @@ -303,13 +245,10 @@ impl Type { } fn ptr_to(&self) -> &Type { - unsafe { - llvm::LLVMPointerType(&self, 0) - } + unsafe { llvm::LLVMPointerType(&self, 0) } } } - impl LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn backend_type(&self, layout: TyLayout<'tcx>) -> &'ll Type { layout.llvm_type(self) @@ -330,7 +269,7 @@ impl LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { &self, layout: TyLayout<'tcx>, index: usize, - immediate: bool + immediate: bool, ) -> &'ll Type { layout.scalar_pair_element_llvm_type(self, index, immediate) } diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index f9cbf4bbe4502..3e6c75e4d6f82 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -1,20 +1,21 @@ -use crate::abi::{FnAbi}; +use crate::abi::FnAbi; use crate::common::*; use crate::type_::Type; -use rustc::ty::{self, Ty, TypeFoldable}; -use rustc::ty::layout::{self, Align, LayoutOf, FnAbiExt, PointeeInfo, Size, TyLayout}; -use rustc_target::abi::TyLayoutMethods; -use rustc::ty::print::obsolete::DefPathBasedNames; -use rustc_codegen_ssa::traits::*; use log::debug; use rustc::bug; +use rustc::ty::layout::{self, Align, FnAbiExt, LayoutOf, PointeeInfo, Size, TyLayout}; +use rustc::ty::print::obsolete::DefPathBasedNames; +use rustc::ty::{self, Ty, TypeFoldable}; +use rustc_codegen_ssa::traits::*; +use rustc_target::abi::TyLayoutMethods; use std::fmt::Write; -fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - layout: TyLayout<'tcx>, - defer: &mut Option<(&'a Type, TyLayout<'tcx>)>) - -> &'a Type { +fn uncached_llvm_type<'a, 'tcx>( + cx: &CodegenCx<'a, 'tcx>, + layout: TyLayout<'tcx>, + defer: &mut Option<(&'a Type, TyLayout<'tcx>)>, +) -> &'a Type { match layout.abi { layout::Abi::Scalar(_) => bug!("handled elsewhere"), layout::Abi::Vector { ref element, count } => { @@ -25,24 +26,27 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // x86_mmx" type. In general there shouldn't be a need for other // one-element SIMD vectors, so it's assumed this won't clash with // much else. - let use_x86_mmx = count == 1 && layout.size.bits() == 64 && - (cx.sess().target.target.arch == "x86" || - cx.sess().target.target.arch == "x86_64"); + let use_x86_mmx = count == 1 + && layout.size.bits() == 64 + && (cx.sess().target.target.arch == "x86" + || cx.sess().target.target.arch == "x86_64"); if use_x86_mmx { - return cx.type_x86_mmx() + return cx.type_x86_mmx(); } else { let element = layout.scalar_llvm_type_at(cx, element, Size::ZERO); return cx.type_vector(element, count); } } layout::Abi::ScalarPair(..) => { - return cx.type_struct( &[ - layout.scalar_pair_element_llvm_type(cx, 0, false), - layout.scalar_pair_element_llvm_type(cx, 1, false), - ], false); + return cx.type_struct( + &[ + layout.scalar_pair_element_llvm_type(cx, 0, false), + layout.scalar_pair_element_llvm_type(cx, 1, false), + ], + false, + ); } - layout::Abi::Uninhabited | - layout::Abi::Aggregate { .. } => {} + layout::Abi::Uninhabited | layout::Abi::Aggregate { .. } => {} } let name = match layout.ty.kind { @@ -79,9 +83,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let fill = cx.type_padding_filler(layout.size, layout.align.abi); let packed = false; match name { - None => { - cx.type_struct(&[fill], packed) - } + None => cx.type_struct(&[fill], packed), Some(ref name) => { let llty = cx.type_named_struct(name); cx.set_struct_body(llty, &[fill], packed); @@ -92,25 +94,24 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, layout::FieldPlacement::Array { count, .. } => { cx.type_array(layout.field(cx, 0).llvm_type(cx), count) } - layout::FieldPlacement::Arbitrary { .. } => { - match name { - None => { - let (llfields, packed) = struct_llfields(cx, layout); - cx.type_struct( &llfields, packed) - } - Some(ref name) => { - let llty = cx.type_named_struct( name); - *defer = Some((llty, layout)); - llty - } + layout::FieldPlacement::Arbitrary { .. } => match name { + None => { + let (llfields, packed) = struct_llfields(cx, layout); + cx.type_struct(&llfields, packed) } - } + Some(ref name) => { + let llty = cx.type_named_struct(name); + *defer = Some((llty, layout)); + llty + } + }, } } -fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - layout: TyLayout<'tcx>) - -> (Vec<&'a Type>, bool) { +fn struct_llfields<'a, 'tcx>( + cx: &CodegenCx<'a, 'tcx>, + layout: TyLayout<'tcx>, +) -> (Vec<&'a Type>, bool) { debug!("struct_llfields: {:#?}", layout); let field_count = layout.fields.count(); @@ -121,19 +122,24 @@ fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, for i in layout.fields.index_by_increasing_offset() { let target_offset = layout.fields.offset(i as usize); let field = layout.field(cx, i); - let effective_field_align = layout.align.abi - .min(field.align.abi) - .restrict_for_offset(target_offset); + let effective_field_align = + layout.align.abi.min(field.align.abi).restrict_for_offset(target_offset); packed |= effective_field_align < field.align.abi; - debug!("struct_llfields: {}: {:?} offset: {:?} target_offset: {:?} \ + debug!( + "struct_llfields: {}: {:?} offset: {:?} target_offset: {:?} \ effective_field_align: {}", - i, field, offset, target_offset, effective_field_align.bytes()); + i, + field, + offset, + target_offset, + effective_field_align.bytes() + ); assert!(target_offset >= offset); let padding = target_offset - offset; let padding_align = prev_effective_align.min(effective_field_align); assert_eq!(offset.align_to(padding_align) + padding, target_offset); - result.push(cx.type_padding_filler( padding, padding_align)); + result.push(cx.type_padding_filler(padding, padding_align)); debug!(" padding before: {:?}", padding); result.push(field.llvm_type(cx)); @@ -142,19 +148,19 @@ fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } if !layout.is_unsized() && field_count > 0 { if offset > layout.size { - bug!("layout: {:#?} stride: {:?} offset: {:?}", - layout, layout.size, offset); + bug!("layout: {:#?} stride: {:?} offset: {:?}", layout, layout.size, offset); } let padding = layout.size - offset; let padding_align = prev_effective_align; assert_eq!(offset.align_to(padding_align) + padding, layout.size); - debug!("struct_llfields: pad_bytes: {:?} offset: {:?} stride: {:?}", - padding, offset, layout.size); + debug!( + "struct_llfields: pad_bytes: {:?} offset: {:?} stride: {:?}", + padding, offset, layout.size + ); result.push(cx.type_padding_filler(padding, padding_align)); assert_eq!(result.len(), 1 + field_count * 2); } else { - debug!("struct_llfields: offset: {:?} stride: {:?}", - offset, layout.size); + debug!("struct_llfields: offset: {:?} stride: {:?}", offset, layout.size); } (result, packed) @@ -180,33 +186,38 @@ pub trait LayoutLlvmExt<'tcx> { fn is_llvm_scalar_pair(&self) -> bool; fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type; fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type; - fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, - scalar: &layout::Scalar, offset: Size) -> &'a Type; - fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>, - index: usize, immediate: bool) -> &'a Type; + fn scalar_llvm_type_at<'a>( + &self, + cx: &CodegenCx<'a, 'tcx>, + scalar: &layout::Scalar, + offset: Size, + ) -> &'a Type; + fn scalar_pair_element_llvm_type<'a>( + &self, + cx: &CodegenCx<'a, 'tcx>, + index: usize, + immediate: bool, + ) -> &'a Type; fn llvm_field_index(&self, index: usize) -> u64; - fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) - -> Option; + fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) -> Option; } impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { fn is_llvm_immediate(&self) -> bool { match self.abi { - layout::Abi::Scalar(_) | - layout::Abi::Vector { .. } => true, + layout::Abi::Scalar(_) | layout::Abi::Vector { .. } => true, layout::Abi::ScalarPair(..) => false, - layout::Abi::Uninhabited | - layout::Abi::Aggregate { .. } => self.is_zst() + layout::Abi::Uninhabited | layout::Abi::Aggregate { .. } => self.is_zst(), } } fn is_llvm_scalar_pair(&self) -> bool { match self.abi { layout::Abi::ScalarPair(..) => true, - layout::Abi::Uninhabited | - layout::Abi::Scalar(_) | - layout::Abi::Vector { .. } | - layout::Abi::Aggregate { .. } => false + layout::Abi::Uninhabited + | layout::Abi::Scalar(_) + | layout::Abi::Vector { .. } + | layout::Abi::Aggregate { .. } => false, } } @@ -229,27 +240,23 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { return llty; } let llty = match self.ty.kind { - ty::Ref(_, ty, _) | - ty::RawPtr(ty::TypeAndMut { ty, .. }) => { + ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => { cx.type_ptr_to(cx.layout_of(ty).llvm_type(cx)) } ty::Adt(def, _) if def.is_box() => { cx.type_ptr_to(cx.layout_of(self.ty.boxed_ty()).llvm_type(cx)) } - ty::FnPtr(sig) => { - cx.fn_ptr_backend_type(&FnAbi::of_fn_ptr(cx, sig, &[])) - } - _ => self.scalar_llvm_type_at(cx, scalar, Size::ZERO) + ty::FnPtr(sig) => cx.fn_ptr_backend_type(&FnAbi::of_fn_ptr(cx, sig, &[])), + _ => self.scalar_llvm_type_at(cx, scalar, Size::ZERO), }; cx.scalar_lltypes.borrow_mut().insert(self.ty, llty); return llty; } - // Check the cache. let variant_index = match self.variants { layout::Variants::Single { index } => Some(index), - _ => None + _ => None, }; if let Some(&llty) = cx.lltypes.borrow().get(&(self.ty, variant_index)) { return llty; @@ -294,10 +301,14 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { self.llvm_type(cx) } - fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, - scalar: &layout::Scalar, offset: Size) -> &'a Type { + fn scalar_llvm_type_at<'a>( + &self, + cx: &CodegenCx<'a, 'tcx>, + scalar: &layout::Scalar, + offset: Size, + ) -> &'a Type { match scalar.value { - layout::Int(i, _) => cx.type_from_integer( i), + layout::Int(i, _) => cx.type_from_integer(i), layout::F32 => cx.type_f32(), layout::F64 => cx.type_f64(), layout::Pointer => { @@ -312,13 +323,16 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { } } - fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>, - index: usize, immediate: bool) -> &'a Type { + fn scalar_pair_element_llvm_type<'a>( + &self, + cx: &CodegenCx<'a, 'tcx>, + index: usize, + immediate: bool, + ) -> &'a Type { // HACK(eddyb) special-case fat pointers until LLVM removes // pointee types, to avoid bitcasting every `OperandRef::deref`. match self.ty.kind { - ty::Ref(..) | - ty::RawPtr(_) => { + ty::Ref(..) | ty::RawPtr(_) => { return self.field(cx, index).llvm_type(cx); } ty::Adt(def, _) if def.is_box() => { @@ -330,7 +344,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { let (a, b) = match self.abi { layout::Abi::ScalarPair(ref a, ref b) => (a, b), - _ => bug!("TyLayout::scalar_pair_element_llty({:?}): not applicable", self) + _ => bug!("TyLayout::scalar_pair_element_llty({:?}): not applicable", self), }; let scalar = [a, b][index]; @@ -344,18 +358,14 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { return cx.type_i1(); } - let offset = if index == 0 { - Size::ZERO - } else { - a.value.size(cx).align_to(b.value.align(cx).abi) - }; + let offset = + if index == 0 { Size::ZERO } else { a.value.size(cx).align_to(b.value.align(cx).abi) }; self.scalar_llvm_type_at(cx, scalar, offset) } fn llvm_field_index(&self, index: usize) -> u64 { match self.abi { - layout::Abi::Scalar(_) | - layout::Abi::ScalarPair(..) => { + layout::Abi::Scalar(_) | layout::Abi::ScalarPair(..) => { bug!("TyLayout::llvm_field_index({:?}): not applicable", self) } _ => {} @@ -365,9 +375,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { bug!("TyLayout::llvm_field_index({:?}): not applicable", self) } - layout::FieldPlacement::Array { .. } => { - index as u64 - } + layout::FieldPlacement::Array { .. } => index as u64, layout::FieldPlacement::Arbitrary { .. } => { 1 + (self.fields.memory_index(index) as u64) * 2 @@ -375,8 +383,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { } } - fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) - -> Option { + fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) -> Option { if let Some(&pointee) = cx.pointee_infos.borrow().get(&(self.ty, offset)) { return pointee; } diff --git a/src/librustc_codegen_llvm/va_arg.rs b/src/librustc_codegen_llvm/va_arg.rs index 86b0ad761af6a..9bc3eec60ae04 100644 --- a/src/librustc_codegen_llvm/va_arg.rs +++ b/src/librustc_codegen_llvm/va_arg.rs @@ -2,17 +2,19 @@ use crate::builder::Builder; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use rustc_codegen_ssa::mir::operand::OperandRef; -use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods, ConstMethods, DerivedTypeMethods}; use rustc::ty::layout::{Align, HasDataLayout, HasTyCtxt, LayoutOf, Size}; use rustc::ty::Ty; +use rustc_codegen_ssa::mir::operand::OperandRef; +use rustc_codegen_ssa::traits::{ + BaseTypeMethods, BuilderMethods, ConstMethods, DerivedTypeMethods, +}; #[allow(dead_code)] fn round_pointer_up_to_alignment( bx: &mut Builder<'a, 'll, 'tcx>, addr: &'ll Value, align: Align, - ptr_ty: &'ll Type + ptr_ty: &'ll Type, ) -> &'ll Value { let mut ptr_as_int = bx.ptrtoint(addr, bx.cx().type_isize()); ptr_as_int = bx.add(ptr_as_int, bx.cx().const_i32(align.bytes() as i32 - 1)); @@ -27,7 +29,7 @@ fn emit_direct_ptr_va_arg( size: Size, align: Align, slot_size: Align, - allow_higher_align: bool + allow_higher_align: bool, ) -> (&'ll Value, Align) { let va_list_ptr_ty = bx.cx().type_ptr_to(bx.cx.type_i8p()); let va_list_addr = if list.layout.llvm_type(bx.cx) != va_list_ptr_ty { @@ -44,14 +46,12 @@ fn emit_direct_ptr_va_arg( (ptr, slot_size) }; - let aligned_size = size.align_to(slot_size).bytes() as i32; let full_direct_size = bx.cx().const_i32(aligned_size); let next = bx.inbounds_gep(addr, &[full_direct_size]); bx.store(next, va_list_addr, bx.tcx().data_layout.pointer_align.abi); - if size.bytes() < slot_size.bytes() && - &*bx.tcx().sess.target.target.target_endian == "big" { + if size.bytes() < slot_size.bytes() && &*bx.tcx().sess.target.target.target_endian == "big" { let adjusted_size = bx.cx().const_i32((slot_size.bytes() - size.bytes()) as i32); let adjusted = bx.inbounds_gep(addr, &[adjusted_size]); (bx.bitcast(adjusted, bx.cx().type_ptr_to(llty)), addr_align) @@ -66,20 +66,20 @@ fn emit_ptr_va_arg( target_ty: Ty<'tcx>, indirect: bool, slot_size: Align, - allow_higher_align: bool + allow_higher_align: bool, ) -> &'ll Value { let layout = bx.cx.layout_of(target_ty); let (llty, size, align) = if indirect { - (bx.cx.layout_of(bx.cx.tcx.mk_imm_ptr(target_ty)).llvm_type(bx.cx), - bx.cx.data_layout().pointer_size, - bx.cx.data_layout().pointer_align) + ( + bx.cx.layout_of(bx.cx.tcx.mk_imm_ptr(target_ty)).llvm_type(bx.cx), + bx.cx.data_layout().pointer_size, + bx.cx.data_layout().pointer_align, + ) } else { - (layout.llvm_type(bx.cx), - layout.size, - layout.align) + (layout.llvm_type(bx.cx), layout.size, layout.align) }; - let (addr, addr_align) = emit_direct_ptr_va_arg(bx, list, llty, size, align.abi, - slot_size, allow_higher_align); + let (addr, addr_align) = + emit_direct_ptr_va_arg(bx, list, llty, size, align.abi, slot_size, allow_higher_align); if indirect { let tmp_ret = bx.load(addr, addr_align); bx.load(tmp_ret, align.abi) @@ -100,38 +100,30 @@ pub(super) fn emit_va_arg( match (&**arch, target.options.is_like_windows) { // Windows x86 ("x86", true) => { - emit_ptr_va_arg(bx, addr, target_ty, false, - Align::from_bytes(4).unwrap(), false) + emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(4).unwrap(), false) } // Generic x86 ("x86", _) => { - emit_ptr_va_arg(bx, addr, target_ty, false, - Align::from_bytes(4).unwrap(), true) + emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(4).unwrap(), true) } // Windows AArch64 ("aarch64", true) => { - emit_ptr_va_arg(bx, addr, target_ty, false, - Align::from_bytes(8).unwrap(), false) + emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(8).unwrap(), false) } // iOS AArch64 ("aarch64", _) if target.target_os == "ios" => { - emit_ptr_va_arg(bx, addr, target_ty, false, - Align::from_bytes(8).unwrap(), true) + emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(8).unwrap(), true) } // Windows x86_64 ("x86_64", true) => { let target_ty_size = bx.cx.size_of(target_ty).bytes(); - let indirect = if target_ty_size > 8 || !target_ty_size.is_power_of_two() { - true - } else { - false - }; - emit_ptr_va_arg(bx, addr, target_ty, indirect, - Align::from_bytes(8).unwrap(), false) + let indirect = + if target_ty_size > 8 || !target_ty_size.is_power_of_two() { true } else { false }; + emit_ptr_va_arg(bx, addr, target_ty, indirect, Align::from_bytes(8).unwrap(), false) } // For all other architecture/OS combinations fall back to using // the LLVM va_arg instruction. // https://llvm.org/docs/LangRef.html#va-arg-instruction - _ => bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)) + _ => bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)), } } diff --git a/src/librustc_codegen_llvm/value.rs b/src/librustc_codegen_llvm/value.rs index eadbe754e8e41..1338a229566c8 100644 --- a/src/librustc_codegen_llvm/value.rs +++ b/src/librustc_codegen_llvm/value.rs @@ -20,11 +20,13 @@ impl Hash for Value { } } - impl fmt::Debug for Value { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&llvm::build_string(|s| unsafe { - llvm::LLVMRustWriteValueToString(self, s); - }).expect("non-UTF8 value description from LLVM")) + f.write_str( + &llvm::build_string(|s| unsafe { + llvm::LLVMRustWriteValueToString(self, s); + }) + .expect("non-UTF8 value description from LLVM"), + ) } } diff --git a/src/librustc_codegen_ssa/back/archive.rs b/src/librustc_codegen_ssa/back/archive.rs index 8d2120a345a8d..5f222311926ca 100644 --- a/src/librustc_codegen_ssa/back/archive.rs +++ b/src/librustc_codegen_ssa/back/archive.rs @@ -4,27 +4,35 @@ use syntax::symbol::Symbol; use std::io; use std::path::{Path, PathBuf}; -pub fn find_library(name: Symbol, search_paths: &[PathBuf], sess: &Session) - -> PathBuf { +pub fn find_library(name: Symbol, search_paths: &[PathBuf], sess: &Session) -> PathBuf { // On Windows, static libraries sometimes show up as libfoo.a and other // times show up as foo.lib - let oslibname = format!("{}{}{}", - sess.target.target.options.staticlib_prefix, - name, - sess.target.target.options.staticlib_suffix); + let oslibname = format!( + "{}{}{}", + sess.target.target.options.staticlib_prefix, + name, + sess.target.target.options.staticlib_suffix + ); let unixlibname = format!("lib{}.a", name); for path in search_paths { debug!("looking for {} inside {:?}", name, path); let test = path.join(&oslibname); - if test.exists() { return test } + if test.exists() { + return test; + } if oslibname != unixlibname { let test = path.join(&unixlibname); - if test.exists() { return test } + if test.exists() { + return test; + } } } - sess.fatal(&format!("could not find native static library `{}`, \ - perhaps an -L flag is missing?", name)); + sess.fatal(&format!( + "could not find native static library `{}`, \ + perhaps an -L flag is missing?", + name + )); } pub trait ArchiveBuilder<'a> { diff --git a/src/librustc_codegen_ssa/back/command.rs b/src/librustc_codegen_ssa/back/command.rs index b8501f0e12a70..5595386be2431 100644 --- a/src/librustc_codegen_ssa/back/command.rs +++ b/src/librustc_codegen_ssa/back/command.rs @@ -22,7 +22,7 @@ pub struct Command { enum Program { Normal(OsString), CmdBatScript(OsString), - Lld(OsString, LldFlavor) + Lld(OsString, LldFlavor), } impl Command { @@ -39,12 +39,7 @@ impl Command { } fn _new(program: Program) -> Command { - Command { - program, - args: Vec::new(), - env: Vec::new(), - env_remove: Vec::new(), - } + Command { program, args: Vec::new(), env: Vec::new(), env_remove: Vec::new() } } pub fn arg>(&mut self, arg: P) -> &mut Command { @@ -72,8 +67,9 @@ impl Command { } pub fn env(&mut self, key: K, value: V) -> &mut Command - where K: AsRef, - V: AsRef + where + K: AsRef, + V: AsRef, { self._env(key.as_ref(), value.as_ref()); self @@ -84,7 +80,8 @@ impl Command { } pub fn env_remove(&mut self, key: K) -> &mut Command - where K: AsRef, + where + K: AsRef, { self._env_remove(key.as_ref()); self @@ -122,7 +119,7 @@ impl Command { for k in &self.env_remove { ret.env_remove(k); } - return ret + return ret; } // extensions @@ -141,14 +138,14 @@ impl Command { // We mostly only care about Windows in this method, on Unix the limits // can be gargantuan anyway so we're pretty unlikely to hit them if cfg!(unix) { - return false + return false; } // Right now LLD doesn't support the `@` syntax of passing an argument // through files, so regardless of the platform we try to go to the OS // on this one. if let Program::Lld(..) = self.program { - return false + return false; } // Ok so on Windows to spawn a process is 32,768 characters in its @@ -174,8 +171,7 @@ impl Command { // [1]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx // [2]: https://blogs.msdn.microsoft.com/oldnewthing/20031210-00/?p=41553 - let estimated_command_line_len = - self.args.iter().map(|a| a.len()).sum::(); + let estimated_command_line_len = self.args.iter().map(|a| a.len()).sum::(); estimated_command_line_len > 1024 * 6 } } diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index a2b50ea8e2bf7..f3420f9a9f9fd 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -1,88 +1,98 @@ -/// For all the linkers we support, and information they might -/// need out of the shared crate context before we get rid of it. - -use rustc::session::{Session, filesearch}; +use rustc::hir::def_id::CrateNum; +use rustc::middle::cstore::{EncodedMetadata, LibSource, NativeLibrary, NativeLibraryKind}; +use rustc::middle::dependency_format::Linkage; use rustc::session::config::{ - self, DebugInfo, OutputFilenames, OutputType, PrintRequest, Sanitizer + self, DebugInfo, OutputFilenames, OutputType, PrintRequest, Sanitizer, }; use rustc::session::search_paths::PathKind; -use rustc::middle::dependency_format::Linkage; -use rustc::middle::cstore::{EncodedMetadata, LibSource, NativeLibrary, NativeLibraryKind}; +/// For all the linkers we support, and information they might +/// need out of the shared crate context before we get rid of it. +use rustc::session::{filesearch, Session}; use rustc::util::common::{time, time_ext}; -use rustc::hir::def_id::CrateNum; use rustc_data_structures::fx::FxHashSet; use rustc_fs_util::fix_windows_verbatim_for_gcc; -use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor}; +use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel}; use syntax::symbol::Symbol; -use crate::{METADATA_FILENAME, RLIB_BYTECODE_EXTENSION, CrateInfo, - looks_like_rust_object_file, CodegenResults}; use super::archive::ArchiveBuilder; use super::command::Command; use super::linker::Linker; use super::rpath::{self, RPathConfig}; +use crate::{ + looks_like_rust_object_file, CodegenResults, CrateInfo, METADATA_FILENAME, + RLIB_BYTECODE_EXTENSION, +}; use cc::windows_registry; use tempfile::{Builder as TempFileBuilder, TempDir}; use std::ascii; use std::char; +use std::env; +use std::ffi::OsString; use std::fmt; use std::fs; use std::io; use std::path::{Path, PathBuf}; -use std::process::{Output, Stdio, ExitStatus}; +use std::process::{ExitStatus, Output, Stdio}; use std::str; -use std::env; -use std::ffi::OsString; pub use rustc_codegen_utils::link::*; pub fn remove(sess: &Session, path: &Path) { if let Err(e) = fs::remove_file(path) { - sess.err(&format!("failed to remove {}: {}", - path.display(), - e)); + sess.err(&format!("failed to remove {}: {}", path.display(), e)); } } /// Performs the linkage portion of the compilation phase. This will generate all /// of the requested outputs for this compilation session. -pub fn link_binary<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, - codegen_results: &CodegenResults, - outputs: &OutputFilenames, - crate_name: &str, - target_cpu: &str) { +pub fn link_binary<'a, B: ArchiveBuilder<'a>>( + sess: &'a Session, + codegen_results: &CodegenResults, + outputs: &OutputFilenames, + crate_name: &str, + target_cpu: &str, +) { let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata); for &crate_type in sess.crate_types.borrow().iter() { // Ignore executable crates if we have -Z no-codegen, as they will error. - if (sess.opts.debugging_opts.no_codegen || !sess.opts.output_types.should_codegen()) && - !output_metadata && - crate_type == config::CrateType::Executable { + if (sess.opts.debugging_opts.no_codegen || !sess.opts.output_types.should_codegen()) + && !output_metadata + && crate_type == config::CrateType::Executable + { continue; } if invalid_output_for_target(sess, crate_type) { - bug!("invalid output type `{:?}` for target os `{}`", - crate_type, sess.opts.target_triple); + bug!( + "invalid output type `{:?}` for target os `{}`", + crate_type, + sess.opts.target_triple + ); } for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) { check_file_is_writeable(obj, sess); } - let tmpdir = TempFileBuilder::new().prefix("rustc").tempdir().unwrap_or_else(|err| - sess.fatal(&format!("couldn't create a temp dir: {}", err))); + let tmpdir = TempFileBuilder::new() + .prefix("rustc") + .tempdir() + .unwrap_or_else(|err| sess.fatal(&format!("couldn't create a temp dir: {}", err))); if outputs.outputs.should_codegen() { let out_filename = out_filename(sess, crate_type, outputs, crate_name); match crate_type { config::CrateType::Rlib => { - link_rlib::(sess, - codegen_results, - RlibFlavor::Normal, - &out_filename, - &tmpdir).build(); + link_rlib::( + sess, + codegen_results, + RlibFlavor::Normal, + &out_filename, + &tmpdir, + ) + .build(); } config::CrateType::Staticlib => { link_staticlib::(sess, codegen_results, &out_filename, &tmpdir); @@ -156,9 +166,9 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB if sess.opts.cg.linker.is_none() && sess.target.target.options.linker.is_none() => { Command::new(msvc_tool.as_ref().map(|t| t.path()).unwrap_or(linker)) - }, + } _ => Command::new(linker), - } + }, }; // UWP apps have API restrictions enforced during Store submissions. @@ -179,8 +189,7 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB let mut arg = OsString::from("/LIBPATH:"); arg.push(format!("{}\\lib\\{}\\store", root_lib_path.display(), a.to_string())); cmd.arg(&arg); - } - else { + } else { warn!("arch is not supported"); } } else { @@ -193,8 +202,7 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB // The compiler's sysroot often has some bundled tools, so add it to the // PATH for the child. - let mut new_path = sess.host_filesearch(PathKind::All) - .get_tools_search_paths(); + let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(); let mut msvc_changed_path = false; if sess.target.target.options.is_like_msvc { if let Some(ref tool) = msvc_tool { @@ -228,10 +236,10 @@ pub fn each_linked_rlib( let mut fmts = None; for (ty, list) in info.dependency_formats.iter() { match ty { - config::CrateType::Executable | - config::CrateType::Staticlib | - config::CrateType::Cdylib | - config::CrateType::ProcMacro => { + config::CrateType::Executable + | config::CrateType::Staticlib + | config::CrateType::Cdylib + | config::CrateType::ProcMacro => { fmts = Some(list); break; } @@ -240,25 +248,24 @@ pub fn each_linked_rlib( } let fmts = match fmts { Some(f) => f, - None => return Err("could not find formats for rlibs".to_string()) + None => return Err("could not find formats for rlibs".to_string()), }; for &(cnum, ref path) in crates { match fmts.get(cnum.as_usize() - 1) { - Some(&Linkage::NotLinked) | - Some(&Linkage::IncludedFromDylib) => continue, + Some(&Linkage::NotLinked) | Some(&Linkage::IncludedFromDylib) => continue, Some(_) => {} - None => return Err("could not find formats for rlibs".to_string()) + None => return Err("could not find formats for rlibs".to_string()), } let name = &info.crate_name[&cnum]; let path = match *path { LibSource::Some(ref p) => p, LibSource::MetadataOnly => { - return Err(format!("could not find rlib for: `{}`, found rmeta (metadata) file", - name)) - } - LibSource::None => { - return Err(format!("could not find rlib for: `{}`", name)) + return Err(format!( + "could not find rlib for: `{}`, found rmeta (metadata) file", + name + )); } + LibSource::None => return Err(format!("could not find rlib for: `{}`", name)), }; f(cnum, &path); } @@ -273,7 +280,7 @@ pub fn each_linked_rlib( pub fn emit_metadata<'a>( sess: &'a Session, metadata: &EncodedMetadata, - tmpdir: &TempDir + tmpdir: &TempDir, ) -> PathBuf { let out_filename = tmpdir.path().join(METADATA_FILENAME); let result = fs::write(&out_filename, &metadata.raw_data); @@ -291,11 +298,13 @@ pub fn emit_metadata<'a>( // rlib primarily contains the object file of the crate, but it also contains // all of the object files from native libraries. This is done by unzipping // native libraries and inserting all of the contents into this archive. -fn link_rlib<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, - codegen_results: &CodegenResults, - flavor: RlibFlavor, - out_filename: &Path, - tmpdir: &TempDir) -> B { +fn link_rlib<'a, B: ArchiveBuilder<'a>>( + sess: &'a Session, + codegen_results: &CodegenResults, + flavor: RlibFlavor, + out_filename: &Path, + tmpdir: &TempDir, +) -> B { info!("preparing rlib to {:?}", out_filename); let mut ab = ::new(sess, out_filename, None); @@ -322,10 +331,10 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, for lib in codegen_results.crate_info.used_libraries.iter() { match lib.kind { NativeLibraryKind::NativeStatic => {} - NativeLibraryKind::NativeStaticNobundle | - NativeLibraryKind::NativeFramework | - NativeLibraryKind::NativeRawDylib | - NativeLibraryKind::NativeUnknown => continue, + NativeLibraryKind::NativeStaticNobundle + | NativeLibraryKind::NativeFramework + | NativeLibraryKind::NativeRawDylib + | NativeLibraryKind::NativeUnknown => continue, } if let Some(name) = lib.name { ab.add_native_library(name); @@ -365,10 +374,8 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, // For LTO purposes, the bytecode of this library is also inserted // into the archive. - for bytecode in codegen_results - .modules - .iter() - .filter_map(|m| m.bytecode_compressed.as_ref()) + for bytecode in + codegen_results.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref()) { ab.add_file(bytecode); } @@ -382,9 +389,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, } RlibFlavor::StaticlibBase => { - let obj = codegen_results.allocator_module - .as_ref() - .and_then(|m| m.object.as_ref()); + let obj = codegen_results.allocator_module.as_ref().and_then(|m| m.object.as_ref()); if let Some(obj) = obj { ab.add_file(obj); } @@ -406,15 +411,14 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, // There's no need to include metadata in a static archive, so ensure to not // link in the metadata object file (and also don't prepare the archive with a // metadata file). -fn link_staticlib<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, - codegen_results: &CodegenResults, - out_filename: &Path, - tempdir: &TempDir) { - let mut ab = link_rlib::(sess, - codegen_results, - RlibFlavor::StaticlibBase, - out_filename, - tempdir); +fn link_staticlib<'a, B: ArchiveBuilder<'a>>( + sess: &'a Session, + codegen_results: &CodegenResults, + out_filename: &Path, + tempdir: &TempDir, +) { + let mut ab = + link_rlib::(sess, codegen_results, RlibFlavor::StaticlibBase, out_filename, tempdir); let mut all_native_libs = vec![]; let res = each_linked_rlib(&codegen_results.crate_info, &mut |cnum, path| { @@ -435,14 +439,17 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, // Clearly this is not sufficient for a general purpose feature, and // we'd want to read from the library's metadata to determine which // object files come from where and selectively skip them. - let skip_object_files = native_libs.iter().any(|lib| { - lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib) - }); - ab.add_rlib(path, - &name.as_str(), - are_upstream_rust_objects_already_included(sess) && - !ignored_for_lto(sess, &codegen_results.crate_info, cnum), - skip_object_files).unwrap(); + let skip_object_files = native_libs + .iter() + .any(|lib| lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib)); + ab.add_rlib( + path, + &name.as_str(), + are_upstream_rust_objects_already_included(sess) + && !ignored_for_lto(sess, &codegen_results.crate_info, cnum), + skip_object_files, + ) + .unwrap(); all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned()); }); @@ -464,12 +471,14 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, // // This will invoke the system linker/cc to create the resulting file. This // links to all upstream files as well. -fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, - crate_type: config::CrateType, - out_filename: &Path, - codegen_results: &CodegenResults, - tmpdir: &Path, - target_cpu: &str) { +fn link_natively<'a, B: ArchiveBuilder<'a>>( + sess: &'a Session, + crate_type: config::CrateType, + out_filename: &Path, + codegen_results: &CodegenResults, + tmpdir: &Path, + target_cpu: &str, +) { info!("preparing {:?} to {:?}", crate_type, out_filename); let (linker, flavor) = linker_and_flavor(sess); @@ -523,8 +532,15 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, { let mut linker = codegen_results.linker_info.to_linker(cmd, &sess, flavor, target_cpu); - link_args::(&mut *linker, flavor, sess, crate_type, tmpdir, - out_filename, codegen_results); + link_args::( + &mut *linker, + flavor, + sess, + crate_type, + tmpdir, + out_filename, + codegen_results, + ); cmd = linker.finalize(); } if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) { @@ -562,15 +578,13 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, let mut i = 0; loop { i += 1; - prog = time(sess, "running linker", || { - exec_linker(sess, &mut cmd, out_filename, tmpdir) - }); + prog = time(sess, "running linker", || exec_linker(sess, &mut cmd, out_filename, tmpdir)); let output = match prog { Ok(ref output) => output, Err(_) => break, }; if output.status.success() { - break + break; } let mut out = output.stderr.clone(); out.extend(&output.stdout); @@ -582,12 +596,13 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, // if the linker doesn't support -no-pie then it should not default to // linking executables as pie. Different versions of gcc seem to use // different quotes in the error message so don't check for them. - if sess.target.target.options.linker_is_gnu && - flavor != LinkerFlavor::Ld && - (out.contains("unrecognized command line option") || - out.contains("unknown argument")) && - out.contains("-no-pie") && - cmd.get_args().iter().any(|e| e.to_string_lossy() == "-no-pie") { + if sess.target.target.options.linker_is_gnu + && flavor != LinkerFlavor::Ld + && (out.contains("unrecognized command line option") + || out.contains("unknown argument")) + && out.contains("-no-pie") + && cmd.get_args().iter().any(|e| e.to_string_lossy() == "-no-pie") + { info!("linker output: {:?}", out); warn!("Linker does not support -no-pie command line option. Retrying without."); for arg in cmd.take_args() { @@ -615,16 +630,15 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, // seems that no one currently knows a fix for this so in the meantime // we're left with this... if !retry_on_segfault || i > 3 { - break + break; } let msg_segv = "clang: error: unable to execute command: Segmentation fault: 11"; - let msg_bus = "clang: error: unable to execute command: Bus error: 10"; + let msg_bus = "clang: error: unable to execute command: Bus error: 10"; if out.contains(msg_segv) || out.contains(msg_bus) { warn!( "looks like the linker segfaulted when we tried to call it, \ automatically retrying again. cmd = {:?}, out = {}.", - cmd, - out, + cmd, out, ); continue; } @@ -634,9 +648,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, "looks like the linker hit an illegal instruction when we \ tried to call it, automatically retrying again. cmd = {:?}, ]\ out = {}, status = {}.", - cmd, - out, - output.status, + cmd, out, output.status, ); continue; } @@ -656,29 +668,28 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, match prog { Ok(prog) => { fn escape_string(s: &[u8]) -> String { - str::from_utf8(s).map(|s| s.to_owned()) - .unwrap_or_else(|_| { - let mut x = "Non-UTF-8 output: ".to_string(); - x.extend(s.iter() - .flat_map(|&b| ascii::escape_default(b)) - .map(char::from)); - x - }) + str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| { + let mut x = "Non-UTF-8 output: ".to_string(); + x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from)); + x + }) } if !prog.status.success() { let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); - sess.struct_err(&format!("linking with `{}` failed: {}", - pname.display(), - prog.status)) - .note(&format!("{:?}", &cmd)) - .note(&escape_string(&output)) - .emit(); + sess.struct_err(&format!( + "linking with `{}` failed: {}", + pname.display(), + prog.status + )) + .note(&format!("{:?}", &cmd)) + .note(&escape_string(&output)) + .emit(); sess.abort_if_errors(); } info!("linker stderr:\n{}", escape_string(&prog.stderr)); info!("linker stdout:\n{}", escape_string(&prog.stdout)); - }, + } Err(e) => { let linker_not_found = e.kind() == io::ErrorKind::NotFound; @@ -712,13 +723,12 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session, } } - // On macOS, debuggers need this utility to get run to do some munging of // the symbols. Note, though, that if the object files are being preserved // for their debug information there's no need for us to run dsymutil. - if sess.target.target.options.is_like_osx && - sess.opts.debuginfo != DebugInfo::None && - !preserve_objects_for_their_debuginfo(sess) + if sess.target.target.options.is_like_osx + && sess.opts.debuginfo != DebugInfo::None + && !preserve_objects_for_their_debuginfo(sess) { if let Err(e) = Command::new("dsymutil").arg(out_filename).output() { sess.fatal(&format!("failed to run dsymutil: {}", e)) @@ -740,8 +750,8 @@ pub fn ignored_for_lto(sess: &Session, info: &CrateInfo, cnum: CrateNum) -> bool // If our target enables builtin function lowering in LLVM then the // crates providing these functions don't participate in LTO (e.g. // no_builtins or compiler builtins crates). - !sess.target.target.options.no_builtins && - (info.compiler_builtins == Some(cnum) || info.is_no_builtins.contains(&cnum)) + !sess.target.target.options.no_builtins + && (info.compiler_builtins == Some(cnum) || info.is_no_builtins.contains(&cnum)) } pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { @@ -753,21 +763,27 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { match (linker, flavor) { (Some(linker), Some(flavor)) => Some((linker, flavor)), // only the linker flavor is known; use the default linker for the selected flavor - (None, Some(flavor)) => Some((PathBuf::from(match flavor { - LinkerFlavor::Em => if cfg!(windows) { "emcc.bat" } else { "emcc" }, - LinkerFlavor::Gcc => "cc", - LinkerFlavor::Ld => "ld", - LinkerFlavor::Msvc => "link.exe", - LinkerFlavor::Lld(_) => "lld", - LinkerFlavor::PtxLinker => "rust-ptx-linker", - }), flavor)), + (None, Some(flavor)) => Some(( + PathBuf::from(match flavor { + LinkerFlavor::Em => { + if cfg!(windows) { + "emcc.bat" + } else { + "emcc" + } + } + LinkerFlavor::Gcc => "cc", + LinkerFlavor::Ld => "ld", + LinkerFlavor::Msvc => "link.exe", + LinkerFlavor::Lld(_) => "lld", + LinkerFlavor::PtxLinker => "rust-ptx-linker", + }), + flavor, + )), (Some(linker), None) => { - let stem = linker - .file_stem() - .and_then(|stem| stem.to_str()) - .unwrap_or_else(|| { - sess.fatal("couldn't extract file stem from specified linker") - }); + let stem = linker.file_stem().and_then(|stem| stem.to_str()).unwrap_or_else(|| { + sess.fatal("couldn't extract file stem from specified linker") + }); let flavor = if stem == "emcc" { LinkerFlavor::Em @@ -789,7 +805,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { }; Some((linker, flavor)) - }, + } (None, None) => None, } } @@ -817,16 +833,18 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { pub fn preserve_objects_for_their_debuginfo(sess: &Session) -> bool { // If the objects don't have debuginfo there's nothing to preserve. if sess.opts.debuginfo == config::DebugInfo::None { - return false + return false; } // If we're only producing artifacts that are archives, no need to preserve // the objects as they're losslessly contained inside the archives. - let output_linked = sess.crate_types.borrow() + let output_linked = sess + .crate_types + .borrow() .iter() .any(|&x| x != config::CrateType::Rlib && x != config::CrateType::Staticlib); if !output_linked { - return false + return false; } // If we're on OSX then the equivalent of split dwarf is turned on by @@ -867,33 +885,34 @@ enum RlibFlavor { } pub fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLibrary]) { - let lib_args: Vec<_> = all_native_libs.iter() + let lib_args: Vec<_> = all_native_libs + .iter() .filter(|l| relevant_lib(sess, l)) .filter_map(|lib| { let name = lib.name?; match lib.kind { - NativeLibraryKind::NativeStaticNobundle | - NativeLibraryKind::NativeUnknown => { + NativeLibraryKind::NativeStaticNobundle | NativeLibraryKind::NativeUnknown => { if sess.target.target.options.is_like_msvc { Some(format!("{}.lib", name)) } else { Some(format!("-l{}", name)) } - }, + } NativeLibraryKind::NativeFramework => { // ld-only syntax, since there are no frameworks in MSVC Some(format!("-framework {}", name)) - }, + } // These are included, no need to print them - NativeLibraryKind::NativeStatic | - NativeLibraryKind::NativeRawDylib => None, + NativeLibraryKind::NativeStatic | NativeLibraryKind::NativeRawDylib => None, } }) .collect(); if !lib_args.is_empty() { - sess.note_without_error("Link against the following native artifacts when linking \ + sess.note_without_error( + "Link against the following native artifacts when linking \ against this static library. The order and any duplication \ - can be significant on some platforms."); + can be significant on some platforms.", + ); // Prefix for greppability sess.note_without_error(&format!("native-static-libs: {}", &lib_args.join(" "))); } @@ -903,20 +922,23 @@ pub fn get_file_path(sess: &Session, name: &str) -> PathBuf { let fs = sess.target_filesearch(PathKind::Native); let file_path = fs.get_lib_path().join(name); if file_path.exists() { - return file_path + return file_path; } for search_path in fs.search_paths() { let file_path = search_path.dir.join(name); if file_path.exists() { - return file_path + return file_path; } } PathBuf::from(name) } -pub fn exec_linker(sess: &Session, cmd: &mut Command, out_filename: &Path, tmpdir: &Path) - -> io::Result -{ +pub fn exec_linker( + sess: &Session, + cmd: &mut Command, + out_filename: &Path, + tmpdir: &Path, +) -> io::Result { // When attempting to spawn the linker we run a risk of blowing out the // size limits for spawning a new process with respect to the arguments // we pass on the command line. @@ -936,7 +958,7 @@ pub fn exec_linker(sess: &Session, cmd: &mut Command, out_filename: &Path, tmpdi Err(ref e) if command_line_too_big(e) => { info!("command line to linker was too big: {}", e); } - Err(e) => return Err(e) + Err(e) => return Err(e), } } @@ -944,10 +966,13 @@ pub fn exec_linker(sess: &Session, cmd: &mut Command, out_filename: &Path, tmpdi let mut cmd2 = cmd.clone(); let mut args = String::new(); for arg in cmd2.take_args() { - args.push_str(&Escape { - arg: arg.to_str().unwrap(), - is_like_msvc: sess.target.target.options.is_like_msvc, - }.to_string()); + args.push_str( + &Escape { + arg: arg.to_str().unwrap(), + is_like_msvc: sess.target.target.options.is_like_msvc, + } + .to_string(), + ); args.push_str("\n"); } let file = tmpdir.join("linker-arguments"); @@ -976,9 +1001,10 @@ pub fn exec_linker(sess: &Session, cmd: &mut Command, out_filename: &Path, tmpdi } #[cfg(windows)] - fn flush_linked_file(command_output: &io::Result, out_filename: &Path) - -> io::Result<()> - { + fn flush_linked_file( + command_output: &io::Result, + out_filename: &Path, + ) -> io::Result<()> { // On Windows, under high I/O load, output buffers are sometimes not flushed, // even long after process exit, causing nasty, non-reproducible output bugs. // @@ -1055,14 +1081,15 @@ pub fn exec_linker(sess: &Session, cmd: &mut Command, out_filename: &Path, tmpdi } } -fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, - flavor: LinkerFlavor, - sess: &'a Session, - crate_type: config::CrateType, - tmpdir: &Path, - out_filename: &Path, - codegen_results: &CodegenResults) { - +fn link_args<'a, B: ArchiveBuilder<'a>>( + cmd: &mut dyn Linker, + flavor: LinkerFlavor, + sess: &'a Session, + crate_type: config::CrateType, + tmpdir: &Path, + out_filename: &Path, + codegen_results: &CodegenResults, +) { // Linker plugins should be specified early in the list of arguments cmd.linker_plugin_lto(); @@ -1080,8 +1107,7 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, } cmd.output_filename(out_filename); - if crate_type == config::CrateType::Executable && - sess.target.target.options.is_like_windows { + if crate_type == config::CrateType::Executable && sess.target.target.options.is_like_windows { if let Some(ref s) = codegen_results.windows_subsystem { cmd.subsystem(s); } @@ -1095,19 +1121,14 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, // When linking a dynamic library, we put the metadata into a section of the // executable. This metadata is in a separate object file from the main // object file, so we link that in here. - if crate_type == config::CrateType::Dylib || - crate_type == config::CrateType::ProcMacro { - let obj = codegen_results.metadata_module - .as_ref() - .and_then(|m| m.object.as_ref()); + if crate_type == config::CrateType::Dylib || crate_type == config::CrateType::ProcMacro { + let obj = codegen_results.metadata_module.as_ref().and_then(|m| m.object.as_ref()); if let Some(obj) = obj { cmd.add_object(obj); } } - let obj = codegen_results.allocator_module - .as_ref() - .and_then(|m| m.object.as_ref()); + let obj = codegen_results.allocator_module.as_ref().and_then(|m| m.object.as_ref()); if let Some(obj) = obj { cmd.add_object(obj); } @@ -1141,8 +1162,7 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, // recent versions of gcc can be configured to generate position // independent executables by default. We have to pass -no-pie to // explicitly turn that off. Not applicable to ld. - if sess.target.target.options.linker_is_gnu - && flavor != LinkerFlavor::Ld { + if sess.target.target.options.linker_is_gnu && flavor != LinkerFlavor::Ld { cmd.no_position_independent_executable(); } } @@ -1155,15 +1175,14 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, match relro_level { RelroLevel::Full => { cmd.full_relro(); - }, + } RelroLevel::Partial => { cmd.partial_relro(); - }, + } RelroLevel::Off => { cmd.no_relro(); - }, - RelroLevel::None => { - }, + } + RelroLevel::None => {} } // Pass optimization flags down to the linker. @@ -1179,9 +1198,7 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, // figure out which subset we wanted. // // This is all naturally configurable via the standard methods as well. - if !sess.opts.cg.default_linker_libraries.unwrap_or(false) && - t.options.no_default_libraries - { + if !sess.opts.cg.default_linker_libraries.unwrap_or(false) && t.options.no_default_libraries { cmd.no_default_libraries(); } @@ -1271,20 +1288,25 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, // Also note that the native libraries linked here are only the ones located // in the current crate. Upstream crates with native library dependencies // may have their native library pulled in above. -pub fn add_local_native_libraries(cmd: &mut dyn Linker, - sess: &Session, - codegen_results: &CodegenResults) { +pub fn add_local_native_libraries( + cmd: &mut dyn Linker, + sess: &Session, + codegen_results: &CodegenResults, +) { let filesearch = sess.target_filesearch(PathKind::All); for search_path in filesearch.search_paths() { match search_path.kind { - PathKind::Framework => { cmd.framework_path(&search_path.dir); } - _ => { cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir)); } + PathKind::Framework => { + cmd.framework_path(&search_path.dir); + } + _ => { + cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir)); + } } } - let relevant_libs = codegen_results.crate_info.used_libraries.iter().filter(|l| { - relevant_lib(sess, l) - }); + let relevant_libs = + codegen_results.crate_info.used_libraries.iter().filter(|l| relevant_lib(sess, l)); let search_path = archive_search_paths(sess); for lib in relevant_libs { @@ -1300,7 +1322,7 @@ pub fn add_local_native_libraries(cmd: &mut dyn Linker, NativeLibraryKind::NativeRawDylib => { // FIXME(#58713): Proper handling for raw dylibs. bug!("raw_dylib feature not yet implemented"); - }, + } } } } @@ -1325,7 +1347,9 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( // will slurp up the object files inside), and linking to a dynamic library // involves just passing the right -l flag. - let (_, data) = codegen_results.crate_info.dependency_formats + let (_, data) = codegen_results + .crate_info + .dependency_formats .iter() .find(|(ty, _)| *ty == crate_type) .expect("failed to find crate type in dependency format list"); @@ -1366,7 +1390,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( end_with.retain(|item| info.lang_item_to_crate.get(item) != Some(&cnum)); if end_with.len() == 0 && group_end.is_some() { group_start = Some(cnum); - break + break; } } @@ -1392,8 +1416,9 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( _ if codegen_results.crate_info.profiler_runtime == Some(cnum) => { add_static_crate::(cmd, sess, codegen_results, tmpdir, crate_type, cnum); } - _ if codegen_results.crate_info.sanitizer_runtime == Some(cnum) && - crate_type == config::CrateType::Executable => { + _ if codegen_results.crate_info.sanitizer_runtime == Some(cnum) + && crate_type == config::CrateType::Executable => + { // Link the sanitizer runtimes only if we are actually producing an executable link_sanitizer_runtime::(cmd, sess, codegen_results, tmpdir, cnum); } @@ -1403,14 +1428,11 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( assert!(compiler_builtins.is_none()); compiler_builtins = Some(cnum); } - Linkage::NotLinked | - Linkage::IncludedFromDylib => {} + Linkage::NotLinked | Linkage::IncludedFromDylib => {} Linkage::Static => { add_static_crate::(cmd, sess, codegen_results, tmpdir, crate_type, cnum); } - Linkage::Dynamic => { - add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0) - } + Linkage::Dynamic => add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0), } if group_end == Some(cnum) { @@ -1440,11 +1462,13 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( // it's packed in a .rlib, it contains stuff that are not objects that will // make the linker error. So we must remove those bits from the .rlib before // linking it. - fn link_sanitizer_runtime<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, - sess: &'a Session, - codegen_results: &CodegenResults, - tmpdir: &Path, - cnum: CrateNum) { + fn link_sanitizer_runtime<'a, B: ArchiveBuilder<'a>>( + cmd: &mut dyn Linker, + sess: &'a Session, + codegen_results: &CodegenResults, + tmpdir: &Path, + cnum: CrateNum, + ) { let src = &codegen_results.crate_info.used_crate_source[&cnum]; let cratepath = &src.rlib.as_ref().unwrap().0; @@ -1507,12 +1531,14 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( // (aka we're making an executable), we can just pass the rlib blindly to // the linker (fast) because it's fine if it's not actually included as // we're at the end of the dependency chain. - fn add_static_crate<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, - sess: &'a Session, - codegen_results: &CodegenResults, - tmpdir: &Path, - crate_type: config::CrateType, - cnum: CrateNum) { + fn add_static_crate<'a, B: ArchiveBuilder<'a>>( + cmd: &mut dyn Linker, + sess: &'a Session, + codegen_results: &CodegenResults, + tmpdir: &Path, + crate_type: config::CrateType, + cnum: CrateNum, + ) { let src = &codegen_results.crate_info.used_crate_source[&cnum]; let cratepath = &src.rlib.as_ref().unwrap().0; @@ -1520,16 +1546,17 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( // there's a static library that's not relevant we skip all object // files. let native_libs = &codegen_results.crate_info.native_libraries[&cnum]; - let skip_native = native_libs.iter().any(|lib| { - lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib) - }); - - if (!are_upstream_rust_objects_already_included(sess) || - ignored_for_lto(sess, &codegen_results.crate_info, cnum)) && - crate_type != config::CrateType::Dylib && - !skip_native { + let skip_native = native_libs + .iter() + .any(|lib| lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib)); + + if (!are_upstream_rust_objects_already_included(sess) + || ignored_for_lto(sess, &codegen_results.crate_info, cnum)) + && crate_type != config::CrateType::Dylib + && !skip_native + { cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath)); - return + return; } let dst = tmpdir.join(cratepath.file_name().unwrap()); @@ -1544,15 +1571,14 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( for f in archive.src_files() { if f.ends_with(RLIB_BYTECODE_EXTENSION) || f == METADATA_FILENAME { archive.remove_file(&f); - continue + continue; } let canonical = f.replace("-", "_"); let canonical_name = name.replace("-", "_"); let is_rust_object = - canonical.starts_with(&canonical_name) && - looks_like_rust_object_file(&f); + canonical.starts_with(&canonical_name) && looks_like_rust_object_file(&f); // If we've been requested to skip all native object files // (those not generated by the rust compiler) then we can skip @@ -1563,10 +1589,10 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( // file, then we don't need the object file as it's part of the // LTO module. Note that `#![no_builtins]` is excluded from LTO, // though, so we let that object file slide. - let skip_because_lto = are_upstream_rust_objects_already_included(sess) && - is_rust_object && - (sess.target.target.options.no_builtins || - !codegen_results.crate_info.is_no_builtins.contains(&cnum)); + let skip_because_lto = are_upstream_rust_objects_already_included(sess) + && is_rust_object + && (sess.target.target.options.no_builtins + || !codegen_results.crate_info.is_no_builtins.contains(&cnum)); if skip_because_cfg_say_so || skip_because_lto { archive.remove_file(&f); @@ -1576,7 +1602,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( } if !any_objects { - return + return; } archive.build(); @@ -1587,8 +1613,9 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( // Note, though, that we don't want to include the whole of a // compiler-builtins crate (e.g., compiler-rt) because it'll get // repeatedly linked anyway. - if crate_type == config::CrateType::Dylib && - codegen_results.crate_info.compiler_builtins != Some(cnum) { + if crate_type == config::CrateType::Dylib + && codegen_results.crate_info.compiler_builtins != Some(cnum) + { cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst)); } else { cmd.link_rlib(&fix_windows_verbatim_for_gcc(&dst)); @@ -1605,8 +1632,10 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( cmd.include_path(&fix_windows_verbatim_for_gcc(dir)); } let filestem = cratepath.file_stem().unwrap().to_str().unwrap(); - cmd.link_rust_dylib(Symbol::intern(&unlib(&sess.target, filestem)), - parent.unwrap_or(Path::new(""))); + cmd.link_rust_dylib( + Symbol::intern(&unlib(&sess.target, filestem)), + parent.unwrap_or(Path::new("")), + ); } } @@ -1643,7 +1672,9 @@ pub fn add_upstream_native_libraries( // This passes RequireStatic, but the actual requirement doesn't matter, // we're just getting an ordering of crate numbers, we're not worried about // the paths. - let (_, data) = codegen_results.crate_info.dependency_formats + let (_, data) = codegen_results + .crate_info + .dependency_formats .iter() .find(|(ty, _)| *ty == crate_type) .expect("failed to find crate type in dependency format list"); @@ -1656,7 +1687,7 @@ pub fn add_upstream_native_libraries( None => continue, }; if !relevant_lib(sess, &lib) { - continue + continue; } match lib.kind { NativeLibraryKind::NativeUnknown => cmd.link_dylib(name), @@ -1669,15 +1700,15 @@ pub fn add_upstream_native_libraries( if data[cnum.as_usize() - 1] == Linkage::Static { cmd.link_staticlib(name) } - }, + } // ignore statically included native libraries here as we've // already included them when we included the rust library // previously - NativeLibraryKind::NativeStatic => {}, + NativeLibraryKind::NativeStatic => {} NativeLibraryKind::NativeRawDylib => { // FIXME(#58713): Proper handling for raw dylibs. bug!("raw_dylib feature not yet implemented"); - }, + } } } } @@ -1698,8 +1729,7 @@ pub fn are_upstream_rust_objects_already_included(sess: &Session) -> bool { // any upstream object files have not been copied yet. !sess.opts.cg.linker_plugin_lto.enabled() } - config::Lto::No | - config::Lto::ThinLocal => false, + config::Lto::No | config::Lto::ThinLocal => false, } } diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 4278852123bea..a3e60f861996a 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -1,6 +1,6 @@ -use super::symbol_export; -use super::command::Command; use super::archive; +use super::command::Command; +use super::symbol_export; use rustc_data_structures::fx::FxHashMap; use std::ffi::{OsStr, OsString}; @@ -9,14 +9,13 @@ use std::io::prelude::*; use std::io::{self, BufWriter}; use std::path::{Path, PathBuf}; -use rustc::hir::def_id::{LOCAL_CRATE, CrateNum}; +use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::middle::dependency_format::Linkage; +use rustc::session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel}; use rustc::session::Session; -use rustc::session::config::{self, CrateType, OptLevel, DebugInfo, - LinkerPluginLto, Lto}; use rustc::ty::TyCtxt; -use rustc_target::spec::{LinkerFlavor, LldFlavor}; use rustc_serialize::{json, Encoder}; +use rustc_target::spec::{LinkerFlavor, LldFlavor}; use syntax::symbol::Symbol; /// For all the linkers we support, and information they might @@ -28,9 +27,13 @@ pub struct LinkerInfo { impl LinkerInfo { pub fn new(tcx: TyCtxt<'_>) -> LinkerInfo { LinkerInfo { - exports: tcx.sess.crate_types.borrow().iter().map(|&c| { - (c, exported_symbols(tcx, c)) - }).collect(), + exports: tcx + .sess + .crate_types + .borrow() + .iter() + .map(|&c| (c, exported_symbols(tcx, c))) + .collect(), } } @@ -40,54 +43,37 @@ impl LinkerInfo { sess: &'a Session, flavor: LinkerFlavor, target_cpu: &'a str, - ) -> Box { + ) -> Box { match flavor { - LinkerFlavor::Lld(LldFlavor::Link) | - LinkerFlavor::Msvc => { - Box::new(MsvcLinker { - cmd, - sess, - info: self - }) as Box - } - LinkerFlavor::Em => { - Box::new(EmLinker { - cmd, - sess, - info: self - }) as Box - } - LinkerFlavor::Gcc => { - Box::new(GccLinker { - cmd, - sess, - info: self, - hinted_static: false, - is_ld: false, - target_cpu, - }) as Box - } - - LinkerFlavor::Lld(LldFlavor::Ld) | - LinkerFlavor::Lld(LldFlavor::Ld64) | - LinkerFlavor::Ld => { - Box::new(GccLinker { - cmd, - sess, - info: self, - hinted_static: false, - is_ld: true, - target_cpu, - }) as Box + LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => { + Box::new(MsvcLinker { cmd, sess, info: self }) as Box } + LinkerFlavor::Em => Box::new(EmLinker { cmd, sess, info: self }) as Box, + LinkerFlavor::Gcc => Box::new(GccLinker { + cmd, + sess, + info: self, + hinted_static: false, + is_ld: false, + target_cpu, + }) as Box, + + LinkerFlavor::Lld(LldFlavor::Ld) + | LinkerFlavor::Lld(LldFlavor::Ld64) + | LinkerFlavor::Ld => Box::new(GccLinker { + cmd, + sess, + info: self, + hinted_static: false, + is_ld: true, + target_cpu, + }) as Box, LinkerFlavor::Lld(LldFlavor::Wasm) => { Box::new(WasmLd::new(cmd, sess, self)) as Box } - LinkerFlavor::PtxLinker => { - Box::new(PtxLinker { cmd, sess }) as Box - } + LinkerFlavor::PtxLinker => Box::new(PtxLinker { cmd, sess }) as Box, } } } @@ -148,7 +134,8 @@ impl<'a> GccLinker<'a> { /// /// These arguments need to be prepended with `-Wl`, when a GCC-style linker is used. fn linker_arg(&mut self, arg: S) -> &mut Self - where S: AsRef + where + S: AsRef, { if !self.is_ld { let mut os = OsString::from("-Wl,"); @@ -169,8 +156,7 @@ impl<'a> GccLinker<'a> { // * On OSX they have their own linker, not binutils' // * For WebAssembly the only functional linker is LLD, which doesn't // support hint flags - !self.sess.target.target.options.is_like_osx && - self.sess.target.target.arch != "wasm32" + !self.sess.target.target.options.is_like_osx && self.sess.target.target.arch != "wasm32" } // Some platforms take hints about whether a library is static or dynamic. @@ -178,7 +164,9 @@ impl<'a> GccLinker<'a> { // was flagged "static" (most defaults are dynamic) to ensure that if // libfoo.a and libfoo.so both exist that the right one is chosen. fn hint_static(&mut self) { - if !self.takes_hints() { return } + if !self.takes_hints() { + return; + } if !self.hinted_static { self.linker_arg("-Bstatic"); self.hinted_static = true; @@ -186,7 +174,9 @@ impl<'a> GccLinker<'a> { } fn hint_dynamic(&mut self) { - if !self.takes_hints() { return } + if !self.takes_hints() { + return; + } if self.hinted_static { self.linker_arg("-Bdynamic"); self.hinted_static = false; @@ -224,18 +214,44 @@ impl<'a> Linker for GccLinker<'a> { self.hint_static(); self.cmd.arg(format!("-l{}", lib)); } - fn link_rlib(&mut self, lib: &Path) { self.hint_static(); self.cmd.arg(lib); } - fn include_path(&mut self, path: &Path) { self.cmd.arg("-L").arg(path); } - fn framework_path(&mut self, path: &Path) { self.cmd.arg("-F").arg(path); } - fn output_filename(&mut self, path: &Path) { self.cmd.arg("-o").arg(path); } - fn add_object(&mut self, path: &Path) { self.cmd.arg(path); } - fn position_independent_executable(&mut self) { self.cmd.arg("-pie"); } - fn no_position_independent_executable(&mut self) { self.cmd.arg("-no-pie"); } - fn full_relro(&mut self) { self.linker_arg("-zrelro"); self.linker_arg("-znow"); } - fn partial_relro(&mut self) { self.linker_arg("-zrelro"); } - fn no_relro(&mut self) { self.linker_arg("-znorelro"); } - fn build_static_executable(&mut self) { self.cmd.arg("-static"); } - fn args(&mut self, args: &[String]) { self.cmd.args(args); } + fn link_rlib(&mut self, lib: &Path) { + self.hint_static(); + self.cmd.arg(lib); + } + fn include_path(&mut self, path: &Path) { + self.cmd.arg("-L").arg(path); + } + fn framework_path(&mut self, path: &Path) { + self.cmd.arg("-F").arg(path); + } + fn output_filename(&mut self, path: &Path) { + self.cmd.arg("-o").arg(path); + } + fn add_object(&mut self, path: &Path) { + self.cmd.arg(path); + } + fn position_independent_executable(&mut self) { + self.cmd.arg("-pie"); + } + fn no_position_independent_executable(&mut self) { + self.cmd.arg("-no-pie"); + } + fn full_relro(&mut self) { + self.linker_arg("-zrelro"); + self.linker_arg("-znow"); + } + fn partial_relro(&mut self) { + self.linker_arg("-zrelro"); + } + fn no_relro(&mut self) { + self.linker_arg("-znorelro"); + } + fn build_static_executable(&mut self) { + self.cmd.arg("-static"); + } + fn args(&mut self, args: &[String]) { + self.cmd.args(args); + } fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) { self.hint_dynamic(); @@ -310,18 +326,23 @@ impl<'a> Linker for GccLinker<'a> { } fn optimize(&mut self) { - if !self.sess.target.target.options.linker_is_gnu { return } + if !self.sess.target.target.options.linker_is_gnu { + return; + } // GNU-style linkers support optimization with -O. GNU ld doesn't // need a numeric argument, but other linkers do. - if self.sess.opts.optimize == config::OptLevel::Default || - self.sess.opts.optimize == config::OptLevel::Aggressive { + if self.sess.opts.optimize == config::OptLevel::Default + || self.sess.opts.optimize == config::OptLevel::Aggressive + { self.linker_arg("-O1"); } } fn pgo_gen(&mut self) { - if !self.sess.target.target.options.linker_is_gnu { return } + if !self.sess.target.target.options.linker_is_gnu { + return; + } // If we're doing PGO generation stuff and on a GNU-like linker, use the // "-u" flag to properly pull in the profiler runtime bits. @@ -377,17 +398,17 @@ impl<'a> Linker for GccLinker<'a> { // The output filename already contains `dll_suffix` so // the resulting import library will have a name in the // form of libfoo.dll.a - let implib_name = out_filename - .file_name() - .and_then(|file| file.to_str()) - .map(|file| format!("{}{}{}", - self.sess.target.target.options.staticlib_prefix, - file, - self.sess.target.target.options.staticlib_suffix)); + let implib_name = + out_filename.file_name().and_then(|file| file.to_str()).map(|file| { + format!( + "{}{}{}", + self.sess.target.target.options.staticlib_prefix, + file, + self.sess.target.target.options.staticlib_suffix + ) + }); if let Some(implib_name) = implib_name { - let implib = out_filename - .parent() - .map(|dir| dir.join(&implib_name)); + let implib = out_filename.parent().map(|dir| dir.join(&implib_name)); if let Some(implib) = implib { self.linker_arg(&format!("--out-implib,{}", (*implib).to_str().unwrap())); } @@ -398,8 +419,9 @@ impl<'a> Linker for GccLinker<'a> { fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) { // Symbol visibility in object files typically takes care of this. - if crate_type == CrateType::Executable && - self.sess.target.target.options.override_export_symbols.is_none() { + if crate_type == CrateType::Executable + && self.sess.target.target.options.override_export_symbols.is_none() + { return; } @@ -412,7 +434,7 @@ impl<'a> Linker for GccLinker<'a> { } if crate_type == CrateType::ProcMacro { - return + return; } let mut arg = OsString::new(); @@ -513,13 +535,19 @@ impl<'a> Linker for GccLinker<'a> { pub struct MsvcLinker<'a> { cmd: Command, sess: &'a Session, - info: &'a LinkerInfo + info: &'a LinkerInfo, } impl<'a> Linker for MsvcLinker<'a> { - fn link_rlib(&mut self, lib: &Path) { self.cmd.arg(lib); } - fn add_object(&mut self, path: &Path) { self.cmd.arg(path); } - fn args(&mut self, args: &[String]) { self.cmd.args(args); } + fn link_rlib(&mut self, lib: &Path) { + self.cmd.arg(lib); + } + fn add_object(&mut self, path: &Path) { + self.cmd.arg(path); + } + fn args(&mut self, args: &[String]) { + self.cmd.args(args); + } fn build_dylib(&mut self, out_filename: &Path) { self.cmd.arg("/DLL"); @@ -648,10 +676,10 @@ impl<'a> Linker for MsvcLinker<'a> { arg.push(path); self.cmd.arg(arg); } - }, + } Err(err) => { self.sess.warn(&format!("error enumerating natvis directory: {}", err)); - }, + } } } } @@ -669,9 +697,7 @@ impl<'a> Linker for MsvcLinker<'a> { // crates. Upstream rlibs may be linked statically to this dynamic library, // in which case they may continue to transitively be used and hence need // their symbols exported. - fn export_symbols(&mut self, - tmpdir: &Path, - crate_type: CrateType) { + fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) { // Symbol visibility takes care of this typically if crate_type == CrateType::Executable { return; @@ -738,7 +764,7 @@ impl<'a> Linker for MsvcLinker<'a> { pub struct EmLinker<'a> { cmd: Command, sess: &'a Session, - info: &'a LinkerInfo + info: &'a LinkerInfo, } impl<'a> Linker for EmLinker<'a> { @@ -825,7 +851,7 @@ impl<'a> Linker for EmLinker<'a> { OptLevel::Default => "-O2", OptLevel::Aggressive => "-O3", OptLevel::Size => "-Os", - OptLevel::SizeMin => "-Oz" + OptLevel::SizeMin => "-Oz", }); // Unusable until https://github.com/rust-lang/rust/issues/38454 is resolved self.cmd.args(&["--memory-init-file", "0"]); @@ -840,7 +866,7 @@ impl<'a> Linker for EmLinker<'a> { self.cmd.arg(match self.sess.opts.debuginfo { DebugInfo::None => "-g0", DebugInfo::Limited => "-g3", - DebugInfo::Full => "-g4" + DebugInfo::Full => "-g4", }); } @@ -870,9 +896,7 @@ impl<'a> Linker for EmLinker<'a> { let mut encoder = json::Encoder::new(&mut encoded); let res = encoder.emit_seq(symbols.len(), |encoder| { for (i, sym) in symbols.iter().enumerate() { - encoder.emit_seq_elt(i, |encoder| { - encoder.emit_str(&("_".to_owned() + sym)) - })?; + encoder.emit_seq_elt(i, |encoder| encoder.emit_str(&("_".to_owned() + sym)))?; } Ok(()) }); @@ -936,8 +960,8 @@ impl<'a> WasmLd<'a> { // // * `--export=*tls*` - when `#[thread_local]` symbols are used these // symbols are how the TLS segments are initialized and configured. - let atomics = sess.opts.cg.target_feature.contains("+atomics") || - sess.target.target.options.features.contains("+atomics"); + let atomics = sess.opts.cg.target_feature.contains("+atomics") + || sess.target.target.options.features.contains("+atomics"); if atomics { cmd.arg("--shared-memory"); cmd.arg("--max-memory=1073741824"); @@ -982,20 +1006,15 @@ impl<'a> Linker for WasmLd<'a> { self.cmd.arg(path); } - fn position_independent_executable(&mut self) { - } + fn position_independent_executable(&mut self) {} - fn full_relro(&mut self) { - } + fn full_relro(&mut self) {} - fn partial_relro(&mut self) { - } + fn partial_relro(&mut self) {} - fn no_relro(&mut self) { - } + fn no_relro(&mut self) {} - fn build_static_executable(&mut self) { - } + fn build_static_executable(&mut self) {} fn args(&mut self, args: &[String]) { self.cmd.args(args); @@ -1030,18 +1049,15 @@ impl<'a> Linker for WasmLd<'a> { // Currently LLD doesn't support `Os` and `Oz`, so pass through `O2` // instead. OptLevel::Size => "-O2", - OptLevel::SizeMin => "-O2" + OptLevel::SizeMin => "-O2", }); } - fn pgo_gen(&mut self) { - } + fn pgo_gen(&mut self) {} - fn debuginfo(&mut self) { - } + fn debuginfo(&mut self) {} - fn no_default_libraries(&mut self) { - } + fn no_default_libraries(&mut self) {} fn build_dylib(&mut self, _out_filename: &Path) { self.cmd.arg("--no-entry"); @@ -1060,11 +1076,9 @@ impl<'a> Linker for WasmLd<'a> { self.cmd.arg("--export=__data_end"); } - fn subsystem(&mut self, _subsystem: &str) { - } + fn subsystem(&mut self, _subsystem: &str) {} - fn no_position_independent_executable(&mut self) { - } + fn no_position_independent_executable(&mut self) {} fn finalize(&mut self) -> Command { ::std::mem::replace(&mut self.cmd, Command::new("")) @@ -1081,7 +1095,7 @@ impl<'a> Linker for WasmLd<'a> { fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec { if let Some(ref exports) = tcx.sess.target.target.options.override_export_symbols { - return exports.clone() + return exports.clone(); } let mut symbols = Vec::new(); @@ -1094,13 +1108,11 @@ fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec { } let formats = tcx.dependency_formats(LOCAL_CRATE); - let deps = formats.iter().filter_map(|(t, list)| { - if *t == crate_type { - Some(list) - } else { - None - } - }).next().unwrap(); + let deps = formats + .iter() + .filter_map(|(t, list)| if *t == crate_type { Some(list) } else { None }) + .next() + .unwrap(); for (index, dep_format) in deps.iter().enumerate() { let cnum = CrateNum::new(index + 1); @@ -1161,9 +1173,9 @@ impl<'a> Linker for PtxLinker<'a> { match self.sess.lto() { Lto::Thin | Lto::Fat | Lto::ThinLocal => { self.cmd.arg("-Olto"); - }, + } - Lto::No => { }, + Lto::No => {} }; } @@ -1175,7 +1187,7 @@ impl<'a> Linker for PtxLinker<'a> { // Provide the linker with fallback to internal `target-cpu`. self.cmd.arg("--fallback-arch").arg(match self.sess.opts.cg.target_cpu { Some(ref s) => s, - None => &self.sess.target.target.options.cpu + None => &self.sess.target.target.options.cpu, }); ::std::mem::replace(&mut self.cmd, Command::new("")) @@ -1205,48 +1217,33 @@ impl<'a> Linker for PtxLinker<'a> { panic!("frameworks not supported") } - fn position_independent_executable(&mut self) { - } + fn position_independent_executable(&mut self) {} - fn full_relro(&mut self) { - } + fn full_relro(&mut self) {} - fn partial_relro(&mut self) { - } + fn partial_relro(&mut self) {} - fn no_relro(&mut self) { - } + fn no_relro(&mut self) {} - fn build_static_executable(&mut self) { - } + fn build_static_executable(&mut self) {} - fn gc_sections(&mut self, _keep_metadata: bool) { - } + fn gc_sections(&mut self, _keep_metadata: bool) {} - fn pgo_gen(&mut self) { - } + fn pgo_gen(&mut self) {} - fn no_default_libraries(&mut self) { - } + fn no_default_libraries(&mut self) {} - fn build_dylib(&mut self, _out_filename: &Path) { - } + fn build_dylib(&mut self, _out_filename: &Path) {} - fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType) { - } + fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType) {} - fn subsystem(&mut self, _subsystem: &str) { - } + fn subsystem(&mut self, _subsystem: &str) {} - fn no_position_independent_executable(&mut self) { - } + fn no_position_independent_executable(&mut self) {} - fn group_start(&mut self) { - } + fn group_start(&mut self) {} - fn group_end(&mut self) { - } + fn group_end(&mut self) {} - fn linker_plugin_lto(&mut self) { - } + fn linker_plugin_lto(&mut self) {} } diff --git a/src/librustc_codegen_ssa/back/lto.rs b/src/librustc_codegen_ssa/back/lto.rs index 47e5d9af33ba4..0d7f4447696f2 100644 --- a/src/librustc_codegen_ssa/back/lto.rs +++ b/src/librustc_codegen_ssa/back/lto.rs @@ -4,8 +4,8 @@ use crate::ModuleCodegen; use rustc_errors::FatalError; -use std::sync::Arc; use std::ffi::CString; +use std::sync::Arc; pub struct ThinModule { pub shared: Arc>, @@ -39,7 +39,6 @@ pub struct ThinShared { pub module_names: Vec, } - pub enum LtoModuleCodegen { Fat { module: Option>, @@ -91,7 +90,6 @@ impl LtoModuleCodegen { } } - pub enum SerializedModule { Local(M), FromRlib(Vec), diff --git a/src/librustc_codegen_ssa/back/mod.rs b/src/librustc_codegen_ssa/back/mod.rs index 901891d85a465..20ca503d43f45 100644 --- a/src/librustc_codegen_ssa/back/mod.rs +++ b/src/librustc_codegen_ssa/back/mod.rs @@ -1,8 +1,8 @@ -pub mod write; +pub mod archive; +pub mod command; +pub mod link; pub mod linker; pub mod lto; -pub mod link; -pub mod command; -pub mod symbol_export; -pub mod archive; pub mod rpath; +pub mod symbol_export; +pub mod write; diff --git a/src/librustc_codegen_ssa/back/rpath.rs b/src/librustc_codegen_ssa/back/rpath.rs index cd3d99951e2b1..b09fd832831c0 100644 --- a/src/librustc_codegen_ssa/back/rpath.rs +++ b/src/librustc_codegen_ssa/back/rpath.rs @@ -1,7 +1,7 @@ use rustc_data_structures::fx::FxHashSet; use std::env; -use std::path::{Path, PathBuf}; use std::fs; +use std::path::{Path, PathBuf}; use rustc::hir::def_id::CrateNum; use rustc::middle::cstore::LibSource; @@ -86,18 +86,13 @@ fn get_rpaths(config: &mut RPathConfig<'_>, libs: &[PathBuf]) -> Vec { rpaths } -fn get_rpaths_relative_to_output(config: &mut RPathConfig<'_>, - libs: &[PathBuf]) -> Vec { +fn get_rpaths_relative_to_output(config: &mut RPathConfig<'_>, libs: &[PathBuf]) -> Vec { libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect() } fn get_rpath_relative_to_output(config: &mut RPathConfig<'_>, lib: &Path) -> String { // Mac doesn't appear to support $ORIGIN - let prefix = if config.is_like_osx { - "@loader_path" - } else { - "$ORIGIN" - }; + let prefix = if config.is_like_osx { "@loader_path" } else { "$ORIGIN" }; let cwd = env::current_dir().unwrap(); let mut lib = fs::canonicalize(&cwd.join(lib)).unwrap_or_else(|_| cwd.join(lib)); @@ -105,8 +100,8 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig<'_>, lib: &Path) -> Str let mut output = cwd.join(&config.out_filename); output.pop(); // strip filename let output = fs::canonicalize(&output).unwrap_or(output); - let relative = path_relative_from(&lib, &output).unwrap_or_else(|| - panic!("couldn't create relative path from {:?} to {:?}", output, lib)); + let relative = path_relative_from(&lib, &output) + .unwrap_or_else(|| panic!("couldn't create relative path from {:?} to {:?}", output, lib)); // FIXME (#9639): This needs to handle non-utf8 paths format!("{}/{}", prefix, relative.to_str().expect("non-utf8 component in path")) } @@ -149,7 +144,6 @@ fn path_relative_from(path: &Path, base: &Path) -> Option { } } - fn get_install_prefix_rpath(config: &mut RPathConfig<'_>) -> String { let path = (config.get_install_prefix_lib_path)(); let path = env::current_dir().unwrap().join(&path); diff --git a/src/librustc_codegen_ssa/back/rpath/tests.rs b/src/librustc_codegen_ssa/back/rpath/tests.rs index e8457fe0e19ea..35836ae719b9c 100644 --- a/src/librustc_codegen_ssa/back/rpath/tests.rs +++ b/src/librustc_codegen_ssa/back/rpath/tests.rs @@ -1,29 +1,17 @@ -use super::{RPathConfig}; -use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output}; +use super::RPathConfig; +use super::{get_rpath_relative_to_output, minimize_rpaths, rpaths_to_flags}; use std::path::{Path, PathBuf}; #[test] fn test_rpaths_to_flags() { - let flags = rpaths_to_flags(&[ - "path1".to_string(), - "path2".to_string() - ]); - assert_eq!(flags, - ["-Wl,-rpath,path1", - "-Wl,-rpath,path2"]); + let flags = rpaths_to_flags(&["path1".to_string(), "path2".to_string()]); + assert_eq!(flags, ["-Wl,-rpath,path1", "-Wl,-rpath,path2"]); } #[test] fn test_minimize1() { - let res = minimize_rpaths(&[ - "rpath1".to_string(), - "rpath2".to_string(), - "rpath1".to_string() - ]); - assert!(res == [ - "rpath1", - "rpath2", - ]); + let res = minimize_rpaths(&["rpath1".to_string(), "rpath2".to_string(), "rpath1".to_string()]); + assert!(res == ["rpath1", "rpath2",]); } #[test] @@ -38,14 +26,9 @@ fn test_minimize2() { "2".to_string(), "3".to_string(), "4a".to_string(), - "3".to_string() - ]); - assert!(res == [ - "1a", - "2", - "4a", - "3", + "3".to_string(), ]); + assert!(res == ["1a", "2", "4a", "3",]); } #[test] @@ -59,8 +42,7 @@ fn test_rpath_relative() { out_filename: PathBuf::from("bin/rustc"), get_install_prefix_lib_path: &mut || panic!(), }; - let res = get_rpath_relative_to_output(config, - Path::new("lib/libstd.so")); + let res = get_rpath_relative_to_output(config, Path::new("lib/libstd.so")); assert_eq!(res, "@loader_path/../lib"); } else { let config = &mut RPathConfig { @@ -71,23 +53,22 @@ fn test_rpath_relative() { is_like_osx: false, linker_is_gnu: true, }; - let res = get_rpath_relative_to_output(config, - Path::new("lib/libstd.so")); + let res = get_rpath_relative_to_output(config, Path::new("lib/libstd.so")); assert_eq!(res, "$ORIGIN/../lib"); } } #[test] fn test_xlinker() { - let args = rpaths_to_flags(&[ - "a/normal/path".to_string(), - "a,comma,path".to_string() - ]); + let args = rpaths_to_flags(&["a/normal/path".to_string(), "a,comma,path".to_string()]); - assert_eq!(args, vec![ - "-Wl,-rpath,a/normal/path".to_string(), - "-Wl,-rpath".to_string(), - "-Xlinker".to_string(), - "a,comma,path".to_string() - ]); + assert_eq!( + args, + vec![ + "-Wl,-rpath,a/normal/path".to_string(), + "-Wl,-rpath".to_string(), + "-Xlinker".to_string(), + "a,comma,path".to_string() + ] + ); } diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index cea5dc18c1362..07ff5c362ebbf 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -1,25 +1,22 @@ use std::collections::hash_map::Entry::*; use std::sync::Arc; -use rustc::ty::Instance; use rustc::hir; -use rustc::hir::Node; +use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::hir::CodegenFnAttrFlags; -use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX}; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc::middle::exported_symbols::{SymbolExportLevel, ExportedSymbol, metadata_symbol_name}; +use rustc::hir::Node; +use rustc::middle::exported_symbols::{metadata_symbol_name, ExportedSymbol, SymbolExportLevel}; use rustc::session::config; -use rustc::ty::{TyCtxt, SymbolName}; use rustc::ty::query::Providers; use rustc::ty::subst::SubstsRef; -use rustc::util::nodemap::{FxHashMap, DefIdMap}; +use rustc::ty::Instance; +use rustc::ty::{SymbolName, TyCtxt}; +use rustc::util::nodemap::{DefIdMap, FxHashMap}; +use rustc_data_structures::fingerprint::Fingerprint; use rustc_index::vec::IndexVec; use syntax::expand::allocator::ALLOCATOR_METHODS; -pub type ExportedSymbols = FxHashMap< - CrateNum, - Arc>, ->; +pub type ExportedSymbols = FxHashMap>>; pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { crates_export_threshold(&tcx.sess.crate_types.borrow()) @@ -27,18 +24,18 @@ pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { fn crate_export_threshold(crate_type: config::CrateType) -> SymbolExportLevel { match crate_type { - config::CrateType::Executable | - config::CrateType::Staticlib | - config::CrateType::ProcMacro | - config::CrateType::Cdylib => SymbolExportLevel::C, - config::CrateType::Rlib | - config::CrateType::Dylib => SymbolExportLevel::Rust, + config::CrateType::Executable + | config::CrateType::Staticlib + | config::CrateType::ProcMacro + | config::CrateType::Cdylib => SymbolExportLevel::C, + config::CrateType::Rlib | config::CrateType::Dylib => SymbolExportLevel::Rust, } } pub fn crates_export_threshold(crate_types: &[config::CrateType]) -> SymbolExportLevel { - if crate_types.iter().any(|&crate_type| - crate_export_threshold(crate_type) == SymbolExportLevel::Rust) + if crate_types + .iter() + .any(|&crate_type| crate_export_threshold(crate_type) == SymbolExportLevel::Rust) { SymbolExportLevel::Rust } else { @@ -63,10 +60,12 @@ fn reachable_non_generics_provider( // export level, however, as they're just implementation details. // Down below we'll hardwire all of the symbols to the `Rust` export // level instead. - let special_runtime_crate = tcx.is_panic_runtime(LOCAL_CRATE) || - tcx.is_compiler_builtins(LOCAL_CRATE); + let special_runtime_crate = + tcx.is_panic_runtime(LOCAL_CRATE) || tcx.is_compiler_builtins(LOCAL_CRATE); - let mut reachable_non_generics: DefIdMap<_> = tcx.reachable_set(LOCAL_CRATE).0 + let mut reachable_non_generics: DefIdMap<_> = tcx + .reachable_set(LOCAL_CRATE) + .0 .iter() .filter_map(|&hir_id| { // We want to ignore some FFI functions that are not exposed from @@ -89,30 +88,23 @@ fn reachable_non_generics_provider( } // Only consider nodes that actually have exported symbols. - Node::Item(&hir::Item { - kind: hir::ItemKind::Static(..), - .. - }) | - Node::Item(&hir::Item { - kind: hir::ItemKind::Fn(..), .. - }) | - Node::ImplItem(&hir::ImplItem { - kind: hir::ImplItemKind::Method(..), - .. - }) => { + Node::Item(&hir::Item { kind: hir::ItemKind::Static(..), .. }) + | Node::Item(&hir::Item { kind: hir::ItemKind::Fn(..), .. }) + | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Method(..), .. }) => { let def_id = tcx.hir().local_def_id(hir_id); let generics = tcx.generics_of(def_id); if !generics.requires_monomorphization(tcx) && // Functions marked with #[inline] are only ever codegened // with "internal" linkage and are never exported. - !Instance::mono(tcx, def_id).def.requires_local(tcx) { + !Instance::mono(tcx, def_id).def.requires_local(tcx) + { Some(def_id) } else { None } } - _ => None + _ => None, } }) .map(|def_id| { @@ -125,9 +117,10 @@ fn reachable_non_generics_provider( // // In general though we won't link right if these // symbols are stripped, and LTO currently strips them. - if name == "rust_eh_personality" || - name == "rust_eh_register_frames" || - name == "rust_eh_unregister_frames" { + if name == "rust_eh_personality" + || name == "rust_eh_register_frames" + || name == "rust_eh_unregister_frames" + { SymbolExportLevel::C } else { SymbolExportLevel::Rust @@ -135,9 +128,11 @@ fn reachable_non_generics_provider( } else { symbol_export_level(tcx, def_id) }; - debug!("EXPORTED SYMBOL (local): {} ({:?})", - tcx.symbol_name(Instance::mono(tcx, def_id)), - export_level); + debug!( + "EXPORTED SYMBOL (local): {} ({:?})", + tcx.symbol_name(Instance::mono(tcx, def_id)), + export_level + ); (def_id, export_level) }) .collect(); @@ -174,15 +169,14 @@ fn exported_symbols_provider_local( assert_eq!(cnum, LOCAL_CRATE); if !tcx.sess.opts.output_types.should_codegen() { - return Arc::new(vec![]) + return Arc::new(vec![]); } - let mut symbols: Vec<_> = tcx.reachable_non_generics(LOCAL_CRATE) - .iter() - .map(|(&def_id, &level)| { - (ExportedSymbol::NonGeneric(def_id), level) - }) - .collect(); + let mut symbols: Vec<_> = tcx + .reachable_non_generics(LOCAL_CRATE) + .iter() + .map(|(&def_id, &level)| (ExportedSymbol::NonGeneric(def_id), level)) + .collect(); if tcx.entry_fn(LOCAL_CRATE).is_some() { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new("main")); @@ -203,10 +197,8 @@ fn exported_symbols_provider_local( // These are weak symbols that point to the profile version and the // profile name, which need to be treated as exported so LTO doesn't nix // them. - const PROFILER_WEAK_SYMBOLS: [&str; 2] = [ - "__llvm_profile_raw_version", - "__llvm_profile_filename", - ]; + const PROFILER_WEAK_SYMBOLS: [&str; 2] = + ["__llvm_profile_raw_version", "__llvm_profile_filename"]; symbols.extend(PROFILER_WEAK_SYMBOLS.iter().map(|sym| { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(sym)); @@ -222,7 +214,7 @@ fn exported_symbols_provider_local( } if tcx.sess.opts.share_generics() && tcx.local_crate_exports_generics() { - use rustc::mir::mono::{Linkage, Visibility, MonoItem}; + use rustc::mir::mono::{Linkage, MonoItem, Visibility}; use rustc::ty::InstanceDef; // Normally, we require that shared monomorphizations are not hidden, @@ -230,32 +222,28 @@ fn exported_symbols_provider_local( // needs to be exported. // However, on platforms that don't allow for Rust dylibs, having // external linkage is enough for monomorphization to be linked to. - let need_visibility = tcx.sess.target.target.options.dynamic_linking && - !tcx.sess.target.target.options.only_cdylib; + let need_visibility = tcx.sess.target.target.options.dynamic_linking + && !tcx.sess.target.target.options.only_cdylib; let (_, cgus) = tcx.collect_and_partition_mono_items(LOCAL_CRATE); - for (mono_item, &(linkage, visibility)) in cgus.iter() - .flat_map(|cgu| cgu.items().iter()) { + for (mono_item, &(linkage, visibility)) in cgus.iter().flat_map(|cgu| cgu.items().iter()) { if linkage != Linkage::External { // We can only re-use things with external linkage, otherwise // we'll get a linker error - continue + continue; } if need_visibility && visibility == Visibility::Hidden { // If we potentially share things from Rust dylibs, they must // not be hidden - continue + continue; } - if let &MonoItem::Fn(Instance { - def: InstanceDef::Item(def_id), - substs, - }) = mono_item { + if let &MonoItem::Fn(Instance { def: InstanceDef::Item(def_id), substs }) = mono_item { if substs.non_erasable_generics().next().is_some() { - symbols.push((ExportedSymbol::Generic(def_id, substs), - SymbolExportLevel::Rust)); + symbols + .push((ExportedSymbol::Generic(def_id, substs), SymbolExportLevel::Rust)); } } } @@ -280,14 +268,11 @@ fn upstream_monomorphizations_provider( let mut instances: DefIdMap> = Default::default(); let cnum_stable_ids: IndexVec = { - let mut cnum_stable_ids = IndexVec::from_elem_n(Fingerprint::ZERO, - cnums.len() + 1); + let mut cnum_stable_ids = IndexVec::from_elem_n(Fingerprint::ZERO, cnums.len() + 1); for &cnum in cnums.iter() { - cnum_stable_ids[cnum] = tcx.def_path_hash(DefId { - krate: cnum, - index: CRATE_DEF_INDEX, - }).0; + cnum_stable_ids[cnum] = + tcx.def_path_hash(DefId { krate: cnum, index: CRATE_DEF_INDEX }).0; } cnum_stable_ids @@ -330,8 +315,7 @@ fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: DefId) -> b if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) { !tcx.reachable_set(LOCAL_CRATE).0.contains(&hir_id) } else { - bug!("is_unreachable_local_definition called with non-local DefId: {:?}", - def_id) + bug!("is_unreachable_local_definition called with non-local DefId: {:?}", def_id) } } @@ -363,10 +347,9 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel let target = &tcx.sess.target.target.llvm_target; // WebAssembly cannot export data symbols, so reduce their export level if target.contains("wasm32") || target.contains("emscripten") { - if let Some(Node::Item(&hir::Item { - kind: hir::ItemKind::Static(..), - .. - })) = tcx.hir().get_if_local(sym_def_id) { + if let Some(Node::Item(&hir::Item { kind: hir::ItemKind::Static(..), .. })) = + tcx.hir().get_if_local(sym_def_id) + { return SymbolExportLevel::Rust; } } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 283295cadfcc5..a5a90980c3a23 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -1,36 +1,40 @@ -use crate::{ModuleCodegen, ModuleKind, CachedModuleCodegen, CompiledModule, CrateInfo, - CodegenResults, RLIB_BYTECODE_EXTENSION}; +use super::command::Command; +use super::link::{self, get_linker, remove}; use super::linker::LinkerInfo; use super::lto::{self, SerializedModule}; -use super::link::{self, remove, get_linker}; -use super::command::Command; use super::symbol_export::ExportedSymbols; +use crate::{ + CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, + RLIB_BYTECODE_EXTENSION, +}; use crate::traits::*; -use rustc_incremental::{copy_cgu_workproducts_to_incr_comp_cache_dir, - in_incr_comp_dir, in_incr_comp_dir_sess}; -use rustc::dep_graph::{WorkProduct, WorkProductId, WorkProductFileKind}; -use rustc_session::cgu_reuse_tracker::CguReuseTracker; +use jobserver::{Acquired, Client}; +use rustc::dep_graph::{WorkProduct, WorkProductFileKind, WorkProductId}; +use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::middle::cstore::EncodedMetadata; -use rustc::session::config::{self, OutputFilenames, OutputType, Passes, Lto, - Sanitizer, SwitchWithOptPath}; +use rustc::session::config::{ + self, Lto, OutputFilenames, OutputType, Passes, Sanitizer, SwitchWithOptPath, +}; use rustc::session::Session; -use rustc::util::nodemap::FxHashMap; -use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::ty::TyCtxt; -use rustc::util::common::{time_depth, set_time_depth, print_time_passes_entry}; +use rustc::util::common::{print_time_passes_entry, set_time_depth, time_depth}; +use rustc::util::nodemap::FxHashMap; use rustc_data_structures::profiling::SelfProfilerRef; -use rustc_fs_util::link_or_copy; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; -use rustc_errors::{Handler, Level, FatalError, DiagnosticId}; -use syntax_pos::source_map::SourceMap; -use rustc_errors::emitter::{Emitter}; +use rustc_errors::emitter::Emitter; +use rustc_errors::{DiagnosticId, FatalError, Handler, Level}; +use rustc_fs_util::link_or_copy; +use rustc_incremental::{ + copy_cgu_workproducts_to_incr_comp_cache_dir, in_incr_comp_dir, in_incr_comp_dir_sess, +}; +use rustc_session::cgu_reuse_tracker::CguReuseTracker; use rustc_target::spec::MergeFunctions; use syntax::attr; use syntax_pos::hygiene::ExpnId; -use syntax_pos::symbol::{Symbol, sym}; -use jobserver::{Client, Acquired}; +use syntax_pos::source_map::SourceMap; +use syntax_pos::symbol::{sym, Symbol}; use std::any::Any; use std::fs; @@ -38,10 +42,10 @@ use std::io; use std::mem; use std::path::{Path, PathBuf}; use std::str; +use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::Arc; -use std::sync::mpsc::{channel, Sender, Receiver}; -use std::time::Instant; use std::thread; +use std::time::Instant; const PRE_LTO_BC_EXT: &str = "pre-lto.bc"; @@ -125,7 +129,7 @@ impl ModuleConfig { vectorize_loop: false, vectorize_slp: false, merge_functions: false, - inline_threshold: None + inline_threshold: None, } } @@ -135,14 +139,13 @@ impl ModuleConfig { self.no_builtins = no_builtins || sess.target.target.options.no_builtins; self.time_passes = sess.time_extended(); self.inline_threshold = sess.opts.cg.inline_threshold; - self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode || - sess.opts.cg.linker_plugin_lto.enabled(); - let embed_bitcode = sess.target.target.options.embed_bitcode || - sess.opts.debugging_opts.embed_bitcode; + self.obj_is_bitcode = + sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled(); + let embed_bitcode = + sess.target.target.options.embed_bitcode || sess.opts.debugging_opts.embed_bitcode; if embed_bitcode { match sess.opts.optimize { - config::OptLevel::No | - config::OptLevel::Less => { + config::OptLevel::No | config::OptLevel::Less => { self.embed_bitcode_marker = embed_bitcode; } _ => self.embed_bitcode = embed_bitcode, @@ -152,12 +155,12 @@ impl ModuleConfig { // Copy what clang does by turning on loop vectorization at O2 and // slp vectorization at O3. Otherwise configure other optimization aspects // of this pass manager builder. - self.vectorize_loop = !sess.opts.cg.no_vectorize_loops && - (sess.opts.optimize == config::OptLevel::Default || - sess.opts.optimize == config::OptLevel::Aggressive); + self.vectorize_loop = !sess.opts.cg.no_vectorize_loops + && (sess.opts.optimize == config::OptLevel::Default + || sess.opts.optimize == config::OptLevel::Aggressive); - self.vectorize_slp = !sess.opts.cg.no_vectorize_slp && - sess.opts.optimize == config::OptLevel::Aggressive; + self.vectorize_slp = + !sess.opts.cg.no_vectorize_slp && sess.opts.optimize == config::OptLevel::Aggressive; // Some targets (namely, NVPTX) interact badly with the MergeFunctions // pass. This is because MergeFunctions can generate new function calls @@ -168,20 +171,22 @@ impl ModuleConfig { // Therefore, allow targets to opt out of the MergeFunctions pass, // but otherwise keep the pass enabled (at O2 and O3) since it can be // useful for reducing code size. - self.merge_functions = match sess.opts.debugging_opts.merge_functions - .unwrap_or(sess.target.target.options.merge_functions) { + self.merge_functions = match sess + .opts + .debugging_opts + .merge_functions + .unwrap_or(sess.target.target.options.merge_functions) + { MergeFunctions::Disabled => false, - MergeFunctions::Trampolines | - MergeFunctions::Aliases => { - sess.opts.optimize == config::OptLevel::Default || - sess.opts.optimize == config::OptLevel::Aggressive + MergeFunctions::Trampolines | MergeFunctions::Aliases => { + sess.opts.optimize == config::OptLevel::Default + || sess.opts.optimize == config::OptLevel::Aggressive } }; } pub fn bitcode_needed(&self) -> bool { - self.emit_bc || self.obj_is_bitcode - || self.emit_bc_compressed || self.embed_bitcode + self.emit_bc || self.obj_is_bitcode || self.emit_bc_compressed || self.embed_bitcode } } @@ -243,7 +248,7 @@ pub struct CodegenContext { // Channel back to the main control thread to send messages to pub coordinator_send: Sender>, // The assembler command if no_integrated_as option is enabled, None otherwise - pub assembler_cmd: Option> + pub assembler_cmd: Option>, } impl CodegenContext { @@ -264,34 +269,36 @@ fn generate_lto_work( cgcx: &CodegenContext, needs_fat_lto: Vec>, needs_thin_lto: Vec<(String, B::ThinBuffer)>, - import_only_modules: Vec<(SerializedModule, WorkProduct)> + import_only_modules: Vec<(SerializedModule, WorkProduct)>, ) -> Vec<(WorkItem, u64)> { let _prof_timer = cgcx.prof.generic_activity("codegen_generate_lto_work"); let (lto_modules, copy_jobs) = if !needs_fat_lto.is_empty() { assert!(needs_thin_lto.is_empty()); - let lto_module = B::run_fat_lto( - cgcx, - needs_fat_lto, - import_only_modules, - ) - .unwrap_or_else(|e| e.raise()); + let lto_module = + B::run_fat_lto(cgcx, needs_fat_lto, import_only_modules).unwrap_or_else(|e| e.raise()); (vec![lto_module], vec![]) } else { assert!(needs_fat_lto.is_empty()); - B::run_thin_lto(cgcx, needs_thin_lto, import_only_modules) - .unwrap_or_else(|e| e.raise()) + B::run_thin_lto(cgcx, needs_thin_lto, import_only_modules).unwrap_or_else(|e| e.raise()) }; - let result = lto_modules.into_iter().map(|module| { - let cost = module.cost(); - (WorkItem::LTO(module), cost) - }).chain(copy_jobs.into_iter().map(|wp| { - (WorkItem::CopyPostLtoArtifacts(CachedModuleCodegen { - name: wp.cgu_name.clone(), - source: wp, - }), 0) - })).collect(); + let result = lto_modules + .into_iter() + .map(|module| { + let cost = module.cost(); + (WorkItem::LTO(module), cost) + }) + .chain(copy_jobs.into_iter().map(|wp| { + ( + WorkItem::CopyPostLtoArtifacts(CachedModuleCodegen { + name: wp.cgu_name.clone(), + source: wp, + }), + 0, + ) + })) + .collect(); result } @@ -303,20 +310,18 @@ pub struct CompiledModules { } fn need_crate_bitcode_for_rlib(sess: &Session) -> bool { - sess.crate_types.borrow().contains(&config::CrateType::Rlib) && - sess.opts.output_types.contains_key(&OutputType::Exe) + sess.crate_types.borrow().contains(&config::CrateType::Rlib) + && sess.opts.output_types.contains_key(&OutputType::Exe) } fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool { if sess.opts.incremental.is_none() { - return false + return false; } match sess.lto() { Lto::No => false, - Lto::Fat | - Lto::Thin | - Lto::ThinLocal => true, + Lto::Fat | Lto::Thin | Lto::ThinLocal => true, } } @@ -332,13 +337,15 @@ pub fn start_async_codegen( let crate_name = tcx.crate_name(LOCAL_CRATE); let crate_hash = tcx.crate_hash(LOCAL_CRATE); let no_builtins = attr::contains_name(&tcx.hir().krate().attrs, sym::no_builtins); - let subsystem = attr::first_attr_value_str_by_name(&tcx.hir().krate().attrs, - sym::windows_subsystem); + let subsystem = + attr::first_attr_value_str_by_name(&tcx.hir().krate().attrs, sym::windows_subsystem); let windows_subsystem = subsystem.map(|subsystem| { if subsystem != sym::windows && subsystem != sym::console { - tcx.sess.fatal(&format!("invalid windows subsystem `{}`, only \ + tcx.sess.fatal(&format!( + "invalid windows subsystem `{}`, only \ `windows` and `console` are allowed", - subsystem)); + subsystem + )); } subsystem.to_string() }); @@ -382,16 +389,19 @@ pub fn start_async_codegen( allocator_config.emit_bc_compressed = true; } - modules_config.emit_pre_lto_bc = - need_pre_lto_bitcode_for_incr_comp(sess); + modules_config.emit_pre_lto_bc = need_pre_lto_bitcode_for_incr_comp(sess); - modules_config.no_integrated_as = tcx.sess.opts.cg.no_integrated_as || - tcx.sess.target.target.options.no_integrated_as; + modules_config.no_integrated_as = + tcx.sess.opts.cg.no_integrated_as || tcx.sess.target.target.options.no_integrated_as; for output_type in sess.opts.output_types.keys() { match *output_type { - OutputType::Bitcode => { modules_config.emit_bc = true; } - OutputType::LlvmAssembly => { modules_config.emit_ir = true; } + OutputType::Bitcode => { + modules_config.emit_bc = true; + } + OutputType::LlvmAssembly => { + modules_config.emit_ir = true; + } OutputType::Assembly => { modules_config.emit_asm = true; // If we're not using the LLVM assembler, this function @@ -402,13 +412,17 @@ pub fn start_async_codegen( allocator_config.emit_obj = true; } } - OutputType::Object => { modules_config.emit_obj = true; } - OutputType::Metadata => { metadata_config.emit_obj = true; } + OutputType::Object => { + modules_config.emit_obj = true; + } + OutputType::Metadata => { + metadata_config.emit_obj = true; + } OutputType::Exe => { modules_config.emit_obj = true; metadata_config.emit_obj = true; allocator_config.emit_obj = true; - }, + } OutputType::Mir => {} OutputType::DepInfo => {} } @@ -426,18 +440,20 @@ pub fn start_async_codegen( let (shared_emitter, shared_emitter_main) = SharedEmitter::new(); let (codegen_worker_send, codegen_worker_receive) = channel(); - let coordinator_thread = start_executing_work(backend.clone(), - tcx, - &crate_info, - shared_emitter, - codegen_worker_send, - coordinator_receive, - total_cgus, - sess.jobserver.clone(), - Arc::new(modules_config), - Arc::new(metadata_config), - Arc::new(allocator_config), - coordinator_send.clone()); + let coordinator_thread = start_executing_work( + backend.clone(), + tcx, + &crate_info, + shared_emitter, + codegen_worker_send, + coordinator_receive, + total_cgus, + sess.jobserver.clone(), + Arc::new(modules_config), + Arc::new(metadata_config), + Arc::new(allocator_config), + coordinator_send.clone(), + ); OngoingCodegen { backend, @@ -480,7 +496,8 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( } if let Some((id, product)) = - copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files) { + copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files) + { work_products.insert(id, product); } } @@ -488,9 +505,11 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( work_products } -fn produce_final_output_artifacts(sess: &Session, - compiled_modules: &CompiledModules, - crate_output: &OutputFilenames) { +fn produce_final_output_artifacts( + sess: &Session, + compiled_modules: &CompiledModules, + crate_output: &OutputFilenames, +) { let mut user_wants_bitcode = false; let mut user_wants_objects = false; @@ -501,37 +520,42 @@ fn produce_final_output_artifacts(sess: &Session, } }; - let copy_if_one_unit = |output_type: OutputType, - keep_numbered: bool| { + let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| { if compiled_modules.modules.len() == 1 { // 1) Only one codegen unit. In this case it's no difficulty // to copy `foo.0.x` to `foo.x`. let module_name = Some(&compiled_modules.modules[0].name[..]); let path = crate_output.temp_path(output_type, module_name); - copy_gracefully(&path, - &crate_output.path(output_type)); + copy_gracefully(&path, &crate_output.path(output_type)); if !sess.opts.cg.save_temps && !keep_numbered { // The user just wants `foo.x`, not `foo.#module-name#.x`. remove(sess, &path); } } else { - let ext = crate_output.temp_path(output_type, None) - .extension() - .unwrap() - .to_str() - .unwrap() - .to_owned(); + let ext = crate_output + .temp_path(output_type, None) + .extension() + .unwrap() + .to_str() + .unwrap() + .to_owned(); if crate_output.outputs.contains_key(&output_type) { // 2) Multiple codegen units, with `--emit foo=some_name`. We have // no good solution for this case, so warn the user. - sess.warn(&format!("ignoring emit path because multiple .{} files \ - were produced", ext)); + sess.warn(&format!( + "ignoring emit path because multiple .{} files \ + were produced", + ext + )); } else if crate_output.single_output_file.is_some() { // 3) Multiple codegen units, with `-o some_name`. We have // no good solution for this case, so warn the user. - sess.warn(&format!("ignoring -o because multiple .{} files \ - were produced", ext)); + sess.warn(&format!( + "ignoring -o because multiple .{} files \ + were produced", + ext + )); } else { // 4) Multiple codegen units, but no explicit name. We // just leave the `foo.0.x` files in place. @@ -562,10 +586,7 @@ fn produce_final_output_artifacts(sess: &Session, user_wants_objects = true; copy_if_one_unit(OutputType::Object, true); } - OutputType::Mir | - OutputType::Metadata | - OutputType::Exe | - OutputType::DepInfo => {} + OutputType::Mir | OutputType::Metadata | OutputType::Exe | OutputType::DepInfo => {} } } @@ -601,8 +622,8 @@ fn produce_final_output_artifacts(sess: &Session, let keep_numbered_bitcode = user_wants_bitcode && sess.codegen_units() > 1; - let keep_numbered_objects = needs_crate_object || - (user_wants_objects && sess.codegen_units() > 1); + let keep_numbered_objects = + needs_crate_object || (user_wants_objects && sess.codegen_units() > 1); for module in compiled_modules.modules.iter() { if let Some(ref path) = module.object { @@ -663,8 +684,7 @@ impl WorkItem { pub fn module_kind(&self) -> ModuleKind { match *self { WorkItem::Optimize(ref m) => m.kind, - WorkItem::CopyPostLtoArtifacts(_) | - WorkItem::LTO(_) => ModuleKind::Regular, + WorkItem::CopyPostLtoArtifacts(_) | WorkItem::LTO(_) => ModuleKind::Regular, } } @@ -684,10 +704,7 @@ enum WorkItemResult { } pub enum FatLTOInput { - Serialized { - name: String, - buffer: B::ModuleBuffer, - }, + Serialized { name: String, buffer: B::ModuleBuffer }, InMemory(ModuleCodegen), } @@ -698,15 +715,11 @@ fn execute_work_item( let module_config = cgcx.config(work_item.module_kind()); match work_item { - WorkItem::Optimize(module) => { - execute_optimize_work_item(cgcx, module, module_config) - } + WorkItem::Optimize(module) => execute_optimize_work_item(cgcx, module, module_config), WorkItem::CopyPostLtoArtifacts(module) => { execute_copy_from_cache_work_item(cgcx, module, module_config) } - WorkItem::LTO(module) => { - execute_lto_work_item(cgcx, module, module_config) - } + WorkItem::LTO(module) => execute_lto_work_item(cgcx, module, module_config), } } @@ -752,8 +765,7 @@ fn execute_optimize_work_item( // require LTO so the request for LTO is always unconditionally // passed down to the backend, but we don't actually want to do // anything about it yet until we've got a final product. - let is_rlib = cgcx.crate_types.len() == 1 - && cgcx.crate_types[0] == config::CrateType::Rlib; + let is_rlib = cgcx.crate_types.len() == 1 && cgcx.crate_types[0] == config::CrateType::Rlib; // Metadata modules never participate in LTO regardless of the lto // settings. @@ -761,10 +773,8 @@ fn execute_optimize_work_item( ComputedLtoType::No } else { match cgcx.lto { - Lto::ThinLocal if !linker_does_lto && !is_allocator - => ComputedLtoType::Thin, - Lto::Thin if !linker_does_lto && !is_rlib - => ComputedLtoType::Thin, + Lto::ThinLocal if !linker_does_lto && !is_allocator => ComputedLtoType::Thin, + Lto::Thin if !linker_does_lto && !is_rlib => ComputedLtoType::Thin, Lto::Fat if !is_rlib => ComputedLtoType::Fat, _ => ComputedLtoType::No, } @@ -781,36 +791,28 @@ fn execute_optimize_work_item( Ok(match lto_type { ComputedLtoType::No => { - let module = unsafe { - B::codegen(cgcx, &diag_handler, module, module_config)? - }; + let module = unsafe { B::codegen(cgcx, &diag_handler, module, module_config)? }; WorkItemResult::Compiled(module) } ComputedLtoType::Thin => { let (name, thin_buffer) = B::prepare_thin(module); if let Some(path) = bitcode { fs::write(&path, thin_buffer.data()).unwrap_or_else(|e| { - panic!("Error writing pre-lto-bitcode file `{}`: {}", - path.display(), - e); + panic!("Error writing pre-lto-bitcode file `{}`: {}", path.display(), e); }); } WorkItemResult::NeedsThinLTO(name, thin_buffer) } - ComputedLtoType::Fat => { - match bitcode { - Some(path) => { - let (name, buffer) = B::serialize_module(module); - fs::write(&path, buffer.data()).unwrap_or_else(|e| { - panic!("Error writing pre-lto-bitcode file `{}`: {}", - path.display(), - e); - }); - WorkItemResult::NeedsFatLTO(FatLTOInput::Serialized { name, buffer }) - } - None => WorkItemResult::NeedsFatLTO(FatLTOInput::InMemory(module)), + ComputedLtoType::Fat => match bitcode { + Some(path) => { + let (name, buffer) = B::serialize_module(module); + fs::write(&path, buffer.data()).unwrap_or_else(|e| { + panic!("Error writing pre-lto-bitcode file `{}`: {}", path.display(), e); + }); + WorkItemResult::NeedsFatLTO(FatLTOInput::Serialized { name, buffer }) } - } + None => WorkItemResult::NeedsFatLTO(FatLTOInput::InMemory(module)), + }, }) } @@ -819,46 +821,46 @@ fn execute_copy_from_cache_work_item( module: CachedModuleCodegen, module_config: &ModuleConfig, ) -> Result, FatalError> { - let incr_comp_session_dir = cgcx.incr_comp_session_dir - .as_ref() - .unwrap(); + let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap(); let mut object = None; let mut bytecode = None; let mut bytecode_compressed = None; for (kind, saved_file) in &module.source.saved_files { let obj_out = match kind { WorkProductFileKind::Object => { - let path = cgcx.output_filenames.temp_path(OutputType::Object, - Some(&module.name)); + let path = cgcx.output_filenames.temp_path(OutputType::Object, Some(&module.name)); object = Some(path.clone()); path } WorkProductFileKind::Bytecode => { - let path = cgcx.output_filenames.temp_path(OutputType::Bitcode, - Some(&module.name)); + let path = cgcx.output_filenames.temp_path(OutputType::Bitcode, Some(&module.name)); bytecode = Some(path.clone()); path } WorkProductFileKind::BytecodeCompressed => { - let path = cgcx.output_filenames.temp_path(OutputType::Bitcode, - Some(&module.name)) + let path = cgcx + .output_filenames + .temp_path(OutputType::Bitcode, Some(&module.name)) .with_extension(RLIB_BYTECODE_EXTENSION); bytecode_compressed = Some(path.clone()); path } }; - let source_file = in_incr_comp_dir(&incr_comp_session_dir, - &saved_file); - debug!("copying pre-existing module `{}` from {:?} to {}", - module.name, - source_file, - obj_out.display()); + let source_file = in_incr_comp_dir(&incr_comp_session_dir, &saved_file); + debug!( + "copying pre-existing module `{}` from {:?} to {}", + module.name, + source_file, + obj_out.display() + ); if let Err(err) = link_or_copy(&source_file, &obj_out) { let diag_handler = cgcx.create_diag_handler(); - diag_handler.err(&format!("unable to copy {} to {}: {}", - source_file.display(), - obj_out.display(), - err)); + diag_handler.err(&format!( + "unable to copy {} to {}: {}", + source_file.display(), + obj_out.display(), + err + )); } } @@ -952,10 +954,11 @@ fn start_executing_work( let mut exported_symbols = FxHashMap::default(); let copy_symbols = |cnum| { - let symbols = tcx.exported_symbols(cnum) - .iter() - .map(|&(s, lvl)| (s.symbol_name(tcx).to_string(), lvl)) - .collect(); + let symbols = tcx + .exported_symbols(cnum) + .iter() + .map(|&(s, lvl)| (s.symbol_name(tcx).to_string(), lvl)) + .collect(); Arc::new(symbols) }; @@ -981,14 +984,16 @@ fn start_executing_work( // get tokens on `coordinator_receive` which will // get managed in the main loop below. let coordinator_send2 = coordinator_send.clone(); - let helper = jobserver.into_helper_thread(move |token| { - drop(coordinator_send2.send(Box::new(Message::Token::(token)))); - }).expect("failed to spawn helper thread"); + let helper = jobserver + .into_helper_thread(move |token| { + drop(coordinator_send2.send(Box::new(Message::Token::(token)))); + }) + .expect("failed to spawn helper thread"); let mut each_linked_rlib_for_lto = Vec::new(); drop(link::each_linked_rlib(crate_info, &mut |cnum, path| { if link::ignored_for_lto(sess, crate_info, cnum) { - return + return; } each_linked_rlib_for_lto.push((cnum, path.to_path_buf())); })); @@ -999,16 +1004,14 @@ fn start_executing_work( let (name, mut cmd) = get_linker(sess, &linker, flavor); cmd.args(&sess.target.target.options.asm_args); - Some(Arc::new(AssemblerCommand { - name, - cmd, - })) + Some(Arc::new(AssemblerCommand { name, cmd })) } else { None }; let ol = if tcx.sess.opts.debugging_opts.no_codegen - || !tcx.sess.opts.output_types.should_codegen() { + || !tcx.sess.opts.output_types.should_codegen() + { // If we know that we won’t be doing codegen, create target machines without optimisation. config::OptLevel::No } else { @@ -1228,17 +1231,15 @@ fn start_executing_work( // wait for all existing work to finish, so many of the conditions here // only apply if codegen hasn't been aborted as they represent pending // work to be done. - while !codegen_done || - running > 0 || - (!codegen_aborted && ( - work_items.len() > 0 || - needs_fat_lto.len() > 0 || - needs_thin_lto.len() > 0 || - lto_import_only_modules.len() > 0 || - main_thread_worker_state != MainThreadWorkerState::Idle - )) + while !codegen_done + || running > 0 + || (!codegen_aborted + && (work_items.len() > 0 + || needs_fat_lto.len() > 0 + || needs_thin_lto.len() > 0 + || lto_import_only_modules.len() > 0 + || main_thread_worker_state != MainThreadWorkerState::Idle)) { - // While there are still CGUs to be codegened, the coordinator has // to decide how to utilize the compiler processes implicit Token: // For codegenning more CGU or for running them through LLVM. @@ -1254,14 +1255,16 @@ fn start_executing_work( // The queue is full enough to not let the worker // threads starve. Use the implicit Token to do some // LLVM work too. - let (item, _) = work_items.pop() - .expect("queue empty - queue_full_enough() broken?"); + let (item, _) = + work_items.pop().expect("queue empty - queue_full_enough() broken?"); let cgcx = CodegenContext { worker: get_worker_id(&mut free_worker_ids), - .. cgcx.clone() + ..cgcx.clone() }; - maybe_start_llvm_timer(cgcx.config(item.module_kind()), - &mut llvm_start_time); + maybe_start_llvm_timer( + cgcx.config(item.module_kind()), + &mut llvm_start_time, + ); main_thread_worker_state = MainThreadWorkerState::LLVMing; spawn_work(cgcx, item); } @@ -1275,9 +1278,10 @@ fn start_executing_work( // Perform the serial work here of figuring out what we're // going to LTO and then push a bunch of work items onto our // queue to do LTO - if work_items.len() == 0 && - running == 0 && - main_thread_worker_state == MainThreadWorkerState::Idle { + if work_items.len() == 0 + && running == 0 + && main_thread_worker_state == MainThreadWorkerState::Idle + { assert!(!started_lto); started_lto = true; @@ -1285,8 +1289,9 @@ fn start_executing_work( let needs_thin_lto = mem::take(&mut needs_thin_lto); let import_only_modules = mem::take(&mut lto_import_only_modules); - for (work, cost) in generate_lto_work(&cgcx, needs_fat_lto, - needs_thin_lto, import_only_modules) { + for (work, cost) in + generate_lto_work(&cgcx, needs_fat_lto, needs_thin_lto, import_only_modules) + { let insertion_index = work_items .binary_search_by_key(&cost, |&(_, cost)| cost) .unwrap_or_else(|e| e); @@ -1305,10 +1310,12 @@ fn start_executing_work( if let Some((item, _)) = work_items.pop() { let cgcx = CodegenContext { worker: get_worker_id(&mut free_worker_ids), - .. cgcx.clone() + ..cgcx.clone() }; - maybe_start_llvm_timer(cgcx.config(item.module_kind()), - &mut llvm_start_time); + maybe_start_llvm_timer( + cgcx.config(item.module_kind()), + &mut llvm_start_time, + ); main_thread_worker_state = MainThreadWorkerState::LLVMing; spawn_work(cgcx, item); } else { @@ -1323,10 +1330,10 @@ fn start_executing_work( main_thread_worker_state = MainThreadWorkerState::LLVMing; } } - MainThreadWorkerState::Codegenning => { - bug!("codegen worker should not be codegenning after \ - codegen was already completed") - } + MainThreadWorkerState::Codegenning => bug!( + "codegen worker should not be codegenning after \ + codegen was already completed" + ), MainThreadWorkerState::LLVMing => { // Already making good use of that token } @@ -1338,13 +1345,10 @@ fn start_executing_work( while !codegen_aborted && work_items.len() > 0 && running < tokens.len() { let (item, _) = work_items.pop().unwrap(); - maybe_start_llvm_timer(cgcx.config(item.module_kind()), - &mut llvm_start_time); + maybe_start_llvm_timer(cgcx.config(item.module_kind()), &mut llvm_start_time); - let cgcx = CodegenContext { - worker: get_worker_id(&mut free_worker_ids), - .. cgcx.clone() - }; + let cgcx = + CodegenContext { worker: get_worker_id(&mut free_worker_ids), ..cgcx.clone() }; spawn_work(cgcx, item); running += 1; @@ -1405,10 +1409,9 @@ fn start_executing_work( // Note, however, that this is not ideal for memory // consumption, as LLVM module sizes are not evenly // distributed. - let insertion_index = - work_items.binary_search_by_key(&cost, |&(_, cost)| cost); + let insertion_index = work_items.binary_search_by_key(&cost, |&(_, cost)| cost); let insertion_index = match insertion_index { - Ok(idx) | Err(idx) => idx + Ok(idx) | Err(idx) => idx, }; work_items.insert(insertion_index, (llvm_work_item, cost)); @@ -1416,16 +1419,14 @@ fn start_executing_work( helper.request_token(); } assert!(!codegen_aborted); - assert_eq!(main_thread_worker_state, - MainThreadWorkerState::Codegenning); + assert_eq!(main_thread_worker_state, MainThreadWorkerState::Codegenning); main_thread_worker_state = MainThreadWorkerState::Idle; } Message::CodegenComplete => { codegen_done = true; assert!(!codegen_aborted); - assert_eq!(main_thread_worker_state, - MainThreadWorkerState::Codegenning); + assert_eq!(main_thread_worker_state, MainThreadWorkerState::Codegenning); main_thread_worker_state = MainThreadWorkerState::Idle; } @@ -1439,8 +1440,7 @@ fn start_executing_work( assert!(!codegen_aborted); codegen_done = true; codegen_aborted = true; - assert_eq!(main_thread_worker_state, - MainThreadWorkerState::Codegenning); + assert_eq!(main_thread_worker_state, MainThreadWorkerState::Codegenning); } Message::Done { result: Ok(compiled_module), worker_id } => { free_worker(worker_id); @@ -1471,8 +1471,7 @@ fn start_executing_work( Message::AddImportOnlyModule { module_data, work_product } => { assert!(!started_lto); assert!(!codegen_done); - assert_eq!(main_thread_worker_state, - MainThreadWorkerState::Codegenning); + assert_eq!(main_thread_worker_state, MainThreadWorkerState::Codegenning); lto_import_only_modules.push((module_data, work_product)); main_thread_worker_state = MainThreadWorkerState::Idle; } @@ -1480,9 +1479,7 @@ fn start_executing_work( Message::Done { result: Err(()), worker_id: _ } => { bug!("worker thread panicked"); } - Message::CodegenItem => { - bug!("the coordinator should not receive codegen requests") - } + Message::CodegenItem => bug!("the coordinator should not receive codegen requests"), } } @@ -1491,9 +1488,7 @@ fn start_executing_work( // This is the top-level timing for all of LLVM, set the time-depth // to zero. set_time_depth(1); - print_time_passes_entry(cgcx.time_passes, - "LLVM passes", - total_llvm_time); + print_time_passes_entry(cgcx.time_passes, "LLVM passes", total_llvm_time); } // Regardless of what order these modules completed in, report them to @@ -1510,16 +1505,16 @@ fn start_executing_work( // A heuristic that determines if we have enough LLVM WorkItems in the // queue so that the main thread can do LLVM work instead of codegen - fn queue_full_enough(items_in_queue: usize, - workers_running: usize, - max_workers: usize) -> bool { + fn queue_full_enough( + items_in_queue: usize, + workers_running: usize, + max_workers: usize, + ) -> bool { // Tune me, plz. - items_in_queue > 0 && - items_in_queue >= max_workers.saturating_sub(workers_running / 2) + items_in_queue > 0 && items_in_queue >= max_workers.saturating_sub(workers_running / 2) } - fn maybe_start_llvm_timer(config: &ModuleConfig, - llvm_start_time: &mut Option) { + fn maybe_start_llvm_timer(config: &ModuleConfig, llvm_start_time: &mut Option) { // We keep track of the -Ztime-passes output manually, // since the closure-based interface does not fit well here. if config.time_passes { @@ -1532,10 +1527,7 @@ fn start_executing_work( pub const CODEGEN_WORKER_ID: usize = ::std::usize::MAX; -fn spawn_work( - cgcx: CodegenContext, - work: WorkItem -) { +fn spawn_work(cgcx: CodegenContext, work: WorkItem) { let depth = time_depth(); thread::spawn(move || { @@ -1561,7 +1553,7 @@ fn spawn_work( Some(WorkItemResult::NeedsThinLTO(name, thin_buffer)) => { Message::NeedsThinLTO:: { name, thin_buffer, worker_id } } - None => Message::Done:: { result: Err(()), worker_id } + None => Message::Done:: { result: Err(()), worker_id }, }; drop(self.coordinator_send.send(Box::new(msg))); } @@ -1590,11 +1582,9 @@ pub fn run_assembler( cgcx: &CodegenContext, handler: &Handler, assembly: &Path, - object: &Path + object: &Path, ) { - let assembler = cgcx.assembler_cmd - .as_ref() - .expect("cgcx.assembler_cmd is missing?"); + let assembler = cgcx.assembler_cmd.as_ref().expect("cgcx.assembler_cmd is missing?"); let pname = &assembler.name; let mut cmd = assembler.cmd.clone(); @@ -1607,15 +1597,18 @@ pub fn run_assembler( let mut note = prog.stderr.clone(); note.extend_from_slice(&prog.stdout); - handler.struct_err(&format!("linking with `{}` failed: {}", - pname.display(), - prog.status)) + handler + .struct_err(&format!( + "linking with `{}` failed: {}", + pname.display(), + prog.status + )) .note(&format!("{:?}", &cmd)) .note(str::from_utf8(¬e[..]).unwrap()) .emit(); handler.abort_if_errors(); } - }, + } Err(e) => { handler.err(&format!("could not exec the linker `{}`: {}", pname.display(), e)); handler.abort_if_errors(); @@ -1623,7 +1616,6 @@ pub fn run_assembler( } } - enum SharedEmitterMessage { Diagnostic(Diagnostic), InlineAsmError(u32, String), @@ -1715,7 +1707,6 @@ impl SharedEmitterMain { break; } } - } } } @@ -1736,17 +1727,14 @@ pub struct OngoingCodegen { } impl OngoingCodegen { - pub fn join( - self, - sess: &Session - ) -> (CodegenResults, FxHashMap) { + pub fn join(self, sess: &Session) -> (CodegenResults, FxHashMap) { self.shared_emitter_main.check(sess, true); let compiled_modules = match self.future.join() { Ok(Ok(compiled_modules)) => compiled_modules, Ok(Err(())) => { sess.abort_if_errors(); panic!("expected abort due to worker thread errors") - }, + } Err(_) => { bug!("panic during codegen/LLVM phase"); } @@ -1757,11 +1745,8 @@ impl OngoingCodegen { sess.abort_if_errors(); let work_products = - copy_all_cgu_workproducts_to_incr_comp_cache_dir(sess, - &compiled_modules); - produce_final_output_artifacts(sess, - &compiled_modules, - &self.output_filenames); + copy_all_cgu_workproducts_to_incr_comp_cache_dir(sess, &compiled_modules); + produce_final_output_artifacts(sess, &compiled_modules, &self.output_filenames); // FIXME: time_llvm_passes support - does this use a global context or // something? @@ -1769,18 +1754,21 @@ impl OngoingCodegen { self.backend.print_pass_timings() } - (CodegenResults { - crate_name: self.crate_name, - crate_hash: self.crate_hash, - metadata: self.metadata, - windows_subsystem: self.windows_subsystem, - linker_info: self.linker_info, - crate_info: self.crate_info, - - modules: compiled_modules.modules, - allocator_module: compiled_modules.allocator_module, - metadata_module: compiled_modules.metadata_module, - }, work_products) + ( + CodegenResults { + crate_name: self.crate_name, + crate_hash: self.crate_hash, + metadata: self.metadata, + windows_subsystem: self.windows_subsystem, + linker_info: self.linker_info, + crate_info: self.crate_info, + + modules: compiled_modules.modules, + allocator_module: compiled_modules.allocator_module, + metadata_module: compiled_modules.metadata_module, + }, + work_products, + ) } pub fn submit_pre_codegened_module_to_llvm( @@ -1840,10 +1828,7 @@ pub fn submit_codegened_module_to_llvm( cost: u64, ) { let llvm_work_item = WorkItem::Optimize(module); - drop(tx_to_llvm_workers.send(Box::new(Message::CodegenDone:: { - llvm_work_item, - cost, - }))); + drop(tx_to_llvm_workers.send(Box::new(Message::CodegenDone:: { llvm_work_item, cost }))); } pub fn submit_post_lto_module_to_llvm( @@ -1852,10 +1837,7 @@ pub fn submit_post_lto_module_to_llvm( module: CachedModuleCodegen, ) { let llvm_work_item = WorkItem::CopyPostLtoArtifacts(module); - drop(tx_to_llvm_workers.send(Box::new(Message::CodegenDone:: { - llvm_work_item, - cost: 0, - }))); + drop(tx_to_llvm_workers.send(Box::new(Message::CodegenDone:: { llvm_work_item, cost: 0 }))); } pub fn submit_pre_lto_module_to_llvm( @@ -1866,9 +1848,8 @@ pub fn submit_pre_lto_module_to_llvm( ) { let filename = pre_lto_bitcode_filename(&module.name); let bc_path = in_incr_comp_dir_sess(tcx.sess, &filename); - let file = fs::File::open(&bc_path).unwrap_or_else(|e| { - panic!("failed to open bitcode file `{}`: {}", bc_path.display(), e) - }); + let file = fs::File::open(&bc_path) + .unwrap_or_else(|e| panic!("failed to open bitcode file `{}`: {}", bc_path.display(), e)); let mmap = unsafe { memmap::Mmap::map(&file).unwrap_or_else(|e| { @@ -1889,9 +1870,11 @@ pub fn pre_lto_bitcode_filename(module_name: &str) -> String { fn msvc_imps_needed(tcx: TyCtxt<'_>) -> bool { // This should never be true (because it's not supported). If it is true, // something is wrong with commandline arg validation. - assert!(!(tcx.sess.opts.cg.linker_plugin_lto.enabled() && - tcx.sess.target.target.options.is_like_msvc && - tcx.sess.opts.cg.prefer_dynamic)); + assert!( + !(tcx.sess.opts.cg.linker_plugin_lto.enabled() + && tcx.sess.target.target.options.is_like_msvc + && tcx.sess.opts.cg.prefer_dynamic) + ); tcx.sess.target.target.options.is_like_msvc && tcx.sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateType::Rlib) && diff --git a/src/librustc_codegen_ssa/common.rs b/src/librustc_codegen_ssa/common.rs index 9bebca93964ea..2cddce21ea99c 100644 --- a/src/librustc_codegen_ssa/common.rs +++ b/src/librustc_codegen_ssa/common.rs @@ -1,16 +1,16 @@ #![allow(non_camel_case_types, non_snake_case)] -use rustc::ty::{Ty, TyCtxt}; use rustc::session::Session; +use rustc::ty::{Ty, TyCtxt}; use syntax_pos::Span; -use rustc::hir::def_id::DefId; -use rustc::middle::lang_items::LangItem; use crate::base; use crate::traits::*; +use rustc::hir::def_id::DefId; +use rustc::middle::lang_items::LangItem; -use rustc::hir; use crate::traits::BuilderMethods; +use rustc::hir; use rustc_error_codes::*; @@ -24,10 +24,9 @@ pub enum IntPredicate { IntSGT, IntSGE, IntSLT, - IntSLE + IntSLE, } - #[allow(dead_code)] pub enum RealPredicate { RealPredicateFalse, @@ -45,7 +44,7 @@ pub enum RealPredicate { RealULT, RealULE, RealUNE, - RealPredicateTrue + RealPredicateTrue, } pub enum AtomicRmwBinOp { @@ -59,7 +58,7 @@ pub enum AtomicRmwBinOp { AtomicMax, AtomicMin, AtomicUMax, - AtomicUMin + AtomicUMin, } pub enum AtomicOrdering { @@ -112,8 +111,8 @@ pub enum TypeKind { // for now we content ourselves with providing a no-op HashStable // implementation for CGUs. mod temp_stable_hash_impls { - use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; use crate::ModuleCodegen; + use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; impl HashStable for ModuleCodegen { fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) { @@ -158,11 +157,7 @@ pub fn build_unchecked_rshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // #1877, #10183: Ensure that input is always valid let rhs = shift_mask_rhs(bx, rhs); let is_signed = lhs_t.is_signed(); - if is_signed { - bx.ashr(lhs, rhs) - } else { - bx.lshr(lhs, rhs) - } + if is_signed { bx.ashr(lhs, rhs) } else { bx.lshr(lhs, rhs) } } fn shift_mask_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( @@ -190,16 +185,12 @@ pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } else { bx.const_uint(mask_llty, val) } - }, + } TypeKind::Vector => { - let mask = shift_mask_val( - bx, - bx.element_type(llty), - bx.element_type(mask_llty), - invert - ); + let mask = + shift_mask_val(bx, bx.element_type(llty), bx.element_type(mask_llty), invert); bx.vector_splat(bx.vector_length(mask_llty), mask) - }, + } _ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind), } } diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs index c5340892daf0c..4d18f49ebf758 100644 --- a/src/librustc_codegen_ssa/debuginfo/type_names.rs +++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs @@ -1,7 +1,7 @@ // Type Names for Debug Info. use rustc::hir::{self, def_id::DefId}; -use rustc::ty::{self, Ty, TyCtxt, subst::SubstsRef}; +use rustc::ty::{self, subst::SubstsRef, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashSet; // Compute the name of the type as it should be stored in debuginfo. Does not do @@ -44,7 +44,7 @@ pub fn push_debuginfo_type_name<'tcx>( ty::Adt(def, substs) => { push_item_name(tcx, def.did, qualified, output); push_type_params(tcx, substs, output, visited); - }, + } ty::Tuple(component_types) => { output.push('('); for &component_type in component_types { @@ -56,8 +56,8 @@ pub fn push_debuginfo_type_name<'tcx>( output.pop(); } output.push(')'); - }, - ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => { + } + ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl }) => { if !cpp_like_names { output.push('*'); } @@ -71,7 +71,7 @@ pub fn push_debuginfo_type_name<'tcx>( if cpp_like_names { output.push('*'); } - }, + } ty::Ref(_, inner_type, mutbl) => { if !cpp_like_names { output.push('&'); @@ -83,13 +83,13 @@ pub fn push_debuginfo_type_name<'tcx>( if cpp_like_names { output.push('*'); } - }, + } ty::Array(inner_type, len) => { output.push('['); push_debuginfo_type_name(tcx, inner_type, true, output, visited); output.push_str(&format!("; {}", len.eval_usize(tcx, ty::ParamEnv::reveal_all()))); output.push(']'); - }, + } ty::Slice(inner_type) => { if cpp_like_names { output.push_str("slice<"); @@ -104,19 +104,17 @@ pub fn push_debuginfo_type_name<'tcx>( } else { output.push(']'); } - }, + } ty::Dynamic(ref trait_data, ..) => { if let Some(principal) = trait_data.principal() { - let principal = tcx.normalize_erasing_late_bound_regions( - ty::ParamEnv::reveal_all(), - &principal, - ); + let principal = tcx + .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &principal); push_item_name(tcx, principal.def_id, false, output); push_type_params(tcx, principal.substs, output, visited); } else { output.push_str("dyn '_"); } - }, + } ty::FnDef(..) | ty::FnPtr(_) => { // We've encountered a weird 'recursive type' // Currently, the only way to generate such a type @@ -136,7 +134,6 @@ pub fn push_debuginfo_type_name<'tcx>( return; } - let sig = t.fn_sig(tcx); output.push_str(sig.unsafety().prefix_str()); @@ -174,7 +171,6 @@ pub fn push_debuginfo_type_name<'tcx>( push_debuginfo_type_name(tcx, sig.output(), true, output, visited); } - // We only keep the type in 'visited' // for the duration of the body of this method. // It's fine for a particular function type @@ -185,7 +181,7 @@ pub fn push_debuginfo_type_name<'tcx>( // directly back to the type we're currently // processing visited.remove(t); - }, + } ty::Closure(def_id, ..) => { output.push_str(&format!( "closure-{}", @@ -198,17 +194,20 @@ pub fn push_debuginfo_type_name<'tcx>( tcx.def_key(def_id).disambiguated_data.disambiguator )); } - ty::Error | - ty::Infer(_) | - ty::Placeholder(..) | - ty::UnnormalizedProjection(..) | - ty::Projection(..) | - ty::Bound(..) | - ty::Opaque(..) | - ty::GeneratorWitness(..) | - ty::Param(_) => { - bug!("debuginfo: Trying to create type name for \ - unexpected type: {:?}", t); + ty::Error + | ty::Infer(_) + | ty::Placeholder(..) + | ty::UnnormalizedProjection(..) + | ty::Projection(..) + | ty::Bound(..) + | ty::Opaque(..) + | ty::GeneratorWitness(..) + | ty::Param(_) => { + bug!( + "debuginfo: Trying to create type name for \ + unexpected type: {:?}", + t + ); } } diff --git a/src/librustc_codegen_ssa/glue.rs b/src/librustc_codegen_ssa/glue.rs index 9818bb78e757b..a43e84272868c 100644 --- a/src/librustc_codegen_ssa/glue.rs +++ b/src/librustc_codegen_ssa/glue.rs @@ -2,10 +2,10 @@ // // Code relating to drop glue. -use rustc::ty::{self, Ty}; use crate::common::IntPredicate; use crate::meth; use crate::traits::*; +use rustc::ty::{self, Ty}; pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, @@ -13,8 +13,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( info: Option, ) -> (Bx::Value, Bx::Value) { let layout = bx.layout_of(t); - debug!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", - t, info, layout); + debug!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", t, info, layout); if !layout.is_unsized() { let size = bx.const_usize(layout.size.bytes()); let align = bx.const_usize(layout.align.abi.bytes()); @@ -30,8 +29,10 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let unit = layout.field(bx, 0); // The info in this case is the length of the str, so the size is that // times the unit size. - (bx.mul(info.unwrap(), bx.const_usize(unit.size.bytes())), - bx.const_usize(unit.align.abi.bytes())) + ( + bx.mul(info.unwrap(), bx.const_usize(unit.size.bytes())), + bx.const_usize(unit.align.abi.bytes()), + ) } _ => { // First get the size of all statically known fields. @@ -43,8 +44,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let i = layout.fields.count() - 1; let sized_size = layout.fields.offset(i).bytes(); let sized_align = layout.align.abi.bytes(); - debug!("DST {} statically sized prefix size: {} align: {}", - t, sized_size, sized_align); + debug!("DST {} statically sized prefix size: {} align: {}", t, sized_size, sized_align); let sized_size = bx.const_usize(sized_size); let sized_align = bx.const_usize(sized_align); @@ -72,8 +72,10 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // Choose max of two known alignments (combined value must // be aligned according to more restrictive of the two). - let align = match (bx.const_to_opt_u128(sized_align, false), - bx.const_to_opt_u128(unsized_align, false)) { + let align = match ( + bx.const_to_opt_u128(sized_align, false), + bx.const_to_opt_u128(unsized_align, false), + ) { (Some(sized_align), Some(unsized_align)) => { // If both alignments are constant, (the sized_align should always be), then // pick the correct alignment statically. @@ -98,7 +100,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let one = bx.const_usize(1); let addend = bx.sub(align, one); let add = bx.add(size, addend); - let neg = bx.neg(align); + let neg = bx.neg(align); let size = bx.and(add, neg); (size, align) diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index 9919666027a21..02385bdab7b19 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -1,5 +1,4 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] - #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] @@ -12,39 +11,41 @@ #![feature(nll)] #![feature(trusted_len)] #![feature(associated_type_bounds)] - -#![recursion_limit="256"] +#![recursion_limit = "256"] //! This crate contains codegen code that is used by all codegen backends (LLVM and others). //! The backend-agnostic functions of this crate use functions defined in various traits that //! have to be implemented by each backends. -#[macro_use] extern crate log; -#[macro_use] extern crate rustc; -#[macro_use] extern crate syntax; +#[macro_use] +extern crate log; +#[macro_use] +extern crate rustc; +#[macro_use] +extern crate syntax; -use std::path::{Path, PathBuf}; use rustc::dep_graph::WorkProduct; -use rustc::session::config::{OutputFilenames, OutputType, RUST_CGU_EXT}; -use rustc::middle::lang_items::LangItem; use rustc::hir::def_id::CrateNum; +use rustc::middle::cstore::{CrateSource, LibSource, NativeLibrary}; +use rustc::middle::dependency_format::Dependencies; +use rustc::middle::lang_items::LangItem; +use rustc::session::config::{OutputFilenames, OutputType, RUST_CGU_EXT}; use rustc::ty::query::Providers; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::sync::Lrc; use rustc_data_structures::svh::Svh; -use rustc::middle::cstore::{LibSource, CrateSource, NativeLibrary}; -use rustc::middle::dependency_format::Dependencies; +use rustc_data_structures::sync::Lrc; +use std::path::{Path, PathBuf}; use syntax_pos::symbol::Symbol; +pub mod back; +pub mod base; pub mod common; -pub mod traits; -pub mod mir; pub mod debuginfo; -pub mod base; pub mod glue; pub mod meth; +pub mod mir; pub mod mono_item; -pub mod back; +pub mod traits; pub struct ModuleCodegen { /// The name of the module. When the crate may be saved between @@ -62,19 +63,19 @@ pub struct ModuleCodegen { pub const METADATA_FILENAME: &str = "lib.rmeta"; pub const RLIB_BYTECODE_EXTENSION: &str = "bc.z"; - impl ModuleCodegen { - pub fn into_compiled_module(self, - emit_obj: bool, - emit_bc: bool, - emit_bc_compressed: bool, - outputs: &OutputFilenames) -> CompiledModule { - let object = emit_obj - .then(|| outputs.temp_path(OutputType::Object, Some(&self.name))); - let bytecode = emit_bc - .then(|| outputs.temp_path(OutputType::Bitcode, Some(&self.name))); + pub fn into_compiled_module( + self, + emit_obj: bool, + emit_bc: bool, + emit_bc_compressed: bool, + outputs: &OutputFilenames, + ) -> CompiledModule { + let object = emit_obj.then(|| outputs.temp_path(OutputType::Object, Some(&self.name))); + let bytecode = emit_bc.then(|| outputs.temp_path(OutputType::Bitcode, Some(&self.name))); let bytecode_compressed = emit_bc_compressed.then(|| { - outputs.temp_path(OutputType::Bitcode, Some(&self.name)) + outputs + .temp_path(OutputType::Bitcode, Some(&self.name)) .with_extension(RLIB_BYTECODE_EXTENSION) }); @@ -137,7 +138,6 @@ pub struct CrateInfo { pub dependency_formats: Lrc, } - pub struct CodegenResults { pub crate_name: Symbol, pub modules: Vec, @@ -167,13 +167,11 @@ pub fn looks_like_rust_object_file(filename: &str) -> bool { let ext = path.extension().and_then(|s| s.to_str()); if ext != Some(OutputType::Object.extension()) { // The file name does not end with ".o", so it can't be an object file. - return false + return false; } // Strip the ".o" at the end - let ext2 = path.file_stem() - .and_then(|s| Path::new(s).extension()) - .and_then(|s| s.to_str()); + let ext2 = path.file_stem().and_then(|s| Path::new(s).extension()).and_then(|s| s.to_str()); // Check if the "inner" extension ext2 == Some(RUST_CGU_EXT) diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs index c14618a15eaeb..c36ef9b480cf0 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/src/librustc_codegen_ssa/meth.rs @@ -1,6 +1,6 @@ use crate::traits::*; -use rustc::ty::{self, Ty, Instance}; +use rustc::ty::{self, Instance, Ty}; use rustc_target::abi::call::FnAbi; #[derive(Copy, Clone, Debug)] @@ -24,10 +24,7 @@ impl<'a, 'tcx> VirtualIndex { // Load the data pointer from the object. debug!("get_fn({:?}, {:?})", llvtable, self); - let llvtable = bx.pointercast( - llvtable, - bx.type_ptr_to(bx.fn_ptr_backend_type(fn_abi)) - ); + let llvtable = bx.pointercast(llvtable, bx.type_ptr_to(bx.fn_ptr_backend_type(fn_abi))); let ptr_align = bx.tcx().data_layout.pointer_align.abi; let gep = bx.inbounds_gep(llvtable, &[bx.const_usize(self.0)]); let ptr = bx.load(gep, ptr_align); @@ -96,7 +93,8 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( ty::ParamEnv::reveal_all(), def_id, substs, - ).unwrap() + ) + .unwrap(), ) }) }); @@ -109,8 +107,12 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( let components: Vec<_> = [ cx.get_fn_addr(Instance::resolve_drop_in_place(cx.tcx(), ty)), cx.const_usize(layout.size.bytes()), - cx.const_usize(layout.align.abi.bytes()) - ].iter().cloned().chain(methods).collect(); + cx.const_usize(layout.align.abi.bytes()), + ] + .iter() + .cloned() + .chain(methods) + .collect(); let vtable_const = cx.const_struct(&components, false); let align = cx.data_layout().pointer_align.abi; diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 7bcd981678640..b6a0a9fed4c59 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -1,20 +1,20 @@ //! An analysis to determine which locals require allocas and //! which do not. -use rustc_index::bit_set::BitSet; -use rustc_data_structures::graph::dominators::Dominators; -use rustc_index::vec::{Idx, IndexVec}; -use rustc::mir::{self, Location, TerminatorKind}; +use super::FunctionCx; +use crate::traits::*; +use rustc::mir::traversal; use rustc::mir::visit::{ - Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext, NonUseContext, + MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, Visitor, }; -use rustc::mir::traversal; +use rustc::mir::{self, Location, TerminatorKind}; use rustc::session::config::DebugInfo; use rustc::ty; -use rustc::ty::layout::{LayoutOf, HasTyCtxt}; +use rustc::ty::layout::{HasTyCtxt, LayoutOf}; +use rustc_data_structures::graph::dominators::Dominators; +use rustc_index::bit_set::BitSet; +use rustc_index::vec::{Idx, IndexVec}; use syntax_pos::DUMMY_SP; -use super::FunctionCx; -use crate::traits::*; pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( fx: &FunctionCx<'a, 'tcx, Bx>, @@ -24,8 +24,7 @@ pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( analyzer.visit_body(mir); - for (local, decl) in mir.local_decls.iter_enumerated() - { + for (local, decl) in mir.local_decls.iter_enumerated() { // FIXME(eddyb): We should figure out how to use llvm.dbg.value instead // of putting everything in allocas just so we can use llvm.dbg.declare. if fx.cx.sess().opts.debuginfo == DebugInfo::Full { @@ -68,14 +67,13 @@ struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { fn new(fx: &'mir FunctionCx<'a, 'tcx, Bx>) -> Self { - let invalid_location = - mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location(); + let invalid_location = mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location(); let dominators = fx.mir.dominators(); let mut analyzer = LocalAnalyzer { fx, dominators, non_ssa_locals: BitSet::new_empty(fx.mir.local_decls.len()), - first_assignment: IndexVec::from_elem(invalid_location, &fx.mir.local_decls) + first_assignment: IndexVec::from_elem(invalid_location, &fx.mir.local_decls), }; // Arguments get assigned to by means of the function being called @@ -125,9 +123,9 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { // Allow uses of projections that are ZSTs or from scalar fields. let is_consume = match context { - PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true, - _ => false + PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) + | PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true, + _ => false, }; if is_consume { let base_ty = @@ -135,9 +133,7 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { let base_ty = self.fx.monomorphize(&base_ty); // ZSTs don't require any actual memory access. - let elem_ty = base_ty - .projection_ty(cx.tcx(), elem) - .ty; + let elem_ty = base_ty.projection_ty(cx.tcx(), elem).ty; let elem_ty = self.fx.monomorphize(&elem_ty); let span = if let mir::PlaceBase::Local(index) = place_ref.base { self.fx.mir.local_decls[*index].source_info.span @@ -196,12 +192,9 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { } self.process_place( - &mir::PlaceRef { - base: place_ref.base, - projection: proj_base, - }, + &mir::PlaceRef { base: place_ref.base, projection: proj_base }, base_context, - location + location, ); // HACK(eddyb) this emulates the old `visit_projection_elem`, this // entire `visit_place`-like `process_place` method should be rewritten, @@ -210,7 +203,7 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { self.visit_local( local, PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy), - location + location, ); } } else { @@ -230,16 +223,17 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { self.visit_projection(place_ref.base, place_ref.projection, context, location); } } - } impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx, Bx> { - fn visit_assign(&mut self, - place: &mir::Place<'tcx>, - rvalue: &mir::Rvalue<'tcx>, - location: Location) { + fn visit_assign( + &mut self, + place: &mir::Place<'tcx>, + rvalue: &mir::Rvalue<'tcx>, + location: Location, + ) { debug!("visit_assign(place={:?}, rvalue={:?})", place, rvalue); if let Some(index) = place.as_local() { @@ -249,27 +243,20 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> self.not_ssa(index); } } else { - self.visit_place( - place, - PlaceContext::MutatingUse(MutatingUseContext::Store), - location - ); + self.visit_place(place, PlaceContext::MutatingUse(MutatingUseContext::Store), location); } self.visit_rvalue(rvalue, location); } - fn visit_terminator_kind(&mut self, - kind: &mir::TerminatorKind<'tcx>, - location: Location) { + fn visit_terminator_kind(&mut self, kind: &mir::TerminatorKind<'tcx>, location: Location) { let check = match *kind { - mir::TerminatorKind::Call { - func: mir::Operand::Constant(ref c), - ref args, .. - } => match c.literal.ty.kind { - ty::FnDef(did, _) => Some((did, args)), - _ => None, - }, + mir::TerminatorKind::Call { func: mir::Operand::Constant(ref c), ref args, .. } => { + match c.literal.ty.kind { + ty::FnDef(did, _) => Some((did, args)), + _ => None, + } + } _ => None, }; if let Some((def_id, args)) = check { @@ -281,7 +268,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> self.visit_place( place, PlaceContext::MutatingUse(MutatingUseContext::Drop), - location + location, ); } } @@ -290,18 +277,12 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> self.super_terminator_kind(kind, location); } - fn visit_place(&mut self, - place: &mir::Place<'tcx>, - context: PlaceContext, - location: Location) { + fn visit_place(&mut self, place: &mir::Place<'tcx>, context: PlaceContext, location: Location) { debug!("visit_place(place={:?}, context={:?})", place, context); self.process_place(&place.as_ref(), context, location); } - fn visit_local(&mut self, - &local: &mir::Local, - context: PlaceContext, - location: Location) { + fn visit_local(&mut self, &local: &mir::Local, context: PlaceContext, location: Location) { match context { PlaceContext::MutatingUse(MutatingUseContext::Call) => { self.assign(local, location); @@ -316,11 +297,10 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> } } - PlaceContext::NonUse(_) | - PlaceContext::MutatingUse(MutatingUseContext::Retag) => {} + PlaceContext::NonUse(_) | PlaceContext::MutatingUse(MutatingUseContext::Retag) => {} - PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => { + PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) + | PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => { // Reads from uninitialized variables (e.g., in dead code, after // optimizations) require locals to be in (uninitialized) memory. // N.B., there can be uninitialized reads of a local visited after @@ -329,24 +309,24 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> Some(assignment_location) => { assignment_location.dominates(location, &self.dominators) } - None => false + None => false, }; if !ssa_read { self.not_ssa(local); } } - PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) | - PlaceContext::MutatingUse(MutatingUseContext::Store) | - PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) | - PlaceContext::MutatingUse(MutatingUseContext::Borrow) | - PlaceContext::MutatingUse(MutatingUseContext::AddressOf) | - PlaceContext::MutatingUse(MutatingUseContext::Projection) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) => { + PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) + | PlaceContext::MutatingUse(MutatingUseContext::Store) + | PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) + | PlaceContext::MutatingUse(MutatingUseContext::Borrow) + | PlaceContext::MutatingUse(MutatingUseContext::AddressOf) + | PlaceContext::MutatingUse(MutatingUseContext::Projection) + | PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) + | PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) + | PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) + | PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) + | PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) => { self.not_ssa(local); } @@ -367,7 +347,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> pub enum CleanupKind { NotCleanup, Funclet, - Internal { funclet: mir::BasicBlock } + Internal { funclet: mir::BasicBlock }, } impl CleanupKind { @@ -381,29 +361,31 @@ impl CleanupKind { } pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec { - fn discover_masters<'tcx>(result: &mut IndexVec, - mir: &mir::Body<'tcx>) { + fn discover_masters<'tcx>( + result: &mut IndexVec, + mir: &mir::Body<'tcx>, + ) { for (bb, data) in mir.basic_blocks().iter_enumerated() { match data.terminator().kind { - TerminatorKind::Goto { .. } | - TerminatorKind::Resume | - TerminatorKind::Abort | - TerminatorKind::Return | - TerminatorKind::GeneratorDrop | - TerminatorKind::Unreachable | - TerminatorKind::SwitchInt { .. } | - TerminatorKind::Yield { .. } | - TerminatorKind::FalseEdges { .. } | - TerminatorKind::FalseUnwind { .. } => { - /* nothing to do */ - } - TerminatorKind::Call { cleanup: unwind, .. } | - TerminatorKind::Assert { cleanup: unwind, .. } | - TerminatorKind::DropAndReplace { unwind, .. } | - TerminatorKind::Drop { unwind, .. } => { + TerminatorKind::Goto { .. } + | TerminatorKind::Resume + | TerminatorKind::Abort + | TerminatorKind::Return + | TerminatorKind::GeneratorDrop + | TerminatorKind::Unreachable + | TerminatorKind::SwitchInt { .. } + | TerminatorKind::Yield { .. } + | TerminatorKind::FalseEdges { .. } + | TerminatorKind::FalseUnwind { .. } => { /* nothing to do */ } + TerminatorKind::Call { cleanup: unwind, .. } + | TerminatorKind::Assert { cleanup: unwind, .. } + | TerminatorKind::DropAndReplace { unwind, .. } + | TerminatorKind::Drop { unwind, .. } => { if let Some(unwind) = unwind { - debug!("cleanup_kinds: {:?}/{:?} registering {:?} as funclet", - bb, data, unwind); + debug!( + "cleanup_kinds: {:?}/{:?} registering {:?} as funclet", + bb, data, unwind + ); result[unwind] = CleanupKind::Funclet; } } @@ -411,20 +393,23 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec(result: &mut IndexVec, - mir: &mir::Body<'tcx>) { + fn propagate<'tcx>(result: &mut IndexVec, mir: &mir::Body<'tcx>) { let mut funclet_succs = IndexVec::from_elem(None, mir.basic_blocks()); - let mut set_successor = |funclet: mir::BasicBlock, succ| { - match funclet_succs[funclet] { - ref mut s @ None => { - debug!("set_successor: updating successor of {:?} to {:?}", - funclet, succ); - *s = Some(succ); - }, - Some(s) => if s != succ { - span_bug!(mir.span, "funclet {:?} has 2 parents - {:?} and {:?}", - funclet, s, succ); + let mut set_successor = |funclet: mir::BasicBlock, succ| match funclet_succs[funclet] { + ref mut s @ None => { + debug!("set_successor: updating successor of {:?} to {:?}", funclet, succ); + *s = Some(succ); + } + Some(s) => { + if s != succ { + span_bug!( + mir.span, + "funclet {:?} has 2 parents - {:?} and {:?}", + funclet, + s, + succ + ); } } }; @@ -436,13 +421,14 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec funclet, }; - debug!("cleanup_kinds: {:?}/{:?}/{:?} propagating funclet {:?}", - bb, data, result[bb], funclet); + debug!( + "cleanup_kinds: {:?}/{:?}/{:?} propagating funclet {:?}", + bb, data, result[bb], funclet + ); for &succ in data.terminator().successors() { let kind = result[succ]; - debug!("cleanup_kinds: propagating {:?} to {:?}/{:?}", - funclet, succ, kind); + debug!("cleanup_kinds: propagating {:?} to {:?}/{:?}", funclet, succ, kind); match kind { CleanupKind::NotCleanup => { result[succ] = CleanupKind::Internal { funclet }; @@ -457,8 +443,10 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec TerminatorCodegenHelper<'tcx> { let target_funclet = fx.cleanup_kinds[target].funclet_bb(target); match (self.funclet_bb, target_funclet) { (None, None) => (lltarget, false), - (Some(f), Some(t_f)) if f == t_f || !base::wants_msvc_seh(fx.cx.tcx().sess) => - (lltarget, false), + (Some(f), Some(t_f)) if f == t_f || !base::wants_msvc_seh(fx.cx.tcx().sess) => { + (lltarget, false) + } // jump *into* cleanup - need a landing pad if GNU (None, Some(_)) => (fx.landing_pad_to(target), false), (Some(_), None) => span_bug!(span, "{:?} - jump out of cleanup?", self.terminator), @@ -75,8 +76,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { debug!("llblock: creating cleanup trampoline for {:?}", target); let name = &format!("{:?}_cleanup_trampoline_{:?}", self.bb, target); let mut trampoline = fx.new_block(name); - trampoline.cleanup_ret(self.funclet(fx).unwrap(), - Some(lltarget)); + trampoline.cleanup_ret(self.funclet(fx).unwrap(), Some(lltarget)); trampoline.llbb() } else { lltarget @@ -117,11 +117,8 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { } else { fx.unreachable_block() }; - let invokeret = bx.invoke(fn_ptr, - &llargs, - ret_bx, - self.llblock(fx, cleanup), - self.funclet(fx)); + let invokeret = + bx.invoke(fn_ptr, &llargs, ret_bx, self.llblock(fx, cleanup), self.funclet(fx)); bx.apply_attrs_callsite(&fn_abi, invokeret); if let Some((ret_dest, target)) = destination { @@ -160,9 +157,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { if bx.tcx().sess.opts.debugging_opts.insert_sideeffect { if targets.iter().any(|&target| { target <= self.bb - && target - .start_location() - .is_predecessor_of(self.bb.start_location(), mir) + && target.start_location().is_predecessor_of(self.bb.start_location(), mir) }) { bx.sideeffect(); } @@ -173,11 +168,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { /// Codegen implementations for some terminator variants. impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { /// Generates code for a `Resume` terminator. - fn codegen_resume_terminator( - &mut self, - helper: TerminatorCodegenHelper<'tcx>, - mut bx: Bx, - ) { + fn codegen_resume_terminator(&mut self, helper: TerminatorCodegenHelper<'tcx>, mut bx: Bx) { if let Some(funclet) = helper.funclet(self) { bx.cleanup_ret(funclet, None); } else { @@ -194,8 +185,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { lp = bx.insert_value(lp, lp1, 1); bx.resume(lp); } else { - bx.call(bx.eh_unwind_resume(), &[lp0], - helper.funclet(self)); + bx.call(bx.eh_unwind_resume(), &[lp0], helper.funclet(self)); bx.unreachable(); } } @@ -225,9 +215,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.cond_br(discr.immediate(), lltrue, llfalse); } } else { - let switch_llty = bx.immediate_backend_type( - bx.layout_of(switch_ty) - ); + let switch_llty = bx.immediate_backend_type(bx.layout_of(switch_ty)); let llval = bx.const_uint_big(switch_llty, values[0]); let cmp = bx.icmp(IntPredicate::IntEQ, discr.immediate(), llval); helper.maybe_sideeffect(self.mir, &mut bx, targets.as_slice()); @@ -239,9 +227,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.switch( discr.immediate(), helper.llblock(self, *otherwise), - values.iter().zip(targets).map(|(&value, target)| { - (value, helper.llblock(self, *target)) - }) + values + .iter() + .zip(targets) + .map(|(&value, target)| (value, helper.llblock(self, *target))), ); } } @@ -276,8 +265,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } PassMode::Direct(_) | PassMode::Pair(..) => { - let op = - self.codegen_consume(&mut bx, &mir::Place::return_place().as_ref()); + let op = self.codegen_consume(&mut bx, &mir::Place::return_place().as_ref()); if let Ref(llval, _, align) = op.val { bx.load(llval, align) } else { @@ -289,37 +277,30 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let op = match self.locals[mir::RETURN_PLACE] { LocalRef::Operand(Some(op)) => op, LocalRef::Operand(None) => bug!("use of return before def"), - LocalRef::Place(cg_place) => { - OperandRef { - val: Ref(cg_place.llval, None, cg_place.align), - layout: cg_place.layout - } - } + LocalRef::Place(cg_place) => OperandRef { + val: Ref(cg_place.llval, None, cg_place.align), + layout: cg_place.layout, + }, LocalRef::UnsizedPlace(_) => bug!("return type must be sized"), }; let llslot = match op.val { Immediate(_) | Pair(..) => { - let scratch = - PlaceRef::alloca(&mut bx, self.fn_abi.ret.layout); + let scratch = PlaceRef::alloca(&mut bx, self.fn_abi.ret.layout); op.val.store(&mut bx, scratch); scratch.llval } Ref(llval, _, align) => { - assert_eq!(align, op.layout.align.abi, - "return place is unaligned!"); + assert_eq!(align, op.layout.align.abi, "return place is unaligned!"); llval } }; - let addr = bx.pointercast(llslot, bx.type_ptr_to( - bx.cast_backend_type(&cast_ty) - )); + let addr = bx.pointercast(llslot, bx.type_ptr_to(bx.cast_backend_type(&cast_ty))); bx.load(addr, self.fn_abi.ret.layout.align.abi) } }; bx.ret(llval); } - fn codegen_drop_terminator( &mut self, helper: TerminatorCodegenHelper<'tcx>, @@ -336,7 +317,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // we don't actually need to drop anything. helper.maybe_sideeffect(self.mir, &mut bx, &[target]); helper.funclet_br(self, &mut bx, target); - return + return; } let place = self.codegen_place(&mut bx, &location.as_ref()); @@ -361,15 +342,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { args = &args[..1]; (meth::DESTRUCTOR.get_fn(&mut bx, vtable, &fn_abi), fn_abi) } - _ => { - (bx.get_fn_addr(drop_fn), - FnAbi::of_instance(&bx, drop_fn, &[])) - } + _ => (bx.get_fn_addr(drop_fn), FnAbi::of_instance(&bx, drop_fn, &[])), }; helper.maybe_sideeffect(self.mir, &mut bx, &[target]); - helper.do_call(self, &mut bx, fn_abi, drop_fn, args, - Some((ReturnDest::Nothing, target)), - unwind); + helper.do_call( + self, + &mut bx, + fn_abi, + drop_fn, + args, + Some((ReturnDest::Nothing, target)), + unwind, + ); } fn codegen_assert_terminator( @@ -466,16 +450,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let callee = self.codegen_operand(&mut bx, func); let (instance, mut llfn) = match callee.layout.ty.kind { - ty::FnDef(def_id, substs) => { - (Some(ty::Instance::resolve(bx.tcx(), - ty::ParamEnv::reveal_all(), - def_id, - substs).unwrap()), - None) - } - ty::FnPtr(_) => { - (None, Some(callee.immediate())) - } + ty::FnDef(def_id, substs) => ( + Some( + ty::Instance::resolve(bx.tcx(), ty::ParamEnv::reveal_all(), def_id, substs) + .unwrap(), + ), + None, + ), + ty::FnPtr(_) => (None, Some(callee.immediate())), _ => bug!("{} is not callable", callee.layout.ty), }; let def = instance.map(|i| i.def); @@ -496,21 +478,23 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Handle intrinsics old codegen wants Expr's for, ourselves. let intrinsic = match def { - Some(ty::InstanceDef::Intrinsic(def_id)) => - Some(bx.tcx().item_name(def_id).as_str()), - _ => None + Some(ty::InstanceDef::Intrinsic(def_id)) => Some(bx.tcx().item_name(def_id).as_str()), + _ => None, }; let intrinsic = intrinsic.as_ref().map(|s| &s[..]); let extra_args = &args[sig.inputs().skip_binder().len()..]; - let extra_args = extra_args.iter().map(|op_arg| { - let op_ty = op_arg.ty(*self.mir, bx.tcx()); - self.monomorphize(&op_ty) - }).collect::>(); + let extra_args = extra_args + .iter() + .map(|op_arg| { + let op_ty = op_arg.ty(*self.mir, bx.tcx()); + self.monomorphize(&op_ty) + }) + .collect::>(); let fn_abi = match instance { Some(instance) => FnAbi::of_instance(&bx, instance, &extra_args), - None => FnAbi::of_fn_ptr(&bx, sig, &extra_args) + None => FnAbi::of_fn_ptr(&bx, sig, &extra_args), }; if intrinsic == Some("transmute") { @@ -585,8 +569,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Prepare the return value destination let ret_dest = if let Some((ref dest, _)) = *destination { let is_intrinsic = intrinsic.is_some(); - self.make_return_dest(&mut bx, dest, &fn_abi.ret, &mut llargs, - is_intrinsic) + self.make_return_dest(&mut bx, dest, &fn_abi.ret, &mut llargs, is_intrinsic) } else { ReturnDest::Nothing }; @@ -609,73 +592,82 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if intrinsic.is_some() && intrinsic != Some("drop_in_place") { let dest = match ret_dest { _ if fn_abi.ret.is_indirect() => llargs[0], - ReturnDest::Nothing => - bx.const_undef(bx.type_ptr_to(bx.arg_memory_ty(&fn_abi.ret))), - ReturnDest::IndirectOperand(dst, _) | ReturnDest::Store(dst) => - dst.llval, - ReturnDest::DirectOperand(_) => - bug!("Cannot use direct operand with an intrinsic call"), + ReturnDest::Nothing => { + bx.const_undef(bx.type_ptr_to(bx.arg_memory_ty(&fn_abi.ret))) + } + ReturnDest::IndirectOperand(dst, _) | ReturnDest::Store(dst) => dst.llval, + ReturnDest::DirectOperand(_) => { + bug!("Cannot use direct operand with an intrinsic call") + } }; - let args: Vec<_> = args.iter().enumerate().map(|(i, arg)| { - // The indices passed to simd_shuffle* in the - // third argument must be constant. This is - // checked by const-qualification, which also - // promotes any complex rvalues to constants. - if i == 2 && intrinsic.unwrap().starts_with("simd_shuffle") { - match arg { - // The shuffle array argument is usually not an explicit constant, - // but specified directly in the code. This means it gets promoted - // and we can then extract the value by evaluating the promoted. - mir::Operand::Copy(place) | mir::Operand::Move(place) => { - if let mir::PlaceRef { - base: - &PlaceBase::Static(box Static { - kind: StaticKind::Promoted(promoted, _), + let args: Vec<_> = args + .iter() + .enumerate() + .map(|(i, arg)| { + // The indices passed to simd_shuffle* in the + // third argument must be constant. This is + // checked by const-qualification, which also + // promotes any complex rvalues to constants. + if i == 2 && intrinsic.unwrap().starts_with("simd_shuffle") { + match arg { + // The shuffle array argument is usually not an explicit constant, + // but specified directly in the code. This means it gets promoted + // and we can then extract the value by evaluating the promoted. + mir::Operand::Copy(place) | mir::Operand::Move(place) => { + if let mir::PlaceRef { + base: + &PlaceBase::Static(box Static { + kind: StaticKind::Promoted(promoted, _), + ty, + def_id: _, + }), + projection: &[], + } = place.as_ref() + { + let c = bx.tcx().const_eval_promoted(self.instance, promoted); + let (llval, ty) = self.simd_shuffle_indices( + &bx, + terminator.source_info.span, ty, - def_id: _, - }), - projection: &[], - } = place.as_ref() - { - let c = bx.tcx().const_eval_promoted(self.instance, promoted); + c, + ); + return OperandRef { + val: Immediate(llval), + layout: bx.layout_of(ty), + }; + } else { + span_bug!(span, "shuffle indices must be constant"); + } + } + + mir::Operand::Constant(constant) => { + let c = self.eval_mir_constant(constant); let (llval, ty) = self.simd_shuffle_indices( &bx, - terminator.source_info.span, - ty, + constant.span, + constant.literal.ty, c, ); return OperandRef { val: Immediate(llval), layout: bx.layout_of(ty), }; - } else { - span_bug!(span, "shuffle indices must be constant"); } } - - mir::Operand::Constant(constant) => { - let c = self.eval_mir_constant(constant); - let (llval, ty) = self.simd_shuffle_indices( - &bx, - constant.span, - constant.literal.ty, - c, - ); - return OperandRef { - val: Immediate(llval), - layout: bx.layout_of(ty) - }; - } } - } - self.codegen_operand(&mut bx, arg) - }).collect(); - - - bx.codegen_intrinsic_call(*instance.as_ref().unwrap(), &fn_abi, &args, dest, - terminator.source_info.span); + self.codegen_operand(&mut bx, arg) + }) + .collect(); + + bx.codegen_intrinsic_call( + *instance.as_ref().unwrap(), + &fn_abi, + &args, + dest, + terminator.source_info.span, + ); if let ReturnDest::IndirectOperand(dst, _) = ret_dest { self.store_return(&mut bx, ret_dest, &fn_abi.ret, dst.llval); @@ -711,7 +703,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // To get a `*mut RcBox`, we just keep unwrapping newtypes until // we get a value of a built-in pointer type 'descend_newtypes: while !op.layout.ty.is_unsafe_ptr() - && !op.layout.ty.is_region_ptr() + && !op.layout.ty.is_region_ptr() { for i in 0..op.layout.fields.count() { let field = op.extract_field(&mut bx, i); @@ -720,7 +712,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // now find *its* non-zero-sized field, or stop if it's a // pointer op = field; - continue 'descend_newtypes + continue 'descend_newtypes; } } @@ -732,17 +724,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // the data pointer as the first argument match op.val { Pair(data_ptr, meta) => { - llfn = Some(meth::VirtualIndex::from_index(idx) - .get_fn(&mut bx, meta, &fn_abi)); + llfn = Some( + meth::VirtualIndex::from_index(idx).get_fn(&mut bx, meta, &fn_abi), + ); llargs.push(data_ptr); - continue 'make_args + continue 'make_args; } other => bug!("expected a Pair, got {:?}", other), } } else if let Ref(data_ptr, Some(meta), _) = op.val { // by-value dynamic dispatch - llfn = Some(meth::VirtualIndex::from_index(idx) - .get_fn(&mut bx, meta, &fn_abi)); + llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(&mut bx, meta, &fn_abi)); llargs.push(data_ptr); continue; } else { @@ -753,8 +745,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // The callee needs to own the argument memory if we pass it // by-ref, so make a local copy of non-immediate constants. match (arg, op.val) { - (&mir::Operand::Copy(_), Ref(_, None, _)) | - (&mir::Operand::Constant(_), Ref(_, None, _)) => { + (&mir::Operand::Copy(_), Ref(_, None, _)) + | (&mir::Operand::Constant(_), Ref(_, None, _)) => { let tmp = PlaceRef::alloca(&mut bx, op.layout); op.val.store(&mut bx, tmp); op.val = Ref(tmp.llval, None, tmp.align); @@ -765,15 +757,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_argument(&mut bx, op, &mut llargs, &fn_abi.args[i]); } if let Some(tup) = untuple { - self.codegen_arguments_untupled(&mut bx, tup, &mut llargs, - &fn_abi.args[first_args.len()..]) + self.codegen_arguments_untupled( + &mut bx, + tup, + &mut llargs, + &fn_abi.args[first_args.len()..], + ) } let needs_location = instance.map_or(false, |i| i.def.requires_caller_location(self.cx.tcx())); if needs_location { assert_eq!( - fn_abi.args.len(), args.len() + 1, + fn_abi.args.len(), + args.len() + 1, "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR", ); let location = self.get_caller_location(&mut bx, span); @@ -790,17 +787,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if let Some((_, target)) = destination.as_ref() { helper.maybe_sideeffect(self.mir, &mut bx, &[*target]); } - helper.do_call(self, &mut bx, fn_abi, fn_ptr, &llargs, - destination.as_ref().map(|&(_, target)| (ret_dest, target)), - cleanup); + helper.do_call( + self, + &mut bx, + fn_abi, + fn_ptr, + &llargs, + destination.as_ref().map(|&(_, target)| (ret_dest, target)), + cleanup, + ); } } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { - pub fn codegen_block( - &mut self, - bb: mir::BasicBlock, - ) { + pub fn codegen_block(&mut self, bb: mir::BasicBlock) { let mut bx = self.build_block(bb); let mir = self.mir; let data = &mir[bb]; @@ -818,21 +818,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &mut self, mut bx: Bx, bb: mir::BasicBlock, - terminator: &'tcx mir::Terminator<'tcx> + terminator: &'tcx mir::Terminator<'tcx>, ) { debug!("codegen_terminator: {:?}", terminator); // Create the cleanup bundle, if needed. let funclet_bb = self.cleanup_kinds[bb].funclet_bb(bb); - let helper = TerminatorCodegenHelper { - bb, terminator, funclet_bb - }; + let helper = TerminatorCodegenHelper { bb, terminator, funclet_bb }; self.set_debug_loc(&mut bx, terminator.source_info); match terminator.kind { - mir::TerminatorKind::Resume => { - self.codegen_resume_terminator(helper, bx) - } + mir::TerminatorKind::Resume => self.codegen_resume_terminator(helper, bx), mir::TerminatorKind::Abort => { bx.abort(); @@ -846,11 +842,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { helper.funclet_br(self, &mut bx, target); } - mir::TerminatorKind::SwitchInt { - ref discr, switch_ty, ref values, ref targets - } => { - self.codegen_switchint_terminator(helper, bx, discr, switch_ty, - values, targets); + mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref values, ref targets } => { + self.codegen_switchint_terminator(helper, bx, discr, switch_ty, values, targets); } mir::TerminatorKind::Return => { @@ -866,8 +859,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::TerminatorKind::Assert { ref cond, expected, ref msg, target, cleanup } => { - self.codegen_assert_terminator(helper, bx, terminator, cond, - expected, msg, target, cleanup); + self.codegen_assert_terminator( + helper, bx, terminator, cond, expected, msg, target, cleanup, + ); } mir::TerminatorKind::DropAndReplace { .. } => { @@ -879,15 +873,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ref args, ref destination, cleanup, - from_hir_call: _ + from_hir_call: _, } => { - self.codegen_call_terminator(helper, bx, terminator, func, - args, destination, cleanup); + self.codegen_call_terminator( + helper, + bx, + terminator, + func, + args, + destination, + cleanup, + ); + } + mir::TerminatorKind::GeneratorDrop | mir::TerminatorKind::Yield { .. } => { + bug!("generator ops in codegen") + } + mir::TerminatorKind::FalseEdges { .. } | mir::TerminatorKind::FalseUnwind { .. } => { + bug!("borrowck false edges in codegen") } - mir::TerminatorKind::GeneratorDrop | - mir::TerminatorKind::Yield { .. } => bug!("generator ops in codegen"), - mir::TerminatorKind::FalseEdges { .. } | - mir::TerminatorKind::FalseUnwind { .. } => bug!("borrowck false edges in codegen"), } } @@ -896,7 +899,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx: &mut Bx, op: OperandRef<'tcx, Bx::Value>, llargs: &mut Vec, - arg: &ArgAbi<'tcx, Ty<'tcx>> + arg: &ArgAbi<'tcx, Ty<'tcx>>, ) { // Fill padding with undef value, where applicable. if let Some(ty) = arg.pad { @@ -914,7 +917,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { llargs.push(b); return; } - _ => bug!("codegen_argument: {:?} invalid for pair argument", op) + _ => bug!("codegen_argument: {:?} invalid for pair argument", op), } } else if arg.is_unsized_indirect() { match op.val { @@ -923,24 +926,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { llargs.push(b); return; } - _ => bug!("codegen_argument: {:?} invalid for unsized indirect argument", op) + _ => bug!("codegen_argument: {:?} invalid for unsized indirect argument", op), } } // Force by-ref if we have to load through a cast pointer. let (mut llval, align, by_ref) = match op.val { - Immediate(_) | Pair(..) => { - match arg.mode { - PassMode::Indirect(..) | PassMode::Cast(_) => { - let scratch = PlaceRef::alloca(bx, arg.layout); - op.val.store(bx, scratch); - (scratch.llval, scratch.align, true) - } - _ => { - (op.immediate_or_packed_pair(bx), arg.layout.align.abi, false) - } + Immediate(_) | Pair(..) => match arg.mode { + PassMode::Indirect(..) | PassMode::Cast(_) => { + let scratch = PlaceRef::alloca(bx, arg.layout); + op.val.store(bx, scratch); + (scratch.llval, scratch.align, true) } - } + _ => (op.immediate_or_packed_pair(bx), arg.layout.align.abi, false), + }, Ref(llval, _, align) => { if arg.is_indirect() && align < arg.layout.align.abi { // `foo(packed.large_field)`. We can't pass the (unaligned) field directly. I @@ -948,8 +947,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // have scary latent bugs around. let scratch = PlaceRef::alloca(bx, arg.layout); - base::memcpy_ty(bx, scratch.llval, scratch.align, llval, align, - op.layout, MemFlags::empty()); + base::memcpy_ty( + bx, + scratch.llval, + scratch.align, + llval, + align, + op.layout, + MemFlags::empty(), + ); (scratch.llval, scratch.align, true) } else { (llval, align, true) @@ -960,9 +966,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if by_ref && !arg.is_indirect() { // Have to load the argument, maybe while casting it. if let PassMode::Cast(ty) = arg.mode { - let addr = bx.pointercast(llval, bx.type_ptr_to( - bx.cast_backend_type(&ty)) - ); + let addr = bx.pointercast(llval, bx.type_ptr_to(bx.cast_backend_type(&ty))); llval = bx.load(addr, align.min(arg.layout.align.abi)); } else { // We can't use `PlaceRef::load` here because the argument @@ -989,7 +993,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx: &mut Bx, operand: &mir::Operand<'tcx>, llargs: &mut Vec, - args: &[ArgAbi<'tcx, Ty<'tcx>>] + args: &[ArgAbi<'tcx, Ty<'tcx>>], ) { let tuple = self.codegen_operand(bx, operand); @@ -1012,11 +1016,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - fn get_caller_location( - &mut self, - bx: &mut Bx, - span: Span, - ) -> OperandRef<'tcx, Bx::Value> { + fn get_caller_location(&mut self, bx: &mut Bx, span: Span) -> OperandRef<'tcx, Bx::Value> { self.caller_location.unwrap_or_else(|| { let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); let caller = bx.tcx().sess.source_map().lookup_char_pos(topmost.lo()); @@ -1029,18 +1029,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }) } - fn get_personality_slot( - &mut self, - bx: &mut Bx - ) -> PlaceRef<'tcx, Bx::Value> { + fn get_personality_slot(&mut self, bx: &mut Bx) -> PlaceRef<'tcx, Bx::Value> { let cx = bx.cx(); if let Some(slot) = self.personality_slot { slot } else { - let layout = cx.layout_of(cx.tcx().intern_tup(&[ - cx.tcx().mk_mut_ptr(cx.tcx().types.u8), - cx.tcx().types.i32 - ])); + let layout = cx.layout_of( + cx.tcx().intern_tup(&[cx.tcx().mk_mut_ptr(cx.tcx().types.u8), cx.tcx().types.i32]), + ); let slot = PlaceRef::alloca(bx, layout); self.personality_slot = Some(slot); slot @@ -1050,10 +1046,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { /// Returns the landing-pad wrapper around the given basic block. /// /// No-op in MSVC SEH scheme. - fn landing_pad_to( - &mut self, - target_bb: mir::BasicBlock - ) -> Bx::BasicBlock { + fn landing_pad_to(&mut self, target_bb: mir::BasicBlock) -> Bx::BasicBlock { if let Some(block) = self.landing_pads[target_bb] { return block; } @@ -1064,10 +1057,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { landing_pad } - fn landing_pad_uncached( - &mut self, - target_bb: Bx::BasicBlock, - ) -> Bx::BasicBlock { + fn landing_pad_uncached(&mut self, target_bb: Bx::BasicBlock) -> Bx::BasicBlock { if base::wants_msvc_seh(self.cx.sess()) { span_bug!(self.mir.span, "landing pad was not inserted?") } @@ -1092,9 +1082,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { cx.type_struct(&[cx.type_i8p(), cx.type_i32()], false) } - fn unreachable_block( - &mut self - ) -> Bx::BasicBlock { + fn unreachable_block(&mut self) -> Bx::BasicBlock { self.unreachable_block.unwrap_or_else(|| { let mut bx = self.new_block("unreachable"); bx.unreachable(); @@ -1107,10 +1095,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Bx::new_block(self.cx, self.llfn, name) } - pub fn build_block( - &self, - bb: mir::BasicBlock - ) -> Bx { + pub fn build_block(&self, bb: mir::BasicBlock) -> Bx { let mut bx = Bx::with_cx(self.cx); bx.position_at_end(self.blocks[bb]); bx @@ -1121,7 +1106,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx: &mut Bx, dest: &mir::Place<'tcx>, fn_ret: &ArgAbi<'tcx, Ty<'tcx>>, - llargs: &mut Vec, is_intrinsic: bool + llargs: &mut Vec, + is_intrinsic: bool, ) -> ReturnDest<'tcx, Bx::Value> { // If the return is ignored, we can just return a do-nothing `ReturnDest`. if fn_ret.is_ignore() { @@ -1157,10 +1143,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } else { - self.codegen_place(bx, &mir::PlaceRef { - base: &dest.base, - projection: &dest.projection, - }) + self.codegen_place( + bx, + &mir::PlaceRef { base: &dest.base, projection: &dest.projection }, + ) }; if fn_ret.is_indirect() { if dest.align < dest.layout.align.abi { @@ -1179,12 +1165,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - fn codegen_transmute( - &mut self, - bx: &mut Bx, - src: &mir::Operand<'tcx>, - dst: &mir::Place<'tcx> - ) { + fn codegen_transmute(&mut self, bx: &mut Bx, src: &mir::Operand<'tcx>, dst: &mir::Place<'tcx>) { if let Some(index) = dst.as_local() { match self.locals[index] { LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place), @@ -1200,8 +1181,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.locals[index] = LocalRef::Operand(Some(op)); } LocalRef::Operand(Some(op)) => { - assert!(op.layout.is_zst(), - "assigning to initialized SSAtemp"); + assert!(op.layout.is_zst(), "assigning to initialized SSAtemp"); } } } else { @@ -1214,7 +1194,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &mut self, bx: &mut Bx, src: &mir::Operand<'tcx>, - dst: PlaceRef<'tcx, Bx::Value> + dst: PlaceRef<'tcx, Bx::Value>, ) { let src = self.codegen_operand(bx, src); let llty = bx.backend_type(src.layout); @@ -1223,14 +1203,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { src.val.store(bx, PlaceRef::new_sized_aligned(cast_ptr, src.layout, align)); } - // Stores the return value of a function call into it's final location. fn store_return( &mut self, bx: &mut Bx, dest: ReturnDest<'tcx, Bx::Value>, ret_abi: &ArgAbi<'tcx, Ty<'tcx>>, - llval: Bx::Value + llval: Bx::Value, ) { use self::ReturnDest::*; @@ -1268,5 +1247,5 @@ enum ReturnDest<'tcx, V> { // Store an indirect return value to an operand local place. IndirectOperand(PlaceRef<'tcx, V>, mir::Local), // Store a direct return value to an operand local place. - DirectOperand(mir::Local) + DirectOperand(mir::Local), } diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index fc17e2c0c71b7..2a4329cdb06bf 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -1,11 +1,11 @@ -use rustc::mir::interpret::ErrorHandled; +use crate::mir::operand::OperandRef; +use crate::traits::*; use rustc::mir; -use rustc_index::vec::Idx; -use rustc::ty::{self, Ty}; +use rustc::mir::interpret::ErrorHandled; use rustc::ty::layout::{self, HasTyCtxt}; +use rustc::ty::{self, Ty}; +use rustc_index::vec::Idx; use syntax::source_map::Span; -use crate::traits::*; -use crate::mir::operand::OperandRef; use super::FunctionCx; @@ -20,15 +20,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // use `get_static` to get at their id. // FIXME(oli-obk): can we unify this somehow, maybe by making const eval of statics // always produce `&STATIC`. This may also simplify how const eval works with statics. - ty::ConstKind::Unevaluated(def_id, substs) - if self.cx.tcx().is_static(def_id) => { - assert!(substs.is_empty(), "we don't support generic statics yet"); - let static_ = bx.get_static(def_id); - // we treat operands referring to statics as if they were `&STATIC` instead - let ptr_ty = self.cx.tcx().mk_mut_ptr(self.monomorphize(&constant.literal.ty)); - let layout = bx.layout_of(ptr_ty); - Ok(OperandRef::from_immediate_or_packed_pair(bx, static_, layout)) - } + ty::ConstKind::Unevaluated(def_id, substs) if self.cx.tcx().is_static(def_id) => { + assert!(substs.is_empty(), "we don't support generic statics yet"); + let static_ = bx.get_static(def_id); + // we treat operands referring to statics as if they were `&STATIC` instead + let ptr_ty = self.cx.tcx().mk_mut_ptr(self.monomorphize(&constant.literal.ty)); + let layout = bx.layout_of(ptr_ty); + Ok(OperandRef::from_immediate_or_packed_pair(bx, static_, layout)) + } _ => { let val = self.eval_mir_constant(constant)?; Ok(OperandRef::from_const(bx, val)) @@ -43,15 +42,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match constant.literal.val { ty::ConstKind::Unevaluated(def_id, substs) => { let substs = self.monomorphize(&substs); - self.cx.tcx() + self.cx + .tcx() .const_eval_resolve(ty::ParamEnv::reveal_all(), def_id, substs, None) .map_err(|err| { - self.cx.tcx().sess.span_err( - constant.span, - "erroneous constant encountered"); + self.cx + .tcx() + .sess + .span_err(constant.span, "erroneous constant encountered"); err }) - }, + } _ => Ok(self.monomorphize(&constant.literal)), } } @@ -71,32 +72,28 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ty::Array(_, n) => n.eval_usize(bx.tcx(), ty::ParamEnv::reveal_all()), _ => bug!("invalid simd shuffle type: {}", c.ty), }; - let values: Vec<_> = (0..fields).map(|field| { - let field = bx.tcx().const_field( - ty::ParamEnv::reveal_all().and((&c, mir::Field::new(field as usize))) - ); - if let Some(prim) = field.val.try_to_scalar() { - let layout = bx.layout_of(field_ty); - let scalar = match layout.abi { - layout::Abi::Scalar(ref x) => x, - _ => bug!("from_const: invalid ByVal layout: {:#?}", layout) - }; - bx.scalar_to_backend( - prim, scalar, - bx.immediate_backend_type(layout), - ) - } else { - bug!("simd shuffle field {:?}", field) - } - }).collect(); + let values: Vec<_> = (0..fields) + .map(|field| { + let field = bx.tcx().const_field( + ty::ParamEnv::reveal_all().and((&c, mir::Field::new(field as usize))), + ); + if let Some(prim) = field.val.try_to_scalar() { + let layout = bx.layout_of(field_ty); + let scalar = match layout.abi { + layout::Abi::Scalar(ref x) => x, + _ => bug!("from_const: invalid ByVal layout: {:#?}", layout), + }; + bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout)) + } else { + bug!("simd shuffle field {:?}", field) + } + }) + .collect(); let llval = bx.const_struct(&values, false); (llval, c.ty) }) .unwrap_or_else(|_| { - bx.tcx().sess.span_err( - span, - "could not evaluate shuffle_indices at compile time", - ); + bx.tcx().sess.span_err(span, "could not evaluate shuffle_indices at compile time"); // We've errored, so we don't have to produce working code. let ty = self.monomorphize(&ty); let llty = bx.backend_type(bx.layout_of(ty)); diff --git a/src/librustc_codegen_ssa/mir/debuginfo.rs b/src/librustc_codegen_ssa/mir/debuginfo.rs index bb2679e214db4..0935b61a86c60 100644 --- a/src/librustc_codegen_ssa/mir/debuginfo.rs +++ b/src/librustc_codegen_ssa/mir/debuginfo.rs @@ -1,16 +1,16 @@ -use rustc_index::vec::IndexVec; +use crate::traits::*; use rustc::hir::def_id::CrateNum; use rustc::mir; use rustc::session::config::DebugInfo; -use rustc::ty::TyCtxt; use rustc::ty::layout::{LayoutOf, Size}; -use crate::traits::*; +use rustc::ty::TyCtxt; +use rustc_index::vec::IndexVec; -use syntax_pos::{BytePos, Span}; use syntax::symbol::kw; +use syntax_pos::{BytePos, Span}; -use super::{FunctionCx, LocalRef}; use super::OperandValue; +use super::{FunctionCx, LocalRef}; pub struct FunctionDebugContext { pub scopes: IndexVec>, @@ -40,11 +40,7 @@ impl DebugScope { } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { - pub fn set_debug_loc( - &mut self, - bx: &mut Bx, - source_info: mir::SourceInfo - ) { + pub fn set_debug_loc(&mut self, bx: &mut Bx, source_info: mir::SourceInfo) { let (scope, span) = self.debug_loc(source_info); if let Some(debug_context) = &mut self.debug_context { // FIXME(eddyb) get rid of this unwrap somehow. @@ -62,8 +58,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // In order to have a good line stepping behavior in debugger, we overwrite debug // locations of macro expansions with that of the outermost expansion site // (unless the crate is being compiled with `-Z debug-macros`). - if !source_info.span.from_expansion() || - self.cx.sess().opts.debugging_opts.debug_macros { + if !source_info.span.from_expansion() || self.cx.sess().opts.debugging_opts.debug_macros { let scope = self.scope_metadata_for_loc(source_info.scope, source_info.span.lo()); (scope, source_info.span) } else { @@ -81,18 +76,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // it may so happen that the current span belongs to a different file than the DIScope // corresponding to span's containing source scope. If so, we need to create a DIScope // "extension" into that file. - fn scope_metadata_for_loc(&self, scope_id: mir::SourceScope, pos: BytePos) - -> Option { + fn scope_metadata_for_loc( + &self, + scope_id: mir::SourceScope, + pos: BytePos, + ) -> Option { let debug_context = self.debug_context.as_ref()?; let scope_metadata = debug_context.scopes[scope_id].scope_metadata; - if pos < debug_context.scopes[scope_id].file_start_pos || - pos >= debug_context.scopes[scope_id].file_end_pos { + if pos < debug_context.scopes[scope_id].file_start_pos + || pos >= debug_context.scopes[scope_id].file_end_pos + { let sm = self.cx.sess().source_map(); let defining_crate = debug_context.defining_crate; Some(self.cx.extend_scope_to_file( scope_metadata.unwrap(), &sm.lookup_char_pos(pos).file, - defining_crate + defining_crate, )) } else { scope_metadata @@ -113,12 +112,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Some(per_local) => &per_local[local], None => return, }; - let whole_local_var = vars.iter().copied().find(|var| { - var.place.projection.is_empty() - }); - let has_proj = || vars.iter().any(|var| { - !var.place.projection.is_empty() - }); + let whole_local_var = vars.iter().copied().find(|var| var.place.projection.is_empty()); + let has_proj = || vars.iter().any(|var| !var.place.projection.is_empty()); let (fallback_var, kind) = if self.mir.local_kind(local) == mir::LocalKind::Arg { let arg_index = local.index() - 1; @@ -150,13 +145,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => format!("{:?}", local), }; match local_ref { - LocalRef::Place(place) | - LocalRef::UnsizedPlace(place) => { + LocalRef::Place(place) | LocalRef::UnsizedPlace(place) => { bx.set_var_name(place.llval, &name); } LocalRef::Operand(Some(operand)) => match operand.val { - OperandValue::Ref(x, ..) | - OperandValue::Immediate(x) => { + OperandValue::Ref(x, ..) | OperandValue::Immediate(x) => { bx.set_var_name(x, &name); } OperandValue::Pair(a, b) => { @@ -165,7 +158,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.set_var_name(a, &(name.clone() + ".0")); bx.set_var_name(b, &(name + ".1")); } - } + }, LocalRef::Operand(None) => {} } } @@ -197,31 +190,26 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // FIXME(eddyb) use smallvec here. let mut indirect_offsets = vec![]; - let kind = if var.place.projection.is_empty() { - kind - } else { - VariableKind::LocalVariable - }; + let kind = + if var.place.projection.is_empty() { kind } else { VariableKind::LocalVariable }; for elem in &var.place.projection[..] { match *elem { mir::ProjectionElem::Deref => { indirect_offsets.push(Size::ZERO); layout = bx.cx().layout_of( - layout.ty.builtin_deref(true) + layout + .ty + .builtin_deref(true) .unwrap_or_else(|| { - span_bug!( - var.source_info.span, - "cannot deref `{}`", - layout.ty, - ) - }).ty, + span_bug!(var.source_info.span, "cannot deref `{}`", layout.ty,) + }) + .ty, ); } mir::ProjectionElem::Field(field, _) => { let i = field.index(); - let offset = indirect_offsets.last_mut() - .unwrap_or(&mut direct_offset); + let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset); *offset += layout.fields.offset(i); layout = layout.field(bx.cx(), i); } @@ -238,8 +226,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (scope, span) = self.debug_loc(var.source_info); if let Some(scope) = scope { - bx.declare_local(debug_context, var.name, layout.ty, scope, - base.llval, direct_offset, &indirect_offsets, kind, span); + bx.declare_local( + debug_context, + var.name, + layout.ty, + scope, + base.llval, + direct_offset, + &indirect_offsets, + kind, + span, + ); } } } diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index e535aecd633da..02b07ebfb7df5 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -1,9 +1,9 @@ -use rustc::ty::{self, Ty, TypeFoldable, Instance}; -use rustc::ty::layout::{TyLayout, HasTyCtxt, FnAbiExt}; -use rustc::mir; -use rustc_target::abi::call::{FnAbi, PassMode}; use crate::base; use crate::traits::*; +use rustc::mir; +use rustc::ty::layout::{FnAbiExt, HasTyCtxt, TyLayout}; +use rustc::ty::{self, Instance, Ty, TypeFoldable}; +use rustc_target::abi::call::{FnAbi, PassMode}; use std::iter; @@ -84,7 +84,8 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn monomorphize(&self, value: &T) -> T - where T: TypeFoldable<'tcx> + where + T: TypeFoldable<'tcx>, { self.cx.tcx().subst_and_normalize_erasing_regions( self.instance.substs, @@ -149,14 +150,17 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // Allocate a `Block` for every basic block, except // the start block, if nothing loops back to it. let reentrant_start_block = !mir.predecessors_for(mir::START_BLOCK).is_empty(); - let block_bxs: IndexVec = - mir.basic_blocks().indices().map(|bb| { + let block_bxs: IndexVec = mir + .basic_blocks() + .indices() + .map(|bb| { if bb == mir::START_BLOCK && !reentrant_start_block { bx.llbb() } else { bx.build_sibling_block(&format!("{:?}", bb)).llbb() } - }).collect(); + }) + .collect(); let (landing_pads, funclets) = create_funclets(&mir, &mut bx, &cleanup_kinds, &block_bxs); let mir_body: &mir::Body<'_> = *mir; @@ -261,62 +265,66 @@ fn create_funclets<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( IndexVec>, IndexVec>, ) { - block_bxs.iter_enumerated().zip(cleanup_kinds).map(|((bb, &llbb), cleanup_kind)| { - match *cleanup_kind { - CleanupKind::Funclet if base::wants_msvc_seh(bx.sess()) => {} - _ => return (None, None) - } - - let funclet; - let ret_llbb; - match mir[bb].terminator.as_ref().map(|t| &t.kind) { - // This is a basic block that we're aborting the program for, - // notably in an `extern` function. These basic blocks are inserted - // so that we assert that `extern` functions do indeed not panic, - // and if they do we abort the process. - // - // On MSVC these are tricky though (where we're doing funclets). If - // we were to do a cleanuppad (like below) the normal functions like - // `longjmp` would trigger the abort logic, terminating the - // program. Instead we insert the equivalent of `catch(...)` for C++ - // which magically doesn't trigger when `longjmp` files over this - // frame. - // - // Lots more discussion can be found on #48251 but this codegen is - // modeled after clang's for: - // - // try { - // foo(); - // } catch (...) { - // bar(); - // } - Some(&mir::TerminatorKind::Abort) => { - let mut cs_bx = bx.build_sibling_block(&format!("cs_funclet{:?}", bb)); - let mut cp_bx = bx.build_sibling_block(&format!("cp_funclet{:?}", bb)); - ret_llbb = cs_bx.llbb(); - - let cs = cs_bx.catch_switch(None, None, 1); - cs_bx.add_handler(cs, cp_bx.llbb()); - - // The "null" here is actually a RTTI type descriptor for the - // C++ personality function, but `catch (...)` has no type so - // it's null. The 64 here is actually a bitfield which - // represents that this is a catch-all block. - let null = bx.const_null(bx.type_i8p()); - let sixty_four = bx.const_i32(64); - funclet = cp_bx.catch_pad(cs, &[null, sixty_four, null]); - cp_bx.br(llbb); + block_bxs + .iter_enumerated() + .zip(cleanup_kinds) + .map(|((bb, &llbb), cleanup_kind)| { + match *cleanup_kind { + CleanupKind::Funclet if base::wants_msvc_seh(bx.sess()) => {} + _ => return (None, None), } - _ => { - let mut cleanup_bx = bx.build_sibling_block(&format!("funclet_{:?}", bb)); - ret_llbb = cleanup_bx.llbb(); - funclet = cleanup_bx.cleanup_pad(None, &[]); - cleanup_bx.br(llbb); - } - }; - (Some(ret_llbb), Some(funclet)) - }).unzip() + let funclet; + let ret_llbb; + match mir[bb].terminator.as_ref().map(|t| &t.kind) { + // This is a basic block that we're aborting the program for, + // notably in an `extern` function. These basic blocks are inserted + // so that we assert that `extern` functions do indeed not panic, + // and if they do we abort the process. + // + // On MSVC these are tricky though (where we're doing funclets). If + // we were to do a cleanuppad (like below) the normal functions like + // `longjmp` would trigger the abort logic, terminating the + // program. Instead we insert the equivalent of `catch(...)` for C++ + // which magically doesn't trigger when `longjmp` files over this + // frame. + // + // Lots more discussion can be found on #48251 but this codegen is + // modeled after clang's for: + // + // try { + // foo(); + // } catch (...) { + // bar(); + // } + Some(&mir::TerminatorKind::Abort) => { + let mut cs_bx = bx.build_sibling_block(&format!("cs_funclet{:?}", bb)); + let mut cp_bx = bx.build_sibling_block(&format!("cp_funclet{:?}", bb)); + ret_llbb = cs_bx.llbb(); + + let cs = cs_bx.catch_switch(None, None, 1); + cs_bx.add_handler(cs, cp_bx.llbb()); + + // The "null" here is actually a RTTI type descriptor for the + // C++ personality function, but `catch (...)` has no type so + // it's null. The 64 here is actually a bitfield which + // represents that this is a catch-all block. + let null = bx.const_null(bx.type_i8p()); + let sixty_four = bx.const_i32(64); + funclet = cp_bx.catch_pad(cs, &[null, sixty_four, null]); + cp_bx.br(llbb); + } + _ => { + let mut cleanup_bx = bx.build_sibling_block(&format!("funclet_{:?}", bb)); + ret_llbb = cleanup_bx.llbb(); + funclet = cleanup_bx.cleanup_pad(None, &[]); + cleanup_bx.br(llbb); + } + }; + + (Some(ret_llbb), Some(funclet)) + }) + .unzip() } /// Produces, for each argument, a `Value` pointing at the @@ -331,107 +339,113 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let mut idx = 0; let mut llarg_idx = fx.fn_abi.ret.is_indirect() as usize; - let args = mir.args_iter().enumerate().map(|(arg_index, local)| { - let arg_decl = &mir.local_decls[local]; - - if Some(local) == mir.spread_arg { - // This argument (e.g., the last argument in the "rust-call" ABI) - // is a tuple that was spread at the ABI level and now we have - // to reconstruct it into a tuple local variable, from multiple - // individual LLVM function arguments. - - let arg_ty = fx.monomorphize(&arg_decl.ty); - let tupled_arg_tys = match arg_ty.kind { - ty::Tuple(ref tys) => tys, - _ => bug!("spread argument isn't a tuple?!") - }; - - let place = PlaceRef::alloca(bx, bx.layout_of(arg_ty)); - for i in 0..tupled_arg_tys.len() { - let arg = &fx.fn_abi.args[idx]; - idx += 1; - if arg.pad.is_some() { - llarg_idx += 1; + let args = mir + .args_iter() + .enumerate() + .map(|(arg_index, local)| { + let arg_decl = &mir.local_decls[local]; + + if Some(local) == mir.spread_arg { + // This argument (e.g., the last argument in the "rust-call" ABI) + // is a tuple that was spread at the ABI level and now we have + // to reconstruct it into a tuple local variable, from multiple + // individual LLVM function arguments. + + let arg_ty = fx.monomorphize(&arg_decl.ty); + let tupled_arg_tys = match arg_ty.kind { + ty::Tuple(ref tys) => tys, + _ => bug!("spread argument isn't a tuple?!"), + }; + + let place = PlaceRef::alloca(bx, bx.layout_of(arg_ty)); + for i in 0..tupled_arg_tys.len() { + let arg = &fx.fn_abi.args[idx]; + idx += 1; + if arg.pad.is_some() { + llarg_idx += 1; + } + let pr_field = place.project_field(bx, i); + bx.store_fn_arg(arg, &mut llarg_idx, pr_field); } - let pr_field = place.project_field(bx, i); - bx.store_fn_arg(arg, &mut llarg_idx, pr_field); - } - return LocalRef::Place(place); - } + return LocalRef::Place(place); + } - if fx.fn_abi.c_variadic && arg_index == fx.fn_abi.args.len() { - let arg_ty = fx.monomorphize(&arg_decl.ty); + if fx.fn_abi.c_variadic && arg_index == fx.fn_abi.args.len() { + let arg_ty = fx.monomorphize(&arg_decl.ty); - let va_list = PlaceRef::alloca(bx, bx.layout_of(arg_ty)); - bx.va_start(va_list.llval); + let va_list = PlaceRef::alloca(bx, bx.layout_of(arg_ty)); + bx.va_start(va_list.llval); - return LocalRef::Place(va_list); - } + return LocalRef::Place(va_list); + } - let arg = &fx.fn_abi.args[idx]; - idx += 1; - if arg.pad.is_some() { - llarg_idx += 1; - } + let arg = &fx.fn_abi.args[idx]; + idx += 1; + if arg.pad.is_some() { + llarg_idx += 1; + } - if !memory_locals.contains(local) { - // We don't have to cast or keep the argument in the alloca. - // FIXME(eddyb): We should figure out how to use llvm.dbg.value instead - // of putting everything in allocas just so we can use llvm.dbg.declare. - let local = |op| LocalRef::Operand(Some(op)); - match arg.mode { - PassMode::Ignore => { - return local(OperandRef::new_zst(bx, arg.layout)); - } - PassMode::Direct(_) => { - let llarg = bx.get_param(llarg_idx); - llarg_idx += 1; - return local( - OperandRef::from_immediate_or_packed_pair(bx, llarg, arg.layout)); + if !memory_locals.contains(local) { + // We don't have to cast or keep the argument in the alloca. + // FIXME(eddyb): We should figure out how to use llvm.dbg.value instead + // of putting everything in allocas just so we can use llvm.dbg.declare. + let local = |op| LocalRef::Operand(Some(op)); + match arg.mode { + PassMode::Ignore => { + return local(OperandRef::new_zst(bx, arg.layout)); + } + PassMode::Direct(_) => { + let llarg = bx.get_param(llarg_idx); + llarg_idx += 1; + return local(OperandRef::from_immediate_or_packed_pair( + bx, llarg, arg.layout, + )); + } + PassMode::Pair(..) => { + let (a, b) = (bx.get_param(llarg_idx), bx.get_param(llarg_idx + 1)); + llarg_idx += 2; + + return local(OperandRef { + val: OperandValue::Pair(a, b), + layout: arg.layout, + }); + } + _ => {} } - PassMode::Pair(..) => { - let (a, b) = (bx.get_param(llarg_idx), bx.get_param(llarg_idx + 1)); - llarg_idx += 2; - - return local(OperandRef { - val: OperandValue::Pair(a, b), - layout: arg.layout - }); - } - _ => {} } - } - if arg.is_sized_indirect() { - // Don't copy an indirect argument to an alloca, the caller - // already put it in a temporary alloca and gave it up. - // FIXME: lifetimes - let llarg = bx.get_param(llarg_idx); - llarg_idx += 1; - LocalRef::Place(PlaceRef::new_sized(llarg, arg.layout)) - } else if arg.is_unsized_indirect() { - // As the storage for the indirect argument lives during - // the whole function call, we just copy the fat pointer. - let llarg = bx.get_param(llarg_idx); - llarg_idx += 1; - let llextra = bx.get_param(llarg_idx); - llarg_idx += 1; - let indirect_operand = OperandValue::Pair(llarg, llextra); - - let tmp = PlaceRef::alloca_unsized_indirect(bx, arg.layout); - indirect_operand.store(bx, tmp); - LocalRef::UnsizedPlace(tmp) - } else { - let tmp = PlaceRef::alloca(bx, arg.layout); - bx.store_fn_arg(arg, &mut llarg_idx, tmp); - LocalRef::Place(tmp) - } - }).collect::>(); + if arg.is_sized_indirect() { + // Don't copy an indirect argument to an alloca, the caller + // already put it in a temporary alloca and gave it up. + // FIXME: lifetimes + let llarg = bx.get_param(llarg_idx); + llarg_idx += 1; + LocalRef::Place(PlaceRef::new_sized(llarg, arg.layout)) + } else if arg.is_unsized_indirect() { + // As the storage for the indirect argument lives during + // the whole function call, we just copy the fat pointer. + let llarg = bx.get_param(llarg_idx); + llarg_idx += 1; + let llextra = bx.get_param(llarg_idx); + llarg_idx += 1; + let indirect_operand = OperandValue::Pair(llarg, llextra); + + let tmp = PlaceRef::alloca_unsized_indirect(bx, arg.layout); + indirect_operand.store(bx, tmp); + LocalRef::UnsizedPlace(tmp) + } else { + let tmp = PlaceRef::alloca(bx, arg.layout); + bx.store_fn_arg(arg, &mut llarg_idx, tmp); + LocalRef::Place(tmp) + } + }) + .collect::>(); if fx.instance.def.requires_caller_location(bx.tcx()) { assert_eq!( - fx.fn_abi.args.len(), args.len() + 1, + fx.fn_abi.args.len(), + args.len() + 1, "#[track_caller] fn's must have 1 more argument in their ABI than in their MIR", ); @@ -454,7 +468,7 @@ mod analyze; mod block; pub mod constant; pub mod debuginfo; -pub mod place; pub mod operand; +pub mod place; mod rvalue; mod statement; diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index a6dec81274915..d530696543720 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -1,15 +1,15 @@ -use super::{FunctionCx, LocalRef}; use super::place::PlaceRef; +use super::{FunctionCx, LocalRef}; -use crate::MemFlags; use crate::base; use crate::glue; use crate::traits::*; +use crate::MemFlags; -use rustc::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar}; use rustc::mir; +use rustc::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar}; use rustc::ty; -use rustc::ty::layout::{self, Align, LayoutOf, TyLayout, Size}; +use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout}; use std::fmt; @@ -26,7 +26,7 @@ pub enum OperandValue { /// A single LLVM value. Immediate(V), /// A pair of immediate LLVM values. Used by fat pointers too. - Pair(V, V) + Pair(V, V), } /// An `OperandRef` is an "SSA" reference to a Rust value, along with @@ -55,18 +55,18 @@ impl fmt::Debug for OperandRef<'tcx, V> { impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { pub fn new_zst>( bx: &mut Bx, - layout: TyLayout<'tcx> + layout: TyLayout<'tcx>, ) -> OperandRef<'tcx, V> { assert!(layout.is_zst()); OperandRef { val: OperandValue::Immediate(bx.const_undef(bx.immediate_backend_type(layout))), - layout + layout, } } pub fn from_const>( bx: &mut Bx, - val: &'tcx ty::Const<'tcx> + val: &'tcx ty::Const<'tcx>, ) -> Self { let layout = bx.layout_of(val.ty); @@ -83,24 +83,21 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { ConstValue::Scalar(x) => { let scalar = match layout.abi { layout::Abi::Scalar(ref x) => x, - _ => bug!("from_const: invalid ByVal layout: {:#?}", layout) + _ => bug!("from_const: invalid ByVal layout: {:#?}", layout), }; - let llval = bx.scalar_to_backend( - x, - scalar, - bx.immediate_backend_type(layout), - ); + let llval = bx.scalar_to_backend(x, scalar, bx.immediate_backend_type(layout)); OperandValue::Immediate(llval) - }, + } ConstValue::Slice { data, start, end } => { let a_scalar = match layout.abi { layout::Abi::ScalarPair(ref a, _) => a, - _ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout) + _ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout), }; let a = Scalar::from(Pointer::new( bx.tcx().alloc_map.lock().create_memory_alloc(data), Size::from_bytes(start as u64), - )).into(); + )) + .into(); let a_llval = bx.scalar_to_backend( a, a_scalar, @@ -108,16 +105,13 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { ); let b_llval = bx.const_usize((end - start) as u64); OperandValue::Pair(a_llval, b_llval) - }, + } ConstValue::ByRef { alloc, offset } => { return bx.load_operand(bx.from_const_alloc(layout, alloc, offset)); - }, + } }; - OperandRef { - val, - layout - } + OperandRef { val, layout } } /// Asserts that this operand refers to a scalar and returns @@ -125,40 +119,35 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { pub fn immediate(self) -> V { match self.val { OperandValue::Immediate(s) => s, - _ => bug!("not immediate: {:?}", self) + _ => bug!("not immediate: {:?}", self), } } - pub fn deref>( - self, - cx: &Cx - ) -> PlaceRef<'tcx, V> { - let projected_ty = self.layout.ty.builtin_deref(true) - .unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)).ty; + pub fn deref>(self, cx: &Cx) -> PlaceRef<'tcx, V> { + let projected_ty = self + .layout + .ty + .builtin_deref(true) + .unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)) + .ty; let (llptr, llextra) = match self.val { OperandValue::Immediate(llptr) => (llptr, None), OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)), - OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self) + OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self), }; let layout = cx.layout_of(projected_ty); - PlaceRef { - llval: llptr, - llextra, - layout, - align: layout.align.abi, - } + PlaceRef { llval: llptr, llextra, layout, align: layout.align.abi } } /// If this operand is a `Pair`, we return an aggregate with the two values. /// For other cases, see `immediate`. pub fn immediate_or_packed_pair>( self, - bx: &mut Bx + bx: &mut Bx, ) -> V { if let OperandValue::Pair(a, b) = self.val { let llty = bx.cx().backend_type(self.layout); - debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}", - self, llty); + 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); @@ -175,11 +164,10 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { pub fn from_immediate_or_packed_pair>( bx: &mut Bx, llval: V, - layout: TyLayout<'tcx> + layout: TyLayout<'tcx>, ) -> Self { let val = if let layout::Abi::ScalarPair(ref a, ref b) = layout.abi { - debug!("Operand::from_immediate_or_packed_pair: unpacking {:?} @ {:?}", - llval, layout); + debug!("Operand::from_immediate_or_packed_pair: unpacking {:?} @ {:?}", llval, layout); // Deconstruct the immediate aggregate. let a_llval = bx.extract_value(llval, 0); @@ -196,7 +184,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { pub fn extract_field>( &self, bx: &mut Bx, - i: usize + i: usize, ) -> Self { let field = self.layout.field(bx.cx(), i); let offset = self.layout.fields.offset(i); @@ -208,8 +196,9 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { } // Newtype of a scalar, scalar pair or vector. - (OperandValue::Immediate(_), _) | - (OperandValue::Pair(..), _) if field.size == self.layout.size => { + (OperandValue::Immediate(_), _) | (OperandValue::Pair(..), _) + if field.size == self.layout.size => + { assert_eq!(offset.bytes(), 0); self.val } @@ -220,8 +209,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { assert_eq!(field.size, a.value.size(bx.cx())); OperandValue::Immediate(a_llval) } else { - assert_eq!(offset, a.value.size(bx.cx()) - .align_to(b.value.align(bx.cx()).abi)); + assert_eq!(offset, a.value.size(bx.cx()).align_to(b.value.align(bx.cx()).abi)); assert_eq!(field.size, b.value.size(bx.cx())); OperandValue::Immediate(b_llval) } @@ -229,21 +217,16 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { // `#[repr(simd)]` types are also immediate. (OperandValue::Immediate(llval), &layout::Abi::Vector { .. }) => { - OperandValue::Immediate( - bx.extract_element(llval, bx.cx().const_usize(i as u64))) + OperandValue::Immediate(bx.extract_element(llval, bx.cx().const_usize(i as u64))) } - _ => bug!("OperandRef::extract_field({:?}): not applicable", self) + _ => 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) - } + if ty == bx.cx().type_i1() { bx.trunc(val, ty) } else { bx.bitcast(val, ty) } }; match val { @@ -251,18 +234,21 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { *llval = to_immediate_or_cast(bx, *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)); + *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::Ref(..) => bug!() + OperandValue::Ref(..) => bug!(), } - OperandRef { - val, - layout: field - } + OperandRef { val, layout: field } } } @@ -270,7 +256,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { pub fn store>( self, bx: &mut Bx, - dest: PlaceRef<'tcx, V> + dest: PlaceRef<'tcx, V>, ) { self.store_with_flags(bx, dest, MemFlags::empty()); } @@ -278,7 +264,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { pub fn volatile_store>( self, bx: &mut Bx, - dest: PlaceRef<'tcx, V> + dest: PlaceRef<'tcx, V>, ) { self.store_with_flags(bx, dest, MemFlags::VOLATILE); } @@ -294,7 +280,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { pub fn nontemporal_store>( self, bx: &mut Bx, - dest: PlaceRef<'tcx, V> + dest: PlaceRef<'tcx, V>, ) { self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL); } @@ -313,8 +299,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { } match self { OperandValue::Ref(r, None, source_align) => { - base::memcpy_ty(bx, dest.llval, dest.align, r, source_align, - dest.layout, flags) + base::memcpy_ty(bx, dest.llval, dest.align, r, source_align, dest.layout, flags) } OperandValue::Ref(_, Some(_), _) => { bug!("cannot directly store unsized values"); @@ -326,7 +311,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { OperandValue::Pair(a, b) => { let (a_scalar, b_scalar) = match dest.layout.abi { layout::Abi::ScalarPair(ref a, ref b) => (a, b), - _ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout) + _ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout), }; let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi); @@ -346,21 +331,24 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { pub fn store_unsized>( self, bx: &mut Bx, - indirect_dest: PlaceRef<'tcx, V> + indirect_dest: PlaceRef<'tcx, V>, ) { debug!("OperandRef::store_unsized: operand={:?}, indirect_dest={:?}", self, indirect_dest); let flags = MemFlags::empty(); // `indirect_dest` must have `*mut T` type. We extract `T` out of it. - let unsized_ty = indirect_dest.layout.ty.builtin_deref(true) - .unwrap_or_else(|| bug!("indirect_dest has non-pointer type: {:?}", indirect_dest)).ty; - - let (llptr, llextra) = - if let OperandValue::Ref(llptr, Some(llextra), _) = self { - (llptr, llextra) - } else { - bug!("store_unsized called with a sized value") - }; + let unsized_ty = indirect_dest + .layout + .ty + .builtin_deref(true) + .unwrap_or_else(|| bug!("indirect_dest has non-pointer type: {:?}", indirect_dest)) + .ty; + + let (llptr, llextra) = if let OperandValue::Ref(llptr, Some(llextra), _) = self { + (llptr, llextra) + } else { + bug!("store_unsized called with a sized value") + }; // FIXME: choose an appropriate alignment, or use dynamic align somehow let max_align = Align::from_bits(128).unwrap(); @@ -381,7 +369,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn maybe_codegen_consume_direct( &mut self, bx: &mut Bx, - place_ref: &mir::PlaceRef<'_, 'tcx> + place_ref: &mir::PlaceRef<'_, 'tcx>, ) -> Option> { debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref); @@ -394,8 +382,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::ProjectionElem::Field(ref f, _) => { o = o.extract_field(bx, f.index()); } - mir::ProjectionElem::Index(_) | - mir::ProjectionElem::ConstantIndex { .. } => { + mir::ProjectionElem::Index(_) + | mir::ProjectionElem::ConstantIndex { .. } => { // ZSTs don't require any actual memory access. // FIXME(eddyb) deduplicate this with the identical // checks in `codegen_consume` and `extract_field`. @@ -429,7 +417,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_consume( &mut self, bx: &mut Bx, - place_ref: &mir::PlaceRef<'_, 'tcx> + place_ref: &mir::PlaceRef<'_, 'tcx>, ) -> OperandRef<'tcx, Bx::Value> { debug!("codegen_consume(place_ref={:?})", place_ref); @@ -454,38 +442,34 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_operand( &mut self, bx: &mut Bx, - operand: &mir::Operand<'tcx> + operand: &mir::Operand<'tcx>, ) -> OperandRef<'tcx, Bx::Value> { debug!("codegen_operand(operand={:?})", operand); match *operand { - mir::Operand::Copy(ref place) | - mir::Operand::Move(ref place) => { + mir::Operand::Copy(ref place) | mir::Operand::Move(ref place) => { self.codegen_consume(bx, &place.as_ref()) } mir::Operand::Constant(ref constant) => { - self.eval_mir_constant_to_operand(bx, constant) - .unwrap_or_else(|err| { - match err { - // errored or at least linted - ErrorHandled::Reported => {}, - ErrorHandled::TooGeneric => { - bug!("codgen encountered polymorphic constant") - }, - } - // Allow RalfJ to sleep soundly knowing that even refactorings that remove - // the above error (or silence it under some conditions) will not cause UB. - bx.abort(); - // We still have to return an operand but it doesn't matter, - // this code is unreachable. - let ty = self.monomorphize(&constant.literal.ty); - let layout = bx.cx().layout_of(ty); - bx.load_operand(PlaceRef::new_sized( - bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))), - layout, - )) - }) + self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|err| { + match err { + // errored or at least linted + ErrorHandled::Reported => {} + ErrorHandled::TooGeneric => bug!("codgen encountered polymorphic constant"), + } + // Allow RalfJ to sleep soundly knowing that even refactorings that remove + // the above error (or silence it under some conditions) will not cause UB. + bx.abort(); + // We still have to return an operand but it doesn't matter, + // this code is unreachable. + let ty = self.monomorphize(&constant.literal.ty); + let layout = bx.cx().layout_of(ty); + bx.load_operand(PlaceRef::new_sized( + bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))), + layout, + )) + }) } } } diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 09405cc02b3d4..bc12c1cc0a3a8 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -1,41 +1,40 @@ -use super::{FunctionCx, LocalRef}; use super::operand::{OperandRef, OperandValue}; use super::place::PlaceRef; +use super::{FunctionCx, LocalRef}; use crate::base; -use crate::MemFlags; -use crate::common::{self, RealPredicate, IntPredicate}; +use crate::common::{self, IntPredicate, RealPredicate}; use crate::traits::*; +use crate::MemFlags; -use rustc::ty::{self, Ty, TyCtxt, adjustment::{PointerCast}, Instance}; -use rustc::ty::cast::{CastTy, IntTy}; -use rustc::ty::layout::{self, LayoutOf, HasTyCtxt}; -use rustc::mir; use rustc::middle::lang_items::ExchangeMallocFnLangItem; -use rustc_apfloat::{ieee, Float, Status, Round}; +use rustc::mir; +use rustc::ty::cast::{CastTy, IntTy}; +use rustc::ty::layout::{self, HasTyCtxt, LayoutOf}; +use rustc::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt}; +use rustc_apfloat::{ieee, Float, Round, Status}; +use syntax::source_map::{Span, DUMMY_SP}; use syntax::symbol::sym; -use syntax::source_map::{DUMMY_SP, Span}; -use std::{u128, i128}; +use std::{i128, u128}; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_rvalue( &mut self, mut bx: Bx, dest: PlaceRef<'tcx, Bx::Value>, - rvalue: &mir::Rvalue<'tcx> + rvalue: &mir::Rvalue<'tcx>, ) -> Bx { - debug!("codegen_rvalue(dest.llval={:?}, rvalue={:?})", - dest.llval, rvalue); + debug!("codegen_rvalue(dest.llval={:?}, rvalue={:?})", dest.llval, rvalue); match *rvalue { - mir::Rvalue::Use(ref operand) => { - let cg_operand = self.codegen_operand(&mut bx, operand); - // FIXME: consider not copying constants through stack. (Fixable by codegen'ing - // constants into `OperandValue::Ref`; why don’t we do that yet if we don’t?) - cg_operand.val.store(&mut bx, dest); - bx - } + mir::Rvalue::Use(ref operand) => { + let cg_operand = self.codegen_operand(&mut bx, operand); + // FIXME: consider not copying constants through stack. (Fixable by codegen'ing + // constants into `OperandValue::Ref`; why don’t we do that yet if we don’t?) + cg_operand.val.store(&mut bx, dest); + bx + } mir::Rvalue::Cast(mir::CastKind::Pointer(PointerCast::Unsize), ref source, _) => { // The destination necessarily contains a fat pointer, so if @@ -54,8 +53,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // so the (generic) MIR may not be able to expand it. let operand = self.codegen_operand(&mut bx, source); match operand.val { - OperandValue::Pair(..) | - OperandValue::Immediate(_) => { + OperandValue::Pair(..) | OperandValue::Immediate(_) => { // Unsize from an immediate structure. We don't // really need a temporary alloca here, but // avoiding it would require us to have @@ -121,7 +119,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (dest, active_field_index) } } - _ => (dest, None) + _ => (dest, None), }; for (i, operand) in operands.iter().enumerate() { let op = self.codegen_operand(&mut bx, operand); @@ -150,8 +148,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { indirect_dest: PlaceRef<'tcx, Bx::Value>, rvalue: &mir::Rvalue<'tcx>, ) -> Bx { - debug!("codegen_rvalue_unsized(indirect_dest.llval={:?}, rvalue={:?})", - indirect_dest.llval, rvalue); + debug!( + "codegen_rvalue_unsized(indirect_dest.llval={:?}, rvalue={:?})", + indirect_dest.llval, rvalue + ); match *rvalue { mir::Rvalue::Use(ref operand) => { @@ -167,7 +167,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_rvalue_operand( &mut self, mut bx: Bx, - rvalue: &mir::Rvalue<'tcx> + rvalue: &mir::Rvalue<'tcx>, ) -> (Bx, OperandRef<'tcx, Bx::Value>) { assert!( self.rvalue_creates_operand(rvalue, DUMMY_SP), @@ -194,14 +194,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.tcx(), ty::ParamEnv::reveal_all(), def_id, - substs - ).unwrap() - ) + substs, + ) + .unwrap(), + ), ) } - _ => { - bug!("{} cannot be reified to a fn ptr", operand.layout.ty) - } + _ => bug!("{} cannot be reified to a fn ptr", operand.layout.ty), } } mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)) => { @@ -211,12 +210,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.cx().tcx(), def_id, substs, - ty::ClosureKind::FnOnce); + ty::ClosureKind::FnOnce, + ); OperandValue::Immediate(bx.cx().get_fn_addr(instance)) } - _ => { - bug!("{} cannot be cast to a fn ptr", operand.layout.ty) - } + _ => bug!("{} cannot be cast to a fn ptr", operand.layout.ty), } } mir::CastKind::Pointer(PointerCast::UnsafeFnPointer) => { @@ -233,30 +231,40 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // HACK(eddyb) have to bitcast pointers // until LLVM removes pointee types. - let lldata = bx.pointercast(lldata, - bx.cx().scalar_pair_element_backend_type(cast, 0, true)); + let lldata = bx.pointercast( + lldata, + bx.cx().scalar_pair_element_backend_type(cast, 0, true), + ); OperandValue::Pair(lldata, llextra) } OperandValue::Immediate(lldata) => { // "standard" unsize - let (lldata, llextra) = base::unsize_thin_ptr(&mut bx, lldata, - operand.layout.ty, cast.ty); + let (lldata, llextra) = base::unsize_thin_ptr( + &mut bx, + lldata, + operand.layout.ty, + cast.ty, + ); OperandValue::Pair(lldata, llextra) } OperandValue::Ref(..) => { - bug!("by-ref operand {:?} in `codegen_rvalue_operand`", - operand); + bug!("by-ref operand {:?} in `codegen_rvalue_operand`", operand); } } } - mir::CastKind::Pointer(PointerCast::MutToConstPointer) | - mir::CastKind::Misc if bx.cx().is_backend_scalar_pair(operand.layout) => { + mir::CastKind::Pointer(PointerCast::MutToConstPointer) + | mir::CastKind::Misc + if bx.cx().is_backend_scalar_pair(operand.layout) => + { if let OperandValue::Pair(data_ptr, meta) = operand.val { if bx.cx().is_backend_scalar_pair(cast) { - let data_cast = bx.pointercast(data_ptr, - bx.cx().scalar_pair_element_backend_type(cast, 0, true)); + let data_cast = bx.pointercast( + data_ptr, + bx.cx().scalar_pair_element_backend_type(cast, 0, true), + ); OperandValue::Pair(data_cast, meta) - } else { // cast to thin-ptr + } else { + // cast to thin-ptr // Cast of fat-ptr to thin-ptr is an extraction of data-ptr and // pointer-cast of that pointer to desired pointer type. let llcast_ty = bx.cx().immediate_backend_type(cast); @@ -267,20 +275,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bug!("unexpected non-pair operand"); } } - mir::CastKind::Pointer(PointerCast::MutToConstPointer) | - mir::CastKind::Pointer(PointerCast::ArrayToPointer) | - mir::CastKind::Misc => { + mir::CastKind::Pointer(PointerCast::MutToConstPointer) + | mir::CastKind::Pointer(PointerCast::ArrayToPointer) + | mir::CastKind::Misc => { assert!(bx.cx().is_backend_immediate(cast)); let ll_t_out = bx.cx().immediate_backend_type(cast); if operand.layout.abi.is_uninhabited() { let val = OperandValue::Immediate(bx.cx().const_undef(ll_t_out)); - return (bx, OperandRef { - val, - layout: cast, - }); + return (bx, OperandRef { val, layout: cast }); } - let r_t_in = CastTy::from_ty(operand.layout.ty) - .expect("bad input type for cast"); + let r_t_in = + CastTy::from_ty(operand.layout.ty).expect("bad input type for cast"); let r_t_out = CastTy::from_ty(cast.ty).expect("bad output type for cast"); let ll_t_in = bx.cx().immediate_backend_type(operand.layout); match operand.layout.variants { @@ -289,13 +294,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { operand.layout.ty.discriminant_for_variant(bx.tcx(), index) { let discr_val = bx.cx().const_uint_big(ll_t_out, discr.val); - return (bx, OperandRef { - val: OperandValue::Immediate(discr_val), - layout: cast, - }); + return ( + bx, + OperandRef { + val: OperandValue::Immediate(discr_val), + layout: cast, + }, + ); } } - layout::Variants::Multiple { .. } => {}, + layout::Variants::Multiple { .. } => {} } let llval = operand.immediate(); @@ -309,27 +317,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { signed = !scalar.is_bool() && s; let er = scalar.valid_range_exclusive(bx.cx()); - if er.end != er.start && - scalar.valid_range.end() > scalar.valid_range.start() { + if er.end != er.start + && scalar.valid_range.end() > scalar.valid_range.start() + { // We want `table[e as usize]` to not // have bound checks, and this is the most // convenient place to put the `assume`. let ll_t_in_const = bx.cx().const_uint_big(ll_t_in, *scalar.valid_range.end()); - let cmp = bx.icmp( - IntPredicate::IntULE, - llval, - ll_t_in_const - ); + let cmp = bx.icmp(IntPredicate::IntULE, llval, ll_t_in_const); bx.assume(cmp); } } } let newval = match (r_t_in, r_t_out) { - (CastTy::Int(_), CastTy::Int(_)) => { - bx.intcast(llval, ll_t_out, signed) - } + (CastTy::Int(_), CastTy::Int(_)) => bx.intcast(llval, ll_t_out, signed), (CastTy::Float, CastTy::Float) => { let srcsz = bx.cx().float_width(ll_t_in); let dstsz = bx.cx().float_width(ll_t_out); @@ -348,43 +351,44 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.uitofp(llval, ll_t_out) } } - (CastTy::Ptr(_), CastTy::Ptr(_)) | - (CastTy::FnPtr, CastTy::Ptr(_)) => - bx.pointercast(llval, ll_t_out), - (CastTy::Ptr(_), CastTy::Int(_)) | - (CastTy::FnPtr, CastTy::Int(_)) => - bx.ptrtoint(llval, ll_t_out), + (CastTy::Ptr(_), CastTy::Ptr(_)) | (CastTy::FnPtr, CastTy::Ptr(_)) => { + bx.pointercast(llval, ll_t_out) + } + (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => { + bx.ptrtoint(llval, ll_t_out) + } (CastTy::Int(_), CastTy::Ptr(_)) => { let usize_llval = bx.intcast(llval, bx.cx().type_isize(), signed); bx.inttoptr(usize_llval, ll_t_out) } - (CastTy::Float, CastTy::Int(IntTy::I)) => - cast_float_to_int(&mut bx, true, llval, ll_t_in, ll_t_out), - (CastTy::Float, CastTy::Int(_)) => - cast_float_to_int(&mut bx, false, llval, ll_t_in, ll_t_out), - _ => bug!("unsupported cast: {:?} to {:?}", operand.layout.ty, cast.ty) + (CastTy::Float, CastTy::Int(IntTy::I)) => { + cast_float_to_int(&mut bx, true, llval, ll_t_in, ll_t_out) + } + (CastTy::Float, CastTy::Int(_)) => { + cast_float_to_int(&mut bx, false, llval, ll_t_in, ll_t_out) + } + _ => bug!("unsupported cast: {:?} to {:?}", operand.layout.ty, cast.ty), }; OperandValue::Immediate(newval) } }; - (bx, OperandRef { - val, - layout: cast - }) + (bx, OperandRef { val, layout: cast }) } mir::Rvalue::Ref(_, bk, ref place) => { - let mk_ref = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| tcx.mk_ref( - tcx.lifetimes.re_erased, - ty::TypeAndMut { ty, mutbl: bk.to_mutbl_lossy() } - ); + let mk_ref = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| { + tcx.mk_ref( + tcx.lifetimes.re_erased, + ty::TypeAndMut { ty, mutbl: bk.to_mutbl_lossy() }, + ) + }; self.codegen_place_to_pointer(bx, place, mk_ref) } mir::Rvalue::AddressOf(mutability, ref place) => { - let mk_ptr = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| tcx.mk_ptr( - ty::TypeAndMut { ty, mutbl: mutability.into() } - ); + let mk_ptr = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| { + tcx.mk_ptr(ty::TypeAndMut { ty, mutbl: mutability.into() }) + }; self.codegen_place_to_pointer(bx, place, mk_ptr) } @@ -401,40 +405,44 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let lhs = self.codegen_operand(&mut bx, lhs); let rhs = self.codegen_operand(&mut bx, rhs); let llresult = match (lhs.val, rhs.val) { - (OperandValue::Pair(lhs_addr, lhs_extra), - OperandValue::Pair(rhs_addr, rhs_extra)) => { - self.codegen_fat_ptr_binop(&mut bx, op, - lhs_addr, lhs_extra, - rhs_addr, rhs_extra, - lhs.layout.ty) - } - - (OperandValue::Immediate(lhs_val), - OperandValue::Immediate(rhs_val)) => { + ( + OperandValue::Pair(lhs_addr, lhs_extra), + OperandValue::Pair(rhs_addr, rhs_extra), + ) => self.codegen_fat_ptr_binop( + &mut bx, + op, + lhs_addr, + lhs_extra, + rhs_addr, + rhs_extra, + lhs.layout.ty, + ), + + (OperandValue::Immediate(lhs_val), OperandValue::Immediate(rhs_val)) => { self.codegen_scalar_binop(&mut bx, op, lhs_val, rhs_val, lhs.layout.ty) } - _ => bug!() + _ => bug!(), }; let operand = OperandRef { val: OperandValue::Immediate(llresult), - layout: bx.cx().layout_of( - op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty)), + layout: bx.cx().layout_of(op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty)), }; (bx, operand) } mir::Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) => { let lhs = self.codegen_operand(&mut bx, lhs); let rhs = self.codegen_operand(&mut bx, rhs); - let result = self.codegen_scalar_checked_binop(&mut bx, op, - lhs.immediate(), rhs.immediate(), - lhs.layout.ty); + let result = self.codegen_scalar_checked_binop( + &mut bx, + op, + lhs.immediate(), + rhs.immediate(), + lhs.layout.ty, + ); let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty); let operand_ty = bx.tcx().intern_tup(&[val_ty, bx.tcx().types.bool]); - let operand = OperandRef { - val: result, - layout: bx.cx().layout_of(operand_ty) - }; + let operand = OperandRef { val: result, layout: bx.cx().layout_of(operand_ty) }; (bx, operand) } @@ -445,36 +453,42 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let is_float = operand.layout.ty.is_floating_point(); let llval = match op { mir::UnOp::Not => bx.not(lloperand), - mir::UnOp::Neg => if is_float { - bx.fneg(lloperand) - } else { - bx.neg(lloperand) + mir::UnOp::Neg => { + if is_float { + bx.fneg(lloperand) + } else { + bx.neg(lloperand) + } } }; - (bx, OperandRef { - val: OperandValue::Immediate(llval), - layout: operand.layout, - }) + (bx, OperandRef { val: OperandValue::Immediate(llval), layout: operand.layout }) } mir::Rvalue::Discriminant(ref place) => { let discr_ty = rvalue.ty(*self.mir, bx.tcx()); - let discr = self.codegen_place(&mut bx, &place.as_ref()) + let discr = self + .codegen_place(&mut bx, &place.as_ref()) .codegen_get_discr(&mut bx, discr_ty); - (bx, OperandRef { - val: OperandValue::Immediate(discr), - layout: self.cx.layout_of(discr_ty) - }) + ( + bx, + OperandRef { + val: OperandValue::Immediate(discr), + layout: self.cx.layout_of(discr_ty), + }, + ) } mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => { assert!(bx.cx().type_is_sized(ty)); let val = bx.cx().const_usize(bx.cx().layout_of(ty).size.bytes()); let tcx = self.cx.tcx(); - (bx, OperandRef { - val: OperandValue::Immediate(val), - layout: self.cx.layout_of(tcx.types.usize), - }) + ( + bx, + OperandRef { + val: OperandValue::Immediate(val), + layout: self.cx.layout_of(tcx.types.usize), + }, + ) } mir::Rvalue::NullaryOp(mir::NullOp::Box, content_ty) => { @@ -497,35 +511,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let call = bx.call(r, &[llsize, llalign], None); let val = bx.pointercast(call, llty_ptr); - let operand = OperandRef { - val: OperandValue::Immediate(val), - layout: box_layout, - }; + let operand = OperandRef { val: OperandValue::Immediate(val), layout: box_layout }; (bx, operand) } mir::Rvalue::Use(ref operand) => { let operand = self.codegen_operand(&mut bx, operand); (bx, operand) } - mir::Rvalue::Repeat(..) | - mir::Rvalue::Aggregate(..) => { + mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) => { // According to `rvalue_creates_operand`, only ZST // aggregate rvalues are allowed to be operands. let ty = rvalue.ty(*self.mir, self.cx.tcx()); - let operand = OperandRef::new_zst( - &mut bx, - self.cx.layout_of(self.monomorphize(&ty)), - ); + let operand = + OperandRef::new_zst(&mut bx, self.cx.layout_of(self.monomorphize(&ty))); (bx, operand) } } } - fn evaluate_array_len( - &mut self, - bx: &mut Bx, - place: &mir::Place<'tcx>, - ) -> Bx::Value { + fn evaluate_array_len(&mut self, bx: &mut Bx, place: &mir::Place<'tcx>) -> Bx::Value { // ZST are passed as operands and require special handling // because codegen_place() panics if Local is operand. if let Some(index) = place.as_local() { @@ -559,10 +563,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } else { OperandValue::Pair(cg_place.llval, cg_place.llextra.unwrap()) }; - (bx, OperandRef { - val, - layout: self.cx.layout_of(mk_ptr_ty(self.cx.tcx(), ty)), - }) + (bx, OperandRef { val, layout: self.cx.layout_of(mk_ptr_ty(self.cx.tcx(), ty)) }) } pub fn codegen_scalar_binop( @@ -576,52 +577,62 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let is_float = input_ty.is_floating_point(); let is_signed = input_ty.is_signed(); match op { - mir::BinOp::Add => if is_float { - bx.fadd(lhs, rhs) - } else { - bx.add(lhs, rhs) - }, - mir::BinOp::Sub => if is_float { - bx.fsub(lhs, rhs) - } else { - bx.sub(lhs, rhs) - }, - mir::BinOp::Mul => if is_float { - bx.fmul(lhs, rhs) - } else { - bx.mul(lhs, rhs) - }, - mir::BinOp::Div => if is_float { - bx.fdiv(lhs, rhs) - } else if is_signed { - bx.sdiv(lhs, rhs) - } else { - bx.udiv(lhs, rhs) - }, - mir::BinOp::Rem => if is_float { - bx.frem(lhs, rhs) - } else if is_signed { - bx.srem(lhs, rhs) - } else { - bx.urem(lhs, rhs) - }, + mir::BinOp::Add => { + if is_float { + bx.fadd(lhs, rhs) + } else { + bx.add(lhs, rhs) + } + } + mir::BinOp::Sub => { + if is_float { + bx.fsub(lhs, rhs) + } else { + bx.sub(lhs, rhs) + } + } + mir::BinOp::Mul => { + if is_float { + bx.fmul(lhs, rhs) + } else { + bx.mul(lhs, rhs) + } + } + mir::BinOp::Div => { + if is_float { + bx.fdiv(lhs, rhs) + } else if is_signed { + bx.sdiv(lhs, rhs) + } else { + bx.udiv(lhs, rhs) + } + } + mir::BinOp::Rem => { + if is_float { + bx.frem(lhs, rhs) + } else if is_signed { + bx.srem(lhs, rhs) + } else { + bx.urem(lhs, rhs) + } + } mir::BinOp::BitOr => bx.or(lhs, rhs), mir::BinOp::BitAnd => bx.and(lhs, rhs), mir::BinOp::BitXor => bx.xor(lhs, rhs), mir::BinOp::Offset => bx.inbounds_gep(lhs, &[rhs]), mir::BinOp::Shl => common::build_unchecked_lshift(bx, lhs, rhs), mir::BinOp::Shr => common::build_unchecked_rshift(bx, input_ty, lhs, rhs), - mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt | - mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => if is_float { - bx.fcmp( - base::bin_op_to_fcmp_predicate(op.to_hir_binop()), - lhs, rhs - ) - } else { - bx.icmp( - base::bin_op_to_icmp_predicate(op.to_hir_binop(), is_signed), - lhs, rhs - ) + mir::BinOp::Ne + | mir::BinOp::Lt + | mir::BinOp::Gt + | mir::BinOp::Eq + | mir::BinOp::Le + | mir::BinOp::Ge => { + if is_float { + bx.fcmp(base::bin_op_to_fcmp_predicate(op.to_hir_binop()), lhs, rhs) + } else { + bx.icmp(base::bin_op_to_icmp_predicate(op.to_hir_binop(), is_signed), lhs, rhs) + } } } } @@ -647,8 +658,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let rhs = bx.icmp(IntPredicate::IntNE, lhs_extra, rhs_extra); bx.or(lhs, rhs) } - mir::BinOp::Le | mir::BinOp::Lt | - mir::BinOp::Ge | mir::BinOp::Gt => { + mir::BinOp::Le | mir::BinOp::Lt | mir::BinOp::Ge | mir::BinOp::Gt => { // a OP b ~ a.0 STRICT(OP) b.0 | (a.0 == b.0 && a.1 OP a.1) let (op, strict_op) = match op { mir::BinOp::Lt => (IntPredicate::IntULT, IntPredicate::IntULT), @@ -675,7 +685,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { op: mir::BinOp, lhs: Bx::Value, rhs: Bx::Value, - input_ty: Ty<'tcx> + input_ty: Ty<'tcx>, ) -> OperandValue { // This case can currently arise only from functions marked // with #[rustc_inherit_overflow_checks] and inlined from @@ -693,7 +703,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::BinOp::Add => OverflowOp::Add, mir::BinOp::Sub => OverflowOp::Sub, mir::BinOp::Mul => OverflowOp::Mul, - _ => unreachable!() + _ => unreachable!(), }; bx.checked_binop(oop, input_ty, lhs, rhs) } @@ -708,9 +718,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (val, of) } - _ => { - bug!("Operator `{:?}` is not a checkable operator", op) - } + _ => bug!("Operator `{:?}` is not a checkable operator", op), }; OperandValue::Pair(val, of) @@ -748,13 +756,9 @@ fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( signed: bool, x: Bx::Value, float_ty: Bx::Type, - int_ty: Bx::Type + int_ty: Bx::Type, ) -> Bx::Value { - let fptosui_result = if signed { - bx.fptosi(x, int_ty) - } else { - bx.fptoui(x, int_ty) - }; + let fptosui_result = if signed { bx.fptosi(x, int_ty) } else { bx.fptoui(x, int_ty) }; if !bx.cx().sess().opts.debugging_opts.saturating_float_casts { return fptosui_result; @@ -783,30 +787,20 @@ fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // This already happens today with u128::MAX = 2^128 - 1 > f32::MAX. let int_max = |signed: bool, int_width: u64| -> u128 { let shift_amount = 128 - int_width; - if signed { - i128::MAX as u128 >> shift_amount - } else { - u128::MAX >> shift_amount - } + if signed { i128::MAX as u128 >> shift_amount } else { u128::MAX >> shift_amount } }; let int_min = |signed: bool, int_width: u64| -> i128 { - if signed { - i128::MIN >> (128 - int_width) - } else { - 0 - } + if signed { i128::MIN >> (128 - int_width) } else { 0 } }; - let compute_clamp_bounds_single = - |signed: bool, int_width: u64| -> (u128, u128) { + let compute_clamp_bounds_single = |signed: bool, int_width: u64| -> (u128, u128) { let rounded_min = ieee::Single::from_i128_r(int_min(signed, int_width), Round::TowardZero); assert_eq!(rounded_min.status, Status::OK); let rounded_max = ieee::Single::from_u128_r(int_max(signed, int_width), Round::TowardZero); assert!(rounded_max.value.is_finite()); (rounded_min.value.to_bits(), rounded_max.value.to_bits()) }; - let compute_clamp_bounds_double = - |signed: bool, int_width: u64| -> (u128, u128) { + let compute_clamp_bounds_double = |signed: bool, int_width: u64| -> (u128, u128) { let rounded_min = ieee::Double::from_i128_r(int_min(signed, int_width), Round::TowardZero); assert_eq!(rounded_min.status, Status::OK); let rounded_max = ieee::Double::from_u128_r(int_max(signed, int_width), Round::TowardZero); @@ -815,7 +809,7 @@ fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( }; let mut float_bits_to_llval = |bits| { - let bits_llval = match float_width { + let bits_llval = match float_width { 32 => bx.cx().const_u32(bits as u32), 64 => bx.cx().const_u64(bits as u64), n => bug!("unsupported float width {}", n), diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs index 0b82edea15790..48ba64143a708 100644 --- a/src/librustc_codegen_ssa/mir/statement.rs +++ b/src/librustc_codegen_ssa/mir/statement.rs @@ -1,29 +1,23 @@ use rustc::mir; -use crate::traits::BuilderMethods; use super::FunctionCx; use super::LocalRef; use super::OperandValue; +use crate::traits::BuilderMethods; use crate::traits::*; use rustc_error_codes::*; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { - pub fn codegen_statement( - &mut self, - mut bx: Bx, - statement: &mir::Statement<'tcx> - ) -> Bx { + pub fn codegen_statement(&mut self, mut bx: Bx, statement: &mir::Statement<'tcx>) -> Bx { debug!("codegen_statement(statement={:?})", statement); self.set_debug_loc(&mut bx, statement.source_info); match statement.kind { - mir::StatementKind::Assign(box(ref place, ref rvalue)) => { + mir::StatementKind::Assign(box (ref place, ref rvalue)) => { if let Some(index) = place.as_local() { match self.locals[index] { - LocalRef::Place(cg_dest) => { - self.codegen_rvalue(bx, cg_dest, rvalue) - } + LocalRef::Place(cg_dest) => self.codegen_rvalue(bx, cg_dest, rvalue), LocalRef::UnsizedPlace(cg_indirect_dest) => { self.codegen_rvalue_unsized(bx, cg_indirect_dest, rvalue) } @@ -35,9 +29,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } LocalRef::Operand(Some(op)) => { if !op.layout.is_zst() { - span_bug!(statement.source_info.span, - "operand {:?} already assigned", - rvalue); + span_bug!( + statement.source_info.span, + "operand {:?} already assigned", + rvalue + ); } // If the type is zero-sized, it's already been set here, @@ -50,7 +46,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_rvalue(bx, cg_dest, rvalue) } } - mir::StatementKind::SetDiscriminant{box ref place, variant_index} => { + mir::StatementKind::SetDiscriminant { box ref place, variant_index } => { self.codegen_place(&mut bx, &place.as_ref()) .codegen_set_discr(&mut bx, variant_index); bx @@ -72,21 +68,29 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx } mir::StatementKind::InlineAsm(ref asm) => { - let outputs = asm.outputs.iter().map(|output| { - self.codegen_place(&mut bx, &output.as_ref()) - }).collect(); + let outputs = asm + .outputs + .iter() + .map(|output| self.codegen_place(&mut bx, &output.as_ref())) + .collect(); - let input_vals = asm.inputs.iter() - .fold(Vec::with_capacity(asm.inputs.len()), |mut acc, (span, input)| { + let input_vals = asm.inputs.iter().fold( + Vec::with_capacity(asm.inputs.len()), + |mut acc, (span, input)| { let op = self.codegen_operand(&mut bx, input); if let OperandValue::Immediate(_) = op.val { acc.push(op.immediate()); } else { - span_err!(bx.sess(), span.to_owned(), E0669, - "invalid value for constraint in inline assembly"); + span_err!( + bx.sess(), + span.to_owned(), + E0669, + "invalid value for constraint in inline assembly" + ); } acc - }); + }, + ); if input_vals.len() == asm.inputs.len() { let res = bx.codegen_inline_asm( @@ -96,16 +100,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { statement.source_info.span, ); if !res { - span_err!(bx.sess(), statement.source_info.span, E0668, - "malformed inline assembly"); + span_err!( + bx.sess(), + statement.source_info.span, + E0668, + "malformed inline assembly" + ); } } bx } - mir::StatementKind::FakeRead(..) | - mir::StatementKind::Retag { .. } | - mir::StatementKind::AscribeUserType(..) | - mir::StatementKind::Nop => bx, + mir::StatementKind::FakeRead(..) + | mir::StatementKind::Retag { .. } + | mir::StatementKind::AscribeUserType(..) + | mir::StatementKind::Nop => bx, } } } diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs index 10177d2997a76..c57da413fff8a 100644 --- a/src/librustc_codegen_ssa/mono_item.rs +++ b/src/librustc_codegen_ssa/mono_item.rs @@ -1,8 +1,8 @@ +use crate::base; +use crate::traits::*; use rustc::hir; use rustc::mir::mono::{Linkage, Visibility}; use rustc::ty::layout::HasTyCtxt; -use crate::base; -use crate::traits::*; use rustc::mir::mono::MonoItem; @@ -12,17 +12,19 @@ pub trait MonoItemExt<'a, 'tcx> { &self, cx: &'a Bx::CodegenCx, linkage: Linkage, - visibility: Visibility + visibility: Visibility, ); fn to_raw_string(&self) -> String; } impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { fn define>(&self, cx: &'a Bx::CodegenCx) { - debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}", - self.to_string(cx.tcx(), true), - self.to_raw_string(), - cx.codegen_unit().name()); + debug!( + "BEGIN IMPLEMENTING '{} ({})' in cgu {}", + self.to_string(cx.tcx(), true), + self.to_raw_string(), + cx.codegen_unit().name() + ); match *self { MonoItem::Static(def_id) => { @@ -41,22 +43,26 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { } } - debug!("END IMPLEMENTING '{} ({})' in cgu {}", - self.to_string(cx.tcx(), true), - self.to_raw_string(), - cx.codegen_unit().name()); + debug!( + "END IMPLEMENTING '{} ({})' in cgu {}", + self.to_string(cx.tcx(), true), + self.to_raw_string(), + cx.codegen_unit().name() + ); } fn predefine>( &self, cx: &'a Bx::CodegenCx, linkage: Linkage, - visibility: Visibility + visibility: Visibility, ) { - debug!("BEGIN PREDEFINING '{} ({})' in cgu {}", - self.to_string(cx.tcx(), true), - self.to_raw_string(), - cx.codegen_unit().name()); + debug!( + "BEGIN PREDEFINING '{} ({})' in cgu {}", + self.to_string(cx.tcx(), true), + self.to_raw_string(), + cx.codegen_unit().name() + ); let symbol_name = self.symbol_name(cx.tcx()).name.as_str(); @@ -72,25 +78,21 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { MonoItem::GlobalAsm(..) => {} } - debug!("END PREDEFINING '{} ({})' in cgu {}", - self.to_string(cx.tcx(), true), - self.to_raw_string(), - cx.codegen_unit().name()); + debug!( + "END PREDEFINING '{} ({})' in cgu {}", + self.to_string(cx.tcx(), true), + self.to_raw_string(), + cx.codegen_unit().name() + ); } fn to_raw_string(&self) -> String { match *self { MonoItem::Fn(instance) => { - format!("Fn({:?}, {})", - instance.def, - instance.substs.as_ptr() as usize) - } - MonoItem::Static(id) => { - format!("Static({:?})", id) - } - MonoItem::GlobalAsm(id) => { - format!("GlobalAsm({:?})", id) + format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr() as usize) } + MonoItem::Static(id) => format!("Static({:?})", id), + MonoItem::GlobalAsm(id) => format!("GlobalAsm({:?})", id), } } } diff --git a/src/librustc_codegen_ssa/traits/abi.rs b/src/librustc_codegen_ssa/traits/abi.rs index fb44a69ce0552..c564552fcb438 100644 --- a/src/librustc_codegen_ssa/traits/abi.rs +++ b/src/librustc_codegen_ssa/traits/abi.rs @@ -1,5 +1,5 @@ use super::BackendTypes; -use rustc::ty::{Ty}; +use rustc::ty::Ty; use rustc_target::abi::call::FnAbi; pub trait AbiBuilderMethods<'tcx>: BackendTypes { diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index cfaa6756261e4..595872bd04d2f 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -1,17 +1,17 @@ use super::write::WriteBackendMethods; use super::CodegenObject; +use rustc::middle::cstore::EncodedMetadata; +use rustc::session::{config, Session}; use rustc::ty::layout::{HasTyCtxt, LayoutOf, TyLayout}; use rustc::ty::Ty; -use rustc::middle::cstore::EncodedMetadata; -use rustc::session::{Session, config}; use rustc::ty::TyCtxt; use rustc_codegen_utils::codegen_backend::CodegenBackend; use syntax::expand::allocator::AllocatorKind; use syntax_pos::symbol::Symbol; -use std::sync::Arc; use std::sync::mpsc; +use std::sync::Arc; pub trait BackendTypes { type Value: CodegenObject; diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 31044d4eb4f27..6f331e14a0d37 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -5,18 +5,19 @@ use super::intrinsic::IntrinsicCallMethods; use super::type_::ArgAbiMethods; use super::{HasCodegen, StaticBuilderMethods}; -use crate::common::{AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, - SynchronizationScope}; +use crate::common::{ + AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, +}; use crate::mir::operand::OperandRef; use crate::mir::place::PlaceRef; use crate::MemFlags; +use rustc::ty::layout::{Align, HasParamEnv, Size}; use rustc::ty::Ty; -use rustc::ty::layout::{Align, Size, HasParamEnv}; use rustc_target::spec::HasTargetSpec; -use std::ops::Range; use std::iter::TrustedLen; +use std::ops::Range; #[derive(Copy, Clone)] pub enum OverflowOp { @@ -35,7 +36,6 @@ pub trait BuilderMethods<'a, 'tcx>: + StaticBuilderMethods + HasParamEnv<'tcx> + HasTargetSpec - { fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Function, name: &'b str) -> Self; fn with_cx(cx: &'a Self::CodegenCx) -> Self; @@ -114,20 +114,15 @@ pub trait BuilderMethods<'a, 'tcx>: 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; + fn array_alloca(&mut self, ty: Self::Type, len: Self::Value, align: Align) -> Self::Value; fn load(&mut self, ptr: Self::Value, align: Align) -> Self::Value; fn volatile_load(&mut self, ptr: Self::Value) -> Self::Value; fn atomic_load(&mut self, ptr: Self::Value, order: AtomicOrdering, size: Size) -> Self::Value; fn load_operand(&mut self, place: PlaceRef<'tcx, Self::Value>) - -> OperandRef<'tcx, Self::Value>; + -> OperandRef<'tcx, Self::Value>; - /// Called for Rvalue::Repeat when the elem is neither a ZST nor optimizable using memset. + /// Called for Rvalue::Repeat when the elem is neither a ZST nor optimizable using memset. fn write_operand_repeatedly( self, elem: OperandRef<'tcx, Self::Value>, diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index e67201b710698..d78571b140f23 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -2,8 +2,8 @@ use super::BackendTypes; use crate::mir::debuginfo::{FunctionDebugContext, VariableKind}; use rustc::hir::def_id::CrateNum; use rustc::mir; -use rustc::ty::{Ty, Instance}; use rustc::ty::layout::Size; +use rustc::ty::{Instance, Ty}; use rustc_target::abi::call::FnAbi; use syntax::ast::Name; use syntax_pos::{SourceFile, Span}; diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/src/librustc_codegen_ssa/traits/mod.rs index 9b673de8b0788..fff1b35507ce6 100644 --- a/src/librustc_codegen_ssa/traits/mod.rs +++ b/src/librustc_codegen_ssa/traits/mod.rs @@ -27,7 +27,7 @@ mod statics; mod type_; mod write; -pub use self::abi::{AbiBuilderMethods}; +pub use self::abi::AbiBuilderMethods; pub use self::asm::{AsmBuilderMethods, AsmMethods}; pub use self::backend::{Backend, BackendTypes, ExtraBackendMethods}; pub use self::builder::{BuilderMethods, OverflowOp}; @@ -36,7 +36,7 @@ pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods}; pub use self::declare::{DeclareMethods, PreDefineMethods}; pub use self::intrinsic::IntrinsicCallMethods; pub use self::misc::MiscMethods; -pub use self::statics::{StaticMethods, StaticBuilderMethods}; +pub use self::statics::{StaticBuilderMethods, StaticMethods}; pub use self::type_::{ ArgAbiMethods, BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods, TypeMethods, }; diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs index f074d4479fab4..6059a6d5b6c19 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -3,8 +3,8 @@ use super::Backend; use super::HasCodegen; use crate::common::TypeKind; use crate::mir::place::PlaceRef; -use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, TyLayout}; +use rustc::ty::{self, Ty}; use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg}; use syntax_pos::DUMMY_SP; diff --git a/src/librustc_codegen_ssa/traits/write.rs b/src/librustc_codegen_ssa/traits/write.rs index 23bb7179557b9..382dc14e789ce 100644 --- a/src/librustc_codegen_ssa/traits/write.rs +++ b/src/librustc_codegen_ssa/traits/write.rs @@ -1,5 +1,5 @@ use crate::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; -use crate::back::write::{CodegenContext, ModuleConfig, FatLTOInput}; +use crate::back::write::{CodegenContext, FatLTOInput, ModuleConfig}; use crate::{CompiledModule, ModuleCodegen}; use rustc::dep_graph::WorkProduct; @@ -45,12 +45,8 @@ pub trait WriteBackendMethods: 'static + Sized + Clone { module: ModuleCodegen, config: &ModuleConfig, ) -> Result; - fn prepare_thin( - module: ModuleCodegen - ) -> (String, Self::ThinBuffer); - fn serialize_module( - module: ModuleCodegen - ) -> (String, Self::ModuleBuffer); + fn prepare_thin(module: ModuleCodegen) -> (String, Self::ThinBuffer); + fn serialize_module(module: ModuleCodegen) -> (String, Self::ModuleBuffer); fn run_lto_pass_manager( cgcx: &CodegenContext, llmod: &ModuleCodegen, diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs index 0e2c3731eae6d..0737fd6b5ca23 100644 --- a/src/librustc_codegen_utils/codegen_backend.rs +++ b/src/librustc_codegen_utils/codegen_backend.rs @@ -8,21 +8,23 @@ use std::any::Any; -use syntax::symbol::Symbol; -use rustc::session::Session; -use rustc::util::common::ErrorReported; +use rustc::dep_graph::DepGraph; +use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; use rustc::session::config::{OutputFilenames, PrintRequest}; -use rustc::ty::TyCtxt; +use rustc::session::Session; use rustc::ty::query::Providers; -use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; -use rustc::dep_graph::DepGraph; +use rustc::ty::TyCtxt; +use rustc::util::common::ErrorReported; +use syntax::symbol::Symbol; pub use rustc_data_structures::sync::MetadataRef; pub trait CodegenBackend { fn init(&self, _sess: &Session) {} fn print(&self, _req: PrintRequest, _sess: &Session) {} - fn target_features(&self, _sess: &Session) -> Vec { vec![] } + fn target_features(&self, _sess: &Session) -> Vec { + vec![] + } fn print_passes(&self) {} fn print_version(&self) {} diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index fb2099e71a31a..578aa591b5c98 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -3,7 +3,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] - #![feature(arbitrary_self_types)] #![feature(box_patterns)] #![feature(box_syntax)] @@ -11,27 +10,25 @@ #![feature(never_type)] #![feature(nll)] #![feature(in_band_lifetimes)] - -#![recursion_limit="256"] +#![recursion_limit = "256"] #[macro_use] extern crate rustc; -use rustc::ty::TyCtxt; +use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::ty::query::Providers; -use rustc::hir::def_id::{LOCAL_CRATE, DefId}; +use rustc::ty::TyCtxt; use syntax::symbol::sym; -pub mod link; pub mod codegen_backend; +pub mod link; pub mod symbol_names; pub mod symbol_names_test; - pub fn trigger_delay_span_bug(tcx: TyCtxt<'_>, key: DefId) { tcx.sess.delay_span_bug( tcx.def_span(key), - "delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]" + "delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]", ); } @@ -48,8 +45,8 @@ pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) { // check if there is a #[rustc_error(delayed)] Some(list) => { if list.iter().any(|list_item| { - list_item.ident().map(|i| i.name) == - Some(sym::delay_span_bug_from_inside_query) + list_item.ident().map(|i| i.name) + == Some(sym::delay_span_bug_from_inside_query) }) { tcx.ensure().trigger_delay_span_bug(def_id); } @@ -58,7 +55,7 @@ pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) { None => { tcx.sess.span_fatal( tcx.def_span(def_id), - "fatal error triggered by #[rustc_error]" + "fatal error triggered by #[rustc_error]", ); } } @@ -69,8 +66,5 @@ pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) { pub fn provide(providers: &mut Providers<'_>) { crate::symbol_names::provide(providers); - *providers = Providers { - trigger_delay_span_bug, - ..*providers - }; + *providers = Providers { trigger_delay_span_bug, ..*providers }; } diff --git a/src/librustc_codegen_utils/link.rs b/src/librustc_codegen_utils/link.rs index 6b9258c32e7b0..89a68d775f20f 100644 --- a/src/librustc_codegen_utils/link.rs +++ b/src/librustc_codegen_utils/link.rs @@ -1,20 +1,23 @@ -use rustc::session::config::{self, OutputFilenames, Input, OutputType}; +use rustc::session::config::{self, Input, OutputFilenames, OutputType}; use rustc::session::Session; use std::path::{Path, PathBuf}; -use syntax::{ast, attr}; use syntax::symbol::sym; +use syntax::{ast, attr}; use syntax_pos::Span; -pub fn out_filename(sess: &Session, - crate_type: config::CrateType, - outputs: &OutputFilenames, - crate_name: &str) - -> PathBuf { +pub fn out_filename( + sess: &Session, + crate_type: config::CrateType, + outputs: &OutputFilenames, + crate_name: &str, +) -> PathBuf { let default_filename = filename_for_input(sess, crate_type, crate_name, outputs); - let out_filename = outputs.outputs.get(&OutputType::Exe) - .and_then(|s| s.to_owned()) - .or_else(|| outputs.single_output_file.clone()) - .unwrap_or(default_filename); + let out_filename = outputs + .outputs + .get(&OutputType::Exe) + .and_then(|s| s.to_owned()) + .or_else(|| outputs.single_output_file.clone()) + .unwrap_or(default_filename); check_file_is_writeable(&out_filename, sess); @@ -26,21 +29,22 @@ pub fn out_filename(sess: &Session, // read-only file. We should be consistent. pub fn check_file_is_writeable(file: &Path, sess: &Session) { if !is_writeable(file) { - sess.fatal(&format!("output file {} is not writeable -- check its \ - permissions", file.display())); + sess.fatal(&format!( + "output file {} is not writeable -- check its \ + permissions", + file.display() + )); } } fn is_writeable(p: &Path) -> bool { match p.metadata() { Err(..) => true, - Ok(m) => !m.permissions().readonly() + Ok(m) => !m.permissions().readonly(), } } -pub fn find_crate_name(sess: Option<&Session>, - attrs: &[ast::Attribute], - input: &Input) -> String { +pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input: &Input) -> String { let validate = |s: String, span: Option| { rustc_metadata::validate_crate_name(sess, &s, span); s @@ -50,16 +54,18 @@ pub fn find_crate_name(sess: Option<&Session>, // as used. After doing this, however, we still prioritize a crate name from // the command line over one found in the #[crate_name] attribute. If we // find both we ensure that they're the same later on as well. - let attr_crate_name = attr::find_by_name(attrs, sym::crate_name) - .and_then(|at| at.value_str().map(|s| (at, s))); + let attr_crate_name = + attr::find_by_name(attrs, sym::crate_name).and_then(|at| at.value_str().map(|s| (at, s))); if let Some(sess) = sess { if let Some(ref s) = sess.opts.crate_name { if let Some((attr, name)) = attr_crate_name { if name.as_str() != *s { - let msg = format!("`--crate-name` and `#[crate_name]` are \ + let msg = format!( + "`--crate-name` and `#[crate_name]` are \ required to match, but `{}` != `{}`", - s, name); + s, name + ); sess.span_err(attr.span, &msg); } } @@ -73,8 +79,11 @@ pub fn find_crate_name(sess: Option<&Session>, if let Input::File(ref path) = *input { if let Some(s) = path.file_stem().and_then(|s| s.to_str()) { if s.starts_with("-") { - let msg = format!("crate names cannot start with a `-`, but \ - `{}` has a leading hyphen", s); + let msg = format!( + "crate names cannot start with a `-`, but \ + `{}` has a leading hyphen", + s + ); if let Some(sess) = sess { sess.err(&msg); } @@ -87,12 +96,16 @@ pub fn find_crate_name(sess: Option<&Session>, "rust_out".to_string() } -pub fn filename_for_metadata(sess: &Session, - crate_name: &str, - outputs: &OutputFilenames) -> PathBuf { +pub fn filename_for_metadata( + sess: &Session, + crate_name: &str, + outputs: &OutputFilenames, +) -> PathBuf { let libname = format!("{}{}", crate_name, sess.opts.cg.extra_filename); - let out_filename = outputs.single_output_file.clone() + let out_filename = outputs + .single_output_file + .clone() .unwrap_or_else(|| outputs.out_directory.join(&format!("lib{}.rmeta", libname))); check_file_is_writeable(&out_filename, sess); @@ -100,38 +113,32 @@ pub fn filename_for_metadata(sess: &Session, out_filename } -pub fn filename_for_input(sess: &Session, - crate_type: config::CrateType, - crate_name: &str, - outputs: &OutputFilenames) -> PathBuf { +pub fn filename_for_input( + sess: &Session, + crate_type: config::CrateType, + crate_name: &str, + outputs: &OutputFilenames, +) -> PathBuf { let libname = format!("{}{}", crate_name, sess.opts.cg.extra_filename); match crate_type { - config::CrateType::Rlib => { - outputs.out_directory.join(&format!("lib{}.rlib", libname)) - } - config::CrateType::Cdylib | - config::CrateType::ProcMacro | - config::CrateType::Dylib => { - let (prefix, suffix) = (&sess.target.target.options.dll_prefix, - &sess.target.target.options.dll_suffix); - outputs.out_directory.join(&format!("{}{}{}", prefix, libname, - suffix)) + config::CrateType::Rlib => outputs.out_directory.join(&format!("lib{}.rlib", libname)), + config::CrateType::Cdylib | config::CrateType::ProcMacro | config::CrateType::Dylib => { + let (prefix, suffix) = + (&sess.target.target.options.dll_prefix, &sess.target.target.options.dll_suffix); + outputs.out_directory.join(&format!("{}{}{}", prefix, libname, suffix)) } config::CrateType::Staticlib => { - let (prefix, suffix) = (&sess.target.target.options.staticlib_prefix, - &sess.target.target.options.staticlib_suffix); - outputs.out_directory.join(&format!("{}{}{}", prefix, libname, - suffix)) + let (prefix, suffix) = ( + &sess.target.target.options.staticlib_prefix, + &sess.target.target.options.staticlib_suffix, + ); + outputs.out_directory.join(&format!("{}{}{}", prefix, libname, suffix)) } config::CrateType::Executable => { let suffix = &sess.target.target.options.exe_suffix; let out_filename = outputs.path(OutputType::Exe); - if suffix.is_empty() { - out_filename - } else { - out_filename.with_extension(&suffix[1..]) - } + if suffix.is_empty() { out_filename } else { out_filename.with_extension(&suffix[1..]) } } } } @@ -154,17 +161,14 @@ pub fn default_output_for_target(sess: &Session) -> config::CrateType { } /// Checks if target supports crate_type as output -pub fn invalid_output_for_target(sess: &Session, - crate_type: config::CrateType) -> bool { +pub fn invalid_output_for_target(sess: &Session, crate_type: config::CrateType) -> bool { match crate_type { - config::CrateType::Cdylib | - config::CrateType::Dylib | - config::CrateType::ProcMacro => { + config::CrateType::Cdylib | config::CrateType::Dylib | config::CrateType::ProcMacro => { if !sess.target.target.options.dynamic_linking { - return true + return true; } if sess.crt_static() && !sess.target.target.options.crt_static_allows_dylibs { - return true + return true; } } _ => {} @@ -177,7 +181,7 @@ pub fn invalid_output_for_target(sess: &Session, } if !sess.target.target.options.executables { if crate_type == config::CrateType::Executable { - return true + return true; } } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 922964ee45f6b..bd714f5c6b715 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -88,12 +88,12 @@ //! DefPaths which are much more robust in the face of changes to the code base. use rustc::hir::def_id::LOCAL_CRATE; -use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; +use rustc::hir::Node; +use rustc::mir::mono::{InstantiationMode, MonoItem}; use rustc::session::config::SymbolManglingVersion; use rustc::ty::query::Providers; -use rustc::ty::{self, TyCtxt, Instance}; -use rustc::mir::mono::{MonoItem, InstantiationMode}; +use rustc::ty::{self, Instance, TyCtxt}; use syntax_pos::symbol::Symbol; @@ -104,9 +104,7 @@ mod v0; pub fn provide(providers: &mut Providers<'_>) { *providers = Providers { - symbol_name: |tcx, instance| ty::SymbolName { - name: symbol_name(tcx, instance), - }, + symbol_name: |tcx, instance| ty::SymbolName { name: symbol_name(tcx, instance) }, ..*providers }; @@ -160,8 +158,8 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Symbol { // // [1]: https://bugs.llvm.org/show_bug.cgi?id=44316 if is_foreign { - if tcx.sess.target.target.arch != "wasm32" || - !tcx.wasm_import_module_map(def_id.krate).contains_key(&def_id) + if tcx.sess.target.target.arch != "wasm32" + || !tcx.wasm_import_module_map(def_id.krate).contains_key(&def_id) { if let Some(name) = attrs.link_name { return name; diff --git a/src/librustc_codegen_utils/symbol_names/legacy.rs b/src/librustc_codegen_utils/symbol_names/legacy.rs index 1597f98771c0a..29869a1dae4f3 100644 --- a/src/librustc_codegen_utils/symbol_names/legacy.rs +++ b/src/librustc_codegen_utils/symbol_names/legacy.rs @@ -2,9 +2,9 @@ use rustc::hir::def_id::CrateNum; use rustc::hir::map::{DefPathData, DisambiguatedDefPathData}; use rustc::ich::NodeIdHashingMode; use rustc::mir::interpret::{ConstValue, Scalar}; -use rustc::ty::print::{PrettyPrinter, Printer, Print}; +use rustc::ty::print::{PrettyPrinter, Print, Printer}; use rustc::ty::subst::{GenericArg, GenericArgKind}; -use rustc::ty::{self, Ty, TyCtxt, TypeFoldable, Instance}; +use rustc::ty::{self, Instance, Ty, TyCtxt, TypeFoldable}; use rustc::util::common::record_time; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -55,11 +55,9 @@ pub(super) fn mangle( let hash = get_symbol_hash(tcx, instance, instance_ty, instantiating_crate); - let mut printer = SymbolPrinter { - tcx, - path: SymbolPath::new(), - keep_within_component: false, - }.print_def_path(def_id, &[]).unwrap(); + let mut printer = SymbolPrinter { tcx, path: SymbolPath::new(), keep_within_component: false } + .print_def_path(def_id, &[]) + .unwrap(); if instance.is_vtable_shim() { let _ = printer.write_str("{{vtable-shim}}"); @@ -84,10 +82,7 @@ fn get_symbol_hash<'tcx>( ) -> u64 { let def_id = instance.def_id(); let substs = instance.substs; - debug!( - "get_symbol_hash(def_id={:?}, parameters={:?})", - def_id, substs - ); + debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs); let mut hasher = StableHasher::new(); let mut hcx = tcx.create_stable_hashing_context(); @@ -121,10 +116,10 @@ fn get_symbol_hash<'tcx>( substs.hash_stable(&mut hcx, &mut hasher); if let Some(instantiating_crate) = instantiating_crate { - tcx.original_crate_name(instantiating_crate).as_str() - .hash_stable(&mut hcx, &mut hasher); - tcx.crate_disambiguator(instantiating_crate) + tcx.original_crate_name(instantiating_crate) + .as_str() .hash_stable(&mut hcx, &mut hasher); + tcx.crate_disambiguator(instantiating_crate).hash_stable(&mut hcx, &mut hasher); } // We want to avoid accidental collision between different types of instances. @@ -157,10 +152,8 @@ struct SymbolPath { impl SymbolPath { fn new() -> Self { - let mut result = SymbolPath { - result: String::with_capacity(64), - temp_buf: String::with_capacity(16), - }; + let mut result = + SymbolPath { result: String::with_capacity(64), temp_buf: String::with_capacity(16) }; result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested result } @@ -208,27 +201,19 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> { self.tcx } - fn print_region( - self, - _region: ty::Region<'_>, - ) -> Result { + fn print_region(self, _region: ty::Region<'_>) -> Result { Ok(self) } - fn print_type( - self, - ty: Ty<'tcx>, - ) -> Result { + fn print_type(self, ty: Ty<'tcx>) -> Result { match ty.kind { // Print all nominal types as paths (unlike `pretty_print_type`). - ty::FnDef(def_id, substs) | - ty::Opaque(def_id, substs) | - ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs }) | - ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs }) | - ty::Closure(def_id, substs) | - ty::Generator(def_id, substs, _) => { - self.print_def_path(def_id, substs) - } + ty::FnDef(def_id, substs) + | ty::Opaque(def_id, substs) + | ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs }) + | ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs }) + | ty::Closure(def_id, substs) + | ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs), _ => self.pretty_print_type(ty), } } @@ -248,10 +233,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> { Ok(self) } - fn print_const( - mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result { + fn print_const(mut self, ct: &'tcx ty::Const<'tcx>) -> Result { // only print integers if let ty::ConstKind::Value(ConstValue::Scalar(Scalar::Raw { .. })) = ct.val { if ct.ty.is_integral() { @@ -262,10 +244,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> { Ok(self) } - fn path_crate( - mut self, - cnum: CrateNum, - ) -> Result { + fn path_crate(mut self, cnum: CrateNum) -> Result { self.write_str(&self.tcx.original_crate_name(cnum).as_str())?; Ok(self) } @@ -277,18 +256,18 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> { // Similar to `pretty_path_qualified`, but for the other // types that are printed as paths (see `print_type` above). match self_ty.kind { - ty::FnDef(..) | - ty::Opaque(..) | - ty::Projection(_) | - ty::UnnormalizedProjection(_) | - ty::Closure(..) | - ty::Generator(..) + ty::FnDef(..) + | ty::Opaque(..) + | ty::Projection(_) + | ty::UnnormalizedProjection(_) + | ty::Closure(..) + | ty::Generator(..) if trait_ref.is_none() => { self.print_type(self_ty) } - _ => self.pretty_path_qualified(self_ty, trait_ref) + _ => self.pretty_path_qualified(self_ty, trait_ref), } } @@ -343,14 +322,12 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> { mut self, print_prefix: impl FnOnce(Self) -> Result, args: &[GenericArg<'tcx>], - ) -> Result { + ) -> Result { self = print_prefix(self)?; - let args = args.iter().cloned().filter(|arg| { - match arg.unpack() { - GenericArgKind::Lifetime(_) => false, - _ => true, - } + let args = args.iter().cloned().filter(|arg| match arg.unpack() { + GenericArgKind::Lifetime(_) => false, + _ => true, }); if args.clone().next().is_some() { @@ -362,10 +339,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> { } impl PrettyPrinter<'tcx> for SymbolPrinter<'tcx> { - fn region_should_not_be_omitted( - &self, - _region: ty::Region<'_>, - ) -> bool { + fn region_should_not_be_omitted(&self, _region: ty::Region<'_>) -> bool { false } fn comma_sep(mut self, mut elems: impl Iterator) -> Result @@ -388,8 +362,7 @@ impl PrettyPrinter<'tcx> for SymbolPrinter<'tcx> { ) -> Result { write!(self, "<")?; - let kept_within_component = - mem::replace(&mut self.keep_within_component, true); + let kept_within_component = mem::replace(&mut self.keep_within_component, true); self = f(self)?; self.keep_within_component = kept_within_component; diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs index 893aea16fd2b9..7cb3050576c76 100644 --- a/src/librustc_codegen_utils/symbol_names_test.rs +++ b/src/librustc_codegen_utils/symbol_names_test.rs @@ -5,8 +5,8 @@ //! paths etc in all kinds of annoying scenarios. use rustc::hir; -use rustc::ty::{TyCtxt, Instance}; -use syntax::symbol::{Symbol, sym}; +use rustc::ty::{Instance, TyCtxt}; +use syntax::symbol::{sym, Symbol}; const SYMBOL_NAME: Symbol = sym::rustc_symbol_name; const DEF_PATH: Symbol = sym::rustc_def_path; @@ -30,8 +30,7 @@ struct SymbolNamesTest<'tcx> { } impl SymbolNamesTest<'tcx> { - fn process_attrs(&mut self, - hir_id: hir::HirId) { + fn process_attrs(&mut self, hir_id: hir::HirId) { let tcx = self.tcx; let def_id = tcx.hir().local_def_id(hir_id); for attr in tcx.get_attrs(def_id).iter() { diff --git a/src/librustc_data_structures/base_n.rs b/src/librustc_data_structures/base_n.rs index 9b63a892b8c93..3c7bea2712409 100644 --- a/src/librustc_data_structures/base_n.rs +++ b/src/librustc_data_structures/base_n.rs @@ -1,6 +1,5 @@ /// Converts unsigned integers into a string representation with some base. /// Bases up to and including 36 can be used for case-insensitive things. - use std::str; #[cfg(test)] diff --git a/src/librustc_data_structures/base_n/tests.rs b/src/librustc_data_structures/base_n/tests.rs index 0b0a8c5e256e4..a86f991cd0e0d 100644 --- a/src/librustc_data_structures/base_n/tests.rs +++ b/src/librustc_data_structures/base_n/tests.rs @@ -15,7 +15,7 @@ fn test_encode() { test(u64::max_value() as u128, base); test(u128::max_value(), base); - for i in 0 .. 1_000 { + for i in 0..1_000 { test(i * 983, base); } } diff --git a/src/librustc_data_structures/box_region.rs b/src/librustc_data_structures/box_region.rs index 278dcdf2bee42..94abb89503c03 100644 --- a/src/librustc_data_structures/box_region.rs +++ b/src/librustc_data_structures/box_region.rs @@ -1,7 +1,7 @@ use std::cell::Cell; use std::marker::PhantomData; -use std::pin::Pin; use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; #[derive(Copy, Clone)] pub struct AccessAction(*mut dyn FnMut()); @@ -21,23 +21,19 @@ pub enum Action { thread_local!(pub static BOX_REGION_ARG: Cell = Cell::new(Action::Complete)); pub struct PinnedGenerator { - generator: Pin, Return = R>>> + generator: Pin, Return = R>>>, } impl PinnedGenerator { - pub fn new< - T: Generator, Return = R> + 'static - >(generator: T) -> (I, Self) { - let mut result = PinnedGenerator { - generator: Box::pin(generator) - }; + pub fn new, Return = R> + 'static>( + generator: T, + ) -> (I, Self) { + let mut result = PinnedGenerator { generator: Box::pin(generator) }; // Run it to the first yield to set it up let init = match Pin::new(&mut result.generator).resume() { - GeneratorState::Yielded( - YieldType::Initial(y) - ) => y, - _ => panic!() + GeneratorState::Yielded(YieldType::Initial(y)) => y, + _ => panic!(), }; (init, result) @@ -56,16 +52,10 @@ impl PinnedGenerator { pub fn complete(&mut self) -> R { // Tell the generator we want it to complete, consuming it and yielding a result - BOX_REGION_ARG.with(|i| { - i.set(Action::Complete) - }); + BOX_REGION_ARG.with(|i| i.set(Action::Complete)); let result = Pin::new(&mut self.generator).resume(); - if let GeneratorState::Complete(r) = result { - r - } else { - panic!() - } + if let GeneratorState::Complete(r) = result { r } else { panic!() } } } diff --git a/src/librustc_data_structures/const_cstr.rs b/src/librustc_data_structures/const_cstr.rs index fbe2f29f706f6..1ebcb87818ecf 100644 --- a/src/librustc_data_structures/const_cstr.rs +++ b/src/librustc_data_structures/const_cstr.rs @@ -16,7 +16,7 @@ /// builds. #[macro_export] macro_rules! const_cstr { - ($s:expr) => ({ + ($s:expr) => {{ use std::ffi::CStr; let str_plus_nul = concat!($s, "\0"); @@ -24,9 +24,7 @@ macro_rules! const_cstr { if cfg!(debug_assertions) { CStr::from_bytes_with_nul(str_plus_nul.as_bytes()).unwrap() } else { - unsafe { - CStr::from_bytes_with_nul_unchecked(str_plus_nul.as_bytes()) - } + unsafe { CStr::from_bytes_with_nul_unchecked(str_plus_nul.as_bytes()) } } - }) + }}; } diff --git a/src/librustc_data_structures/fingerprint.rs b/src/librustc_data_structures/fingerprint.rs index b43df6045d6aa..282626611d50b 100644 --- a/src/librustc_data_structures/fingerprint.rs +++ b/src/librustc_data_structures/fingerprint.rs @@ -1,12 +1,11 @@ use crate::stable_hasher; +use rustc_serialize::opaque::{Decoder, EncodeResult, Encoder}; use std::mem; -use rustc_serialize::opaque::{EncodeResult, Encoder, Decoder}; #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)] pub struct Fingerprint(u64, u64); impl Fingerprint { - pub const ZERO: Fingerprint = Fingerprint(0, 0); #[inline] @@ -30,7 +29,7 @@ impl Fingerprint { // implemented this way. Fingerprint( self.0.wrapping_mul(3).wrapping_add(other.0), - self.1.wrapping_mul(3).wrapping_add(other.1) + self.1.wrapping_mul(3).wrapping_add(other.1), ) } @@ -84,9 +83,9 @@ impl stable_hasher::StableHasherResult for Fingerprint { impl_stable_hash_via_hash!(Fingerprint); -impl rustc_serialize::UseSpecializedEncodable for Fingerprint { } +impl rustc_serialize::UseSpecializedEncodable for Fingerprint {} -impl rustc_serialize::UseSpecializedDecodable for Fingerprint { } +impl rustc_serialize::UseSpecializedDecodable for Fingerprint {} impl rustc_serialize::SpecializedEncoder for Encoder { fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> { diff --git a/src/librustc_data_structures/fx.rs b/src/librustc_data_structures/fx.rs index cf73fe8cf85ce..a9e8c2edbff9e 100644 --- a/src/librustc_data_structures/fx.rs +++ b/src/librustc_data_structures/fx.rs @@ -1,6 +1,6 @@ use std::hash::BuildHasherDefault; -pub use rustc_hash::{FxHasher, FxHashMap, FxHashSet}; +pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; pub type FxIndexMap = indexmap::IndexMap>; pub type FxIndexSet = indexmap::IndexSet>; diff --git a/src/librustc_data_structures/graph/dominators/mod.rs b/src/librustc_data_structures/graph/dominators/mod.rs index 5fb58eea3819d..5283bd78a3029 100644 --- a/src/librustc_data_structures/graph/dominators/mod.rs +++ b/src/librustc_data_structures/graph/dominators/mod.rs @@ -4,9 +4,9 @@ //! Rice Computer Science TS-06-33870 //! -use rustc_index::vec::{Idx, IndexVec}; use super::iterate::reverse_post_order; use super::ControlFlowGraph; +use rustc_index::vec::{Idx, IndexVec}; use std::borrow::BorrowMut; #[cfg(test)] @@ -60,10 +60,7 @@ fn dominators_given_rpo>( } } - Dominators { - post_order_rank, - immediate_dominators, - } + Dominators { post_order_rank, immediate_dominators } } fn intersect( @@ -103,10 +100,7 @@ impl Dominators { pub fn dominators(&self, node: Node) -> Iter<'_, Node> { assert!(self.is_reachable(node), "node {:?} is not reachable", node); - Iter { - dominators: self, - node: Some(node), - } + Iter { dominators: self, node: Some(node) } } pub fn is_dominated_by(&self, node: Node, dom: Node) -> bool { diff --git a/src/librustc_data_structures/graph/dominators/tests.rs b/src/librustc_data_structures/graph/dominators/tests.rs index 92301ff6526d1..1160df5186b36 100644 --- a/src/librustc_data_structures/graph/dominators/tests.rs +++ b/src/librustc_data_structures/graph/dominators/tests.rs @@ -17,9 +17,10 @@ fn diamond() { #[test] fn paper() { // example from the paper: - let graph = TestGraph::new(6, - &[(6, 5), (6, 4), (5, 1), (4, 2), (4, 3), (1, 2), (2, 3), (3, 2), - (2, 1)]); + let graph = TestGraph::new( + 6, + &[(6, 5), (6, 4), (5, 1), (4, 2), (4, 3), (1, 2), (2, 3), (3, 2), (2, 1)], + ); let dominators = dominators(&graph); let immediate_dominators = &dominators.immediate_dominators; diff --git a/src/librustc_data_structures/graph/implementation/mod.rs b/src/librustc_data_structures/graph/implementation/mod.rs index 9fdcea6df88c5..f705c2f0b75f3 100644 --- a/src/librustc_data_structures/graph/implementation/mod.rs +++ b/src/librustc_data_structures/graph/implementation/mod.rs @@ -20,8 +20,8 @@ //! the field `next_edge`). Each of those fields is an array that should //! be indexed by the direction (see the type `Direction`). -use rustc_index::bit_set::BitSet; use crate::snapshot_vec::{SnapshotVec, SnapshotVecDelegate}; +use rustc_index::bit_set::BitSet; use std::fmt::Debug; use std::usize; @@ -87,17 +87,11 @@ impl NodeIndex { impl Graph { pub fn new() -> Graph { - Graph { - nodes: SnapshotVec::new(), - edges: SnapshotVec::new(), - } + Graph { nodes: SnapshotVec::new(), edges: SnapshotVec::new() } } pub fn with_capacity(nodes: usize, edges: usize) -> Graph { - Graph { - nodes: SnapshotVec::with_capacity(nodes), - edges: SnapshotVec::with_capacity(edges), - } + Graph { nodes: SnapshotVec::with_capacity(nodes), edges: SnapshotVec::with_capacity(edges) } } // # Simple accessors @@ -130,10 +124,7 @@ impl Graph { pub fn add_node(&mut self, data: N) -> NodeIndex { let idx = self.next_node_index(); - self.nodes.push(Node { - first_edge: [INVALID_EDGE_INDEX, INVALID_EDGE_INDEX], - data, - }); + self.nodes.push(Node { first_edge: [INVALID_EDGE_INDEX, INVALID_EDGE_INDEX], data }); idx } @@ -166,12 +157,7 @@ impl Graph { // create the new edge, with the previous firsts from each node // as the next pointers - self.edges.push(Edge { - next_edge: [source_first, target_first], - source, - target, - data, - }); + self.edges.push(Edge { next_edge: [source_first, target_first], source, target, data }); // adjust the firsts for each node target be the next object. self.nodes[source.0].first_edge[OUTGOING.repr] = idx; @@ -187,29 +173,21 @@ impl Graph { // # Iterating over nodes, edges pub fn enumerated_nodes(&self) -> impl Iterator)> { - self.nodes - .iter() - .enumerate() - .map(|(idx, n)| (NodeIndex(idx), n)) + self.nodes.iter().enumerate().map(|(idx, n)| (NodeIndex(idx), n)) } pub fn enumerated_edges(&self) -> impl Iterator)> { - self.edges - .iter() - .enumerate() - .map(|(idx, e)| (EdgeIndex(idx), e)) + self.edges.iter().enumerate().map(|(idx, e)| (EdgeIndex(idx), e)) } pub fn each_node<'a>(&'a self, mut f: impl FnMut(NodeIndex, &'a Node) -> bool) -> bool { //! Iterates over all edges defined in the graph. - self.enumerated_nodes() - .all(|(node_idx, node)| f(node_idx, node)) + self.enumerated_nodes().all(|(node_idx, node)| f(node_idx, node)) } pub fn each_edge<'a>(&'a self, mut f: impl FnMut(EdgeIndex, &'a Edge) -> bool) -> bool { //! Iterates over all edges defined in the graph - self.enumerated_edges() - .all(|(edge_idx, edge)| f(edge_idx, edge)) + self.enumerated_edges().all(|(edge_idx, edge)| f(edge_idx, edge)) } pub fn outgoing_edges(&self, source: NodeIndex) -> AdjacentEdges<'_, N, E> { @@ -223,14 +201,10 @@ impl Graph { pub fn adjacent_edges( &self, source: NodeIndex, - direction: Direction + direction: Direction, ) -> AdjacentEdges<'_, N, E> { let first_edge = self.node(source).first_edge[direction.repr]; - AdjacentEdges { - graph: self, - direction, - next: first_edge, - } + AdjacentEdges { graph: self, direction, next: first_edge } } pub fn successor_nodes<'a>( @@ -269,9 +243,8 @@ impl Graph { } }; - for node in Some(entry_node) - .into_iter() - .chain(self.enumerated_nodes().map(|(node, _)| node)) + for node in + Some(entry_node).into_iter().chain(self.enumerated_nodes().map(|(node, _)| node)) { push_node(&mut stack, node); while let Some((node, mut iter)) = stack.pop() { @@ -346,12 +319,7 @@ impl<'g, N: Debug, E: Debug> DepthFirstTraversal<'g, N, E> { ) -> Self { let mut visited = BitSet::new_empty(graph.len_nodes()); visited.insert(start_node.node_id()); - DepthFirstTraversal { - graph, - stack: vec![start_node], - visited, - direction, - } + DepthFirstTraversal { graph, stack: vec![start_node], visited, direction } } fn visit(&mut self, node: NodeIndex) { @@ -394,10 +362,6 @@ impl Edge { } pub fn source_or_target(&self, direction: Direction) -> NodeIndex { - if direction == OUTGOING { - self.target - } else { - self.source - } + if direction == OUTGOING { self.target } else { self.source } } } diff --git a/src/librustc_data_structures/graph/implementation/tests.rs b/src/librustc_data_structures/graph/implementation/tests.rs index 82c6da3f42711..e4e4d0d44baba 100644 --- a/src/librustc_data_structures/graph/implementation/tests.rs +++ b/src/librustc_data_structures/graph/implementation/tests.rs @@ -54,21 +54,22 @@ fn each_edge() { }); } -fn test_adjacent_edges(graph: &Graph, - start_index: NodeIndex, - start_data: N, - expected_incoming: &[(E, N)], - expected_outgoing: &[(E, N)]) { +fn test_adjacent_edges( + graph: &Graph, + start_index: NodeIndex, + start_data: N, + expected_incoming: &[(E, N)], + expected_outgoing: &[(E, N)], +) { assert!(graph.node_data(start_index) == &start_data); let mut counter = 0; for (edge_index, edge) in graph.incoming_edges(start_index) { assert!(counter < expected_incoming.len()); - debug!("counter={:?} expected={:?} edge_index={:?} edge={:?}", - counter, - expected_incoming[counter], - edge_index, - edge); + debug!( + "counter={:?} expected={:?} edge_index={:?} edge={:?}", + counter, expected_incoming[counter], edge_index, edge + ); match expected_incoming[counter] { (ref e, ref n) => { assert!(e == &edge.data); @@ -83,11 +84,10 @@ fn test_adjacent_edges(graph: &Graph let mut counter = 0; for (edge_index, edge) in graph.outgoing_edges(start_index) { assert!(counter < expected_outgoing.len()); - debug!("counter={:?} expected={:?} edge_index={:?} edge={:?}", - counter, - expected_outgoing[counter], - edge_index, - edge); + debug!( + "counter={:?} expected={:?} edge_index={:?} edge={:?}", + counter, expected_outgoing[counter], edge_index, edge + ); match expected_outgoing[counter] { (ref e, ref n) => { assert!(e == &edge.data); @@ -109,11 +109,13 @@ fn each_adjacent_from_a() { #[test] fn each_adjacent_from_b() { let graph = create_graph(); - test_adjacent_edges(&graph, - NodeIndex(1), - "B", - &[("FB", "F"), ("AB", "A")], - &[("BD", "D"), ("BC", "C")]); + test_adjacent_edges( + &graph, + NodeIndex(1), + "B", + &[("FB", "F"), ("AB", "A")], + &[("BD", "D"), ("BC", "C")], + ); } #[test] diff --git a/src/librustc_data_structures/graph/iterate/mod.rs b/src/librustc_data_structures/graph/iterate/mod.rs index e268b28174474..53475cdf4ba42 100644 --- a/src/librustc_data_structures/graph/iterate/mod.rs +++ b/src/librustc_data_structures/graph/iterate/mod.rs @@ -1,6 +1,6 @@ -use rustc_index::vec::IndexVec; -use super::{DirectedGraph, WithNumNodes, WithSuccessors, WithStartNode}; +use super::{DirectedGraph, WithNumNodes, WithStartNode, WithSuccessors}; use rustc_index::bit_set::BitSet; +use rustc_index::vec::IndexVec; #[cfg(test)] mod tests; @@ -172,7 +172,7 @@ where where V: TriColorVisitor, { - use NodeStatus::{Visited, Settled}; + use NodeStatus::{Settled, Visited}; self.stack.push(Event { node: root, becomes: Visited }); diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index 37335799d19af..e0903e4324124 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -26,10 +26,7 @@ pub trait WithSuccessors: DirectedGraph where Self: for<'graph> GraphSuccessors<'graph, Item = ::Node>, { - fn successors( - &self, - node: Self::Node, - ) -> >::Iter; + fn successors(&self, node: Self::Node) -> >::Iter; fn depth_first_search(&self, from: Self::Node) -> iterate::DepthFirstSearch<'_, Self> where @@ -49,10 +46,7 @@ pub trait WithPredecessors: DirectedGraph where Self: for<'graph> GraphPredecessors<'graph, Item = ::Node>, { - fn predecessors( - &self, - node: Self::Node, - ) -> >::Iter; + fn predecessors(&self, node: Self::Node) -> >::Iter; } #[allow(unused_lifetimes)] @@ -71,14 +65,13 @@ pub trait ControlFlowGraph: // convenient trait } -impl ControlFlowGraph for T -where +impl ControlFlowGraph for T where T: DirectedGraph + WithStartNode + WithPredecessors + WithStartNode + WithSuccessors - + WithNumNodes, + + WithNumNodes { } diff --git a/src/librustc_data_structures/graph/reference.rs b/src/librustc_data_structures/graph/reference.rs index 9442bb3cdec3b..c259fe56c1509 100644 --- a/src/librustc_data_structures/graph/reference.rs +++ b/src/librustc_data_structures/graph/reference.rs @@ -23,9 +23,7 @@ impl<'graph, G: WithSuccessors> WithSuccessors for &'graph G { } impl<'graph, G: WithPredecessors> WithPredecessors for &'graph G { - fn predecessors(&self, - node: Self::Node) - -> >::Iter { + fn predecessors(&self, node: Self::Node) -> >::Iter { (**self).predecessors(node) } } diff --git a/src/librustc_data_structures/graph/scc/mod.rs b/src/librustc_data_structures/graph/scc/mod.rs index c214f66cd15cd..70fc2d7dad9ee 100644 --- a/src/librustc_data_structures/graph/scc/mod.rs +++ b/src/librustc_data_structures/graph/scc/mod.rs @@ -4,8 +4,8 @@ //! O(n) time. use crate::fx::FxHashSet; -use crate::graph::{DirectedGraph, WithNumNodes, WithNumEdges, WithSuccessors, GraphSuccessors}; use crate::graph::vec_graph::VecGraph; +use crate::graph::{DirectedGraph, GraphSuccessors, WithNumEdges, WithNumNodes, WithSuccessors}; use rustc_index::vec::{Idx, IndexVec}; use std::ops::Range; @@ -48,7 +48,7 @@ impl Sccs { /// Returns an iterator over the SCCs in the graph. pub fn all_sccs(&self) -> impl Iterator { - (0 .. self.scc_data.len()).map(S::new) + (0..self.scc_data.len()).map(S::new) } /// Returns the SCC to which a node `r` belongs. @@ -66,9 +66,9 @@ impl Sccs { VecGraph::new( self.num_sccs(), self.all_sccs() - .flat_map(|source| self.successors(source).iter().map(move |&target| { - (target, source) - })) + .flat_map(|source| { + self.successors(source).iter().map(move |&target| (target, source)) + }) .collect(), ) } @@ -97,10 +97,7 @@ impl GraphSuccessors<'graph> for Sccs { } impl WithSuccessors for Sccs { - fn successors<'graph>( - &'graph self, - node: S - ) -> >::Iter { + fn successors<'graph>(&'graph self, node: S) -> >::Iter { self.successors(node).iter().cloned() } } @@ -221,10 +218,7 @@ where node_states: IndexVec::from_elem_n(NodeState::NotVisited, num_nodes), node_stack: Vec::with_capacity(num_nodes), successors_stack: Vec::new(), - scc_data: SccData { - ranges: IndexVec::new(), - all_successors: Vec::new(), - }, + scc_data: SccData { ranges: IndexVec::new(), all_successors: Vec::new() }, duplicate_set: FxHashSet::default(), }; @@ -232,17 +226,13 @@ where .map(G::Node::new) .map(|node| match this.walk_node(0, node) { WalkReturn::Complete { scc_index } => scc_index, - WalkReturn::Cycle { min_depth } => panic!( - "`walk_node(0, {:?})` returned cycle with depth {:?}", - node, min_depth - ), + WalkReturn::Cycle { min_depth } => { + panic!("`walk_node(0, {:?})` returned cycle with depth {:?}", node, min_depth) + } }) .collect(); - Sccs { - scc_indices, - scc_data: this.scc_data, - } + Sccs { scc_indices, scc_data: this.scc_data } } /// Visits a node during the DFS. We first examine its current @@ -293,9 +283,8 @@ where } NodeState::BeingVisited { depth } => { - self.node_states[r] = NodeState::InCycleWith { - parent: self.node_stack[depth], - }; + self.node_states[r] = + NodeState::InCycleWith { parent: self.node_stack[depth] }; parent_state } @@ -309,10 +298,7 @@ where /// Walks a node that has never been visited before. fn walk_unvisited_node(&mut self, depth: usize, node: G::Node) -> WalkReturn { - debug!( - "walk_unvisited_node(depth = {:?}, node = {:?})", - depth, node - ); + debug!("walk_unvisited_node(depth = {:?}, node = {:?})", depth, node); debug_assert!(match self.node_states[node] { NodeState::NotVisited => true, @@ -330,14 +316,9 @@ where let mut min_cycle_root = node; let successors_len = self.successors_stack.len(); for successor_node in self.graph.successors(node) { - debug!( - "walk_unvisited_node: node = {:?} successor_ode = {:?}", - node, successor_node - ); + debug!("walk_unvisited_node: node = {:?} successor_ode = {:?}", node, successor_node); match self.walk_node(depth + 1, successor_node) { - WalkReturn::Cycle { - min_depth: successor_min_depth, - } => { + WalkReturn::Cycle { min_depth: successor_min_depth } => { // Track the minimum depth we can reach. assert!(successor_min_depth <= depth); if successor_min_depth < min_depth { @@ -350,9 +331,7 @@ where } } - WalkReturn::Complete { - scc_index: successor_scc_index, - } => { + WalkReturn::Complete { scc_index: successor_scc_index } => { // Push the completed SCC indices onto // the `successors_stack` for later. debug!( @@ -387,9 +366,7 @@ where // We are not the head of the cycle. Return back to our // caller. They will take ownership of the // `self.successors` data that we pushed. - self.node_states[node] = NodeState::InCycleWith { - parent: min_cycle_root, - }; + self.node_states[node] = NodeState::InCycleWith { parent: min_cycle_root }; WalkReturn::Cycle { min_depth } } } diff --git a/src/librustc_data_structures/graph/scc/tests.rs b/src/librustc_data_structures/graph/scc/tests.rs index 6da3ac0ecb8b9..1d5f46ebab199 100644 --- a/src/librustc_data_structures/graph/scc/tests.rs +++ b/src/librustc_data_structures/graph/scc/tests.rs @@ -1,5 +1,5 @@ -use crate::graph::tests::TestGraph; use super::*; +use crate::graph::tests::TestGraph; #[test] fn diamond() { @@ -23,21 +23,15 @@ fn test_big_scc() { // hence it too will return a cycle. /* -+-> 0 -| | -| v -| 1 -> 3 -| | | -| v | -+-- 2 <--+ - */ - let graph = TestGraph::new(0, &[ - (0, 1), - (1, 2), - (1, 3), - (2, 0), - (3, 2), - ]); + +-> 0 + | | + | v + | 1 -> 3 + | | | + | v | + +-- 2 <--+ + */ + let graph = TestGraph::new(0, &[(0, 1), (1, 2), (1, 3), (2, 0), (3, 2)]); let sccs: Sccs<_, usize> = Sccs::new(&graph); assert_eq!(sccs.num_sccs(), 1); } @@ -45,20 +39,15 @@ fn test_big_scc() { #[test] fn test_three_sccs() { /* - 0 - | - v -+-> 1 3 -| | | -| v | -+-- 2 <--+ - */ - let graph = TestGraph::new(0, &[ - (0, 1), - (1, 2), - (2, 1), - (3, 2), - ]); + 0 + | + v + +-> 1 3 + | | | + | v | + +-- 2 <--+ + */ + let graph = TestGraph::new(0, &[(0, 1), (1, 2), (2, 1), (3, 2)]); let sccs: Sccs<_, usize> = Sccs::new(&graph); assert_eq!(sccs.num_sccs(), 3); assert_eq!(sccs.scc(0), 1); @@ -86,15 +75,7 @@ fn test_find_state_2() { // | v | // +-- 2 <----+ - let graph = TestGraph::new(0, &[ - (0, 1), - (0, 4), - (1, 2), - (1, 3), - (2, 1), - (3, 0), - (4, 2), - ]); + let graph = TestGraph::new(0, &[(0, 1), (0, 4), (1, 2), (1, 3), (2, 1), (3, 0), (4, 2)]); // For this graph, we will start in our DFS by visiting: // @@ -136,25 +117,17 @@ fn test_find_state_2() { #[test] fn test_find_state_3() { /* - /----+ - 0 <--+ | - | | | - v | | -+-> 1 -> 3 4 5 -| | | | -| v | | -+-- 2 <----+-+ - */ - let graph = TestGraph::new(0, &[ - (0, 1), - (0, 4), - (1, 2), - (1, 3), - (2, 1), - (3, 0), - (4, 2), - (5, 2), - ]); + /----+ + 0 <--+ | + | | | + v | | + +-> 1 -> 3 4 5 + | | | | + | v | | + +-- 2 <----+-+ + */ + let graph = + TestGraph::new(0, &[(0, 1), (0, 4), (1, 2), (1, 3), (2, 1), (3, 0), (4, 2), (5, 2)]); let sccs: Sccs<_, usize> = Sccs::new(&graph); assert_eq!(sccs.num_sccs(), 2); assert_eq!(sccs.scc(0), 0); diff --git a/src/librustc_data_structures/graph/tests.rs b/src/librustc_data_structures/graph/tests.rs index bc142144e930f..7f4ef906b361e 100644 --- a/src/librustc_data_structures/graph/tests.rs +++ b/src/librustc_data_structures/graph/tests.rs @@ -1,7 +1,7 @@ use crate::fx::FxHashMap; use std::cmp::max; -use std::slice; use std::iter; +use std::slice; use super::*; @@ -51,9 +51,7 @@ impl WithNumNodes for TestGraph { } impl WithPredecessors for TestGraph { - fn predecessors(&self, - node: usize) - -> >::Iter { + fn predecessors(&self, node: usize) -> >::Iter { self.predecessors[&node].iter().cloned() } } diff --git a/src/librustc_data_structures/graph/vec_graph/mod.rs b/src/librustc_data_structures/graph/vec_graph/mod.rs index aad5944dcd0be..22c50afe6d0b4 100644 --- a/src/librustc_data_structures/graph/vec_graph/mod.rs +++ b/src/librustc_data_structures/graph/vec_graph/mod.rs @@ -1,5 +1,5 @@ +use crate::graph::{DirectedGraph, GraphSuccessors, WithNumEdges, WithNumNodes, WithSuccessors}; use rustc_index::vec::{Idx, IndexVec}; -use crate::graph::{DirectedGraph, WithNumNodes, WithNumEdges, WithSuccessors, GraphSuccessors}; #[cfg(test)] mod tests; @@ -18,10 +18,7 @@ pub struct VecGraph { } impl VecGraph { - pub fn new( - num_nodes: usize, - mut edge_pairs: Vec<(N, N)>, - ) -> Self { + pub fn new(num_nodes: usize, mut edge_pairs: Vec<(N, N)>) -> Self { // Sort the edges by the source -- this is important. edge_pairs.sort(); @@ -104,10 +101,7 @@ impl GraphSuccessors<'graph> for VecGraph { } impl WithSuccessors for VecGraph { - fn successors<'graph>( - &'graph self, - node: N - ) -> >::Iter { + fn successors<'graph>(&'graph self, node: N) -> >::Iter { self.successors(node).iter().cloned() } } diff --git a/src/librustc_data_structures/graph/vec_graph/tests.rs b/src/librustc_data_structures/graph/vec_graph/tests.rs index 97a9bd2ad0b08..1db8bd4b102bf 100644 --- a/src/librustc_data_structures/graph/vec_graph/tests.rs +++ b/src/librustc_data_structures/graph/vec_graph/tests.rs @@ -13,16 +13,7 @@ fn create_graph() -> VecGraph { // // 6 - VecGraph::new( - 7, - vec![ - (0, 1), - (1, 2), - (1, 3), - (3, 4), - (5, 1), - ], - ) + VecGraph::new(7, vec![(0, 1), (1, 2), (1, 3), (3, 4), (5, 1)]) } #[test] diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index fb541637e5f79..e035f39e34fd7 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -7,7 +7,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] - #![feature(in_band_lifetimes)] #![feature(unboxed_closures)] #![feature(generators)] @@ -24,9 +23,7 @@ #![feature(integer_atomics)] #![feature(test)] #![feature(associated_type_bounds)] - #![cfg_attr(unix, feature(libc))] - #![allow(rustc::default_hash_types)] #[macro_use] @@ -41,77 +38,78 @@ pub use rustc_serialize::hex::ToHex; #[inline(never)] #[cold] pub fn cold_path R, R>(f: F) -> R { - f() + f() } #[macro_export] macro_rules! likely { - ($e:expr) => { - #[allow(unused_unsafe)] - { - unsafe { std::intrinsics::likely($e) } - } - } + ($e:expr) => { + #[allow(unused_unsafe)] + { + unsafe { std::intrinsics::likely($e) } + } + }; } #[macro_export] macro_rules! unlikely { ($e:expr) => { - #[allow(unused_unsafe)] - { - unsafe { std::intrinsics::unlikely($e) } - } - } + #[allow(unused_unsafe)] + { + unsafe { std::intrinsics::unlikely($e) } + } + }; } -pub mod macros; -pub mod svh; pub mod base_n; pub mod binary_search_util; pub mod box_region; pub mod const_cstr; pub mod flock; pub mod fx; -pub mod stable_map; pub mod graph; pub mod jobserver; +pub mod macros; pub mod obligation_forest; pub mod owning_ref; pub mod ptr_key; pub mod sip128; pub mod small_c_str; pub mod snapshot_map; +pub mod stable_map; +pub mod svh; pub use ena::snapshot_vec; pub mod sorted_map; pub mod stable_set; -#[macro_use] pub mod stable_hasher; -pub mod sync; +#[macro_use] +pub mod stable_hasher; pub mod sharded; -pub mod tiny_list; +pub mod sync; pub mod thin_vec; +pub mod tiny_list; pub mod transitive_relation; pub use ena::unify; -pub mod vec_linked_list; -pub mod work_queue; pub mod fingerprint; pub mod profiling; +pub mod vec_linked_list; +pub mod work_queue; pub struct OnDrop(pub F); impl OnDrop { - /// Forgets the function which prevents it from running. - /// Ensure that the function owns no memory, otherwise it will be leaked. - #[inline] - pub fn disable(self) { - std::mem::forget(self); - } + /// Forgets the function which prevents it from running. + /// Ensure that the function owns no memory, otherwise it will be leaked. + #[inline] + pub fn disable(self) { + std::mem::forget(self); + } } impl Drop for OnDrop { - #[inline] - fn drop(&mut self) { - (self.0)(); - } + #[inline] + fn drop(&mut self) { + (self.0)(); + } } // See comments in src/librustc/lib.rs diff --git a/src/librustc_data_structures/macros.rs b/src/librustc_data_structures/macros.rs index 3f75523a81584..83e6dbedee226 100644 --- a/src/librustc_data_structures/macros.rs +++ b/src/librustc_data_structures/macros.rs @@ -7,7 +7,7 @@ macro_rules! static_assert { // is out-of-bounds. #[allow(dead_code)] const _: () = [()][!($test: bool) as usize]; - } + }; } /// Type size assertion. The first argument is a type and the second argument is its expected size. @@ -15,5 +15,5 @@ macro_rules! static_assert { macro_rules! static_assert_size { ($ty:ty, $size:expr) => { const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()]; - } + }; } diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index b1931ca459f61..92bd196aaa3cf 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -85,19 +85,20 @@ mod graphviz; #[cfg(test)] mod tests; -pub trait ForestObligation : Clone + Debug { - type Predicate : Clone + hash::Hash + Eq + Debug; +pub trait ForestObligation: Clone + Debug { + type Predicate: Clone + hash::Hash + Eq + Debug; fn as_predicate(&self) -> &Self::Predicate; } pub trait ObligationProcessor { - type Obligation : ForestObligation; - type Error : Debug; + type Obligation: ForestObligation; + type Error: Debug; - fn process_obligation(&mut self, - obligation: &mut Self::Obligation) - -> ProcessResult; + fn process_obligation( + &mut self, + obligation: &mut Self::Obligation, + ) -> ProcessResult; /// As we do the cycle check, we invoke this callback when we /// encounter an actual cycle. `cycle` is an iterator that starts @@ -107,10 +108,9 @@ pub trait ObligationProcessor { /// In other words, if we had O1 which required O2 which required /// O3 which required O1, we would give an iterator yielding O1, /// O2, O3 (O1 is not yielded twice). - fn process_backedge<'c, I>(&mut self, - cycle: I, - _marker: PhantomData<&'c Self::Obligation>) - where I: Clone + Iterator; + fn process_backedge<'c, I>(&mut self, cycle: I, _marker: PhantomData<&'c Self::Obligation>) + where + I: Clone + Iterator; } /// The result type used by `process_obligation`. @@ -185,20 +185,11 @@ struct Node { } impl Node { - fn new( - parent: Option, - obligation: O, - obligation_tree_id: ObligationTreeId - ) -> Node { + fn new(parent: Option, obligation: O, obligation_tree_id: ObligationTreeId) -> Node { Node { obligation, state: Cell::new(NodeState::Pending), - dependents: - if let Some(parent_index) = parent { - vec![parent_index] - } else { - vec![] - }, + dependents: if let Some(parent_index) = parent { vec![parent_index] } else { vec![] }, has_parent: parent.is_some(), obligation_tree_id, } @@ -339,11 +330,7 @@ impl ObligationForest { node.dependents.push(parent_index); } } - if let NodeState::Error = node.state.get() { - Err(()) - } else { - Ok(()) - } + if let NodeState::Error = node.state.get() { Err(()) } else { Ok(()) } } Entry::Vacant(v) => { let obligation_tree_id = match parent { @@ -351,12 +338,12 @@ impl ObligationForest { None => self.obligation_tree_id_generator.next().unwrap(), }; - let already_failed = - parent.is_some() - && self.error_cache - .get(&obligation_tree_id) - .map(|errors| errors.contains(obligation.as_predicate())) - .unwrap_or(false); + let already_failed = parent.is_some() + && self + .error_cache + .get(&obligation_tree_id) + .map(|errors| errors.contains(obligation.as_predicate())) + .unwrap_or(false); if already_failed { Err(()) @@ -372,14 +359,12 @@ impl ObligationForest { /// Converts all remaining obligations to the given error. pub fn to_errors(&mut self, error: E) -> Vec> { - let errors = self.nodes.iter().enumerate() + let errors = self + .nodes + .iter() + .enumerate() .filter(|(_index, node)| node.state.get() == NodeState::Pending) - .map(|(index, _node)| { - Error { - error: error.clone(), - backtrace: self.error_at(index), - } - }) + .map(|(index, _node)| Error { error: error.clone(), backtrace: self.error_at(index) }) .collect(); let successful_obligations = self.compress(DoCompleted::Yes); @@ -389,9 +374,11 @@ impl ObligationForest { /// Returns the set of obligations that are in a pending state. pub fn map_pending_obligations(&self, f: F) -> Vec

- where F: Fn(&O) -> P + where + F: Fn(&O) -> P, { - self.nodes.iter() + self.nodes + .iter() .filter(|node| node.state.get() == NodeState::Pending) .map(|node| f(&node.obligation)) .collect() @@ -421,9 +408,13 @@ impl ObligationForest { /// be called in a loop until `outcome.stalled` is false. /// /// This _cannot_ be unrolled (presently, at least). - pub fn process_obligations

(&mut self, processor: &mut P, do_completed: DoCompleted) - -> Outcome - where P: ObligationProcessor + pub fn process_obligations

( + &mut self, + processor: &mut P, + do_completed: DoCompleted, + ) -> Outcome + where + P: ObligationProcessor, { self.gen += 1; @@ -462,10 +453,7 @@ impl ObligationForest { node.state.set(NodeState::Success(Self::not_waiting())); for child in children { - let st = self.register_obligation_at( - child, - Some(index) - ); + let st = self.register_obligation_at(child, Some(index)); if let Err(()) = st { // Error already reported - propagate it // to our node. @@ -475,10 +463,7 @@ impl ObligationForest { } ProcessResult::Error(err) => { stalled = false; - errors.push(Error { - error: err, - backtrace: self.error_at(index), - }); + errors.push(Error { error: err, backtrace: self.error_at(index) }); } } index += 1; @@ -498,11 +483,7 @@ impl ObligationForest { self.process_cycles(processor); let completed = self.compress(do_completed); - Outcome { - completed, - errors, - stalled, - } + Outcome { completed, errors, stalled } } /// Returns a vector of obligations for `p` and all of its @@ -574,7 +555,8 @@ impl ObligationForest { /// Report cycles between all `Success` nodes that aren't still waiting. /// This must be called after `mark_still_waiting_nodes`. fn process_cycles

(&self, processor: &mut P) - where P: ObligationProcessor + where + P: ObligationProcessor, { let mut stack = vec![]; @@ -592,9 +574,14 @@ impl ObligationForest { debug_assert!(stack.is_empty()); } - fn find_cycles_from_node

(&self, stack: &mut Vec, processor: &mut P, min_index: usize, - index: usize) - where P: ObligationProcessor + fn find_cycles_from_node

( + &self, + stack: &mut Vec, + processor: &mut P, + min_index: usize, + index: usize, + ) where + P: ObligationProcessor, { let node = &self.nodes[index]; if let NodeState::Success(waiting) = node.state.get() { @@ -614,7 +601,7 @@ impl ObligationForest { // Cycle detected. processor.process_backedge( stack[rpos..].iter().map(GetObligation(&self.nodes)), - PhantomData + PhantomData, ); } } @@ -697,11 +684,7 @@ impl ObligationForest { node_rewrites.truncate(0); self.node_rewrites.replace(node_rewrites); - if do_completed == DoCompleted::Yes { - Some(removed_success_obligations) - } else { - None - } + if do_completed == DoCompleted::Yes { Some(removed_success_obligations) } else { None } } fn apply_rewrites(&mut self, node_rewrites: &[usize]) { diff --git a/src/librustc_data_structures/obligation_forest/tests.rs b/src/librustc_data_structures/obligation_forest/tests.rs index 995c99bfec307..e29335aab2808 100644 --- a/src/librustc_data_structures/obligation_forest/tests.rs +++ b/src/librustc_data_structures/obligation_forest/tests.rs @@ -19,40 +19,41 @@ struct ClosureObligationProcessor { #[allow(non_snake_case)] fn C(of: OF, bf: BF) -> ClosureObligationProcessor - where OF: FnMut(&mut O) -> ProcessResult, - BF: FnMut(&[O]) +where + OF: FnMut(&mut O) -> ProcessResult, + BF: FnMut(&[O]), { ClosureObligationProcessor { process_obligation: of, _process_backedge: bf, - marker: PhantomData + marker: PhantomData, } } impl ObligationProcessor for ClosureObligationProcessor - where O: super::ForestObligation + fmt::Debug, - E: fmt::Debug, - OF: FnMut(&mut O) -> ProcessResult, - BF: FnMut(&[O]) +where + O: super::ForestObligation + fmt::Debug, + E: fmt::Debug, + OF: FnMut(&mut O) -> ProcessResult, + BF: FnMut(&[O]), { type Obligation = O; type Error = E; - fn process_obligation(&mut self, - obligation: &mut Self::Obligation) - -> ProcessResult - { + fn process_obligation( + &mut self, + obligation: &mut Self::Obligation, + ) -> ProcessResult { (self.process_obligation)(obligation) } - fn process_backedge<'c, I>(&mut self, _cycle: I, - _marker: PhantomData<&'c Self::Obligation>) - where I: Clone + Iterator + fn process_backedge<'c, I>(&mut self, _cycle: I, _marker: PhantomData<&'c Self::Obligation>) + where + I: Clone + Iterator, { } } - #[test] fn push_pop() { let mut forest = ObligationForest::new(); @@ -64,22 +65,21 @@ fn push_pop() { // A |-> A.1 // |-> A.2 // |-> A.3 - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]), "B" => ProcessResult::Error("B is for broken"), "C" => ProcessResult::Changed(vec![]), "A.1" | "A.2" | "A.3" => ProcessResult::Unchanged, _ => unreachable!(), - } - }, |_| {}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap(), vec!["C"]); - assert_eq!(err, - vec![Error { - error: "B is for broken", - backtrace: vec!["B"], - }]); + assert_eq!(err, vec![Error { error: "B is for broken", backtrace: vec!["B"] }]); // second round: two delays, one success, creating an uneven set of subtasks: // A |-> A.1 @@ -88,28 +88,30 @@ fn push_pop() { // D |-> D.1 // |-> D.2 forest.register_obligation("D"); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A.1" => ProcessResult::Unchanged, "A.2" => ProcessResult::Unchanged, "A.3" => ProcessResult::Changed(vec!["A.3.i"]), "D" => ProcessResult::Changed(vec!["D.1", "D.2"]), "A.3.i" | "D.1" | "D.2" => ProcessResult::Unchanged, _ => unreachable!(), - } - }, |_| {}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap(), Vec::<&'static str>::new()); assert_eq!(err, Vec::new()); - // third round: ok in A.1 but trigger an error in A.2. Check that it // propagates to A, but not D.1 or D.2. // D |-> D.1 |-> D.1.i // |-> D.2 |-> D.2.i - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A.1" => ProcessResult::Changed(vec![]), "A.2" => ProcessResult::Error("A is for apple"), "A.3.i" => ProcessResult::Changed(vec![]), @@ -117,34 +119,32 @@ fn push_pop() { "D.2" => ProcessResult::Changed(vec!["D.2.i"]), "D.1.i" | "D.2.i" => ProcessResult::Unchanged, _ => unreachable!(), - } - }, |_| {}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); let mut ok = ok.unwrap(); ok.sort(); assert_eq!(ok, vec!["A.1", "A.3", "A.3.i"]); - assert_eq!(err, - vec![Error { - error: "A is for apple", - backtrace: vec!["A.2", "A"], - }]); + assert_eq!(err, vec![Error { error: "A is for apple", backtrace: vec!["A.2", "A"] }]); // fourth round: error in D.1.i - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "D.1.i" => ProcessResult::Error("D is for dumb"), "D.2.i" => ProcessResult::Changed(vec![]), _ => panic!("unexpected obligation {:?}", obligation), - } - }, |_| {}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); let mut ok = ok.unwrap(); ok.sort(); assert_eq!(ok, vec!["D.2", "D.2.i"]); - assert_eq!(err, - vec![Error { - error: "D is for dumb", - backtrace: vec!["D.1.i", "D.1", "D"], - }]); + assert_eq!(err, vec![Error { error: "D is for dumb", backtrace: vec!["D.1.i", "D.1", "D"] }]); } // Test that if a tree with grandchildren succeeds, everything is @@ -160,59 +160,70 @@ fn success_in_grandchildren() { let mut forest = ObligationForest::new(); forest.register_obligation("A"); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]), "A.1" => ProcessResult::Changed(vec![]), "A.2" => ProcessResult::Changed(vec!["A.2.i", "A.2.ii"]), "A.3" => ProcessResult::Changed(vec![]), "A.2.i" | "A.2.ii" => ProcessResult::Unchanged, _ => unreachable!(), - } - }, |_| {}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); let mut ok = ok.unwrap(); ok.sort(); assert_eq!(ok, vec!["A.1", "A.3"]); assert!(err.is_empty()); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A.2.i" => ProcessResult::Unchanged, "A.2.ii" => ProcessResult::Changed(vec![]), _ => unreachable!(), - } - }, |_| {}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap(), vec!["A.2.ii"]); assert!(err.is_empty()); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A.2.i" => ProcessResult::Changed(vec!["A.2.i.a"]), "A.2.i.a" => ProcessResult::Unchanged, _ => unreachable!(), - } - }, |_| {}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert!(ok.unwrap().is_empty()); assert!(err.is_empty()); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A.2.i.a" => ProcessResult::Changed(vec![]), _ => unreachable!(), - } - }, |_| {}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); let mut ok = ok.unwrap(); ok.sort(); assert_eq!(ok, vec!["A", "A.2", "A.2.i", "A.2.i.a"]); assert!(err.is_empty()); let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|_| unreachable!(), |_| {}), - DoCompleted::Yes); + forest.process_obligations(&mut C(|_| unreachable!(), |_| {}), DoCompleted::Yes); assert!(ok.unwrap().is_empty()); assert!(err.is_empty()); @@ -224,14 +235,17 @@ fn to_errors_no_throw() { // yields to correct errors (and does not panic, in particular). let mut forest = ObligationForest::new(); forest.register_obligation("A"); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]), "A.1" | "A.2" | "A.3" => ProcessResult::Unchanged, _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap().len(), 0); assert_eq!(err.len(), 0); let errors = forest.to_errors(()); @@ -246,37 +260,49 @@ fn diamond() { // check that diamond dependencies are handled correctly let mut forest = ObligationForest::new(); forest.register_obligation("A"); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A" => ProcessResult::Changed(vec!["A.1", "A.2"]), "A.1" | "A.2" => ProcessResult::Unchanged, _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap().len(), 0); assert_eq!(err.len(), 0); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A.1" => ProcessResult::Changed(vec!["D"]), "A.2" => ProcessResult::Changed(vec!["D"]), "D" => ProcessResult::Unchanged, _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap().len(), 0); assert_eq!(err.len(), 0); let mut d_count = 0; - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { - "D" => { d_count += 1; ProcessResult::Changed(vec![]) }, + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { + "D" => { + d_count += 1; + ProcessResult::Changed(vec![]) + } _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(d_count, 1); let mut ok = ok.unwrap(); ok.sort(); @@ -287,43 +313,55 @@ fn diamond() { assert_eq!(errors.len(), 0); forest.register_obligation("A'"); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A'" => ProcessResult::Changed(vec!["A'.1", "A'.2"]), "A'.1" | "A'.2" => ProcessResult::Unchanged, _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap().len(), 0); assert_eq!(err.len(), 0); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A'.1" => ProcessResult::Changed(vec!["D'", "A'"]), "A'.2" => ProcessResult::Changed(vec!["D'"]), "D'" | "A'" => ProcessResult::Unchanged, _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap().len(), 0); assert_eq!(err.len(), 0); let mut d_count = 0; - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { - "D'" => { d_count += 1; ProcessResult::Error("operation failed") }, + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { + "D'" => { + d_count += 1; + ProcessResult::Error("operation failed") + } _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(d_count, 1); assert_eq!(ok.unwrap().len(), 0); - assert_eq!(err, vec![super::Error { - error: "operation failed", - backtrace: vec!["D'", "A'.1", "A'"] - }]); + assert_eq!( + err, + vec![super::Error { error: "operation failed", backtrace: vec!["D'", "A'.1", "A'"] }] + ); let errors = forest.to_errors(()); assert_eq!(errors.len(), 0); @@ -337,30 +375,34 @@ fn done_dependency() { forest.register_obligation("B: Sized"); forest.register_obligation("C: Sized"); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A: Sized" | "B: Sized" | "C: Sized" => ProcessResult::Changed(vec![]), _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); let mut ok = ok.unwrap(); ok.sort(); assert_eq!(ok, vec!["A: Sized", "B: Sized", "C: Sized"]); assert_eq!(err.len(), 0); forest.register_obligation("(A,B,C): Sized"); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { - "(A,B,C): Sized" => ProcessResult::Changed(vec![ - "A: Sized", - "B: Sized", - "C: Sized" - ]), + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { + "(A,B,C): Sized" => { + ProcessResult::Changed(vec!["A: Sized", "B: Sized", "C: Sized"]) + } _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap(), vec!["(A,B,C): Sized"]); assert_eq!(err.len(), 0); } @@ -374,59 +416,65 @@ fn orphan() { forest.register_obligation("C1"); forest.register_obligation("C2"); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A" => ProcessResult::Changed(vec!["D", "E"]), "B" => ProcessResult::Unchanged, "C1" => ProcessResult::Changed(vec![]), "C2" => ProcessResult::Changed(vec![]), "D" | "E" => ProcessResult::Unchanged, _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); let mut ok = ok.unwrap(); ok.sort(); assert_eq!(ok, vec!["C1", "C2"]); assert_eq!(err.len(), 0); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "D" | "E" => ProcessResult::Unchanged, "B" => ProcessResult::Changed(vec!["D"]), _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap().len(), 0); assert_eq!(err.len(), 0); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "D" => ProcessResult::Unchanged, "E" => ProcessResult::Error("E is for error"), _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap().len(), 0); - assert_eq!(err, vec![super::Error { - error: "E is for error", - backtrace: vec!["E", "A"] - }]); + assert_eq!(err, vec![super::Error { error: "E is for error", backtrace: vec!["E", "A"] }]); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "D" => ProcessResult::Error("D is dead"), _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap().len(), 0); - assert_eq!(err, vec![super::Error { - error: "D is dead", - backtrace: vec!["D"] - }]); + assert_eq!(err, vec![super::Error { error: "D is dead", backtrace: vec!["D"] }]); let errors = forest.to_errors(()); assert_eq!(errors.len(), 0); @@ -439,35 +487,35 @@ fn simultaneous_register_and_error() { forest.register_obligation("A"); forest.register_obligation("B"); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A" => ProcessResult::Error("An error"), "B" => ProcessResult::Changed(vec!["A"]), _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap().len(), 0); - assert_eq!(err, vec![super::Error { - error: "An error", - backtrace: vec!["A"] - }]); + assert_eq!(err, vec![super::Error { error: "An error", backtrace: vec!["A"] }]); let mut forest = ObligationForest::new(); forest.register_obligation("B"); forest.register_obligation("A"); - let Outcome { completed: ok, errors: err, .. } = - forest.process_obligations(&mut C(|obligation| { - match *obligation { + let Outcome { completed: ok, errors: err, .. } = forest.process_obligations( + &mut C( + |obligation| match *obligation { "A" => ProcessResult::Error("An error"), "B" => ProcessResult::Changed(vec!["A"]), _ => unreachable!(), - } - }, |_|{}), DoCompleted::Yes); + }, + |_| {}, + ), + DoCompleted::Yes, + ); assert_eq!(ok.unwrap().len(), 0); - assert_eq!(err, vec![super::Error { - error: "An error", - backtrace: vec!["A"] - }]); + assert_eq!(err, vec![super::Error { error: "An error", backtrace: vec!["A"] }]); } diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/src/librustc_data_structures/owning_ref/mod.rs index 0213eb4f2a2a4..ad4b79de2361d 100644 --- a/src/librustc_data_structures/owning_ref/mod.rs +++ b/src/librustc_data_structures/owning_ref/mod.rs @@ -244,8 +244,10 @@ fn main() { ``` */ +pub use stable_deref_trait::{ + CloneStableDeref as CloneStableAddress, StableDeref as StableAddress, +}; use std::mem; -pub use stable_deref_trait::{StableDeref as StableAddress, CloneStableDeref as CloneStableAddress}; /// An owning reference. /// @@ -333,13 +335,11 @@ impl OwningRef { /// } /// ``` pub fn new(o: O) -> Self - where O: StableAddress, - O: Deref, + where + O: StableAddress, + O: Deref, { - OwningRef { - reference: &*o, - owner: o, - } + OwningRef { reference: &*o, owner: o } } /// Like `new`, but doesn’t require `O` to implement the `StableAddress` trait. @@ -348,12 +348,10 @@ impl OwningRef { /// This is useful for cases where coherence rules prevents implementing the trait /// without adding a dependency to this crate in a third-party library. pub unsafe fn new_assert_stable_address(o: O) -> Self - where O: Deref, + where + O: Deref, { - OwningRef { - reference: &*o, - owner: o, - } + OwningRef { reference: &*o, owner: o } } /// Converts `self` into a new owning reference that points at something reachable @@ -377,13 +375,11 @@ impl OwningRef { /// } /// ``` pub fn map(self, f: F) -> OwningRef - where O: StableAddress, - F: FnOnce(&T) -> &U + where + O: StableAddress, + F: FnOnce(&T) -> &U, { - OwningRef { - reference: f(&self), - owner: self.owner, - } + OwningRef { reference: f(&self), owner: self.owner } } /// Tries to convert `self` into a new owning reference that points @@ -409,13 +405,11 @@ impl OwningRef { /// } /// ``` pub fn try_map(self, f: F) -> Result, E> - where O: StableAddress, - F: FnOnce(&T) -> Result<&U, E> + where + O: StableAddress, + F: FnOnce(&T) -> Result<&U, E>, { - Ok(OwningRef { - reference: f(&self)?, - owner: self.owner, - }) + Ok(OwningRef { reference: f(&self)?, owner: self.owner }) } /// Converts `self` into a new owning reference with a different owner type. @@ -424,14 +418,12 @@ impl OwningRef { /// so that the reference into it remains valid. This function is marked unsafe /// because the user needs to manually uphold this guarantee. pub unsafe fn map_owner(self, f: F) -> OwningRef - where O: StableAddress, - P: StableAddress, - F: FnOnce(O) -> P + where + O: StableAddress, + P: StableAddress, + F: FnOnce(O) -> P, { - OwningRef { - reference: self.reference, - owner: f(self.owner), - } + OwningRef { reference: self.reference, owner: f(self.owner) } } /// Converts `self` into a new owning reference where the owner is wrapped @@ -440,10 +432,7 @@ impl OwningRef { /// This can be used to safely erase the owner of any `OwningRef` /// to a `OwningRef, T>`. pub fn map_owner_box(self) -> OwningRef, T> { - OwningRef { - reference: self.reference, - owner: Box::new(self.owner), - } + OwningRef { reference: self.reference, owner: Box::new(self.owner) } } /// Erases the concrete base type of the owner with a trait object. @@ -479,24 +468,20 @@ impl OwningRef { /// } /// ``` pub fn erase_owner<'a>(self) -> OwningRef - where O: IntoErased<'a>, + where + O: IntoErased<'a>, { - OwningRef { - reference: self.reference, - owner: self.owner.into_erased(), - } + OwningRef { reference: self.reference, owner: self.owner.into_erased() } } /// Erases the concrete base type of the owner with a trait object which implements `Send`. /// /// This allows mixing of owned references with different owner base types. pub fn erase_send_owner<'a>(self) -> OwningRef - where O: IntoErasedSend<'a>, + where + O: IntoErasedSend<'a>, { - OwningRef { - reference: self.reference, - owner: self.owner.into_erased_send(), - } + OwningRef { reference: self.reference, owner: self.owner.into_erased_send() } } /// Erases the concrete base type of the owner with a trait object @@ -504,12 +489,10 @@ impl OwningRef { /// /// This allows mixing of owned references with different owner base types. pub fn erase_send_sync_owner<'a>(self) -> OwningRef - where O: IntoErasedSendSync<'a>, + where + O: IntoErasedSendSync<'a>, { - OwningRef { - reference: self.reference, - owner: self.owner.into_erased_send_sync(), - } + OwningRef { reference: self.reference, owner: self.owner.into_erased_send_sync() } } // UNIMPLEMENTED: wrap_owner @@ -542,13 +525,11 @@ impl OwningRefMut { /// } /// ``` pub fn new(mut o: O) -> Self - where O: StableAddress, - O: DerefMut, + where + O: StableAddress, + O: DerefMut, { - OwningRefMut { - reference: &mut *o, - owner: o, - } + OwningRefMut { reference: &mut *o, owner: o } } /// Like `new`, but doesn’t require `O` to implement the `StableAddress` trait. @@ -557,12 +538,10 @@ impl OwningRefMut { /// This is useful for cases where coherence rules prevents implementing the trait /// without adding a dependency to this crate in a third-party library. pub unsafe fn new_assert_stable_address(mut o: O) -> Self - where O: DerefMut, + where + O: DerefMut, { - OwningRefMut { - reference: &mut *o, - owner: o, - } + OwningRefMut { reference: &mut *o, owner: o } } /// Converts `self` into a new _shared_ owning reference that points at @@ -586,13 +565,11 @@ impl OwningRefMut { /// } /// ``` pub fn map(mut self, f: F) -> OwningRef - where O: StableAddress, - F: FnOnce(&mut T) -> &U + where + O: StableAddress, + F: FnOnce(&mut T) -> &U, { - OwningRef { - reference: f(&mut self), - owner: self.owner, - } + OwningRef { reference: f(&mut self), owner: self.owner } } /// Converts `self` into a new _mutable_ owning reference that points at @@ -616,13 +593,11 @@ impl OwningRefMut { /// } /// ``` pub fn map_mut(mut self, f: F) -> OwningRefMut - where O: StableAddress, - F: FnOnce(&mut T) -> &mut U + where + O: StableAddress, + F: FnOnce(&mut T) -> &mut U, { - OwningRefMut { - reference: f(&mut self), - owner: self.owner, - } + OwningRefMut { reference: f(&mut self), owner: self.owner } } /// Tries to convert `self` into a new _shared_ owning reference that points @@ -648,13 +623,11 @@ impl OwningRefMut { /// } /// ``` pub fn try_map(mut self, f: F) -> Result, E> - where O: StableAddress, - F: FnOnce(&mut T) -> Result<&U, E> + where + O: StableAddress, + F: FnOnce(&mut T) -> Result<&U, E>, { - Ok(OwningRef { - reference: f(&mut self)?, - owner: self.owner, - }) + Ok(OwningRef { reference: f(&mut self)?, owner: self.owner }) } /// Tries to convert `self` into a new _mutable_ owning reference that points @@ -680,13 +653,11 @@ impl OwningRefMut { /// } /// ``` pub fn try_map_mut(mut self, f: F) -> Result, E> - where O: StableAddress, - F: FnOnce(&mut T) -> Result<&mut U, E> + where + O: StableAddress, + F: FnOnce(&mut T) -> Result<&mut U, E>, { - Ok(OwningRefMut { - reference: f(&mut self)?, - owner: self.owner, - }) + Ok(OwningRefMut { reference: f(&mut self)?, owner: self.owner }) } /// Converts `self` into a new owning reference with a different owner type. @@ -695,14 +666,12 @@ impl OwningRefMut { /// so that the reference into it remains valid. This function is marked unsafe /// because the user needs to manually uphold this guarantee. pub unsafe fn map_owner(self, f: F) -> OwningRefMut - where O: StableAddress, - P: StableAddress, - F: FnOnce(O) -> P + where + O: StableAddress, + P: StableAddress, + F: FnOnce(O) -> P, { - OwningRefMut { - reference: self.reference, - owner: f(self.owner), - } + OwningRefMut { reference: self.reference, owner: f(self.owner) } } /// Converts `self` into a new owning reference where the owner is wrapped @@ -711,10 +680,7 @@ impl OwningRefMut { /// This can be used to safely erase the owner of any `OwningRefMut` /// to a `OwningRefMut, T>`. pub fn map_owner_box(self) -> OwningRefMut, T> { - OwningRefMut { - reference: self.reference, - owner: Box::new(self.owner), - } + OwningRefMut { reference: self.reference, owner: Box::new(self.owner) } } /// Erases the concrete base type of the owner with a trait object. @@ -750,12 +716,10 @@ impl OwningRefMut { /// } /// ``` pub fn erase_owner<'a>(self) -> OwningRefMut - where O: IntoErased<'a>, + where + O: IntoErased<'a>, { - OwningRefMut { - reference: self.reference, - owner: self.owner.into_erased(), - } + OwningRefMut { reference: self.reference, owner: self.owner.into_erased() } } // UNIMPLEMENTED: wrap_owner @@ -799,14 +763,18 @@ use std::ops::{Deref, DerefMut}; /// implemented for common data structures. Types that implement `ToHandle` can /// be wrapped into an `OwningHandle` without passing a callback. pub struct OwningHandle - where O: StableAddress, H: Deref, +where + O: StableAddress, + H: Deref, { handle: H, _owner: O, } impl Deref for OwningHandle - where O: StableAddress, H: Deref, +where + O: StableAddress, + H: Deref, { type Target = H::Target; fn deref(&self) -> &H::Target { @@ -815,11 +783,16 @@ impl Deref for OwningHandle } unsafe impl StableAddress for OwningHandle - where O: StableAddress, H: StableAddress, -{} +where + O: StableAddress, + H: StableAddress, +{ +} impl DerefMut for OwningHandle - where O: StableAddress, H: DerefMut, +where + O: StableAddress, + H: DerefMut, { fn deref_mut(&mut self) -> &mut H::Target { self.handle.deref_mut() @@ -871,24 +844,24 @@ where } impl OwningHandle - where O: StableAddress, H: Deref, +where + O: StableAddress, + H: Deref, { /// Creates a new OwningHandle. The provided callback will be invoked with /// a pointer to the object owned by `o`, and the returned value is stored /// as the object to which this `OwningHandle` will forward `Deref` and /// `DerefMut`. pub fn new_with_fn(o: O, f: F) -> Self - where F: FnOnce(*const O::Target) -> H + where + F: FnOnce(*const O::Target) -> H, { let h: H; { h = f(o.deref() as *const O::Target); } - OwningHandle { - handle: h, - _owner: o, - } + OwningHandle { handle: h, _owner: o } } /// Creates a new OwningHandle. The provided callback will be invoked with @@ -896,17 +869,15 @@ impl OwningHandle /// as the object to which this `OwningHandle` will forward `Deref` and /// `DerefMut`. pub fn try_new(o: O, f: F) -> Result - where F: FnOnce(*const O::Target) -> Result + where + F: FnOnce(*const O::Target) -> Result, { let h: H; { h = f(o.deref() as *const O::Target)?; } - Ok(OwningHandle { - handle: h, - _owner: o, - }) + Ok(OwningHandle { handle: h, _owner: o }) } } @@ -914,20 +885,18 @@ impl OwningHandle // std traits ///////////////////////////////////////////////////////////////////////////// +use std::borrow::Borrow; +use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; use std::convert::From; use std::fmt::{self, Debug}; -use std::marker::{Send, Sync}; -use std::cmp::{Eq, PartialEq, Ord, PartialOrd, Ordering}; use std::hash::{Hash, Hasher}; -use std::borrow::Borrow; +use std::marker::{Send, Sync}; impl Deref for OwningRef { type Target = T; fn deref(&self) -> &T { - unsafe { - &*self.reference - } + unsafe { &*self.reference } } } @@ -935,17 +904,13 @@ impl Deref for OwningRefMut { type Target = T; fn deref(&self) -> &T { - unsafe { - &*self.reference - } + unsafe { &*self.reference } } } impl DerefMut for OwningRefMut { fn deref_mut(&mut self) -> &mut T { - unsafe { - &mut *self.reference - } + unsafe { &mut *self.reference } } } @@ -976,8 +941,9 @@ impl Borrow for OwningRef { } impl From for OwningRef - where O: StableAddress, - O: Deref, +where + O: StableAddress, + O: Deref, { fn from(owner: O) -> Self { OwningRef::new(owner) @@ -985,8 +951,9 @@ impl From for OwningRef } impl From for OwningRefMut - where O: StableAddress, - O: DerefMut +where + O: StableAddress, + O: DerefMut, { fn from(owner: O) -> Self { OwningRefMut::new(owner) @@ -994,66 +961,73 @@ impl From for OwningRefMut } impl From> for OwningRef - where O: StableAddress, - O: DerefMut +where + O: StableAddress, + O: DerefMut, { fn from(other: OwningRefMut) -> Self { - OwningRef { - owner: other.owner, - reference: other.reference, - } + OwningRef { owner: other.owner, reference: other.reference } } } // ^ FIXME: Is a Into impl for calling into_inner() possible as well? impl Debug for OwningRef - where O: Debug, - T: Debug, +where + O: Debug, + T: Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, - "OwningRef {{ owner: {:?}, reference: {:?} }}", - self.owner(), - &**self) + write!(f, "OwningRef {{ owner: {:?}, reference: {:?} }}", self.owner(), &**self) } } impl Debug for OwningRefMut - where O: Debug, - T: Debug, +where + O: Debug, + T: Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, - "OwningRefMut {{ owner: {:?}, reference: {:?} }}", - self.owner(), - &**self) + write!(f, "OwningRefMut {{ owner: {:?}, reference: {:?} }}", self.owner(), &**self) } } impl Clone for OwningRef - where O: CloneStableAddress, +where + O: CloneStableAddress, { fn clone(&self) -> Self { - OwningRef { - owner: self.owner.clone(), - reference: self.reference, - } + OwningRef { owner: self.owner.clone(), reference: self.reference } } } -unsafe impl CloneStableAddress for OwningRef - where O: CloneStableAddress {} +unsafe impl CloneStableAddress for OwningRef where O: CloneStableAddress {} unsafe impl Send for OwningRef - where O: Send, for<'a> &'a T: Send {} +where + O: Send, + for<'a> &'a T: Send, +{ +} unsafe impl Sync for OwningRef - where O: Sync, for<'a> &'a T: Sync {} +where + O: Sync, + for<'a> &'a T: Sync, +{ +} unsafe impl Send for OwningRefMut - where O: Send, for<'a> &'a mut T: Send {} +where + O: Send, + for<'a> &'a mut T: Send, +{ +} unsafe impl Sync for OwningRefMut - where O: Sync, for<'a> &'a mut T: Sync {} +where + O: Sync, + for<'a> &'a mut T: Sync, +{ +} impl Debug for dyn Erased { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -1061,53 +1035,77 @@ impl Debug for dyn Erased { } } -impl PartialEq for OwningRef where T: PartialEq { +impl PartialEq for OwningRef +where + T: PartialEq, +{ fn eq(&self, other: &Self) -> bool { (&*self as &T).eq(&*other as &T) - } + } } impl Eq for OwningRef where T: Eq {} -impl PartialOrd for OwningRef where T: PartialOrd { +impl PartialOrd for OwningRef +where + T: PartialOrd, +{ fn partial_cmp(&self, other: &Self) -> Option { (&*self as &T).partial_cmp(&*other as &T) } } -impl Ord for OwningRef where T: Ord { +impl Ord for OwningRef +where + T: Ord, +{ fn cmp(&self, other: &Self) -> Ordering { (&*self as &T).cmp(&*other as &T) } } -impl Hash for OwningRef where T: Hash { +impl Hash for OwningRef +where + T: Hash, +{ fn hash(&self, state: &mut H) { (&*self as &T).hash(state); } } -impl PartialEq for OwningRefMut where T: PartialEq { +impl PartialEq for OwningRefMut +where + T: PartialEq, +{ fn eq(&self, other: &Self) -> bool { (&*self as &T).eq(&*other as &T) - } + } } impl Eq for OwningRefMut where T: Eq {} -impl PartialOrd for OwningRefMut where T: PartialOrd { +impl PartialOrd for OwningRefMut +where + T: PartialOrd, +{ fn partial_cmp(&self, other: &Self) -> Option { (&*self as &T).partial_cmp(&*other as &T) } } -impl Ord for OwningRefMut where T: Ord { +impl Ord for OwningRefMut +where + T: Ord, +{ fn cmp(&self, other: &Self) -> Ordering { (&*self as &T).cmp(&*other as &T) } } -impl Hash for OwningRefMut where T: Hash { +impl Hash for OwningRefMut +where + T: Hash, +{ fn hash(&self, state: &mut H) { (&*self as &T).hash(state); } @@ -1118,19 +1116,23 @@ impl Hash for OwningRefMut where T: Hash { ///////////////////////////////////////////////////////////////////////////// use std::boxed::Box; +use std::cell::{Ref, RefCell, RefMut}; use std::rc::Rc; use std::sync::Arc; use std::sync::{MutexGuard, RwLockReadGuard, RwLockWriteGuard}; -use std::cell::{Ref, RefCell, RefMut}; impl ToHandle for RefCell { type Handle = Ref<'static, T>; - unsafe fn to_handle(x: *const Self) -> Self::Handle { (*x).borrow() } + unsafe fn to_handle(x: *const Self) -> Self::Handle { + (*x).borrow() + } } impl ToHandleMut for RefCell { type HandleMut = RefMut<'static, T>; - unsafe fn to_handle_mut(x: *const Self) -> Self::HandleMut { (*x).borrow_mut() } + unsafe fn to_handle_mut(x: *const Self) -> Self::HandleMut { + (*x).borrow_mut() + } } // N.B., implementing ToHandle{,Mut} for Mutex and RwLock requires a decision @@ -1206,9 +1208,7 @@ unsafe impl<'a, T: Send + 'a> IntoErasedSendSync<'a> for Box { let result: Box = self; // This is safe since Erased can always implement Sync // Only the destructor is available and it takes &mut self - unsafe { - mem::transmute(result) - } + unsafe { mem::transmute(result) } } } diff --git a/src/librustc_data_structures/owning_ref/tests.rs b/src/librustc_data_structures/owning_ref/tests.rs index 5bff5e035b529..7b8179e90bd07 100644 --- a/src/librustc_data_structures/owning_ref/tests.rs +++ b/src/librustc_data_structures/owning_ref/tests.rs @@ -1,10 +1,10 @@ mod owning_ref { use super::super::OwningRef; - use super::super::{RcRef, BoxRef, Erased, ErasedBoxRef}; - use std::cmp::{PartialEq, Ord, PartialOrd, Ordering}; - use std::hash::{Hash, Hasher}; + use super::super::{BoxRef, Erased, ErasedBoxRef, RcRef}; + use std::cmp::{Ord, Ordering, PartialEq, PartialOrd}; use std::collections::hash_map::DefaultHasher; use std::collections::HashMap; + use std::hash::{Hash, Hasher}; use std::rc::Rc; #[derive(Debug, PartialEq)] @@ -60,9 +60,7 @@ mod owning_ref { #[test] fn map_chained_inference() { - let or = BoxRef::new(Box::new(example().1)) - .map(|x| &x[..5]) - .map(|x| &x[1..3]); + let or = BoxRef::new(Box::new(example().1)).map(|x| &x[..5]).map(|x| &x[1..3]); assert_eq!(&*or, "el"); } @@ -93,11 +91,9 @@ mod owning_ref { #[test] fn erased_owner() { - let o1: BoxRef = BoxRef::new(Box::new(example())) - .map(|x| &x.1[..]); + let o1: BoxRef = BoxRef::new(Box::new(example())).map(|x| &x.1[..]); - let o2: BoxRef = BoxRef::new(Box::new(example().1)) - .map(|x| &x[..]); + let o2: BoxRef = BoxRef::new(Box::new(example().1)).map(|x| &x[..]); let os: Vec> = vec![o1.erase_owner(), o2.erase_owner()]; assert!(os.iter().all(|e| &e[..] == "hello world")); @@ -105,9 +101,9 @@ mod owning_ref { #[test] fn raii_locks() { - use super::super::{RefRef, RefMutRef}; - use std::cell::RefCell; use super::super::{MutexGuardRef, RwLockReadGuardRef, RwLockWriteGuardRef}; + use super::super::{RefMutRef, RefRef}; + use std::cell::RefCell; use std::sync::{Mutex, RwLock}; { @@ -200,7 +196,7 @@ mod owning_ref { #[test] fn borrow() { let mut hash = HashMap::new(); - let key = RcRef::::new(Rc::new("foo-bar".to_string())).map(|s| &s[..]); + let key = RcRef::::new(Rc::new("foo-bar".to_string())).map(|s| &s[..]); hash.insert(key.clone().map(|s| &s[..3]), 42); hash.insert(key.clone().map(|s| &s[4..]), 23); @@ -211,13 +207,12 @@ mod owning_ref { #[test] fn total_erase() { - let a: OwningRef, [u8]> - = OwningRef::new(vec![]).map(|x| &x[..]); - let b: OwningRef, [u8]> - = OwningRef::new(vec![].into_boxed_slice()).map(|x| &x[..]); + let a: OwningRef, [u8]> = OwningRef::new(vec![]).map(|x| &x[..]); + let b: OwningRef, [u8]> = + OwningRef::new(vec![].into_boxed_slice()).map(|x| &x[..]); - let c: OwningRef>, [u8]> = unsafe {a.map_owner(Rc::new)}; - let d: OwningRef>, [u8]> = unsafe {b.map_owner(Rc::new)}; + let c: OwningRef>, [u8]> = unsafe { a.map_owner(Rc::new) }; + let d: OwningRef>, [u8]> = unsafe { b.map_owner(Rc::new) }; let e: OwningRef, [u8]> = c.erase_owner(); let f: OwningRef, [u8]> = d.erase_owner(); @@ -228,10 +223,9 @@ mod owning_ref { #[test] fn total_erase_box() { - let a: OwningRef, [u8]> - = OwningRef::new(vec![]).map(|x| &x[..]); - let b: OwningRef, [u8]> - = OwningRef::new(vec![].into_boxed_slice()).map(|x| &x[..]); + let a: OwningRef, [u8]> = OwningRef::new(vec![]).map(|x| &x[..]); + let b: OwningRef, [u8]> = + OwningRef::new(vec![].into_boxed_slice()).map(|x| &x[..]); let c: OwningRef>, [u8]> = a.map_owner_box(); let d: OwningRef>, [u8]> = b.map_owner_box(); @@ -264,8 +258,8 @@ mod owning_ref { mod owning_handle { use super::super::OwningHandle; use super::super::RcRef; - use std::rc::Rc; use std::cell::RefCell; + use std::rc::Rc; use std::sync::Arc; use std::sync::RwLock; @@ -274,9 +268,8 @@ mod owning_handle { use std::cell::RefCell; let cell = Rc::new(RefCell::new(2)); let cell_ref = RcRef::new(cell); - let mut handle = OwningHandle::new_with_fn(cell_ref, |x| { - unsafe { x.as_ref() }.unwrap().borrow_mut() - }); + let mut handle = + OwningHandle::new_with_fn(cell_ref, |x| unsafe { x.as_ref() }.unwrap().borrow_mut()); assert_eq!(*handle, 2); *handle = 3; assert_eq!(*handle, 3); @@ -288,10 +281,9 @@ mod owning_handle { let cell = Rc::new(RefCell::new(2)); let cell_ref = RcRef::new(cell); let mut handle = OwningHandle::try_new::<_, ()>(cell_ref, |x| { - Ok(unsafe { - x.as_ref() - }.unwrap().borrow_mut()) - }).unwrap(); + Ok(unsafe { x.as_ref() }.unwrap().borrow_mut()) + }) + .unwrap(); assert_eq!(*handle, 2); *handle = 3; assert_eq!(*handle, 3); @@ -304,9 +296,7 @@ mod owning_handle { let cell_ref = RcRef::new(cell); let handle = OwningHandle::try_new::<_, ()>(cell_ref, |x| { if false { - return Ok(unsafe { - x.as_ref() - }.unwrap().borrow_mut()) + return Ok(unsafe { x.as_ref() }.unwrap().borrow_mut()); } Err(()) }); @@ -321,9 +311,8 @@ mod owning_handle { let result = { let complex = Rc::new(RefCell::new(Arc::new(RwLock::new("someString")))); let curr = RcRef::new(complex); - let curr = OwningHandle::new_with_fn(curr, |x| { - unsafe { x.as_ref() }.unwrap().borrow_mut() - }); + let curr = + OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().borrow_mut()); let mut curr = OwningHandle::new_with_fn(curr, |x| { unsafe { x.as_ref() }.unwrap().try_write().unwrap() }); @@ -359,9 +348,8 @@ mod owning_handle { let result = { let complex = Rc::new(RefCell::new(Arc::new(RwLock::new("someString")))); let curr = RcRef::new(complex); - let curr = OwningHandle::new_with_fn(curr, |x| { - unsafe { x.as_ref() }.unwrap().borrow_mut() - }); + let curr = + OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().borrow_mut()); let mut curr = OwningHandle::new_with_fn(curr, |x| { unsafe { x.as_ref() }.unwrap().try_write().unwrap() }); @@ -374,12 +362,12 @@ mod owning_handle { } mod owning_ref_mut { - use super::super::{OwningRefMut, BoxRefMut, Erased, ErasedBoxRefMut}; use super::super::BoxRef; - use std::cmp::{PartialEq, Ord, PartialOrd, Ordering}; - use std::hash::{Hash, Hasher}; + use super::super::{BoxRefMut, Erased, ErasedBoxRefMut, OwningRefMut}; + use std::cmp::{Ord, Ordering, PartialEq, PartialOrd}; use std::collections::hash_map::DefaultHasher; use std::collections::HashMap; + use std::hash::{Hash, Hasher}; #[derive(Debug, PartialEq)] struct Example(u32, String, [u8; 3]); @@ -516,17 +504,16 @@ mod owning_ref_mut { let or: BoxRefMut = Box::new(example().1).into(); let or = or.map_mut(|x| &mut x[..5]); let s = format!("{:?}", or); - assert_eq!(&s, - "OwningRefMut { owner: \"hello world\", reference: \"hello\" }"); + assert_eq!(&s, "OwningRefMut { owner: \"hello world\", reference: \"hello\" }"); } #[test] fn erased_owner() { - let o1: BoxRefMut = BoxRefMut::new(Box::new(example())) - .map_mut(|x| &mut x.1[..]); + let o1: BoxRefMut = + BoxRefMut::new(Box::new(example())).map_mut(|x| &mut x.1[..]); - let o2: BoxRefMut = BoxRefMut::new(Box::new(example().1)) - .map_mut(|x| &mut x[..]); + let o2: BoxRefMut = + BoxRefMut::new(Box::new(example().1)).map_mut(|x| &mut x[..]); let os: Vec> = vec![o1.erase_owner(), o2.erase_owner()]; assert!(os.iter().all(|e| &e[..] == "hello world")); @@ -535,8 +522,8 @@ mod owning_ref_mut { #[test] fn raii_locks() { use super::super::RefMutRefMut; - use std::cell::RefCell; use super::super::{MutexGuardRefMut, RwLockWriteGuardRefMut}; + use std::cell::RefCell; use std::sync::{Mutex, RwLock}; { @@ -609,8 +596,8 @@ mod owning_ref_mut { #[test] fn borrow() { let mut hash = HashMap::new(); - let key1 = BoxRefMut::::new(Box::new("foo".to_string())).map(|s| &s[..]); - let key2 = BoxRefMut::::new(Box::new("bar".to_string())).map(|s| &s[..]); + let key1 = BoxRefMut::::new(Box::new("foo".to_string())).map(|s| &s[..]); + let key2 = BoxRefMut::::new(Box::new("bar".to_string())).map(|s| &s[..]); hash.insert(key1, 42); hash.insert(key2, 23); @@ -621,13 +608,12 @@ mod owning_ref_mut { #[test] fn total_erase() { - let a: OwningRefMut, [u8]> - = OwningRefMut::new(vec![]).map_mut(|x| &mut x[..]); - let b: OwningRefMut, [u8]> - = OwningRefMut::new(vec![].into_boxed_slice()).map_mut(|x| &mut x[..]); + let a: OwningRefMut, [u8]> = OwningRefMut::new(vec![]).map_mut(|x| &mut x[..]); + let b: OwningRefMut, [u8]> = + OwningRefMut::new(vec![].into_boxed_slice()).map_mut(|x| &mut x[..]); - let c: OwningRefMut>, [u8]> = unsafe {a.map_owner(Box::new)}; - let d: OwningRefMut>, [u8]> = unsafe {b.map_owner(Box::new)}; + let c: OwningRefMut>, [u8]> = unsafe { a.map_owner(Box::new) }; + let d: OwningRefMut>, [u8]> = unsafe { b.map_owner(Box::new) }; let _e: OwningRefMut, [u8]> = c.erase_owner(); let _f: OwningRefMut, [u8]> = d.erase_owner(); @@ -635,10 +621,9 @@ mod owning_ref_mut { #[test] fn total_erase_box() { - let a: OwningRefMut, [u8]> - = OwningRefMut::new(vec![]).map_mut(|x| &mut x[..]); - let b: OwningRefMut, [u8]> - = OwningRefMut::new(vec![].into_boxed_slice()).map_mut(|x| &mut x[..]); + let a: OwningRefMut, [u8]> = OwningRefMut::new(vec![]).map_mut(|x| &mut x[..]); + let b: OwningRefMut, [u8]> = + OwningRefMut::new(vec![].into_boxed_slice()).map_mut(|x| &mut x[..]); let c: OwningRefMut>, [u8]> = a.map_owner_box(); let d: OwningRefMut>, [u8]> = b.map_owner_box(); diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index f9bfe5a1652ae..73dd3b0b3f3e5 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use std::thread::ThreadId; use std::u32; -use measureme::{StringId}; +use measureme::StringId; /// MmapSerializatioSink is faster on macOS and Linux /// but FileSerializationSink is faster on Windows @@ -59,7 +59,7 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[ ("generic-activity", EventFilter::GENERIC_ACTIVITIES), ("query-provider", EventFilter::QUERY_PROVIDERS), ("query-cache-hit", EventFilter::QUERY_CACHE_HITS), - ("query-blocked" , EventFilter::QUERY_BLOCKED), + ("query-blocked", EventFilter::QUERY_BLOCKED), ("incr-cache-load", EventFilter::INCR_CACHE_LOADS), ]; @@ -67,7 +67,6 @@ fn thread_id_to_u32(tid: ThreadId) -> u32 { unsafe { mem::transmute::(tid) as u32 } } - /// A reference to the SelfProfiler. It can be cloned and sent across thread /// boundaries at will. #[derive(Clone)] @@ -83,19 +82,13 @@ pub struct SelfProfilerRef { } impl SelfProfilerRef { - pub fn new(profiler: Option>) -> SelfProfilerRef { // If there is no SelfProfiler then the filter mask is set to NONE, // ensuring that nothing ever tries to actually access it. - let event_filter_mask = profiler - .as_ref() - .map(|p| p.event_filter_mask) - .unwrap_or(EventFilter::NONE); + let event_filter_mask = + profiler.as_ref().map(|p| p.event_filter_mask).unwrap_or(EventFilter::NONE); - SelfProfilerRef { - profiler, - event_filter_mask, - } + SelfProfilerRef { profiler, event_filter_mask } } // This shim makes sure that calls only get executed if the filter mask @@ -105,11 +98,13 @@ impl SelfProfilerRef { // path. #[inline(always)] fn exec(&self, event_filter: EventFilter, f: F) -> TimingGuard<'_> - where F: for<'a> FnOnce(&'a SelfProfiler) -> TimingGuard<'a> + where + F: for<'a> FnOnce(&'a SelfProfiler) -> TimingGuard<'a>, { #[inline(never)] fn cold_call(profiler_ref: &SelfProfilerRef, f: F) -> TimingGuard<'_> - where F: for<'a> FnOnce(&'a SelfProfiler) -> TimingGuard<'a> + where + F: for<'a> FnOnce(&'a SelfProfiler) -> TimingGuard<'a>, { let profiler = profiler_ref.profiler.as_ref().unwrap(); f(&**profiler) @@ -128,11 +123,7 @@ impl SelfProfilerRef { pub fn generic_activity(&self, event_id: &str) -> TimingGuard<'_> { self.exec(EventFilter::GENERIC_ACTIVITIES, |profiler| { let event_id = profiler.profiler.alloc_string(event_id); - TimingGuard::start( - profiler, - profiler.generic_activity_event_kind, - event_id - ) + TimingGuard::start(profiler, profiler.generic_activity_event_kind, event_id) }) } @@ -174,11 +165,7 @@ impl SelfProfilerRef { pub fn incr_cache_loading(&self, query_name: impl QueryName) -> TimingGuard<'_> { self.exec(EventFilter::INCR_CACHE_LOADS, |profiler| { let event_id = SelfProfiler::get_query_name_string_id(query_name); - TimingGuard::start( - profiler, - profiler.incremental_load_result_event_kind, - event_id - ) + TimingGuard::start(profiler, profiler.incremental_load_result_event_kind, event_id) }) } @@ -193,11 +180,7 @@ impl SelfProfilerRef { let event_id = SelfProfiler::get_query_name_string_id(query_name); let thread_id = thread_id_to_u32(std::thread::current().id()); - profiler.profiler.record_instant_event( - event_kind(profiler), - event_id, - thread_id, - ); + profiler.profiler.record_instant_event(event_kind(profiler), event_id, thread_id); TimingGuard::none() })); @@ -224,7 +207,7 @@ impl SelfProfiler { pub fn new( output_directory: &Path, crate_name: Option<&str>, - event_filters: &Option> + event_filters: &Option>, ) -> Result> { fs::create_dir_all(output_directory)?; @@ -244,8 +227,9 @@ impl SelfProfiler { if let Some(ref event_filters) = *event_filters { let mut unknown_events = vec![]; for item in event_filters { - if let Some(&(_, mask)) = EVENT_FILTERS_BY_NAME.iter() - .find(|&(name, _)| name == item) { + if let Some(&(_, mask)) = + EVENT_FILTERS_BY_NAME.iter().find(|&(name, _)| name == item) + { event_filter_mask |= mask; } else { unknown_events.push(item.clone()); @@ -257,12 +241,15 @@ impl SelfProfiler { unknown_events.sort(); unknown_events.dedup(); - warn!("Unknown self-profiler events specified: {}. Available options are: {}.", + warn!( + "Unknown self-profiler events specified: {}. Available options are: {}.", unknown_events.join(", "), - EVENT_FILTERS_BY_NAME.iter() - .map(|&(name, _)| name.to_string()) - .collect::>() - .join(", ")); + EVENT_FILTERS_BY_NAME + .iter() + .map(|&(name, _)| name.to_string()) + .collect::>() + .join(", ") + ); } } else { event_filter_mask = EventFilter::DEFAULT; @@ -280,9 +267,8 @@ impl SelfProfiler { } fn get_query_name_string_id(query_name: impl QueryName) -> StringId { - let discriminant = unsafe { - mem::transmute::, u64>(query_name.discriminant()) - }; + let discriminant = + unsafe { mem::transmute::, u64>(query_name.discriminant()) }; StringId::reserved(discriminant as u32) } @@ -305,9 +291,8 @@ impl<'a> TimingGuard<'a> { ) -> TimingGuard<'a> { let thread_id = thread_id_to_u32(std::thread::current().id()); let raw_profiler = &profiler.profiler; - let timing_guard = raw_profiler.start_recording_interval_event(event_kind, - event_id, - thread_id); + let timing_guard = + raw_profiler.start_recording_interval_event(event_kind, event_id, thread_id); TimingGuard(Some(timing_guard)) } diff --git a/src/librustc_data_structures/ptr_key.rs b/src/librustc_data_structures/ptr_key.rs index bf3ae2d7af58f..440ccb05d86e4 100644 --- a/src/librustc_data_structures/ptr_key.rs +++ b/src/librustc_data_structures/ptr_key.rs @@ -1,5 +1,5 @@ -use std::{hash, ptr}; use std::ops::Deref; +use std::{hash, ptr}; /// A wrapper around reference that compares and hashes like a pointer. /// Can be used as a key in sets/maps indexed by pointers to avoid `unsafe`. @@ -7,7 +7,9 @@ use std::ops::Deref; pub struct PtrKey<'a, T>(pub &'a T); impl<'a, T> Clone for PtrKey<'a, T> { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } impl<'a, T> Copy for PtrKey<'a, T> {} diff --git a/src/librustc_data_structures/sharded.rs b/src/librustc_data_structures/sharded.rs index a28a5e0f0415a..8b85d97a1d4fe 100644 --- a/src/librustc_data_structures/sharded.rs +++ b/src/librustc_data_structures/sharded.rs @@ -1,10 +1,10 @@ -use std::hash::{Hasher, Hash}; -use std::mem; +use crate::fx::{FxHashMap, FxHasher}; +use crate::sync::{Lock, LockGuard}; +use smallvec::SmallVec; use std::borrow::Borrow; use std::collections::hash_map::RawEntryMut; -use smallvec::SmallVec; -use crate::fx::{FxHasher, FxHashMap}; -use crate::sync::{Lock, LockGuard}; +use std::hash::{Hash, Hasher}; +use std::mem; #[derive(Clone, Default)] #[cfg_attr(parallel_compiler, repr(align(64)))] @@ -38,9 +38,8 @@ impl Sharded { #[inline] pub fn new(mut value: impl FnMut() -> T) -> Self { // Create a vector of the values we want - let mut values: SmallVec<[_; SHARDS]> = (0..SHARDS).map(|_| { - CacheAligned(Lock::new(value())) - }).collect(); + let mut values: SmallVec<[_; SHARDS]> = + (0..SHARDS).map(|_| CacheAligned(Lock::new(value()))).collect(); // Create an unintialized array let mut shards: mem::MaybeUninit<[CacheAligned>; SHARDS]> = @@ -54,20 +53,14 @@ impl Sharded { // Ignore the content of the vector values.set_len(0); - Sharded { - shards: shards.assume_init(), - } + Sharded { shards: shards.assume_init() } } } /// The shard is selected by hashing `val` with `FxHasher`. #[inline] pub fn get_shard_by_value(&self, val: &K) -> &Lock { - if SHARDS == 1 { - &self.shards[0].0 - } else { - self.get_shard_by_hash(make_hash(val)) - } + if SHARDS == 1 { &self.shards[0].0 } else { self.get_shard_by_hash(make_hash(val)) } } /// Get a shard with a pre-computed hash value. If `get_shard_by_value` is @@ -105,8 +98,9 @@ impl ShardedHashMap { impl ShardedHashMap { #[inline] pub fn intern_ref(&self, value: &Q, make: impl FnOnce() -> K) -> K - where K: Borrow, - Q: Hash + Eq + where + K: Borrow, + Q: Hash + Eq, { let hash = make_hash(value); let mut shard = self.get_shard_by_hash(hash).lock(); @@ -124,8 +118,9 @@ impl ShardedHashMap { #[inline] pub fn intern(&self, value: Q, make: impl FnOnce(Q) -> K) -> K - where K: Borrow, - Q: Hash + Eq + where + K: Borrow, + Q: Hash + Eq, { let hash = make_hash(&value); let mut shard = self.get_shard_by_hash(hash).lock(); diff --git a/src/librustc_data_structures/sip128.rs b/src/librustc_data_structures/sip128.rs index 1c58eda24f459..f805be8499b63 100644 --- a/src/librustc_data_structures/sip128.rs +++ b/src/librustc_data_structures/sip128.rs @@ -2,9 +2,9 @@ use std::cmp; use std::hash::Hasher; -use std::slice; -use std::ptr; use std::mem; +use std::ptr; +use std::slice; #[cfg(test)] mod tests; @@ -14,9 +14,9 @@ pub struct SipHasher128 { k0: u64, k1: u64, length: usize, // how many bytes we've processed - state: State, // hash State - tail: u64, // unprocessed bytes le - ntail: usize, // how many bytes in tail are valid + state: State, // hash State + tail: u64, // unprocessed bytes le + ntail: usize, // how many bytes in tail are valid } #[derive(Debug, Clone, Copy)] @@ -33,18 +33,23 @@ struct State { } macro_rules! compress { - ($state:expr) => ({ - compress!($state.v0, $state.v1, $state.v2, $state.v3) - }); - ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => - ({ - $v0 = $v0.wrapping_add($v1); $v1 = $v1.rotate_left(13); $v1 ^= $v0; + ($state:expr) => {{ compress!($state.v0, $state.v1, $state.v2, $state.v3) }}; + ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {{ + $v0 = $v0.wrapping_add($v1); + $v1 = $v1.rotate_left(13); + $v1 ^= $v0; $v0 = $v0.rotate_left(32); - $v2 = $v2.wrapping_add($v3); $v3 = $v3.rotate_left(16); $v3 ^= $v2; - $v0 = $v0.wrapping_add($v3); $v3 = $v3.rotate_left(21); $v3 ^= $v0; - $v2 = $v2.wrapping_add($v1); $v1 = $v1.rotate_left(17); $v1 ^= $v2; + $v2 = $v2.wrapping_add($v3); + $v3 = $v3.rotate_left(16); + $v3 ^= $v2; + $v0 = $v0.wrapping_add($v3); + $v3 = $v3.rotate_left(21); + $v3 ^= $v0; + $v2 = $v2.wrapping_add($v1); + $v1 = $v1.rotate_left(17); + $v1 ^= $v2; $v2 = $v2.rotate_left(32); - }); + }}; } /// Loads an integer of the desired type from a byte stream, in LE order. Uses @@ -53,15 +58,16 @@ macro_rules! compress { /// /// Unsafe because: unchecked indexing at i..i+size_of(int_ty) macro_rules! load_int_le { - ($buf:expr, $i:expr, $int_ty:ident) => - ({ - debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len()); - let mut data = 0 as $int_ty; - ptr::copy_nonoverlapping($buf.get_unchecked($i), - &mut data as *mut _ as *mut u8, - mem::size_of::<$int_ty>()); - data.to_le() - }); + ($buf:expr, $i:expr, $int_ty:ident) => {{ + debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len()); + let mut data = 0 as $int_ty; + ptr::copy_nonoverlapping( + $buf.get_unchecked($i), + &mut data as *mut _ as *mut u8, + mem::size_of::<$int_ty>(), + ); + data.to_le() + }}; } /// Loads an u64 using up to 7 bytes of a byte slice. @@ -88,7 +94,6 @@ unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 { out } - impl SipHasher128 { #[inline] pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher128 { @@ -96,12 +101,7 @@ impl SipHasher128 { k0: key0, k1: key1, length: 0, - state: State { - v0: 0, - v1: 0, - v2: 0, - v3: 0, - }, + state: State { v0: 0, v1: 0, v2: 0, v3: 0 }, tail: 0, ntail: 0, }; @@ -155,9 +155,8 @@ impl SipHasher128 { #[inline(always)] fn short_write_gen(&mut self, x: T) { - let bytes = unsafe { - slice::from_raw_parts(&x as *const T as *const u8, mem::size_of::()) - }; + let bytes = + unsafe { slice::from_raw_parts(&x as *const T as *const u8, mem::size_of::()) }; self.short_write(bytes); } @@ -243,7 +242,7 @@ impl Hasher for SipHasher128 { self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail); if length < needed { self.ntail += length; - return + return; } else { self.state.v3 ^= self.tail; Sip24Rounds::c_rounds(&mut self.state); diff --git a/src/librustc_data_structures/sip128/tests.rs b/src/librustc_data_structures/sip128/tests.rs index 90cc54448b407..80b7fc7475610 100644 --- a/src/librustc_data_structures/sip128/tests.rs +++ b/src/librustc_data_structures/sip128/tests.rs @@ -1,7 +1,7 @@ use super::*; use std::hash::{Hash, Hasher}; -use std::{slice, mem}; +use std::{mem, slice}; // Hash just the bytes of the slice, without length prefix struct Bytes<'a>(&'a [u8]); @@ -24,71 +24,263 @@ fn hash(x: &T) -> (u64, u64) { hash_with(SipHasher128::new_with_keys(0, 0), x) } -const TEST_VECTOR : [[u8; 16]; 64] = [ - [0xa3,0x81,0x7f,0x04,0xba,0x25,0xa8,0xe6,0x6d,0xf6,0x72,0x14,0xc7,0x55,0x02,0x93], - [0xda,0x87,0xc1,0xd8,0x6b,0x99,0xaf,0x44,0x34,0x76,0x59,0x11,0x9b,0x22,0xfc,0x45], - [0x81,0x77,0x22,0x8d,0xa4,0xa4,0x5d,0xc7,0xfc,0xa3,0x8b,0xde,0xf6,0x0a,0xff,0xe4], - [0x9c,0x70,0xb6,0x0c,0x52,0x67,0xa9,0x4e,0x5f,0x33,0xb6,0xb0,0x29,0x85,0xed,0x51], - [0xf8,0x81,0x64,0xc1,0x2d,0x9c,0x8f,0xaf,0x7d,0x0f,0x6e,0x7c,0x7b,0xcd,0x55,0x79], - [0x13,0x68,0x87,0x59,0x80,0x77,0x6f,0x88,0x54,0x52,0x7a,0x07,0x69,0x0e,0x96,0x27], - [0x14,0xee,0xca,0x33,0x8b,0x20,0x86,0x13,0x48,0x5e,0xa0,0x30,0x8f,0xd7,0xa1,0x5e], - [0xa1,0xf1,0xeb,0xbe,0xd8,0xdb,0xc1,0x53,0xc0,0xb8,0x4a,0xa6,0x1f,0xf0,0x82,0x39], - [0x3b,0x62,0xa9,0xba,0x62,0x58,0xf5,0x61,0x0f,0x83,0xe2,0x64,0xf3,0x14,0x97,0xb4], - [0x26,0x44,0x99,0x06,0x0a,0xd9,0xba,0xab,0xc4,0x7f,0x8b,0x02,0xbb,0x6d,0x71,0xed], - [0x00,0x11,0x0d,0xc3,0x78,0x14,0x69,0x56,0xc9,0x54,0x47,0xd3,0xf3,0xd0,0xfb,0xba], - [0x01,0x51,0xc5,0x68,0x38,0x6b,0x66,0x77,0xa2,0xb4,0xdc,0x6f,0x81,0xe5,0xdc,0x18], - [0xd6,0x26,0xb2,0x66,0x90,0x5e,0xf3,0x58,0x82,0x63,0x4d,0xf6,0x85,0x32,0xc1,0x25], - [0x98,0x69,0xe2,0x47,0xe9,0xc0,0x8b,0x10,0xd0,0x29,0x93,0x4f,0xc4,0xb9,0x52,0xf7], - [0x31,0xfc,0xef,0xac,0x66,0xd7,0xde,0x9c,0x7e,0xc7,0x48,0x5f,0xe4,0x49,0x49,0x02], - [0x54,0x93,0xe9,0x99,0x33,0xb0,0xa8,0x11,0x7e,0x08,0xec,0x0f,0x97,0xcf,0xc3,0xd9], - [0x6e,0xe2,0xa4,0xca,0x67,0xb0,0x54,0xbb,0xfd,0x33,0x15,0xbf,0x85,0x23,0x05,0x77], - [0x47,0x3d,0x06,0xe8,0x73,0x8d,0xb8,0x98,0x54,0xc0,0x66,0xc4,0x7a,0xe4,0x77,0x40], - [0xa4,0x26,0xe5,0xe4,0x23,0xbf,0x48,0x85,0x29,0x4d,0xa4,0x81,0xfe,0xae,0xf7,0x23], - [0x78,0x01,0x77,0x31,0xcf,0x65,0xfa,0xb0,0x74,0xd5,0x20,0x89,0x52,0x51,0x2e,0xb1], - [0x9e,0x25,0xfc,0x83,0x3f,0x22,0x90,0x73,0x3e,0x93,0x44,0xa5,0xe8,0x38,0x39,0xeb], - [0x56,0x8e,0x49,0x5a,0xbe,0x52,0x5a,0x21,0x8a,0x22,0x14,0xcd,0x3e,0x07,0x1d,0x12], - [0x4a,0x29,0xb5,0x45,0x52,0xd1,0x6b,0x9a,0x46,0x9c,0x10,0x52,0x8e,0xff,0x0a,0xae], - [0xc9,0xd1,0x84,0xdd,0xd5,0xa9,0xf5,0xe0,0xcf,0x8c,0xe2,0x9a,0x9a,0xbf,0x69,0x1c], - [0x2d,0xb4,0x79,0xae,0x78,0xbd,0x50,0xd8,0x88,0x2a,0x8a,0x17,0x8a,0x61,0x32,0xad], - [0x8e,0xce,0x5f,0x04,0x2d,0x5e,0x44,0x7b,0x50,0x51,0xb9,0xea,0xcb,0x8d,0x8f,0x6f], - [0x9c,0x0b,0x53,0xb4,0xb3,0xc3,0x07,0xe8,0x7e,0xae,0xe0,0x86,0x78,0x14,0x1f,0x66], - [0xab,0xf2,0x48,0xaf,0x69,0xa6,0xea,0xe4,0xbf,0xd3,0xeb,0x2f,0x12,0x9e,0xeb,0x94], - [0x06,0x64,0xda,0x16,0x68,0x57,0x4b,0x88,0xb9,0x35,0xf3,0x02,0x73,0x58,0xae,0xf4], - [0xaa,0x4b,0x9d,0xc4,0xbf,0x33,0x7d,0xe9,0x0c,0xd4,0xfd,0x3c,0x46,0x7c,0x6a,0xb7], - [0xea,0x5c,0x7f,0x47,0x1f,0xaf,0x6b,0xde,0x2b,0x1a,0xd7,0xd4,0x68,0x6d,0x22,0x87], - [0x29,0x39,0xb0,0x18,0x32,0x23,0xfa,0xfc,0x17,0x23,0xde,0x4f,0x52,0xc4,0x3d,0x35], - [0x7c,0x39,0x56,0xca,0x5e,0xea,0xfc,0x3e,0x36,0x3e,0x9d,0x55,0x65,0x46,0xeb,0x68], - [0x77,0xc6,0x07,0x71,0x46,0xf0,0x1c,0x32,0xb6,0xb6,0x9d,0x5f,0x4e,0xa9,0xff,0xcf], - [0x37,0xa6,0x98,0x6c,0xb8,0x84,0x7e,0xdf,0x09,0x25,0xf0,0xf1,0x30,0x9b,0x54,0xde], - [0xa7,0x05,0xf0,0xe6,0x9d,0xa9,0xa8,0xf9,0x07,0x24,0x1a,0x2e,0x92,0x3c,0x8c,0xc8], - [0x3d,0xc4,0x7d,0x1f,0x29,0xc4,0x48,0x46,0x1e,0x9e,0x76,0xed,0x90,0x4f,0x67,0x11], - [0x0d,0x62,0xbf,0x01,0xe6,0xfc,0x0e,0x1a,0x0d,0x3c,0x47,0x51,0xc5,0xd3,0x69,0x2b], - [0x8c,0x03,0x46,0x8b,0xca,0x7c,0x66,0x9e,0xe4,0xfd,0x5e,0x08,0x4b,0xbe,0xe7,0xb5], - [0x52,0x8a,0x5b,0xb9,0x3b,0xaf,0x2c,0x9c,0x44,0x73,0xcc,0xe5,0xd0,0xd2,0x2b,0xd9], - [0xdf,0x6a,0x30,0x1e,0x95,0xc9,0x5d,0xad,0x97,0xae,0x0c,0xc8,0xc6,0x91,0x3b,0xd8], - [0x80,0x11,0x89,0x90,0x2c,0x85,0x7f,0x39,0xe7,0x35,0x91,0x28,0x5e,0x70,0xb6,0xdb], - [0xe6,0x17,0x34,0x6a,0xc9,0xc2,0x31,0xbb,0x36,0x50,0xae,0x34,0xcc,0xca,0x0c,0x5b], - [0x27,0xd9,0x34,0x37,0xef,0xb7,0x21,0xaa,0x40,0x18,0x21,0xdc,0xec,0x5a,0xdf,0x89], - [0x89,0x23,0x7d,0x9d,0xed,0x9c,0x5e,0x78,0xd8,0xb1,0xc9,0xb1,0x66,0xcc,0x73,0x42], - [0x4a,0x6d,0x80,0x91,0xbf,0x5e,0x7d,0x65,0x11,0x89,0xfa,0x94,0xa2,0x50,0xb1,0x4c], - [0x0e,0x33,0xf9,0x60,0x55,0xe7,0xae,0x89,0x3f,0xfc,0x0e,0x3d,0xcf,0x49,0x29,0x02], - [0xe6,0x1c,0x43,0x2b,0x72,0x0b,0x19,0xd1,0x8e,0xc8,0xd8,0x4b,0xdc,0x63,0x15,0x1b], - [0xf7,0xe5,0xae,0xf5,0x49,0xf7,0x82,0xcf,0x37,0x90,0x55,0xa6,0x08,0x26,0x9b,0x16], - [0x43,0x8d,0x03,0x0f,0xd0,0xb7,0xa5,0x4f,0xa8,0x37,0xf2,0xad,0x20,0x1a,0x64,0x03], - [0xa5,0x90,0xd3,0xee,0x4f,0xbf,0x04,0xe3,0x24,0x7e,0x0d,0x27,0xf2,0x86,0x42,0x3f], - [0x5f,0xe2,0xc1,0xa1,0x72,0xfe,0x93,0xc4,0xb1,0x5c,0xd3,0x7c,0xae,0xf9,0xf5,0x38], - [0x2c,0x97,0x32,0x5c,0xbd,0x06,0xb3,0x6e,0xb2,0x13,0x3d,0xd0,0x8b,0x3a,0x01,0x7c], - [0x92,0xc8,0x14,0x22,0x7a,0x6b,0xca,0x94,0x9f,0xf0,0x65,0x9f,0x00,0x2a,0xd3,0x9e], - [0xdc,0xe8,0x50,0x11,0x0b,0xd8,0x32,0x8c,0xfb,0xd5,0x08,0x41,0xd6,0x91,0x1d,0x87], - [0x67,0xf1,0x49,0x84,0xc7,0xda,0x79,0x12,0x48,0xe3,0x2b,0xb5,0x92,0x25,0x83,0xda], - [0x19,0x38,0xf2,0xcf,0x72,0xd5,0x4e,0xe9,0x7e,0x94,0x16,0x6f,0xa9,0x1d,0x2a,0x36], - [0x74,0x48,0x1e,0x96,0x46,0xed,0x49,0xfe,0x0f,0x62,0x24,0x30,0x16,0x04,0x69,0x8e], - [0x57,0xfc,0xa5,0xde,0x98,0xa9,0xd6,0xd8,0x00,0x64,0x38,0xd0,0x58,0x3d,0x8a,0x1d], - [0x9f,0xec,0xde,0x1c,0xef,0xdc,0x1c,0xbe,0xd4,0x76,0x36,0x74,0xd9,0x57,0x53,0x59], - [0xe3,0x04,0x0c,0x00,0xeb,0x28,0xf1,0x53,0x66,0xca,0x73,0xcb,0xd8,0x72,0xe7,0x40], - [0x76,0x97,0x00,0x9a,0x6a,0x83,0x1d,0xfe,0xcc,0xa9,0x1c,0x59,0x93,0x67,0x0f,0x7a], - [0x58,0x53,0x54,0x23,0x21,0xf5,0x67,0xa0,0x05,0xd5,0x47,0xa4,0xf0,0x47,0x59,0xbd], - [0x51,0x50,0xd1,0x77,0x2f,0x50,0x83,0x4a,0x50,0x3e,0x06,0x9a,0x97,0x3f,0xbd,0x7c], +const TEST_VECTOR: [[u8; 16]; 64] = [ + [ + 0xa3, 0x81, 0x7f, 0x04, 0xba, 0x25, 0xa8, 0xe6, 0x6d, 0xf6, 0x72, 0x14, 0xc7, 0x55, 0x02, + 0x93, + ], + [ + 0xda, 0x87, 0xc1, 0xd8, 0x6b, 0x99, 0xaf, 0x44, 0x34, 0x76, 0x59, 0x11, 0x9b, 0x22, 0xfc, + 0x45, + ], + [ + 0x81, 0x77, 0x22, 0x8d, 0xa4, 0xa4, 0x5d, 0xc7, 0xfc, 0xa3, 0x8b, 0xde, 0xf6, 0x0a, 0xff, + 0xe4, + ], + [ + 0x9c, 0x70, 0xb6, 0x0c, 0x52, 0x67, 0xa9, 0x4e, 0x5f, 0x33, 0xb6, 0xb0, 0x29, 0x85, 0xed, + 0x51, + ], + [ + 0xf8, 0x81, 0x64, 0xc1, 0x2d, 0x9c, 0x8f, 0xaf, 0x7d, 0x0f, 0x6e, 0x7c, 0x7b, 0xcd, 0x55, + 0x79, + ], + [ + 0x13, 0x68, 0x87, 0x59, 0x80, 0x77, 0x6f, 0x88, 0x54, 0x52, 0x7a, 0x07, 0x69, 0x0e, 0x96, + 0x27, + ], + [ + 0x14, 0xee, 0xca, 0x33, 0x8b, 0x20, 0x86, 0x13, 0x48, 0x5e, 0xa0, 0x30, 0x8f, 0xd7, 0xa1, + 0x5e, + ], + [ + 0xa1, 0xf1, 0xeb, 0xbe, 0xd8, 0xdb, 0xc1, 0x53, 0xc0, 0xb8, 0x4a, 0xa6, 0x1f, 0xf0, 0x82, + 0x39, + ], + [ + 0x3b, 0x62, 0xa9, 0xba, 0x62, 0x58, 0xf5, 0x61, 0x0f, 0x83, 0xe2, 0x64, 0xf3, 0x14, 0x97, + 0xb4, + ], + [ + 0x26, 0x44, 0x99, 0x06, 0x0a, 0xd9, 0xba, 0xab, 0xc4, 0x7f, 0x8b, 0x02, 0xbb, 0x6d, 0x71, + 0xed, + ], + [ + 0x00, 0x11, 0x0d, 0xc3, 0x78, 0x14, 0x69, 0x56, 0xc9, 0x54, 0x47, 0xd3, 0xf3, 0xd0, 0xfb, + 0xba, + ], + [ + 0x01, 0x51, 0xc5, 0x68, 0x38, 0x6b, 0x66, 0x77, 0xa2, 0xb4, 0xdc, 0x6f, 0x81, 0xe5, 0xdc, + 0x18, + ], + [ + 0xd6, 0x26, 0xb2, 0x66, 0x90, 0x5e, 0xf3, 0x58, 0x82, 0x63, 0x4d, 0xf6, 0x85, 0x32, 0xc1, + 0x25, + ], + [ + 0x98, 0x69, 0xe2, 0x47, 0xe9, 0xc0, 0x8b, 0x10, 0xd0, 0x29, 0x93, 0x4f, 0xc4, 0xb9, 0x52, + 0xf7, + ], + [ + 0x31, 0xfc, 0xef, 0xac, 0x66, 0xd7, 0xde, 0x9c, 0x7e, 0xc7, 0x48, 0x5f, 0xe4, 0x49, 0x49, + 0x02, + ], + [ + 0x54, 0x93, 0xe9, 0x99, 0x33, 0xb0, 0xa8, 0x11, 0x7e, 0x08, 0xec, 0x0f, 0x97, 0xcf, 0xc3, + 0xd9, + ], + [ + 0x6e, 0xe2, 0xa4, 0xca, 0x67, 0xb0, 0x54, 0xbb, 0xfd, 0x33, 0x15, 0xbf, 0x85, 0x23, 0x05, + 0x77, + ], + [ + 0x47, 0x3d, 0x06, 0xe8, 0x73, 0x8d, 0xb8, 0x98, 0x54, 0xc0, 0x66, 0xc4, 0x7a, 0xe4, 0x77, + 0x40, + ], + [ + 0xa4, 0x26, 0xe5, 0xe4, 0x23, 0xbf, 0x48, 0x85, 0x29, 0x4d, 0xa4, 0x81, 0xfe, 0xae, 0xf7, + 0x23, + ], + [ + 0x78, 0x01, 0x77, 0x31, 0xcf, 0x65, 0xfa, 0xb0, 0x74, 0xd5, 0x20, 0x89, 0x52, 0x51, 0x2e, + 0xb1, + ], + [ + 0x9e, 0x25, 0xfc, 0x83, 0x3f, 0x22, 0x90, 0x73, 0x3e, 0x93, 0x44, 0xa5, 0xe8, 0x38, 0x39, + 0xeb, + ], + [ + 0x56, 0x8e, 0x49, 0x5a, 0xbe, 0x52, 0x5a, 0x21, 0x8a, 0x22, 0x14, 0xcd, 0x3e, 0x07, 0x1d, + 0x12, + ], + [ + 0x4a, 0x29, 0xb5, 0x45, 0x52, 0xd1, 0x6b, 0x9a, 0x46, 0x9c, 0x10, 0x52, 0x8e, 0xff, 0x0a, + 0xae, + ], + [ + 0xc9, 0xd1, 0x84, 0xdd, 0xd5, 0xa9, 0xf5, 0xe0, 0xcf, 0x8c, 0xe2, 0x9a, 0x9a, 0xbf, 0x69, + 0x1c, + ], + [ + 0x2d, 0xb4, 0x79, 0xae, 0x78, 0xbd, 0x50, 0xd8, 0x88, 0x2a, 0x8a, 0x17, 0x8a, 0x61, 0x32, + 0xad, + ], + [ + 0x8e, 0xce, 0x5f, 0x04, 0x2d, 0x5e, 0x44, 0x7b, 0x50, 0x51, 0xb9, 0xea, 0xcb, 0x8d, 0x8f, + 0x6f, + ], + [ + 0x9c, 0x0b, 0x53, 0xb4, 0xb3, 0xc3, 0x07, 0xe8, 0x7e, 0xae, 0xe0, 0x86, 0x78, 0x14, 0x1f, + 0x66, + ], + [ + 0xab, 0xf2, 0x48, 0xaf, 0x69, 0xa6, 0xea, 0xe4, 0xbf, 0xd3, 0xeb, 0x2f, 0x12, 0x9e, 0xeb, + 0x94, + ], + [ + 0x06, 0x64, 0xda, 0x16, 0x68, 0x57, 0x4b, 0x88, 0xb9, 0x35, 0xf3, 0x02, 0x73, 0x58, 0xae, + 0xf4, + ], + [ + 0xaa, 0x4b, 0x9d, 0xc4, 0xbf, 0x33, 0x7d, 0xe9, 0x0c, 0xd4, 0xfd, 0x3c, 0x46, 0x7c, 0x6a, + 0xb7, + ], + [ + 0xea, 0x5c, 0x7f, 0x47, 0x1f, 0xaf, 0x6b, 0xde, 0x2b, 0x1a, 0xd7, 0xd4, 0x68, 0x6d, 0x22, + 0x87, + ], + [ + 0x29, 0x39, 0xb0, 0x18, 0x32, 0x23, 0xfa, 0xfc, 0x17, 0x23, 0xde, 0x4f, 0x52, 0xc4, 0x3d, + 0x35, + ], + [ + 0x7c, 0x39, 0x56, 0xca, 0x5e, 0xea, 0xfc, 0x3e, 0x36, 0x3e, 0x9d, 0x55, 0x65, 0x46, 0xeb, + 0x68, + ], + [ + 0x77, 0xc6, 0x07, 0x71, 0x46, 0xf0, 0x1c, 0x32, 0xb6, 0xb6, 0x9d, 0x5f, 0x4e, 0xa9, 0xff, + 0xcf, + ], + [ + 0x37, 0xa6, 0x98, 0x6c, 0xb8, 0x84, 0x7e, 0xdf, 0x09, 0x25, 0xf0, 0xf1, 0x30, 0x9b, 0x54, + 0xde, + ], + [ + 0xa7, 0x05, 0xf0, 0xe6, 0x9d, 0xa9, 0xa8, 0xf9, 0x07, 0x24, 0x1a, 0x2e, 0x92, 0x3c, 0x8c, + 0xc8, + ], + [ + 0x3d, 0xc4, 0x7d, 0x1f, 0x29, 0xc4, 0x48, 0x46, 0x1e, 0x9e, 0x76, 0xed, 0x90, 0x4f, 0x67, + 0x11, + ], + [ + 0x0d, 0x62, 0xbf, 0x01, 0xe6, 0xfc, 0x0e, 0x1a, 0x0d, 0x3c, 0x47, 0x51, 0xc5, 0xd3, 0x69, + 0x2b, + ], + [ + 0x8c, 0x03, 0x46, 0x8b, 0xca, 0x7c, 0x66, 0x9e, 0xe4, 0xfd, 0x5e, 0x08, 0x4b, 0xbe, 0xe7, + 0xb5, + ], + [ + 0x52, 0x8a, 0x5b, 0xb9, 0x3b, 0xaf, 0x2c, 0x9c, 0x44, 0x73, 0xcc, 0xe5, 0xd0, 0xd2, 0x2b, + 0xd9, + ], + [ + 0xdf, 0x6a, 0x30, 0x1e, 0x95, 0xc9, 0x5d, 0xad, 0x97, 0xae, 0x0c, 0xc8, 0xc6, 0x91, 0x3b, + 0xd8, + ], + [ + 0x80, 0x11, 0x89, 0x90, 0x2c, 0x85, 0x7f, 0x39, 0xe7, 0x35, 0x91, 0x28, 0x5e, 0x70, 0xb6, + 0xdb, + ], + [ + 0xe6, 0x17, 0x34, 0x6a, 0xc9, 0xc2, 0x31, 0xbb, 0x36, 0x50, 0xae, 0x34, 0xcc, 0xca, 0x0c, + 0x5b, + ], + [ + 0x27, 0xd9, 0x34, 0x37, 0xef, 0xb7, 0x21, 0xaa, 0x40, 0x18, 0x21, 0xdc, 0xec, 0x5a, 0xdf, + 0x89, + ], + [ + 0x89, 0x23, 0x7d, 0x9d, 0xed, 0x9c, 0x5e, 0x78, 0xd8, 0xb1, 0xc9, 0xb1, 0x66, 0xcc, 0x73, + 0x42, + ], + [ + 0x4a, 0x6d, 0x80, 0x91, 0xbf, 0x5e, 0x7d, 0x65, 0x11, 0x89, 0xfa, 0x94, 0xa2, 0x50, 0xb1, + 0x4c, + ], + [ + 0x0e, 0x33, 0xf9, 0x60, 0x55, 0xe7, 0xae, 0x89, 0x3f, 0xfc, 0x0e, 0x3d, 0xcf, 0x49, 0x29, + 0x02, + ], + [ + 0xe6, 0x1c, 0x43, 0x2b, 0x72, 0x0b, 0x19, 0xd1, 0x8e, 0xc8, 0xd8, 0x4b, 0xdc, 0x63, 0x15, + 0x1b, + ], + [ + 0xf7, 0xe5, 0xae, 0xf5, 0x49, 0xf7, 0x82, 0xcf, 0x37, 0x90, 0x55, 0xa6, 0x08, 0x26, 0x9b, + 0x16, + ], + [ + 0x43, 0x8d, 0x03, 0x0f, 0xd0, 0xb7, 0xa5, 0x4f, 0xa8, 0x37, 0xf2, 0xad, 0x20, 0x1a, 0x64, + 0x03, + ], + [ + 0xa5, 0x90, 0xd3, 0xee, 0x4f, 0xbf, 0x04, 0xe3, 0x24, 0x7e, 0x0d, 0x27, 0xf2, 0x86, 0x42, + 0x3f, + ], + [ + 0x5f, 0xe2, 0xc1, 0xa1, 0x72, 0xfe, 0x93, 0xc4, 0xb1, 0x5c, 0xd3, 0x7c, 0xae, 0xf9, 0xf5, + 0x38, + ], + [ + 0x2c, 0x97, 0x32, 0x5c, 0xbd, 0x06, 0xb3, 0x6e, 0xb2, 0x13, 0x3d, 0xd0, 0x8b, 0x3a, 0x01, + 0x7c, + ], + [ + 0x92, 0xc8, 0x14, 0x22, 0x7a, 0x6b, 0xca, 0x94, 0x9f, 0xf0, 0x65, 0x9f, 0x00, 0x2a, 0xd3, + 0x9e, + ], + [ + 0xdc, 0xe8, 0x50, 0x11, 0x0b, 0xd8, 0x32, 0x8c, 0xfb, 0xd5, 0x08, 0x41, 0xd6, 0x91, 0x1d, + 0x87, + ], + [ + 0x67, 0xf1, 0x49, 0x84, 0xc7, 0xda, 0x79, 0x12, 0x48, 0xe3, 0x2b, 0xb5, 0x92, 0x25, 0x83, + 0xda, + ], + [ + 0x19, 0x38, 0xf2, 0xcf, 0x72, 0xd5, 0x4e, 0xe9, 0x7e, 0x94, 0x16, 0x6f, 0xa9, 0x1d, 0x2a, + 0x36, + ], + [ + 0x74, 0x48, 0x1e, 0x96, 0x46, 0xed, 0x49, 0xfe, 0x0f, 0x62, 0x24, 0x30, 0x16, 0x04, 0x69, + 0x8e, + ], + [ + 0x57, 0xfc, 0xa5, 0xde, 0x98, 0xa9, 0xd6, 0xd8, 0x00, 0x64, 0x38, 0xd0, 0x58, 0x3d, 0x8a, + 0x1d, + ], + [ + 0x9f, 0xec, 0xde, 0x1c, 0xef, 0xdc, 0x1c, 0xbe, 0xd4, 0x76, 0x36, 0x74, 0xd9, 0x57, 0x53, + 0x59, + ], + [ + 0xe3, 0x04, 0x0c, 0x00, 0xeb, 0x28, 0xf1, 0x53, 0x66, 0xca, 0x73, 0xcb, 0xd8, 0x72, 0xe7, + 0x40, + ], + [ + 0x76, 0x97, 0x00, 0x9a, 0x6a, 0x83, 0x1d, 0xfe, 0xcc, 0xa9, 0x1c, 0x59, 0x93, 0x67, 0x0f, + 0x7a, + ], + [ + 0x58, 0x53, 0x54, 0x23, 0x21, 0xf5, 0x67, 0xa0, 0x05, 0xd5, 0x47, 0xa4, 0xf0, 0x47, 0x59, + 0xbd, + ], + [ + 0x51, 0x50, 0xd1, 0x77, 0x2f, 0x50, 0x83, 0x4a, 0x50, 0x3e, 0x06, 0x9a, 0x97, 0x3f, 0xbd, + 0x7c, + ], ]; // Test vector from reference implementation @@ -99,27 +291,25 @@ fn test_siphash_2_4_test_vector() { let mut input: Vec = Vec::new(); - for i in 0 .. 64 { - let out = hash_with(SipHasher128::new_with_keys(k0, k1), - &Bytes(&input[..])); + for i in 0..64 { + let out = hash_with(SipHasher128::new_with_keys(k0, k1), &Bytes(&input[..])); let expected = ( - ((TEST_VECTOR[i][0] as u64) << 0) | - ((TEST_VECTOR[i][1] as u64) << 8) | - ((TEST_VECTOR[i][2] as u64) << 16) | - ((TEST_VECTOR[i][3] as u64) << 24) | - ((TEST_VECTOR[i][4] as u64) << 32) | - ((TEST_VECTOR[i][5] as u64) << 40) | - ((TEST_VECTOR[i][6] as u64) << 48) | - ((TEST_VECTOR[i][7] as u64) << 56), - - ((TEST_VECTOR[i][8] as u64) << 0) | - ((TEST_VECTOR[i][9] as u64) << 8) | - ((TEST_VECTOR[i][10] as u64) << 16) | - ((TEST_VECTOR[i][11] as u64) << 24) | - ((TEST_VECTOR[i][12] as u64) << 32) | - ((TEST_VECTOR[i][13] as u64) << 40) | - ((TEST_VECTOR[i][14] as u64) << 48) | - ((TEST_VECTOR[i][15] as u64) << 56), + ((TEST_VECTOR[i][0] as u64) << 0) + | ((TEST_VECTOR[i][1] as u64) << 8) + | ((TEST_VECTOR[i][2] as u64) << 16) + | ((TEST_VECTOR[i][3] as u64) << 24) + | ((TEST_VECTOR[i][4] as u64) << 32) + | ((TEST_VECTOR[i][5] as u64) << 40) + | ((TEST_VECTOR[i][6] as u64) << 48) + | ((TEST_VECTOR[i][7] as u64) << 56), + ((TEST_VECTOR[i][8] as u64) << 0) + | ((TEST_VECTOR[i][9] as u64) << 8) + | ((TEST_VECTOR[i][10] as u64) << 16) + | ((TEST_VECTOR[i][11] as u64) << 24) + | ((TEST_VECTOR[i][12] as u64) << 32) + | ((TEST_VECTOR[i][13] as u64) << 40) + | ((TEST_VECTOR[i][14] as u64) << 48) + | ((TEST_VECTOR[i][15] as u64) << 56), ); assert_eq!(out, expected); @@ -127,19 +317,22 @@ fn test_siphash_2_4_test_vector() { } } -#[test] #[cfg(target_arch = "arm")] +#[test] +#[cfg(target_arch = "arm")] fn test_hash_usize() { let val = 0xdeadbeef_deadbeef_u64; assert!(hash(&(val as u64)) != hash(&(val as usize))); assert_eq!(hash(&(val as u32)), hash(&(val as usize))); } -#[test] #[cfg(target_arch = "x86_64")] +#[test] +#[cfg(target_arch = "x86_64")] fn test_hash_usize() { let val = 0xdeadbeef_deadbeef_u64; assert_eq!(hash(&(val as u64)), hash(&(val as usize))); assert!(hash(&(val as u32)) != hash(&(val as usize))); } -#[test] #[cfg(target_arch = "x86")] +#[test] +#[cfg(target_arch = "x86")] fn test_hash_usize() { let val = 0xdeadbeef_deadbeef_u64; assert!(hash(&(val as u64)) != hash(&(val as usize))); @@ -216,8 +409,7 @@ fn test_write_short_works() { h1.write_u8(0x01u8); let mut h2 = SipHasher128::new_with_keys(0, 0); h2.write(unsafe { - slice::from_raw_parts(&test_usize as *const _ as *const u8, - mem::size_of::()) + slice::from_raw_parts(&test_usize as *const _ as *const u8, mem::size_of::()) }); h2.write(b"bytes"); h2.write(b"string"); diff --git a/src/librustc_data_structures/small_c_str.rs b/src/librustc_data_structures/small_c_str.rs index 9d90b9052d1c2..4a089398ce61e 100644 --- a/src/librustc_data_structures/small_c_str.rs +++ b/src/librustc_data_structures/small_c_str.rs @@ -44,12 +44,9 @@ impl SmallCStr { SmallCStr { data: SmallVec::from_slice(s.as_bytes()) } } - #[inline] pub fn as_c_str(&self) -> &ffi::CStr { - unsafe { - ffi::CStr::from_bytes_with_nul_unchecked(&self.data[..]) - } + unsafe { ffi::CStr::from_bytes_with_nul_unchecked(&self.data[..]) } } #[inline] diff --git a/src/librustc_data_structures/snapshot_map/mod.rs b/src/librustc_data_structures/snapshot_map/mod.rs index bdd3dc9665629..b71163a8f9433 100644 --- a/src/librustc_data_structures/snapshot_map/mod.rs +++ b/src/librustc_data_structures/snapshot_map/mod.rs @@ -1,13 +1,14 @@ use crate::fx::FxHashMap; use std::hash::Hash; -use std::ops; use std::mem; +use std::ops; #[cfg(test)] mod tests; pub struct SnapshotMap - where K: Clone + Eq +where + K: Clone + Eq, { map: FxHashMap, undo_log: Vec>, @@ -16,14 +17,11 @@ pub struct SnapshotMap // HACK(eddyb) manual impl avoids `Default` bounds on `K` and `V`. impl Default for SnapshotMap - where K: Hash + Clone + Eq +where + K: Hash + Clone + Eq, { fn default() -> Self { - SnapshotMap { - map: Default::default(), - undo_log: Default::default(), - num_open_snapshots: 0, - } + SnapshotMap { map: Default::default(), undo_log: Default::default(), num_open_snapshots: 0 } } } @@ -38,7 +36,8 @@ enum UndoLog { } impl SnapshotMap - where K: Hash + Clone + Eq +where + K: Hash + Clone + Eq, { pub fn clear(&mut self) { self.map.clear(); @@ -107,13 +106,12 @@ impl SnapshotMap self.num_open_snapshots -= 1; } - pub fn partial_rollback(&mut self, - snapshot: &Snapshot, - should_revert_key: &F) - where F: Fn(&K) -> bool + pub fn partial_rollback(&mut self, snapshot: &Snapshot, should_revert_key: &F) + where + F: Fn(&K) -> bool, { self.assert_open_snapshot(snapshot); - for i in (snapshot.len .. self.undo_log.len()).rev() { + for i in (snapshot.len..self.undo_log.len()).rev() { let reverse = match self.undo_log[i] { UndoLog::Purged => false, UndoLog::Inserted(ref k) => should_revert_key(k), @@ -153,7 +151,8 @@ impl SnapshotMap } impl<'k, K, V> ops::Index<&'k K> for SnapshotMap - where K: Hash + Clone + Eq +where + K: Hash + Clone + Eq, { type Output = V; fn index(&self, key: &'k K) -> &V { diff --git a/src/librustc_data_structures/sorted_map.rs b/src/librustc_data_structures/sorted_map.rs index fb819dd18a8d6..b29ffd7594008 100644 --- a/src/librustc_data_structures/sorted_map.rs +++ b/src/librustc_data_structures/sorted_map.rs @@ -2,7 +2,7 @@ use std::borrow::Borrow; use std::cmp::Ordering; use std::iter::FromIterator; use std::mem; -use std::ops::{RangeBounds, Bound, Index, IndexMut}; +use std::ops::{Bound, Index, IndexMut, RangeBounds}; /// `SortedMap` is a data structure with similar characteristics as BTreeMap but /// slightly different trade-offs: lookup, insertion, and removal are O(log(N)) @@ -12,18 +12,26 @@ use std::ops::{RangeBounds, Bound, Index, IndexMut}; /// stores data in a more compact way. It also supports accessing contiguous /// ranges of elements as a slice, and slices of already sorted elements can be /// inserted efficiently. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug, RustcEncodable, - RustcDecodable)] +#[derive( + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Default, + Debug, + RustcEncodable, + RustcDecodable +)] pub struct SortedMap { - data: Vec<(K, V)> + data: Vec<(K, V)>, } impl SortedMap { #[inline] pub fn new() -> SortedMap { - SortedMap { - data: vec![] - } + SortedMap { data: vec![] } } /// Construct a `SortedMap` from a presorted set of elements. This is faster @@ -32,22 +40,17 @@ impl SortedMap { /// It is up to the caller to make sure that the elements are sorted by key /// and that there are no duplicates. #[inline] - pub fn from_presorted_elements(elements: Vec<(K, V)>) -> SortedMap - { + pub fn from_presorted_elements(elements: Vec<(K, V)>) -> SortedMap { debug_assert!(elements.windows(2).all(|w| w[0].0 < w[1].0)); - SortedMap { - data: elements - } + SortedMap { data: elements } } #[inline] pub fn insert(&mut self, key: K, mut value: V) -> Option { match self.lookup_index_for(&key) { Ok(index) => { - let slot = unsafe { - self.data.get_unchecked_mut(index) - }; + let slot = unsafe { self.data.get_unchecked_mut(index) }; mem::swap(&mut slot.1, &mut value); Some(value) } @@ -61,46 +64,32 @@ impl SortedMap { #[inline] pub fn remove(&mut self, key: &K) -> Option { match self.lookup_index_for(key) { - Ok(index) => { - Some(self.data.remove(index).1) - } - Err(_) => { - None - } + Ok(index) => Some(self.data.remove(index).1), + Err(_) => None, } } #[inline] pub fn get(&self, key: &Q) -> Option<&V> - where K: Borrow, - Q: Ord + ?Sized + where + K: Borrow, + Q: Ord + ?Sized, { match self.lookup_index_for(key) { - Ok(index) => { - unsafe { - Some(&self.data.get_unchecked(index).1) - } - } - Err(_) => { - None - } + Ok(index) => unsafe { Some(&self.data.get_unchecked(index).1) }, + Err(_) => None, } } #[inline] pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> - where K: Borrow, - Q: Ord + ?Sized + where + K: Borrow, + Q: Ord + ?Sized, { match self.lookup_index_for(key) { - Ok(index) => { - unsafe { - Some(&mut self.data.get_unchecked_mut(index).1) - } - } - Err(_) => { - None - } + Ok(index) => unsafe { Some(&mut self.data.get_unchecked_mut(index).1) }, + Err(_) => None, } } @@ -139,25 +128,28 @@ impl SortedMap { #[inline] pub fn range(&self, range: R) -> &[(K, V)] - where R: RangeBounds + where + R: RangeBounds, { let (start, end) = self.range_slice_indices(range); - (&self.data[start .. end]) + (&self.data[start..end]) } #[inline] pub fn remove_range(&mut self, range: R) - where R: RangeBounds + where + R: RangeBounds, { let (start, end) = self.range_slice_indices(range); - self.data.splice(start .. end, ::std::iter::empty()); + self.data.splice(start..end, ::std::iter::empty()); } /// Mutate all keys with the given function `f`. This mutation must not /// change the sort-order of keys. #[inline] pub fn offset_keys(&mut self, f: F) - where F: Fn(&mut K) + where + F: Fn(&mut K), { self.data.iter_mut().map(|&mut (ref mut k, _)| k).for_each(f); } @@ -171,7 +163,7 @@ impl SortedMap { #[inline] pub fn insert_presorted(&mut self, mut elements: Vec<(K, V)>) { if elements.is_empty() { - return + return; } debug_assert!(elements.windows(2).all(|w| w[0].0 < w[1].0)); @@ -185,12 +177,11 @@ impl SortedMap { drain } Err(index) => { - if index == self.data.len() || - elements.last().unwrap().0 < self.data[index].0 { + if index == self.data.len() || elements.last().unwrap().0 < self.data[index].0 { // We can copy the whole range without having to mix with // existing elements. - self.data.splice(index .. index, elements.drain(..)); - return + self.data.splice(index..index, elements.drain(..)); + return; } let mut drain = elements.drain(..); @@ -208,43 +199,37 @@ impl SortedMap { /// Looks up the key in `self.data` via `slice::binary_search()`. #[inline(always)] fn lookup_index_for(&self, key: &Q) -> Result - where K: Borrow, - Q: Ord + ?Sized + where + K: Borrow, + Q: Ord + ?Sized, { self.data.binary_search_by(|&(ref x, _)| x.borrow().cmp(key)) } #[inline] fn range_slice_indices(&self, range: R) -> (usize, usize) - where R: RangeBounds + where + R: RangeBounds, { let start = match range.start_bound() { - Bound::Included(ref k) => { - match self.lookup_index_for(k) { - Ok(index) | Err(index) => index - } - } - Bound::Excluded(ref k) => { - match self.lookup_index_for(k) { - Ok(index) => index + 1, - Err(index) => index, - } - } + Bound::Included(ref k) => match self.lookup_index_for(k) { + Ok(index) | Err(index) => index, + }, + Bound::Excluded(ref k) => match self.lookup_index_for(k) { + Ok(index) => index + 1, + Err(index) => index, + }, Bound::Unbounded => 0, }; let end = match range.end_bound() { - Bound::Included(ref k) => { - match self.lookup_index_for(k) { - Ok(index) => index + 1, - Err(index) => index, - } - } - Bound::Excluded(ref k) => { - match self.lookup_index_for(k) { - Ok(index) | Err(index) => index, - } - } + Bound::Included(ref k) => match self.lookup_index_for(k) { + Ok(index) => index + 1, + Err(index) => index, + }, + Bound::Excluded(ref k) => match self.lookup_index_for(k) { + Ok(index) | Err(index) => index, + }, Bound::Unbounded => self.data.len(), }; @@ -253,8 +238,9 @@ impl SortedMap { #[inline] pub fn contains_key(&self, key: &Q) -> bool - where K: Borrow, - Q: Ord + ?Sized + where + K: Borrow, + Q: Ord + ?Sized, { self.get(key).is_some() } @@ -270,8 +256,9 @@ impl IntoIterator for SortedMap { } impl<'a, K, Q, V> Index<&'a Q> for SortedMap - where K: Ord + Borrow, - Q: Ord + ?Sized +where + K: Ord + Borrow, + Q: Ord + ?Sized, { type Output = V; @@ -281,8 +268,9 @@ impl<'a, K, Q, V> Index<&'a Q> for SortedMap } impl<'a, K, Q, V> IndexMut<&'a Q> for SortedMap - where K: Ord + Borrow, - Q: Ord + ?Sized +where + K: Ord + Borrow, + Q: Ord + ?Sized, { fn index_mut(&mut self, key: &Q) -> &mut Self::Output { self.get_mut(key).expect("no entry found for key") @@ -294,13 +282,9 @@ impl FromIterator<(K, V)> for SortedMap { let mut data: Vec<(K, V)> = iter.into_iter().collect(); data.sort_unstable_by(|&(ref k1, _), &(ref k2, _)| k1.cmp(k2)); - data.dedup_by(|&mut (ref k1, _), &mut (ref k2, _)| { - k1.cmp(k2) == Ordering::Equal - }); + data.dedup_by(|&mut (ref k1, _), &mut (ref k2, _)| k1.cmp(k2) == Ordering::Equal); - SortedMap { - data - } + SortedMap { data } } } diff --git a/src/librustc_data_structures/sorted_map/tests.rs b/src/librustc_data_structures/sorted_map/tests.rs index f970409cc3d58..692e1deb4be65 100644 --- a/src/librustc_data_structures/sorted_map/tests.rs +++ b/src/librustc_data_structures/sorted_map/tests.rs @@ -5,7 +5,7 @@ fn test_insert_and_iter() { let mut map = SortedMap::new(); let mut expected = Vec::new(); - for x in 0 .. 100 { + for x in 0..100 { assert_eq!(map.iter().cloned().collect::>(), expected); let x = 1000 - x * 2; @@ -19,7 +19,7 @@ fn test_get_and_index() { let mut map = SortedMap::new(); let mut expected = Vec::new(); - for x in 0 .. 100 { + for x in 0..100 { let x = 1000 - x; if x & 1 == 0 { map.insert(x, x); @@ -48,14 +48,12 @@ fn test_range() { map.insert(6, 6); map.insert(9, 9); - let keys = |s: &[(_, _)]| { - s.into_iter().map(|e| e.0).collect::>() - }; + let keys = |s: &[(_, _)]| s.into_iter().map(|e| e.0).collect::>(); - for start in 0 .. 11 { - for end in 0 .. 11 { + for start in 0..11 { + for end in 0..11 { if end < start { - continue + continue; } let mut expected = vec![1, 3, 6, 9]; @@ -66,7 +64,6 @@ fn test_range() { } } - #[test] fn test_offset_keys() { let mut map = SortedMap::new(); @@ -100,17 +97,17 @@ fn test_remove_range() { map.insert(6, 6); map.insert(9, 9); - for start in 0 .. 11 { - for end in 0 .. 11 { + for start in 0..11 { + for end in 0..11 { if end < start { - continue + continue; } let mut expected = vec![1, 3, 6, 9]; expected.retain(|&x| x < start || x >= end); let mut map = map.clone(); - map.remove_range(start .. end); + map.remove_range(start..end); assert_eq!(keys(map), expected, "range = {}..{}", start, end); } @@ -127,7 +124,7 @@ fn test_remove() { expected.push((x, x)); } - for x in 0 .. 10 { + for x in 0..10 { let mut map = map.clone(); let mut expected = expected.clone(); diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index 70492d499222f..0a26bf3bdc93f 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -1,9 +1,9 @@ -use std::hash::{Hash, Hasher, BuildHasher}; -use std::mem; -use smallvec::SmallVec; use crate::sip128::SipHasher128; -use rustc_index::vec; use rustc_index::bit_set; +use rustc_index::vec; +use smallvec::SmallVec; +use std::hash::{BuildHasher, Hash, Hasher}; +use std::mem; /// When hashing something that ends up affecting properties like symbol names, /// we want these symbol names to be calculated independently of other factors @@ -28,9 +28,7 @@ pub trait StableHasherResult: Sized { impl StableHasher { pub fn new() -> Self { - StableHasher { - state: SipHasher128::new_with_keys(0, 0), - } + StableHasher { state: SipHasher128::new_with_keys(0, 0) } } pub fn finish(self) -> W { @@ -177,18 +175,14 @@ pub trait ToStableHashKey { // self-contained values that don't depend on the hashing context `CTX`. #[macro_export] macro_rules! impl_stable_hash_via_hash { - ($t:ty) => ( + ($t:ty) => { impl $crate::stable_hasher::HashStable for $t { #[inline] - fn hash_stable( - &self, - _: &mut CTX, - hasher: &mut $crate::stable_hasher::StableHasher - ) { + fn hash_stable(&self, _: &mut CTX, hasher: &mut $crate::stable_hasher::StableHasher) { ::std::hash::Hash::hash(self, hasher); } } - ); + }; } impl_stable_hash_via_hash!(i8); @@ -217,18 +211,14 @@ impl HashStable for ::std::num::NonZeroU32 { impl HashStable for f32 { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - let val: u32 = unsafe { - ::std::mem::transmute(*self) - }; + let val: u32 = unsafe { ::std::mem::transmute(*self) }; val.hash_stable(ctx, hasher); } } impl HashStable for f64 { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { - let val: u64 = unsafe { - ::std::mem::transmute(*self) - }; + let val: u64 = unsafe { ::std::mem::transmute(*self) }; val.hash_stable(ctx, hasher); } } @@ -255,9 +245,10 @@ impl, T2: HashStable, CTX> HashStable for (T1, T2) } impl HashStable for (T1, T2, T3) - where T1: HashStable, - T2: HashStable, - T3: HashStable, +where + T1: HashStable, + T2: HashStable, + T3: HashStable, { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { let (ref _0, ref _1, ref _2) = *self; @@ -268,10 +259,11 @@ impl HashStable for (T1, T2, T3) } impl HashStable for (T1, T2, T3, T4) - where T1: HashStable, - T2: HashStable, - T3: HashStable, - T4: HashStable, +where + T1: HashStable, + T2: HashStable, + T3: HashStable, + T4: HashStable, { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { let (ref _0, ref _1, ref _2, ref _3) = *self; @@ -299,9 +291,10 @@ impl, CTX> HashStable for Vec { } impl HashStable for indexmap::IndexMap - where K: HashStable + Eq + Hash, - V: HashStable, - R: BuildHasher, +where + K: HashStable + Eq + Hash, + V: HashStable, + R: BuildHasher, { #[inline] fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { @@ -313,8 +306,9 @@ impl HashStable for indexmap::IndexMap } impl HashStable for indexmap::IndexSet - where K: HashStable + Eq + Hash, - R: BuildHasher, +where + K: HashStable + Eq + Hash, + R: BuildHasher, { #[inline] fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { @@ -325,7 +319,10 @@ impl HashStable for indexmap::IndexSet } } -impl HashStable for SmallVec<[A; 1]> where A: HashStable { +impl HashStable for SmallVec<[A; 1]> +where + A: HashStable, +{ #[inline] fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { (&self[..]).hash_stable(ctx, hasher); @@ -361,7 +358,6 @@ impl HashStable for str { } } - impl HashStable for String { #[inline] fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { @@ -384,9 +380,9 @@ impl HashStable for bool { } } - impl HashStable for Option - where T: HashStable +where + T: HashStable, { #[inline] fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { @@ -400,8 +396,9 @@ impl HashStable for Option } impl HashStable for Result - where T1: HashStable, - T2: HashStable, +where + T1: HashStable, + T2: HashStable, { #[inline] fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { @@ -414,7 +411,8 @@ impl HashStable for Result } impl<'a, T, CTX> HashStable for &'a T - where T: HashStable + ?Sized +where + T: HashStable + ?Sized, { #[inline] fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { @@ -430,7 +428,8 @@ impl HashStable for ::std::mem::Discriminant { } impl HashStable for ::std::ops::RangeInclusive - where T: HashStable +where + T: HashStable, { #[inline] fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { @@ -440,7 +439,8 @@ impl HashStable for ::std::ops::RangeInclusive } impl HashStable for vec::IndexVec - where T: HashStable, +where + T: HashStable, { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { self.len().hash_stable(ctx, hasher); @@ -450,17 +450,13 @@ impl HashStable for vec::IndexVec } } - -impl HashStable for bit_set::BitSet -{ +impl HashStable for bit_set::BitSet { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { self.words().hash_stable(ctx, hasher); } } -impl HashStable -for bit_set::BitMatrix -{ +impl HashStable for bit_set::BitMatrix { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { self.words().hash_stable(ctx, hasher); } @@ -470,9 +466,10 @@ impl_stable_hash_via_hash!(::std::path::Path); impl_stable_hash_via_hash!(::std::path::PathBuf); impl HashStable for ::std::collections::HashMap - where K: ToStableHashKey + Eq, - V: HashStable, - R: BuildHasher, +where + K: ToStableHashKey + Eq, + V: HashStable, + R: BuildHasher, { #[inline] fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { @@ -481,38 +478,36 @@ impl HashStable for ::std::collections::HashMap } impl HashStable for ::std::collections::HashSet - where K: ToStableHashKey + Eq, - R: BuildHasher, +where + K: ToStableHashKey + Eq, + R: BuildHasher, { fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { - let mut keys: Vec<_> = self.iter() - .map(|k| k.to_stable_hash_key(hcx)) - .collect(); + let mut keys: Vec<_> = self.iter().map(|k| k.to_stable_hash_key(hcx)).collect(); keys.sort_unstable(); keys.hash_stable(hcx, hasher); } } impl HashStable for ::std::collections::BTreeMap - where K: ToStableHashKey, - V: HashStable, +where + K: ToStableHashKey, + V: HashStable, { fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { - let mut entries: Vec<_> = self.iter() - .map(|(k, v)| (k.to_stable_hash_key(hcx), v)) - .collect(); + let mut entries: Vec<_> = + self.iter().map(|(k, v)| (k.to_stable_hash_key(hcx), v)).collect(); entries.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2)); entries.hash_stable(hcx, hasher); } } impl HashStable for ::std::collections::BTreeSet - where K: ToStableHashKey, +where + K: ToStableHashKey, { fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { - let mut keys: Vec<_> = self.iter() - .map(|k| k.to_stable_hash_key(hcx)) - .collect(); + let mut keys: Vec<_> = self.iter().map(|k| k.to_stable_hash_key(hcx)).collect(); keys.sort_unstable(); keys.hash_stable(hcx, hasher); } @@ -522,21 +517,19 @@ pub fn hash_stable_hashmap( hcx: &mut HCX, hasher: &mut StableHasher, map: &::std::collections::HashMap, - to_stable_hash_key: F) - where K: Eq, - V: HashStable, - R: BuildHasher, - SK: HashStable + Ord, - F: Fn(&K, &HCX) -> SK, + to_stable_hash_key: F, +) where + K: Eq, + V: HashStable, + R: BuildHasher, + SK: HashStable + Ord, + F: Fn(&K, &HCX) -> SK, { - let mut entries: Vec<_> = map.iter() - .map(|(k, v)| (to_stable_hash_key(k, hcx), v)) - .collect(); + let mut entries: Vec<_> = map.iter().map(|(k, v)| (to_stable_hash_key(k, hcx), v)).collect(); entries.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2)); entries.hash_stable(hcx, hasher); } - /// A vector container that makes sure that its items are hashed in a stable /// order. pub struct StableVec(Vec); @@ -556,14 +549,13 @@ impl ::std::ops::Deref for StableVec { } impl HashStable for StableVec - where T: HashStable + ToStableHashKey +where + T: HashStable + ToStableHashKey, { fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { let StableVec(ref v) = *self; - let mut sorted: Vec<_> = v.iter() - .map(|x| x.to_stable_hash_key(hcx)) - .collect(); + let mut sorted: Vec<_> = v.iter().map(|x| x.to_stable_hash_key(hcx)).collect(); sorted.sort_unstable(); sorted.hash_stable(hcx, hasher); } diff --git a/src/librustc_data_structures/stable_map.rs b/src/librustc_data_structures/stable_map.rs index f69f28e14b2a1..670452d0d8c5a 100644 --- a/src/librustc_data_structures/stable_map.rs +++ b/src/librustc_data_structures/stable_map.rs @@ -46,7 +46,8 @@ impl Eq for StableMap where K: Eq + Hash, V: Eq, -{} +{ +} impl StableMap where diff --git a/src/librustc_data_structures/svh.rs b/src/librustc_data_structures/svh.rs index 64042264d794f..476eb9e14f98f 100644 --- a/src/librustc_data_structures/svh.rs +++ b/src/librustc_data_structures/svh.rs @@ -5,9 +5,9 @@ //! mismatches where we have two versions of the same crate that were //! compiled from distinct sources. +use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fmt; use std::hash::{Hash, Hasher}; -use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; use crate::stable_hasher; @@ -34,7 +34,10 @@ impl Svh { } impl Hash for Svh { - fn hash(&self, state: &mut H) where H: Hasher { + fn hash(&self, state: &mut H) + where + H: Hasher, + { self.hash.to_le().hash(state); } } @@ -53,18 +56,14 @@ impl Encodable for Svh { impl Decodable for Svh { fn decode(d: &mut D) -> Result { - d.read_u64() - .map(u64::from_le) - .map(Svh::new) + d.read_u64().map(u64::from_le).map(Svh::new) } } impl stable_hasher::HashStable for Svh { #[inline] fn hash_stable(&self, ctx: &mut T, hasher: &mut stable_hasher::StableHasher) { - let Svh { - hash - } = *self; + let Svh { hash } = *self; hash.hash_stable(ctx, hasher); } } diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index 6a19f52897e5d..fa98b4d72dda2 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -17,14 +17,14 @@ //! `rustc_erase_owner!` erases a OwningRef owner into Erased or Erased + Send + Sync //! depending on the value of cfg!(parallel_compiler). +use crate::owning_ref::{Erased, OwningRef}; use std::collections::HashMap; -use std::hash::{Hash, BuildHasher}; +use std::hash::{BuildHasher, Hash}; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; -use crate::owning_ref::{Erased, OwningRef}; -pub use std::sync::atomic::Ordering::SeqCst; pub use std::sync::atomic::Ordering; +pub use std::sync::atomic::Ordering::SeqCst; cfg_if! { if #[cfg(not(parallel_compiler))] { @@ -476,7 +476,10 @@ impl Once { /// otherwise if the inner value was already set it asserts that `value` is equal to the inner /// value and then returns `value` back to the caller #[inline] - pub fn try_set_same(&self, value: T) -> Option where T: Eq { + pub fn try_set_same(&self, value: T) -> Option + where + T: Eq, + { let mut lock = self.0.lock(); if let Some(ref inner) = *lock { assert!(*inner == value); @@ -518,11 +521,7 @@ impl Once { /// If the value is already initialized, the closure is not called and `None` is returned. #[inline] pub fn init_nonlocking T>(&self, f: F) -> Option { - if self.0.lock().is_some() { - None - } else { - self.try_set(f()) - } + if self.0.lock().is_some() { None } else { self.try_set(f()) } } /// Tries to initialize the inner value by calling the closure without ensuring that no-one @@ -535,12 +534,11 @@ impl Once { /// If our closure set the value, `None` is returned. /// If the value is already initialized, the closure is not called and `None` is returned. #[inline] - pub fn init_nonlocking_same T>(&self, f: F) -> Option where T: Eq { - if self.0.lock().is_some() { - None - } else { - self.try_set_same(f()) - } + pub fn init_nonlocking_same T>(&self, f: F) -> Option + where + T: Eq, + { + if self.0.lock().is_some() { None } else { self.try_set_same(f()) } } /// Tries to get a reference to the inner value, returns `None` if it is not yet initialized diff --git a/src/librustc_data_structures/thin_vec.rs b/src/librustc_data_structures/thin_vec.rs index d97da489db8df..2befc0aa50487 100644 --- a/src/librustc_data_structures/thin_vec.rs +++ b/src/librustc_data_structures/thin_vec.rs @@ -1,4 +1,4 @@ -use crate::stable_hasher::{StableHasher, HashStable}; +use crate::stable_hasher::{HashStable, StableHasher}; /// A vector type optimized for cases where this size is usually 0 (cf. `SmallVector`). /// The `Option>` wrapping allows us to represent a zero sized vector with `None`, @@ -14,11 +14,7 @@ impl ThinVec { impl From> for ThinVec { fn from(vec: Vec) -> Self { - if vec.is_empty() { - ThinVec(None) - } else { - ThinVec(Some(Box::new(vec))) - } + if vec.is_empty() { ThinVec(None) } else { ThinVec(Some(Box::new(vec))) } } } diff --git a/src/librustc_data_structures/tiny_list/tests.rs b/src/librustc_data_structures/tiny_list/tests.rs index 0142631590cc9..a8ae2bc872789 100644 --- a/src/librustc_data_structures/tiny_list/tests.rs +++ b/src/librustc_data_structures/tiny_list/tests.rs @@ -1,18 +1,18 @@ use super::*; extern crate test; -use test::{Bencher, black_box}; +use test::{black_box, Bencher}; #[test] fn test_contains_and_insert() { - fn do_insert(i : u32) -> bool { + fn do_insert(i: u32) -> bool { i % 2 == 0 } let mut list = TinyList::new(); - for i in 0 .. 10 { - for j in 0 .. i { + for i in 0..10 { + for j in 0..i { if do_insert(j) { assert!(list.contains(&j)); } else { @@ -115,42 +115,30 @@ fn bench_insert_one(b: &mut Bencher) { #[bench] fn bench_contains_empty(b: &mut Bencher) { - b.iter(|| { - black_box(TinyList::new()).contains(&1) - }); + b.iter(|| black_box(TinyList::new()).contains(&1)); } #[bench] fn bench_contains_unknown(b: &mut Bencher) { - b.iter(|| { - black_box(TinyList::new_single(0)).contains(&1) - }); + b.iter(|| black_box(TinyList::new_single(0)).contains(&1)); } #[bench] fn bench_contains_one(b: &mut Bencher) { - b.iter(|| { - black_box(TinyList::new_single(1)).contains(&1) - }); + b.iter(|| black_box(TinyList::new_single(1)).contains(&1)); } #[bench] fn bench_remove_empty(b: &mut Bencher) { - b.iter(|| { - black_box(TinyList::new()).remove(&1) - }); + b.iter(|| black_box(TinyList::new()).remove(&1)); } #[bench] fn bench_remove_unknown(b: &mut Bencher) { - b.iter(|| { - black_box(TinyList::new_single(0)).remove(&1) - }); + b.iter(|| black_box(TinyList::new_single(0)).remove(&1)); } #[bench] fn bench_remove_one(b: &mut Bencher) { - b.iter(|| { - black_box(TinyList::new_single(1)).remove(&1) - }); + b.iter(|| black_box(TinyList::new_single(1)).remove(&1)); } diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs index bbf6999b98375..16f2e740104ca 100644 --- a/src/librustc_data_structures/transitive_relation.rs +++ b/src/librustc_data_structures/transitive_relation.rs @@ -1,8 +1,8 @@ -use rustc_index::bit_set::BitMatrix; use crate::fx::FxHashMap; use crate::stable_hasher::{HashStable, StableHasher}; use crate::sync::Lock; -use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; +use rustc_index::bit_set::BitMatrix; +use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fmt::Debug; use std::hash::Hash; use std::mem; @@ -60,7 +60,7 @@ impl TransitiveRelation { self.edges.is_empty() } - pub fn elements(&self) -> impl Iterator { + pub fn elements(&self) -> impl Iterator { self.elements.iter() } @@ -69,30 +69,25 @@ impl TransitiveRelation { } fn add_index(&mut self, a: T) -> Index { - let &mut TransitiveRelation { - ref mut elements, - ref mut closure, - ref mut map, - .. - } = self; - - *map.entry(a.clone()) - .or_insert_with(|| { - elements.push(a); - - // if we changed the dimensions, clear the cache - *closure.get_mut() = None; - - Index(elements.len() - 1) - }) + let &mut TransitiveRelation { ref mut elements, ref mut closure, ref mut map, .. } = self; + + *map.entry(a.clone()).or_insert_with(|| { + elements.push(a); + + // if we changed the dimensions, clear the cache + *closure.get_mut() = None; + + Index(elements.len() - 1) + }) } /// Applies the (partial) function to each edge and returns a new /// relation. If `f` returns `None` for any end-point, returns /// `None`. pub fn maybe_map(&self, mut f: F) -> Option> - where F: FnMut(&T) -> Option, - U: Clone + Debug + Eq + Hash + Clone, + where + F: FnMut(&T) -> Option, + U: Clone + Debug + Eq + Hash + Clone, { let mut result = TransitiveRelation::default(); for edge in &self.edges { @@ -105,10 +100,7 @@ impl TransitiveRelation { pub fn add(&mut self, a: T, b: T) { let a = self.add_index(a); let b = self.add_index(b); - let edge = Edge { - source: a, - target: b, - }; + let edge = Edge { source: a, target: b }; if !self.edges.contains(&edge) { self.edges.push(edge); @@ -133,9 +125,9 @@ impl TransitiveRelation { /// strategy -- it'd be a touch tricky anyhow. pub fn reachable_from(&self, a: &T) -> Vec<&T> { match self.index(a) { - Some(a) => self.with_closure(|closure| { - closure.iter(a.0).map(|i| &self.elements[i]).collect() - }), + Some(a) => { + self.with_closure(|closure| closure.iter(a.0).map(|i| &self.elements[i]).collect()) + } None => vec![], } } @@ -285,10 +277,11 @@ impl TransitiveRelation { candidates }); - lub_indices.into_iter() - .rev() // (4) - .map(|i| &self.elements[i]) - .collect() + lub_indices + .into_iter() + .rev() // (4) + .map(|i| &self.elements[i]) + .collect() } /// Given an element A, returns the maximal set {B} of elements B @@ -313,7 +306,7 @@ impl TransitiveRelation { pub fn parents(&self, a: &T) -> Vec<&T> { let a = match self.index(a) { Some(a) => a, - None => return vec![] + None => return vec![], }; // Steal the algorithm for `minimal_upper_bounds` above, but @@ -332,10 +325,11 @@ impl TransitiveRelation { ancestors }); - ancestors.into_iter() - .rev() // (4) - .map(|i| &self.elements[i]) - .collect() + ancestors + .into_iter() + .rev() // (4) + .map(|i| &self.elements[i]) + .collect() } /// A "best" parent in some sense. See `parents` and @@ -345,7 +339,8 @@ impl TransitiveRelation { } fn with_closure(&self, op: OP) -> R - where OP: FnOnce(&BitMatrix) -> R + where + OP: FnOnce(&BitMatrix) -> R, { let mut closure_cell = self.closure.borrow_mut(); let mut closure = closure_cell.take(); @@ -358,8 +353,7 @@ impl TransitiveRelation { } fn compute_closure(&self) -> BitMatrix { - let mut matrix = BitMatrix::new(self.elements.len(), - self.elements.len()); + let mut matrix = BitMatrix::new(self.elements.len(), self.elements.len()); let mut changed = true; while changed { changed = false; @@ -376,7 +370,7 @@ impl TransitiveRelation { /// Lists all the base edges in the graph: the initial _non-transitive_ set of element /// relations, which will be later used as the basis for the transitive closure computation. - pub fn base_edges(&self) -> impl Iterator { + pub fn base_edges(&self) -> impl Iterator { self.edges .iter() .map(move |edge| (&self.elements[edge.source.0], &self.elements[edge.target.0])) @@ -420,7 +414,8 @@ fn pare_down(candidates: &mut Vec, closure: &BitMatrix) { } impl Encodable for TransitiveRelation - where T: Clone + Encodable + Debug + Eq + Hash + Clone +where + T: Clone + Encodable + Debug + Eq + Hash + Clone, { fn encode(&self, s: &mut E) -> Result<(), E::Error> { s.emit_struct("TransitiveRelation", 2, |s| { @@ -432,23 +427,26 @@ impl Encodable for TransitiveRelation } impl Decodable for TransitiveRelation - where T: Clone + Decodable + Debug + Eq + Hash + Clone +where + T: Clone + Decodable + Debug + Eq + Hash + Clone, { fn decode(d: &mut D) -> Result { d.read_struct("TransitiveRelation", 2, |d| { let elements: Vec = d.read_struct_field("elements", 0, |d| Decodable::decode(d))?; let edges = d.read_struct_field("edges", 1, |d| Decodable::decode(d))?; - let map = elements.iter() - .enumerate() - .map(|(index, elem)| (elem.clone(), Index(index))) - .collect(); + let map = elements + .iter() + .enumerate() + .map(|(index, elem)| (elem.clone(), Index(index))) + .collect(); Ok(TransitiveRelation { elements, edges, map, closure: Lock::new(None) }) }) } } impl HashStable for TransitiveRelation - where T: HashStable + Eq + Debug + Clone + Hash +where + T: HashStable + Eq + Debug + Clone + Hash, { fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { // We are assuming here that the relation graph has been built in a @@ -459,7 +457,7 @@ impl HashStable for TransitiveRelation // "map" is just a copy of elements vec map: _, // "closure" is just a copy of the data above - closure: _ + closure: _, } = *self; elements.hash_stable(hcx, hasher); @@ -469,10 +467,7 @@ impl HashStable for TransitiveRelation impl HashStable for Edge { fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { - let Edge { - ref source, - ref target, - } = *self; + let Edge { ref source, ref target } = *self; source.hash_stable(hcx, hasher); target.hash_stable(hcx, hasher); diff --git a/src/librustc_data_structures/transitive_relation/tests.rs b/src/librustc_data_structures/transitive_relation/tests.rs index a462dbdb58383..ca90ba176ae1a 100644 --- a/src/librustc_data_structures/transitive_relation/tests.rs +++ b/src/librustc_data_structures/transitive_relation/tests.rs @@ -157,8 +157,7 @@ fn pdub_crisscross() { relation.add("a1", "x"); relation.add("b1", "x"); - assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), - vec![&"a1", &"b1"]); + assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"a1", &"b1"]); assert_eq!(relation.postdom_upper_bound(&"a", &"b"), Some(&"x")); assert_eq!(relation.postdom_parent(&"a"), Some(&"x")); assert_eq!(relation.postdom_parent(&"b"), Some(&"x")); @@ -188,10 +187,8 @@ fn pdub_crisscross_more() { relation.add("a3", "x"); relation.add("b2", "x"); - assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), - vec![&"a1", &"b1"]); - assert_eq!(relation.minimal_upper_bounds(&"a1", &"b1"), - vec![&"a2", &"b2"]); + assert_eq!(relation.minimal_upper_bounds(&"a", &"b"), vec![&"a1", &"b1"]); + assert_eq!(relation.minimal_upper_bounds(&"a1", &"b1"), vec![&"a2", &"b2"]); assert_eq!(relation.postdom_upper_bound(&"a", &"b"), Some(&"x")); assert_eq!(relation.postdom_parent(&"a"), Some(&"x")); diff --git a/src/librustc_data_structures/vec_linked_list.rs b/src/librustc_data_structures/vec_linked_list.rs index 7744c30655dce..1cf030d852e9f 100644 --- a/src/librustc_data_structures/vec_linked_list.rs +++ b/src/librustc_data_structures/vec_linked_list.rs @@ -7,10 +7,7 @@ pub fn iter( where Ls: Links, { - VecLinkedListIterator { - links, - current: first, - } + VecLinkedListIterator { links, current: first } } pub struct VecLinkedListIterator diff --git a/src/librustc_data_structures/work_queue.rs b/src/librustc_data_structures/work_queue.rs index af63b18e9e922..0c848eb144d79 100644 --- a/src/librustc_data_structures/work_queue.rs +++ b/src/librustc_data_structures/work_queue.rs @@ -17,19 +17,13 @@ impl WorkQueue { /// Creates a new work queue with all the elements from (0..len). #[inline] pub fn with_all(len: usize) -> Self { - WorkQueue { - deque: (0..len).map(T::new).collect(), - set: BitSet::new_filled(len), - } + WorkQueue { deque: (0..len).map(T::new).collect(), set: BitSet::new_filled(len) } } /// Creates a new work queue that starts empty, where elements range from (0..len). #[inline] pub fn with_none(len: usize) -> Self { - WorkQueue { - deque: VecDeque::with_capacity(len), - set: BitSet::new_empty(len), - } + WorkQueue { deque: VecDeque::with_capacity(len), set: BitSet::new_empty(len) } } /// Attempt to enqueue `element` in the work queue. Returns false if it was already present. diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 3230e048a3bf3..adcf6ae2a7c45 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -5,15 +5,13 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] - #![feature(box_syntax)] #![cfg_attr(unix, feature(libc))] #![feature(nll)] #![feature(set_stdio)] #![feature(no_debug)] #![feature(integer_atomics)] - -#![recursion_limit="256"] +#![recursion_limit = "256"] pub extern crate getopts; #[cfg(unix)] @@ -26,25 +24,25 @@ extern crate lazy_static; pub extern crate rustc_plugin_impl as plugin; //use rustc_resolve as resolve; -use rustc_save_analysis as save; -use rustc_save_analysis::DumpHandler; -use rustc::session::{config, Session, DiagnosticOutput}; -use rustc::session::config::{Input, PrintRequest, ErrorOutputType, OutputType}; -use rustc::session::config::nightly_options; -use rustc::session::{early_error, early_warn}; -use rustc::lint::Lint; +use errors::{registry::Registry, PResult}; +use rustc::hir::def_id::LOCAL_CRATE; use rustc::lint; +use rustc::lint::Lint; use rustc::middle::cstore::MetadataLoader; -use rustc::hir::def_id::LOCAL_CRATE; +use rustc::session::config::nightly_options; +use rustc::session::config::{ErrorOutputType, Input, OutputType, PrintRequest}; +use rustc::session::{config, DiagnosticOutput, Session}; +use rustc::session::{early_error, early_warn}; use rustc::ty::TyCtxt; -use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorReported}; -use rustc_metadata::locator; +use rustc::util::common::{print_time_passes_entry, set_time_depth, time, ErrorReported}; use rustc_codegen_utils::codegen_backend::CodegenBackend; -use errors::{PResult, registry::Registry}; -use rustc_interface::{interface, Queries}; -use rustc_interface::util::get_builtin_codegen_backend; use rustc_data_structures::sync::SeqCst; use rustc_feature::{find_gated_cfg, UnstableFeatures}; +use rustc_interface::util::get_builtin_codegen_backend; +use rustc_interface::{interface, Queries}; +use rustc_metadata::locator; +use rustc_save_analysis as save; +use rustc_save_analysis::DumpHandler; use rustc_serialize::json::ToJson; use std::borrow::Cow; @@ -65,8 +63,8 @@ use syntax_pos::source_map::FileLoader; use syntax_pos::symbol::sym; use syntax_pos::FileName; -pub mod pretty; mod args; +pub mod pretty; /// Exit status code used for successful compilation and help output. pub const EXIT_SUCCESS: i32 = 0; @@ -138,9 +136,8 @@ impl Callbacks for TimePassesCallbacks { fn config(&mut self, config: &mut interface::Config) { // If a --prints=... option has been given, we don't print the "total" // time because it will mess up the --prints output. See #64339. - self.time_passes = - config.opts.prints.is_empty() && - (config.opts.debugging_opts.time_passes || config.opts.debugging_opts.time); + self.time_passes = config.opts.prints.is_empty() + && (config.opts.debugging_opts.time_passes || config.opts.debugging_opts.time); } } @@ -155,18 +152,20 @@ pub fn run_compiler( at_args: &[String], callbacks: &mut (dyn Callbacks + Send), file_loader: Option>, - emitter: Option> + emitter: Option>, ) -> interface::Result<()> { let mut args = Vec::new(); for arg in at_args { match args::arg_expand(arg.clone()) { Ok(arg) => args.extend(arg), - Err(err) => early_error(ErrorOutputType::default(), - &format!("Failed to load argument file: {}", err)), + Err(err) => early_error( + ErrorOutputType::default(), + &format!("Failed to load argument file: {}", err), + ), } } - let diagnostic_output = emitter.map(|emitter| DiagnosticOutput::Raw(emitter)) - .unwrap_or(DiagnosticOutput::Default); + let diagnostic_output = + emitter.map(|emitter| DiagnosticOutput::Raw(emitter)).unwrap_or(DiagnosticOutput::Default); let matches = match handle_options(&args) { Some(matches) => matches, None => return Ok(()), @@ -204,47 +203,43 @@ pub fn run_compiler( let (odir, ofile) = make_output(&matches); let (input, input_file_path, input_err) = match make_input(&matches.free) { Some(v) => v, - None => { - match matches.free.len() { - 0 => { - let config = dummy_config(sopts, cfg, diagnostic_output); - interface::run_compiler(config, |compiler| { - let sopts = &compiler.session().opts; - if sopts.describe_lints { - let lint_store = rustc_lint::new_lint_store( - sopts.debugging_opts.no_interleave_lints, - compiler.session().unstable_options(), - ); - describe_lints( - compiler.session(), - &lint_store, - false - ); - return; - } - let should_stop = RustcDefaultCalls::print_crate_info( - &***compiler.codegen_backend(), - compiler.session(), - None, - &odir, - &ofile + None => match matches.free.len() { + 0 => { + let config = dummy_config(sopts, cfg, diagnostic_output); + interface::run_compiler(config, |compiler| { + let sopts = &compiler.session().opts; + if sopts.describe_lints { + let lint_store = rustc_lint::new_lint_store( + sopts.debugging_opts.no_interleave_lints, + compiler.session().unstable_options(), ); + describe_lints(compiler.session(), &lint_store, false); + return; + } + let should_stop = RustcDefaultCalls::print_crate_info( + &***compiler.codegen_backend(), + compiler.session(), + None, + &odir, + &ofile, + ); - if should_stop == Compilation::Stop { - return; - } - early_error(sopts.error_format, "no input filename given") - }); - return Ok(()); - } - 1 => panic!("make_input should have provided valid inputs"), - _ => early_error(sopts.error_format, &format!( - "multiple input filenames provided (first two filenames are `{}` and `{}`)", - matches.free[0], - matches.free[1], - )), + if should_stop == Compilation::Stop { + return; + } + early_error(sopts.error_format, "no input filename given") + }); + return Ok(()); } - } + 1 => panic!("make_input should have provided valid inputs"), + _ => early_error( + sopts.error_format, + &format!( + "multiple input filenames provided (first two filenames are `{}` and `{}`)", + matches.free[0], matches.free[1], + ), + ), + }, }; if let Some(err) = input_err { @@ -283,12 +278,15 @@ pub fn run_compiler( Some(compiler.input()), compiler.output_dir(), compiler.output_file(), - ).and_then(|| RustcDefaultCalls::list_metadata( - sess, - &*compiler.codegen_backend().metadata_loader(), - &matches, - compiler.input() - )); + ) + .and_then(|| { + RustcDefaultCalls::list_metadata( + sess, + &*compiler.codegen_backend().metadata_loader(), + &matches, + compiler.input(), + ) + }); if should_stop == Compilation::Stop { return sess.compile_status(); @@ -328,10 +326,11 @@ pub fn run_compiler( return early_exit(); } - if sess.opts.debugging_opts.parse_only || - sess.opts.debugging_opts.show_span.is_some() || - sess.opts.debugging_opts.ast_json_noexpand { - return early_exit(); + if sess.opts.debugging_opts.parse_only + || sess.opts.debugging_opts.show_span.is_some() + || sess.opts.debugging_opts.ast_json_noexpand + { + return early_exit(); } { @@ -359,9 +358,8 @@ pub fn run_compiler( queries.global_ctxt()?; - if sess.opts.debugging_opts.no_analysis || - sess.opts.debugging_opts.ast_json { - return early_exit(); + if sess.opts.debugging_opts.no_analysis || sess.opts.debugging_opts.ast_json { + return early_exit(); } if sess.opts.debugging_opts.save_analysis { @@ -378,8 +376,9 @@ pub fn run_compiler( &compiler.input(), None, DumpHandler::new( - compiler.output_dir().as_ref().map(|p| &**p), &crate_name - ) + compiler.output_dir().as_ref().map(|p| &**p), + &crate_name, + ), ) }); @@ -421,9 +420,11 @@ pub fn run_compiler( } if sess.print_fuel_crate.is_some() { - eprintln!("Fuel used by {}: {}", + eprintln!( + "Fuel used by {}: {}", sess.print_fuel_crate.as_ref().unwrap(), - sess.print_fuel.load(SeqCst)); + sess.print_fuel.load(SeqCst) + ); } Ok(()) @@ -456,25 +457,26 @@ fn make_input(free_matches: &[String]) -> Option<(Input, Option, Option if ifile == "-" { let mut src = String::new(); let err = if io::stdin().read_to_string(&mut src).is_err() { - Some(io::Error::new(io::ErrorKind::InvalidData, - "couldn't read from stdin, as it did not contain valid UTF-8")) + Some(io::Error::new( + io::ErrorKind::InvalidData, + "couldn't read from stdin, as it did not contain valid UTF-8", + )) } else { None }; if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") { - let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE"). - expect("when UNSTABLE_RUSTDOC_TEST_PATH is set \ - UNSTABLE_RUSTDOC_TEST_LINE also needs to be set"); - let line = isize::from_str_radix(&line, 10). - expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number"); + let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect( + "when UNSTABLE_RUSTDOC_TEST_PATH is set \ + UNSTABLE_RUSTDOC_TEST_LINE also needs to be set", + ); + let line = isize::from_str_radix(&line, 10) + .expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number"); let file_name = FileName::doc_test_source_code(PathBuf::from(path), line); return Some((Input::Str { name: file_name, input: src }, None, err)); } - Some((Input::Str { name: FileName::anon_source_code(&src), input: src }, - None, err)) + Some((Input::Str { name: FileName::anon_source_code(&src), input: src }, None, err)) } else { - Some((Input::File(PathBuf::from(ifile)), - Some(PathBuf::from(ifile)), None)) + Some((Input::File(PathBuf::from(ifile)), Some(PathBuf::from(ifile)), None)) } } else { None @@ -527,11 +529,8 @@ fn stdout_isatty() -> bool { } fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { - let normalised = if code.starts_with("E") { - code.to_string() - } else { - format!("E{0:0>4}", code) - }; + let normalised = + if code.starts_with("E") { code.to_string() } else { format!("E{0:0>4}", code) }; match registry.find_description(&normalised) { Some(ref description) => { let mut is_in_code_block = false; @@ -539,8 +538,8 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { // Slice off the leading newline and print. for line in description.lines() { - let indent_level = line.find(|c: char| !c.is_whitespace()) - .unwrap_or_else(|| line.len()); + let indent_level = + line.find(|c: char| !c.is_whitespace()).unwrap_or_else(|| line.len()); let dedented_line = &line[indent_level..]; if dedented_line.starts_with("```") { is_in_code_block = !is_in_code_block; @@ -566,10 +565,8 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { } fn show_content_with_pager(content: &String) { - let pager_name = env::var_os("PAGER").unwrap_or_else(|| if cfg!(windows) { - OsString::from("more.com") - } else { - OsString::from("less") + let pager_name = env::var_os("PAGER").unwrap_or_else(|| { + if cfg!(windows) { OsString::from("more.com") } else { OsString::from("less") } }); let mut fallback_to_println = false; @@ -599,22 +596,20 @@ fn show_content_with_pager(content: &String) { } impl RustcDefaultCalls { - pub fn list_metadata(sess: &Session, - metadata_loader: &dyn MetadataLoader, - matches: &getopts::Matches, - input: &Input) - -> Compilation { + pub fn list_metadata( + sess: &Session, + metadata_loader: &dyn MetadataLoader, + matches: &getopts::Matches, + input: &Input, + ) -> Compilation { let r = matches.opt_strs("Z"); if r.iter().any(|s| *s == "ls") { match input { &Input::File(ref ifile) => { let path = &(*ifile); let mut v = Vec::new(); - locator::list_file_metadata(&sess.target.target, - path, - metadata_loader, - &mut v) - .unwrap(); + locator::list_file_metadata(&sess.target.target, path, metadata_loader, &mut v) + .unwrap(); println!("{}", String::from_utf8(v).unwrap()); } &Input::Str { .. } => { @@ -627,13 +622,13 @@ impl RustcDefaultCalls { Compilation::Continue } - - fn print_crate_info(codegen_backend: &dyn CodegenBackend, - sess: &Session, - input: Option<&Input>, - odir: &Option, - ofile: &Option) - -> Compilation { + fn print_crate_info( + codegen_backend: &dyn CodegenBackend, + sess: &Session, + input: Option<&Input>, + odir: &Option, + ofile: &Option, + ) -> Compilation { use rustc::session::config::PrintRequest::*; // PrintRequest::NativeStaticLibs is special - printed during linking // (empty iterator returns true) @@ -660,19 +655,16 @@ impl RustcDefaultCalls { let mut targets = rustc_target::spec::get_targets().collect::>(); targets.sort(); println!("{}", targets.join("\n")); - }, + } Sysroot => println!("{}", sess.sysroot.display()), TargetSpec => println!("{}", sess.target.target.to_json().pretty()), FileNames | CrateName => { - let input = input.unwrap_or_else(|| - early_error(ErrorOutputType::default(), "no input file provided")); + let input = input.unwrap_or_else(|| { + early_error(ErrorOutputType::default(), "no input file provided") + }); let attrs = attrs.as_ref().unwrap(); let t_outputs = rustc_interface::util::build_output_filenames( - input, - odir, - ofile, - attrs, - sess + input, odir, ofile, attrs, sess, ); let id = rustc_codegen_utils::link::find_crate_name(Some(sess), attrs, input); if *req == PrintRequest::CrateName { @@ -682,42 +674,44 @@ impl RustcDefaultCalls { let crate_types = rustc_interface::util::collect_crate_types(sess, attrs); for &style in &crate_types { let fname = rustc_codegen_utils::link::filename_for_input( - sess, - style, - &id, - &t_outputs + sess, style, &id, &t_outputs, ); println!("{}", fname.file_name().unwrap().to_string_lossy()); } } Cfg => { - let allow_unstable_cfg = UnstableFeatures::from_environment() - .is_nightly_build(); - - let mut cfgs = sess.parse_sess.config.iter().filter_map(|&(name, ref value)| { - // Note that crt-static is a specially recognized cfg - // directive that's printed out here as part of - // rust-lang/rust#37406, but in general the - // `target_feature` cfg is gated under - // rust-lang/rust#29717. For now this is just - // specifically allowing the crt-static cfg and that's - // it, this is intended to get into Cargo and then go - // through to build scripts. - let value = value.as_ref().map(|s| s.as_str()); - let value = value.as_ref().map(|s| s.as_ref()); - if (name != sym::target_feature || value != Some("crt-static")) - && !allow_unstable_cfg - && find_gated_cfg(|cfg_sym| cfg_sym == name).is_some() - { - return None; - } - - if let Some(value) = value { - Some(format!("{}=\"{}\"", name, value)) - } else { - Some(name.to_string()) - } - }).collect::>(); + let allow_unstable_cfg = + UnstableFeatures::from_environment().is_nightly_build(); + + let mut cfgs = sess + .parse_sess + .config + .iter() + .filter_map(|&(name, ref value)| { + // Note that crt-static is a specially recognized cfg + // directive that's printed out here as part of + // rust-lang/rust#37406, but in general the + // `target_feature` cfg is gated under + // rust-lang/rust#29717. For now this is just + // specifically allowing the crt-static cfg and that's + // it, this is intended to get into Cargo and then go + // through to build scripts. + let value = value.as_ref().map(|s| s.as_str()); + let value = value.as_ref().map(|s| s.as_ref()); + if (name != sym::target_feature || value != Some("crt-static")) + && !allow_unstable_cfg + && find_gated_cfg(|cfg_sym| cfg_sym == name).is_some() + { + return None; + } + + if let Some(value) = value { + Some(format!("{}=\"{}\"", name, value)) + } else { + Some(name.to_string()) + } + }) + .collect::>(); cfgs.sort(); for cfg in cfgs { @@ -770,11 +764,7 @@ pub fn version(binary: &str, matches: &getopts::Matches) { } fn usage(verbose: bool, include_unstable_options: bool) { - let groups = if verbose { - config::rustc_optgroups() - } else { - config::rustc_short_optgroups() - }; + let groups = if verbose { config::rustc_optgroups() } else { config::rustc_short_optgroups() }; let mut options = getopts::Options::new(); for option in groups.iter().filter(|x| include_unstable_options || x.is_stable()) { (option.apply)(&mut options); @@ -795,27 +785,32 @@ fn usage(verbose: bool, include_unstable_options: bool) { } else { "" }; - println!("{options}{at_path}\nAdditional help: + println!( + "{options}{at_path}\nAdditional help: -C help Print codegen options -W help \ Print 'lint' options and default settings{nightly}{verbose}\n", - options = options.usage(message), - at_path = at_path, - nightly = nightly_help, - verbose = verbose_help); + options = options.usage(message), + at_path = at_path, + nightly = nightly_help, + verbose = verbose_help + ); } fn print_wall_help() { - println!(" + println!( + " The flag `-Wall` does not exist in `rustc`. Most useful lints are enabled by default. Use `rustc -W help` to see all available lints. It's more common to put warning settings in the crate root using `#![warn(LINT_NAME)]` instead of using the command line flag directly. -"); +" + ); } fn describe_lints(sess: &Session, lint_store: &lint::LintStore, loaded_plugins: bool) { - println!(" + println!( + " Available lint options: -W Warn about -A \ @@ -824,7 +819,8 @@ Available lint options: -F Forbid \ (deny and all attempts to override) -"); +" + ); fn sort_lints(sess: &Session, mut lints: Vec<&'static Lint>) -> Vec<&'static Lint> { // The sort doesn't case-fold but it's doubtful we care. @@ -832,32 +828,26 @@ Available lint options: lints } - fn sort_lint_groups(lints: Vec<(&'static str, Vec, bool)>) - -> Vec<(&'static str, Vec)> { + fn sort_lint_groups( + lints: Vec<(&'static str, Vec, bool)>, + ) -> Vec<(&'static str, Vec)> { let mut lints: Vec<_> = lints.into_iter().map(|(x, y, _)| (x, y)).collect(); lints.sort_by_key(|l| l.0); lints } - let (plugin, builtin): (Vec<_>, _) = lint_store.get_lints() - .iter() - .cloned() - .partition(|&lint| lint.is_plugin); + let (plugin, builtin): (Vec<_>, _) = + lint_store.get_lints().iter().cloned().partition(|&lint| lint.is_plugin); let plugin = sort_lints(sess, plugin); let builtin = sort_lints(sess, builtin); - let (plugin_groups, builtin_groups): (Vec<_>, _) = lint_store.get_lint_groups() - .iter() - .cloned() - .partition(|&(.., p)| p); + let (plugin_groups, builtin_groups): (Vec<_>, _) = + lint_store.get_lint_groups().iter().cloned().partition(|&(.., p)| p); let plugin_groups = sort_lint_groups(plugin_groups); let builtin_groups = sort_lint_groups(builtin_groups); - let max_name_len = plugin.iter() - .chain(&builtin) - .map(|&s| s.name.chars().count()) - .max() - .unwrap_or(0); + let max_name_len = + plugin.iter().chain(&builtin).map(|&s| s.name.chars().count()).max().unwrap_or(0); let padded = |x: &str| { let mut s = " ".repeat(max_name_len - x.chars().count()); s.push_str(x); @@ -871,22 +861,22 @@ Available lint options: let print_lints = |lints: Vec<&Lint>| { for lint in lints { let name = lint.name_lower().replace("_", "-"); - println!(" {} {:7.7} {}", - padded(&name), - lint.default_level.as_str(), - lint.desc); + println!(" {} {:7.7} {}", padded(&name), lint.default_level.as_str(), lint.desc); } println!("\n"); }; print_lints(builtin); - let max_name_len = max("warnings".len(), - plugin_groups.iter() - .chain(&builtin_groups) - .map(|&(s, _)| s.chars().count()) - .max() - .unwrap_or(0)); + let max_name_len = max( + "warnings".len(), + plugin_groups + .iter() + .chain(&builtin_groups) + .map(|&(s, _)| s.chars().count()) + .max() + .unwrap_or(0), + ); let padded = |x: &str| { let mut s = " ".repeat(max_name_len - x.chars().count()); @@ -902,10 +892,11 @@ Available lint options: let print_lint_groups = |lints: Vec<(&'static str, Vec)>| { for (name, to) in lints { let name = name.to_lowercase().replace("_", "-"); - let desc = to.into_iter() - .map(|x| x.to_string().replace("_", "-")) - .collect::>() - .join(", "); + let desc = to + .into_iter() + .map(|x| x.to_string().replace("_", "-")) + .collect::>() + .join(", "); println!(" {} {}", padded(&name), desc); } println!("\n"); @@ -915,8 +906,10 @@ Available lint options: match (loaded_plugins, plugin.len(), plugin_groups.len()) { (false, 0, _) | (false, _, 0) => { - println!("Compiler plugins can provide additional lints and lint groups. To see a \ - listing of these, re-run `rustc -W help` with a crate filename."); + println!( + "Compiler plugins can provide additional lints and lint groups. To see a \ + listing of these, re-run `rustc -W help` with a crate filename." + ); } (false, ..) => panic!("didn't load lint plugins but got them anyway!"), (true, 0, 0) => println!("This crate does not load any lint plugins or lint groups."), @@ -943,30 +936,35 @@ fn describe_codegen_flags() { print_flag_list("-C", config::CG_OPTIONS); } -fn print_flag_list(cmdline_opt: &str, - flag_list: &[(&'static str, T, Option<&'static str>, &'static str)]) { - let max_len = flag_list.iter() - .map(|&(name, _, opt_type_desc, _)| { - let extra_len = match opt_type_desc { - Some(..) => 4, - None => 0, - }; - name.chars().count() + extra_len - }) - .max() - .unwrap_or(0); +fn print_flag_list( + cmdline_opt: &str, + flag_list: &[(&'static str, T, Option<&'static str>, &'static str)], +) { + let max_len = flag_list + .iter() + .map(|&(name, _, opt_type_desc, _)| { + let extra_len = match opt_type_desc { + Some(..) => 4, + None => 0, + }; + name.chars().count() + extra_len + }) + .max() + .unwrap_or(0); for &(name, _, opt_type_desc, desc) in flag_list { let (width, extra) = match opt_type_desc { Some(..) => (max_len - 4, "=val"), None => (max_len, ""), }; - println!(" {} {:>width$}{} -- {}", - cmdline_opt, - name.replace("_", "-"), - extra, - desc, - width = width); + println!( + " {} {:>width$}{} -- {}", + cmdline_opt, + name.replace("_", "-"), + extra, + desc, + width = width + ); } } @@ -1010,8 +1008,9 @@ pub fn handle_options(args: &[String]) -> Option { for option in config::rustc_optgroups() { (option.apply)(&mut options); } - let matches = options.parse(args).unwrap_or_else(|f| - early_error(ErrorOutputType::default(), &f.to_string())); + let matches = options + .parse(args) + .unwrap_or_else(|f| early_error(ErrorOutputType::default(), &f.to_string())); // For all options we just parsed, we check a few aspects: // @@ -1054,8 +1053,10 @@ pub fn handle_options(args: &[String]) -> Option { } if cg_flags.iter().any(|x| *x == "no-stack-check") { - early_warn(ErrorOutputType::default(), - "the --no-stack-check flag is deprecated and does nothing"); + early_warn( + ErrorOutputType::default(), + "the --no-stack-check flag is deprecated and does nothing", + ); } if cg_flags.iter().any(|x| *x == "passes=list") { @@ -1073,16 +1074,12 @@ pub fn handle_options(args: &[String]) -> Option { fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, Vec> { match input { - Input::File(ifile) => { - rustc_parse::parse_crate_attrs_from_file(ifile, &sess.parse_sess) - } - Input::Str { name, input } => { - rustc_parse::parse_crate_attrs_from_source_str( - name.clone(), - input.clone(), - &sess.parse_sess, - ) - } + Input::File(ifile) => rustc_parse::parse_crate_attrs_from_file(ifile, &sess.parse_sess), + Input::Str { name, input } => rustc_parse::parse_crate_attrs_from_source_str( + name.clone(), + input.clone(), + &sess.parse_sess, + ), } } @@ -1113,17 +1110,10 @@ fn extra_compiler_flags() -> Option<(Vec, bool)> { for content in &matches.opt_strs(flag) { // Split always returns the first element - let name = if let Some(first) = content.split('=').next() { - first - } else { - &content - }; + let name = if let Some(first) = content.split('=').next() { first } else { &content }; - let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) { - name - } else { - content - }; + let content = + if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) { name } else { content }; if !ICE_REPORT_COMPILER_FLAGS_EXCLUDE.contains(&name) { result.push(format!("{}{} {}", prefix, flag, content)); @@ -1133,11 +1123,7 @@ fn extra_compiler_flags() -> Option<(Vec, bool)> { } } - if !result.is_empty() { - Some((result, excluded_cargo_defaults)) - } else { - None - } + if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None } } /// Runs a closure and catches unwinds triggered by fatal errors. @@ -1197,9 +1183,12 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { let mut xs: Vec> = vec![ "the compiler unexpectedly panicked. this is a bug.".into(), format!("we would appreciate a bug report: {}", bug_report_url).into(), - format!("rustc {} running on {}", - option_env!("CFG_VERSION").unwrap_or("unknown_version"), - config::host_triple()).into(), + format!( + "rustc {} running on {}", + option_env!("CFG_VERSION").unwrap_or("unknown_version"), + config::host_triple() + ) + .into(), ]; if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() { @@ -1252,14 +1241,20 @@ pub fn main() { let mut callbacks = TimePassesCallbacks::default(); install_ice_hook(); let result = catch_fatal_errors(|| { - let args = env::args_os().enumerate() - .map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| { - early_error(ErrorOutputType::default(), - &format!("Argument {} is not valid Unicode: {:?}", i, arg)) - })) + let args = env::args_os() + .enumerate() + .map(|(i, arg)| { + arg.into_string().unwrap_or_else(|arg| { + early_error( + ErrorOutputType::default(), + &format!("Argument {} is not valid Unicode: {:?}", i, arg), + ) + }) + }) .collect::>(); run_compiler(&args, &mut callbacks, None, None) - }).and_then(|result| result); + }) + .and_then(|result| result); let exit_code = match result { Ok(_) => EXIT_SUCCESS, Err(_) => EXIT_FAILURE, diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 97e4cf7212447..87ce637c6f5c4 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -1,17 +1,17 @@ //! The various pretty-printing routines. use rustc::hir; +use rustc::hir::def_id::LOCAL_CRATE; use rustc::hir::map as hir_map; use rustc::hir::print as pprust_hir; -use rustc::hir::def_id::LOCAL_CRATE; +use rustc::session::config::{Input, PpMode, PpSourceMode}; use rustc::session::Session; -use rustc::session::config::{PpMode, PpSourceMode, Input}; use rustc::ty::{self, TyCtxt}; use rustc::util::common::ErrorReported; -use rustc_mir::util::{write_mir_pretty, write_mir_graphviz}; +use rustc_mir::util::{write_mir_graphviz, write_mir_pretty}; use syntax::ast; -use syntax::print::{pprust}; +use syntax::print::pprust; use syntax_pos::FileName; use std::cell::Cell; @@ -19,8 +19,8 @@ use std::fs::File; use std::io::Write; use std::path::Path; -pub use self::PpSourceMode::*; pub use self::PpMode::*; +pub use self::PpSourceMode::*; use crate::abort_on_err; // This slightly awkward construction is to allow for each PpMode to @@ -48,24 +48,16 @@ where { match *ppmode { PpmNormal | PpmEveryBodyLoops | PpmExpanded => { - let annotation = NoAnn { - sess, - tcx, - }; + let annotation = NoAnn { sess, tcx }; f(&annotation) } PpmIdentified | PpmExpandedIdentified => { - let annotation = IdentifiedAnnotation { - sess, - tcx, - }; + let annotation = IdentifiedAnnotation { sess, tcx }; f(&annotation) } PpmExpandedHygiene => { - let annotation = HygieneAnnotation { - sess, - }; + let annotation = HygieneAnnotation { sess }; f(&annotation) } _ => panic!("Should use call_with_pp_support_hir"), @@ -77,31 +69,20 @@ where { match *ppmode { PpmNormal => { - let annotation = NoAnn { - sess: tcx.sess, - tcx: Some(tcx), - }; + let annotation = NoAnn { sess: tcx.sess, tcx: Some(tcx) }; f(&annotation, tcx.hir().forest.krate()) } PpmIdentified => { - let annotation = IdentifiedAnnotation { - sess: tcx.sess, - tcx: Some(tcx), - }; + let annotation = IdentifiedAnnotation { sess: tcx.sess, tcx: Some(tcx) }; f(&annotation, tcx.hir().forest.krate()) } PpmTyped => { abort_on_err(tcx.analysis(LOCAL_CRATE), tcx.sess); let empty_tables = ty::TypeckTables::empty(None); - let annotation = TypedAnnotation { - tcx, - tables: Cell::new(&empty_tables) - }; - tcx.dep_graph.with_ignore(|| { - f(&annotation, tcx.hir().forest.krate()) - }) + let annotation = TypedAnnotation { tcx, tables: Cell::new(&empty_tables) }; + tcx.dep_graph.with_ignore(|| f(&annotation, tcx.hir().forest.krate())) } _ => panic!("Should use call_with_pp_support"), } @@ -136,14 +117,8 @@ trait HirPrinterSupport<'hir>: pprust_hir::PpAnn { /// Computes an user-readable representation of a path, if possible. fn node_path(&self, id: hir::HirId) -> Option { - self.hir_map().and_then(|map| { - map.def_path_from_hir_id(id) - }).map(|path| { - path.data - .into_iter() - .map(|elem| elem.data.to_string()) - .collect::>() - .join("::") + self.hir_map().and_then(|map| map.def_path_from_hir_id(id)).map(|path| { + path.data.into_iter().map(|elem| elem.data.to_string()).collect::>().join("::") }) } } @@ -210,9 +185,7 @@ impl<'hir> pprust::PpAnn for IdentifiedAnnotation<'hir> { } fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) { match node { - pprust::AnnNode::Crate(_) | - pprust::AnnNode::Ident(_) | - pprust::AnnNode::Name(_) => {}, + pprust::AnnNode::Crate(_) | pprust::AnnNode::Ident(_) | pprust::AnnNode::Name(_) => {} pprust::AnnNode::Item(item) => { s.s.space(); @@ -267,7 +240,7 @@ impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> { } fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { match node { - pprust_hir::AnnNode::Name(_) => {}, + pprust_hir::AnnNode::Name(_) => {} pprust_hir::AnnNode::Item(item) => { s.s.space(); s.synth_comment(format!("hir_id: {}", item.hir_id)); @@ -298,7 +271,7 @@ impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> { } struct HygieneAnnotation<'a> { - sess: &'a Session + sess: &'a Session, } impl<'a> PrinterSupport for HygieneAnnotation<'a> { @@ -380,39 +353,35 @@ impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> { s.s.word(self.tables.get().expr_ty(expr).to_string()); s.pclose(); } - _ => {}, + _ => {} } } } fn get_source(input: &Input, sess: &Session) -> (String, FileName) { let src_name = input.source_name(); - let src = String::clone(&sess.source_map() - .get_source_file(&src_name) - .unwrap() - .src - .as_ref() - .unwrap()); + let src = + String::clone(&sess.source_map().get_source_file(&src_name).unwrap().src.as_ref().unwrap()); (src, src_name) } fn write_output(out: Vec, ofile: Option<&Path>) { match ofile { None => print!("{}", String::from_utf8(out).unwrap()), - Some(p) => { - match File::create(p) { - Ok(mut w) => w.write_all(&out).unwrap(), - Err(e) => panic!("print-print failed to open {} due to {}", p.display(), e), - } - } + Some(p) => match File::create(p) { + Ok(mut w) => w.write_all(&out).unwrap(), + Err(e) => panic!("print-print failed to open {} due to {}", p.display(), e), + }, } } -pub fn print_after_parsing(sess: &Session, - input: &Input, - krate: &ast::Crate, - ppm: PpMode, - ofile: Option<&Path>) { +pub fn print_after_parsing( + sess: &Session, + input: &Input, + krate: &ast::Crate, + ppm: PpMode, + ofile: Option<&Path>, +) { let (src, src_name) = get_source(input, sess); let mut out = String::new(); @@ -423,13 +392,15 @@ pub fn print_after_parsing(sess: &Session, call_with_pp_support(&s, sess, None, move |annotation| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); - *out = pprust::print_crate(sess.source_map(), - &sess.parse_sess, - krate, - src_name, - src, - annotation.pp_ann(), - false) + *out = pprust::print_crate( + sess.source_map(), + &sess.parse_sess, + krate, + src_name, + src, + annotation.pp_ann(), + false, + ) }) } else { unreachable!(); @@ -446,11 +417,7 @@ pub fn print_after_hir_lowering<'tcx>( ofile: Option<&Path>, ) { if ppm.needs_analysis() { - abort_on_err(print_with_analysis( - tcx, - ppm, - ofile - ), tcx.sess); + abort_on_err(print_with_analysis(tcx, ppm, ofile), tcx.sess); return; } @@ -459,49 +426,53 @@ pub fn print_after_hir_lowering<'tcx>( let mut out = String::new(); match ppm { - PpmSource(s) => { - // Silently ignores an identified node. - let out = &mut out; - let src = src.clone(); - call_with_pp_support(&s, tcx.sess, Some(tcx), move |annotation| { - debug!("pretty printing source code {:?}", s); - let sess = annotation.sess(); - *out = pprust::print_crate(sess.source_map(), - &sess.parse_sess, - krate, - src_name, - src, - annotation.pp_ann(), - true) - }) - } - - PpmHir(s) => { - let out = &mut out; - let src = src.clone(); - call_with_pp_support_hir(&s, tcx, move |annotation, krate| { - debug!("pretty printing source code {:?}", s); - let sess = annotation.sess(); - *out = pprust_hir::print_crate(sess.source_map(), - &sess.parse_sess, - krate, - src_name, - src, - annotation.pp_ann()) - }) - } + PpmSource(s) => { + // Silently ignores an identified node. + let out = &mut out; + let src = src.clone(); + call_with_pp_support(&s, tcx.sess, Some(tcx), move |annotation| { + debug!("pretty printing source code {:?}", s); + let sess = annotation.sess(); + *out = pprust::print_crate( + sess.source_map(), + &sess.parse_sess, + krate, + src_name, + src, + annotation.pp_ann(), + true, + ) + }) + } - PpmHirTree(s) => { - let out = &mut out; - call_with_pp_support_hir(&s, tcx, move |_annotation, krate| { - debug!("pretty printing source code {:?}", s); - *out = format!("{:#?}", krate); - }); - } + PpmHir(s) => { + let out = &mut out; + let src = src.clone(); + call_with_pp_support_hir(&s, tcx, move |annotation, krate| { + debug!("pretty printing source code {:?}", s); + let sess = annotation.sess(); + *out = pprust_hir::print_crate( + sess.source_map(), + &sess.parse_sess, + krate, + src_name, + src, + annotation.pp_ann(), + ) + }) + } - _ => unreachable!(), + PpmHirTree(s) => { + let out = &mut out; + call_with_pp_support_hir(&s, tcx, move |_annotation, krate| { + debug!("pretty printing source code {:?}", s); + *out = format!("{:#?}", krate); + }); } + _ => unreachable!(), + } + write_output(out.into_bytes(), ofile); } @@ -519,15 +490,14 @@ fn print_with_analysis( tcx.analysis(LOCAL_CRATE)?; match ppm { - PpmMir | PpmMirCFG => { - match ppm { - PpmMir => write_mir_pretty(tcx, None, &mut out), - PpmMirCFG => write_mir_graphviz(tcx, None, &mut out), - _ => unreachable!(), - } - } + PpmMir | PpmMirCFG => match ppm { + PpmMir => write_mir_pretty(tcx, None, &mut out), + PpmMirCFG => write_mir_graphviz(tcx, None, &mut out), + _ => unreachable!(), + }, _ => unreachable!(), - }.unwrap(); + } + .unwrap(); write_output(out, ofile); diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs index 4c5d0178b2c64..e63e124fbc5d8 100644 --- a/src/librustc_errors/annotate_snippet_emitter_writer.rs +++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs @@ -5,19 +5,15 @@ //! //! [annotate_snippets]: https://docs.rs/crate/annotate-snippets/ -use syntax_pos::{SourceFile, MultiSpan, Loc}; -use syntax_pos::source_map::SourceMap; -use crate::{ - Level, CodeSuggestion, Diagnostic, Emitter, - SubDiagnostic, DiagnosticId -}; use crate::emitter::FileWithAnnotatedLines; -use rustc_data_structures::sync::Lrc; use crate::snippet::Line; -use annotate_snippets::snippet::*; +use crate::{CodeSuggestion, Diagnostic, DiagnosticId, Emitter, Level, SubDiagnostic}; use annotate_snippets::display_list::DisplayList; use annotate_snippets::formatter::DisplayListFormatter; - +use annotate_snippets::snippet::*; +use rustc_data_structures::sync::Lrc; +use syntax_pos::source_map::SourceMap; +use syntax_pos::{Loc, MultiSpan, SourceFile}; /// Generates diagnostics using annotate-snippet pub struct AnnotateSnippetEmitterWriter { @@ -36,18 +32,22 @@ impl Emitter for AnnotateSnippetEmitterWriter { let mut children = diag.children.clone(); let (mut primary_span, suggestions) = self.primary_span_formatted(&diag); - self.fix_multispans_in_std_macros(&self.source_map, - &mut primary_span, - &mut children, - &diag.level, - self.external_macro_backtrace); - - self.emit_messages_default(&diag.level, - diag.message(), - &diag.code, - &primary_span, - &children, - &suggestions); + self.fix_multispans_in_std_macros( + &self.source_map, + &mut primary_span, + &mut children, + &diag.level, + self.external_macro_backtrace, + ); + + self.emit_messages_default( + &diag.level, + diag.message(), + &diag.code, + &primary_span, + &children, + &suggestions, + ); } fn source_map(&self) -> Option<&Lrc> { @@ -70,35 +70,30 @@ struct DiagnosticConverter<'a> { #[allow(dead_code)] children: &'a [SubDiagnostic], #[allow(dead_code)] - suggestions: &'a [CodeSuggestion] + suggestions: &'a [CodeSuggestion], } -impl<'a> DiagnosticConverter<'a> { +impl<'a> DiagnosticConverter<'a> { /// Turns rustc Diagnostic information into a `annotate_snippets::snippet::Snippet`. fn to_annotation_snippet(&self) -> Option { if let Some(source_map) = &self.source_map { // Make sure our primary file comes first - let primary_lo = if let Some(ref primary_span) = - self.msp.primary_span().as_ref() { + let primary_lo = if let Some(ref primary_span) = self.msp.primary_span().as_ref() { source_map.lookup_char_pos(primary_span.lo()) } else { // FIXME(#59346): Not sure when this is the case and what // should be done if it happens - return None + return None; }; - let annotated_files = FileWithAnnotatedLines::collect_annotations( - &self.msp, - &self.source_map - ); + let annotated_files = + FileWithAnnotatedLines::collect_annotations(&self.msp, &self.source_map); let slices = self.slices_for_files(annotated_files, primary_lo); Some(Snippet { title: Some(Annotation { label: Some(self.message.to_string()), - id: self.code.clone().map(|c| { - match c { - DiagnosticId::Error(val) | DiagnosticId::Lint(val) => val - } + id: self.code.clone().map(|c| match c { + DiagnosticId::Error(val) | DiagnosticId::Lint(val) => val, }), annotation_type: Self::annotation_type_for_level(self.level), }), @@ -114,43 +109,49 @@ impl<'a> DiagnosticConverter<'a> { fn slices_for_files( &self, annotated_files: Vec, - primary_lo: Loc + primary_lo: Loc, ) -> Vec { // FIXME(#64205): Provide a test case where `annotated_files` is > 1 - annotated_files.iter().flat_map(|annotated_file| { - annotated_file.lines.iter().map(|line| { - let line_source = Self::source_string(annotated_file.file.clone(), &line); - Slice { - source: line_source, - line_start: line.line_index, - origin: Some(primary_lo.file.name.to_string()), - // FIXME(#59346): Not really sure when `fold` should be true or false - fold: false, - annotations: line.annotations.iter().map(|a| { - self.annotation_to_source_annotation(a.clone()) - }).collect(), - } - }).collect::>() - }).collect::>() + annotated_files + .iter() + .flat_map(|annotated_file| { + annotated_file + .lines + .iter() + .map(|line| { + let line_source = Self::source_string(annotated_file.file.clone(), &line); + Slice { + source: line_source, + line_start: line.line_index, + origin: Some(primary_lo.file.name.to_string()), + // FIXME(#59346): Not really sure when `fold` should be true or false + fold: false, + annotations: line + .annotations + .iter() + .map(|a| self.annotation_to_source_annotation(a.clone())) + .collect(), + } + }) + .collect::>() + }) + .collect::>() } /// Turns a `crate::snippet::Annotation` into a `SourceAnnotation` fn annotation_to_source_annotation( &self, - annotation: crate::snippet::Annotation + annotation: crate::snippet::Annotation, ) -> SourceAnnotation { SourceAnnotation { range: (annotation.start_col, annotation.end_col), label: annotation.label.unwrap_or("".to_string()), - annotation_type: Self::annotation_type_for_level(self.level) + annotation_type: Self::annotation_type_for_level(self.level), } } /// Provides the source string for the given `line` of `file` - fn source_string( - file: Lrc, - line: &Line - ) -> String { + fn source_string(file: Lrc, line: &Line) -> String { file.get_line(line.line_index - 1).map(|a| a.to_string()).unwrap_or(String::new()) } @@ -162,7 +163,7 @@ impl<'a> DiagnosticConverter<'a> { Level::Note => AnnotationType::Note, Level::Help => AnnotationType::Help, // FIXME(#59346): Not sure how to map these two levels - Level::Cancelled | Level::FailureNote => AnnotationType::Error + Level::Cancelled | Level::FailureNote => AnnotationType::Error, } } } @@ -173,12 +174,7 @@ impl AnnotateSnippetEmitterWriter { short_message: bool, external_macro_backtrace: bool, ) -> Self { - Self { - source_map, - short_message, - ui_testing: false, - external_macro_backtrace, - } + Self { source_map, short_message, ui_testing: false, external_macro_backtrace } } /// Allows to modify `Self` to enable or disable the `ui_testing` flag. @@ -196,7 +192,7 @@ impl AnnotateSnippetEmitterWriter { code: &Option, msp: &MultiSpan, children: &[SubDiagnostic], - suggestions: &[CodeSuggestion] + suggestions: &[CodeSuggestion], ) { let converter = DiagnosticConverter { source_map: self.source_map.clone(), @@ -205,7 +201,7 @@ impl AnnotateSnippetEmitterWriter { code: code.clone(), msp: msp.clone(), children, - suggestions + suggestions, }; if let Some(snippet) = converter.to_annotation_snippet() { let dl = DisplayList::from(snippet); diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index 744f4a47b6035..6112269ef7fec 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -1,10 +1,10 @@ -use crate::CodeSuggestion; -use crate::SuggestionStyle; -use crate::SubstitutionPart; -use crate::Substitution; +use crate::snippet::Style; use crate::Applicability; +use crate::CodeSuggestion; use crate::Level; -use crate::snippet::Style; +use crate::Substitution; +use crate::SubstitutionPart; +use crate::SuggestionStyle; use std::fmt; use syntax_pos::{MultiSpan, Span, DUMMY_SP}; @@ -81,7 +81,7 @@ pub enum StringPart { impl StringPart { pub fn content(&self) -> &str { match self { - &StringPart::Normal(ref s) | & StringPart::Highlighted(ref s) => s + &StringPart::Normal(ref s) | &StringPart::Highlighted(ref s) => s, } } } @@ -105,19 +105,9 @@ impl Diagnostic { pub fn is_error(&self) -> bool { match self.level { - Level::Bug | - Level::Fatal | - Level::Error | - Level::FailureNote => { - true - } + Level::Bug | Level::Fatal | Level::Error | Level::FailureNote => true, - Level::Warning | - Level::Note | - Level::Help | - Level::Cancelled => { - false - } + Level::Warning | Level::Note | Level::Help | Level::Cancelled => false, } } @@ -177,19 +167,16 @@ impl Diagnostic { found: DiagnosticStyledString, ) -> &mut Self { let mut msg: Vec<_> = - vec![(format!("required when trying to coerce from type `"), - Style::NoStyle)]; - msg.extend(expected.0.iter() - .map(|x| match *x { - StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle), - StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight), - })); + vec![(format!("required when trying to coerce from type `"), Style::NoStyle)]; + msg.extend(expected.0.iter().map(|x| match *x { + StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle), + StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight), + })); msg.push((format!("` to type '"), Style::NoStyle)); - msg.extend(found.0.iter() - .map(|x| match *x { - StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle), - StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight), - })); + msg.extend(found.0.iter().map(|x| match *x { + StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle), + StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight), + })); msg.push((format!("`"), Style::NoStyle)); // For now, just attach these as notes @@ -213,22 +200,18 @@ impl Diagnostic { } else { (0, found_label.len() - expected_label.len()) }; - let mut msg: Vec<_> = vec![( - format!("{}{} `", " ".repeat(expected_padding), expected_label), - Style::NoStyle, - )]; - msg.extend(expected.0.iter() - .map(|x| match *x { - StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle), - StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight), - })); + let mut msg: Vec<_> = + vec![(format!("{}{} `", " ".repeat(expected_padding), expected_label), Style::NoStyle)]; + msg.extend(expected.0.iter().map(|x| match *x { + StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle), + StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight), + })); msg.push((format!("`{}\n", expected_extra), Style::NoStyle)); msg.push((format!("{}{} `", " ".repeat(found_padding), found_label), Style::NoStyle)); - msg.extend(found.0.iter() - .map(|x| match *x { - StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle), - StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight), - })); + msg.extend(found.0.iter().map(|x| match *x { + StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle), + StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight), + })); msg.push((format!("`{}", found_extra), Style::NoStyle)); // For now, just attach these as notes. @@ -240,7 +223,8 @@ impl Diagnostic { self.highlighted_note(vec![ (format!("`{}` from trait: `", name), Style::NoStyle), (signature, Style::Highlight), - ("`".to_string(), Style::NoStyle)]); + ("`".to_string(), Style::NoStyle), + ]); self } @@ -255,10 +239,7 @@ impl Diagnostic { } /// Prints the span with a note above it. - pub fn span_note>(&mut self, - sp: S, - msg: &str) - -> &mut Self { + pub fn span_note>(&mut self, sp: S, msg: &str) -> &mut Self { self.sub(Level::Note, msg, sp.into(), None); self } @@ -269,24 +250,18 @@ impl Diagnostic { } /// Prints the span with a warn above it. - pub fn span_warn>(&mut self, - sp: S, - msg: &str) - -> &mut Self { + pub fn span_warn>(&mut self, sp: S, msg: &str) -> &mut Self { self.sub(Level::Warning, msg, sp.into(), None); self } - pub fn help(&mut self , msg: &str) -> &mut Self { + pub fn help(&mut self, msg: &str) -> &mut Self { self.sub(Level::Help, msg, MultiSpan::new(), None); self } /// Prints the span with some help above it. - pub fn span_help>(&mut self, - sp: S, - msg: &str) - -> &mut Self { + pub fn span_help>(&mut self, sp: S, msg: &str) -> &mut Self { self.sub(Level::Help, msg, sp.into(), None); self } @@ -381,10 +356,7 @@ impl Diagnostic { ) -> &mut Self { self.suggestions.push(CodeSuggestion { substitutions: vec![Substitution { - parts: vec![SubstitutionPart { - snippet: suggestion, - span: sp, - }], + parts: vec![SubstitutionPart { snippet: suggestion, span: sp }], }], msg: msg.to_owned(), style, @@ -419,12 +391,9 @@ impl Diagnostic { applicability: Applicability, ) -> &mut Self { self.suggestions.push(CodeSuggestion { - substitutions: suggestions.map(|snippet| Substitution { - parts: vec![SubstitutionPart { - snippet, - span: sp, - }], - }).collect(), + substitutions: suggestions + .map(|snippet| Substitution { parts: vec![SubstitutionPart { snippet, span: sp }] }) + .collect(), msg: msg.to_owned(), style: SuggestionStyle::ShowCode, applicability, @@ -437,7 +406,11 @@ impl Diagnostic { /// /// See `CodeSuggestion` for more information. pub fn span_suggestion_short( - &mut self, sp: Span, msg: &str, suggestion: String, applicability: Applicability + &mut self, + sp: Span, + msg: &str, + suggestion: String, + applicability: Applicability, ) -> &mut Self { self.span_suggestion_with_style( sp, @@ -456,7 +429,11 @@ impl Diagnostic { /// (marginally overlapping spans or multiline spans) and showing the snippet window wouldn't /// improve understandability. pub fn span_suggestion_hidden( - &mut self, sp: Span, msg: &str, suggestion: String, applicability: Applicability + &mut self, + sp: Span, + msg: &str, + suggestion: String, + applicability: Applicability, ) -> &mut Self { self.span_suggestion_with_style( sp, @@ -473,7 +450,11 @@ impl Diagnostic { /// This is intended to be used for suggestions that are *very* obvious in what the changes /// need to be from the message, but we still want other tools to be able to apply them. pub fn tool_only_span_suggestion( - &mut self, sp: Span, msg: &str, suggestion: String, applicability: Applicability + &mut self, + sp: Span, + msg: &str, + suggestion: String, + applicability: Applicability, ) -> &mut Self { self.span_suggestion_with_style( sp, @@ -530,11 +511,13 @@ impl Diagnostic { /// Convenience function for internal use, clients should use one of the /// public methods above. - pub fn sub(&mut self, - level: Level, - message: &str, - span: MultiSpan, - render_span: Option) { + pub fn sub( + &mut self, + level: Level, + message: &str, + span: MultiSpan, + render_span: Option, + ) { let sub = SubDiagnostic { level, message: vec![(message.to_owned(), Style::NoStyle)], @@ -546,17 +529,14 @@ impl Diagnostic { /// Convenience function for internal use, clients should use one of the /// public methods above. - fn sub_with_highlights(&mut self, - level: Level, - message: Vec<(String, Style)>, - span: MultiSpan, - render_span: Option) { - let sub = SubDiagnostic { - level, - message, - span, - render_span, - }; + fn sub_with_highlights( + &mut self, + level: Level, + message: Vec<(String, Style)>, + span: MultiSpan, + render_span: Option, + ) { + let sub = SubDiagnostic { level, message, span, render_span }; self.children.push(sub); } } diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index a95c29f8c2729..ef3a4a9a7080d 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -1,11 +1,11 @@ +use crate::{Applicability, Handler, Level, StashKey}; use crate::{Diagnostic, DiagnosticId, DiagnosticStyledString}; -use crate::{Applicability, Level, Handler, StashKey}; +use log::debug; use std::fmt::{self, Debug}; use std::ops::{Deref, DerefMut}; use std::thread::panicking; use syntax_pos::{MultiSpan, Span}; -use log::debug; /// Used for emitting structured error messages and other diagnostic information. /// @@ -106,11 +106,7 @@ impl<'a> DiagnosticBuilder<'a> { /// /// See `emit` and `delay_as_bug` for details. pub fn emit_unless(&mut self, delay: bool) { - if delay { - self.delay_as_bug() - } else { - self.emit() - } + if delay { self.delay_as_bug() } else { self.emit() } } /// Stashes diagnostic for possible later improvement in a different, @@ -127,8 +123,8 @@ impl<'a> DiagnosticBuilder<'a> { /// Converts the builder to a `Diagnostic` for later emission, /// unless handler has disabled such buffering. pub fn into_diagnostic(mut self) -> Option<(Diagnostic, &'a Handler)> { - if self.0.handler.flags.dont_buffer_diagnostics || - self.0.handler.flags.treat_err_as_bug.is_some() + if self.0.handler.flags.dont_buffer_diagnostics + || self.0.handler.flags.treat_err_as_bug.is_some() { self.emit(); return None; @@ -241,13 +237,9 @@ impl<'a> DiagnosticBuilder<'a> { applicability: Applicability, ) -> &mut Self { if !self.0.allow_suggestions { - return self + return self; } - self.0.diagnostic.multipart_suggestion( - msg, - suggestion, - applicability, - ); + self.0.diagnostic.multipart_suggestion(msg, suggestion, applicability); self } @@ -258,13 +250,9 @@ impl<'a> DiagnosticBuilder<'a> { applicability: Applicability, ) -> &mut Self { if !self.0.allow_suggestions { - return self + return self; } - self.0.diagnostic.tool_only_multipart_suggestion( - msg, - suggestion, - applicability, - ); + self.0.diagnostic.tool_only_multipart_suggestion(msg, suggestion, applicability); self } @@ -276,14 +264,9 @@ impl<'a> DiagnosticBuilder<'a> { applicability: Applicability, ) -> &mut Self { if !self.0.allow_suggestions { - return self + return self; } - self.0.diagnostic.span_suggestion( - sp, - msg, - suggestion, - applicability, - ); + self.0.diagnostic.span_suggestion(sp, msg, suggestion, applicability); self } @@ -295,14 +278,9 @@ impl<'a> DiagnosticBuilder<'a> { applicability: Applicability, ) -> &mut Self { if !self.0.allow_suggestions { - return self + return self; } - self.0.diagnostic.span_suggestions( - sp, - msg, - suggestions, - applicability, - ); + self.0.diagnostic.span_suggestions(sp, msg, suggestions, applicability); self } @@ -314,14 +292,9 @@ impl<'a> DiagnosticBuilder<'a> { applicability: Applicability, ) -> &mut Self { if !self.0.allow_suggestions { - return self + return self; } - self.0.diagnostic.span_suggestion_short( - sp, - msg, - suggestion, - applicability, - ); + self.0.diagnostic.span_suggestion_short(sp, msg, suggestion, applicability); self } @@ -333,14 +306,9 @@ impl<'a> DiagnosticBuilder<'a> { applicability: Applicability, ) -> &mut Self { if !self.0.allow_suggestions { - return self + return self; } - self.0.diagnostic.span_suggestion_hidden( - sp, - msg, - suggestion, - applicability, - ); + self.0.diagnostic.span_suggestion_hidden(sp, msg, suggestion, applicability); self } @@ -352,14 +320,9 @@ impl<'a> DiagnosticBuilder<'a> { applicability: Applicability, ) -> &mut Self { if !self.0.allow_suggestions { - return self + return self; } - self.0.diagnostic.tool_only_span_suggestion( - sp, - msg, - suggestion, - applicability, - ); + self.0.diagnostic.tool_only_span_suggestion(sp, msg, suggestion, applicability); self } @@ -379,19 +342,19 @@ impl<'a> DiagnosticBuilder<'a> { /// Convenience function for internal use, clients should use one of the /// struct_* methods on Handler. - crate fn new_with_code(handler: &'a Handler, - level: Level, - code: Option, - message: &str) - -> DiagnosticBuilder<'a> { + crate fn new_with_code( + handler: &'a Handler, + level: Level, + code: Option, + message: &str, + ) -> DiagnosticBuilder<'a> { let diagnostic = Diagnostic::new_with_code(level, code, message); DiagnosticBuilder::new_diagnostic(handler, diagnostic) } /// Creates a new `DiagnosticBuilder` with an already constructed /// diagnostic. - crate fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) - -> DiagnosticBuilder<'a> { + crate fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> DiagnosticBuilder<'a> { DiagnosticBuilder(Box::new(DiagnosticBuilderInner { handler, diagnostic, diff --git a/src/librustc_errors/json.rs b/src/librustc_errors/json.rs index ebbd49bd84a73..5f529c08c7836 100644 --- a/src/librustc_errors/json.rs +++ b/src/librustc_errors/json.rs @@ -9,19 +9,19 @@ // FIXME: spec the JSON output properly. -use syntax_pos::source_map::{SourceMap, FilePathMapping}; +use syntax_pos::source_map::{FilePathMapping, SourceMap}; -use crate::registry::Registry; -use crate::{SubDiagnostic, CodeSuggestion}; -use crate::{DiagnosticId, Applicability}; use crate::emitter::{Emitter, HumanReadableErrorType}; +use crate::registry::Registry; +use crate::{Applicability, DiagnosticId}; +use crate::{CodeSuggestion, SubDiagnostic}; -use syntax_pos::{MacroBacktrace, Span, SpanLabel, MultiSpan}; use rustc_data_structures::sync::Lrc; use std::io::{self, Write}; use std::path::Path; -use std::vec; use std::sync::{Arc, Mutex}; +use std::vec; +use syntax_pos::{MacroBacktrace, MultiSpan, Span, SpanLabel}; use rustc_serialize::json::{as_json, as_pretty_json}; @@ -63,8 +63,13 @@ impl JsonEmitter { external_macro_backtrace: bool, ) -> JsonEmitter { let file_path_mapping = FilePathMapping::empty(); - JsonEmitter::stderr(None, Lrc::new(SourceMap::new(file_path_mapping)), - pretty, json_rendered, external_macro_backtrace) + JsonEmitter::stderr( + None, + Lrc::new(SourceMap::new(file_path_mapping)), + pretty, + json_rendered, + external_macro_backtrace, + ) } pub fn new( @@ -212,18 +217,14 @@ struct ArtifactNotification<'a> { } impl Diagnostic { - fn from_errors_diagnostic(diag: &crate::Diagnostic, - je: &JsonEmitter) - -> Diagnostic { - let sugg = diag.suggestions.iter().map(|sugg| { - Diagnostic { - message: sugg.msg.clone(), - code: None, - level: "help", - spans: DiagnosticSpan::from_suggestion(sugg, je), - children: vec![], - rendered: None, - } + fn from_errors_diagnostic(diag: &crate::Diagnostic, je: &JsonEmitter) -> Diagnostic { + let sugg = diag.suggestions.iter().map(|sugg| Diagnostic { + message: sugg.msg.clone(), + code: None, + level: "help", + spans: DiagnosticSpan::from_suggestion(sugg, je), + children: vec![], + rendered: None, }); // generate regular command line output and store it in the json @@ -242,9 +243,16 @@ impl Diagnostic { } let buf = BufWriter::default(); let output = buf.clone(); - je.json_rendered.new_emitter( - Box::new(buf), Some(je.sm.clone()), false, None, je.external_macro_backtrace - ).ui_testing(je.ui_testing).emit_diagnostic(diag); + je.json_rendered + .new_emitter( + Box::new(buf), + Some(je.sm.clone()), + false, + None, + je.external_macro_backtrace, + ) + .ui_testing(je.ui_testing) + .emit_diagnostic(diag); let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap(); let output = String::from_utf8(output).unwrap(); @@ -253,9 +261,12 @@ impl Diagnostic { code: DiagnosticCode::map_opt_string(diag.code.clone(), je), level: diag.level.to_str(), spans: DiagnosticSpan::from_multispan(&diag.span, je), - children: diag.children.iter().map(|c| { - Diagnostic::from_sub_diagnostic(c, je) - }).chain(sugg).collect(), + children: diag + .children + .iter() + .map(|c| Diagnostic::from_sub_diagnostic(c, je)) + .chain(sugg) + .collect(), rendered: Some(output), } } @@ -265,9 +276,11 @@ impl Diagnostic { message: diag.message(), code: None, level: diag.level.to_str(), - spans: diag.render_span.as_ref() - .map(|sp| DiagnosticSpan::from_multispan(sp, je)) - .unwrap_or_else(|| DiagnosticSpan::from_multispan(&diag.span, je)), + spans: diag + .render_span + .as_ref() + .map(|sp| DiagnosticSpan::from_multispan(sp, je)) + .unwrap_or_else(|| DiagnosticSpan::from_multispan(&diag.span, je)), children: vec![], rendered: None, } @@ -275,61 +288,44 @@ impl Diagnostic { } impl DiagnosticSpan { - fn from_span_label(span: SpanLabel, - suggestion: Option<(&String, Applicability)>, - je: &JsonEmitter) - -> DiagnosticSpan { - Self::from_span_etc(span.span, - span.is_primary, - span.label, - suggestion, - je) + fn from_span_label( + span: SpanLabel, + suggestion: Option<(&String, Applicability)>, + je: &JsonEmitter, + ) -> DiagnosticSpan { + Self::from_span_etc(span.span, span.is_primary, span.label, suggestion, je) } - fn from_span_etc(span: Span, - is_primary: bool, - label: Option, - suggestion: Option<(&String, Applicability)>, - je: &JsonEmitter) - -> DiagnosticSpan { + fn from_span_etc( + span: Span, + is_primary: bool, + label: Option, + suggestion: Option<(&String, Applicability)>, + je: &JsonEmitter, + ) -> DiagnosticSpan { // obtain the full backtrace from the `macro_backtrace` // helper; in some ways, it'd be better to expand the // backtrace ourselves, but the `macro_backtrace` helper makes // some decision, such as dropping some frames, and I don't // want to duplicate that logic here. let backtrace = span.macro_backtrace().into_iter(); - DiagnosticSpan::from_span_full(span, - is_primary, - label, - suggestion, - backtrace, - je) + DiagnosticSpan::from_span_full(span, is_primary, label, suggestion, backtrace, je) } - fn from_span_full(span: Span, - is_primary: bool, - label: Option, - suggestion: Option<(&String, Applicability)>, - mut backtrace: vec::IntoIter, - je: &JsonEmitter) - -> DiagnosticSpan { + fn from_span_full( + span: Span, + is_primary: bool, + label: Option, + suggestion: Option<(&String, Applicability)>, + mut backtrace: vec::IntoIter, + je: &JsonEmitter, + ) -> DiagnosticSpan { let start = je.sm.lookup_char_pos(span.lo()); let end = je.sm.lookup_char_pos(span.hi()); let backtrace_step = backtrace.next().map(|bt| { - let call_site = - Self::from_span_full(bt.call_site, - false, - None, - None, - backtrace, - je); + let call_site = Self::from_span_full(bt.call_site, false, None, None, backtrace, je); let def_site_span = - Self::from_span_full(bt.def_site_span, - false, - None, - None, - vec![].into_iter(), - je); + Self::from_span_full(bt.def_site_span, false, None, None, vec![].into_iter(), je); Box::new(DiagnosticSpanMacroExpansion { span: call_site, macro_decl_name: bt.macro_decl_name, @@ -356,38 +352,37 @@ impl DiagnosticSpan { fn from_multispan(msp: &MultiSpan, je: &JsonEmitter) -> Vec { msp.span_labels() - .into_iter() - .map(|span_str| Self::from_span_label(span_str, None, je)) - .collect() + .into_iter() + .map(|span_str| Self::from_span_label(span_str, None, je)) + .collect() } - fn from_suggestion(suggestion: &CodeSuggestion, je: &JsonEmitter) - -> Vec { - suggestion.substitutions - .iter() - .flat_map(|substitution| { - substitution.parts.iter().map(move |suggestion_inner| { - let span_label = SpanLabel { - span: suggestion_inner.span, - is_primary: true, - label: None, - }; - DiagnosticSpan::from_span_label(span_label, - Some((&suggestion_inner.snippet, - suggestion.applicability)), - je) - }) - }) - .collect() + fn from_suggestion(suggestion: &CodeSuggestion, je: &JsonEmitter) -> Vec { + suggestion + .substitutions + .iter() + .flat_map(|substitution| { + substitution.parts.iter().map(move |suggestion_inner| { + let span_label = + SpanLabel { span: suggestion_inner.span, is_primary: true, label: None }; + DiagnosticSpan::from_span_label( + span_label, + Some((&suggestion_inner.snippet, suggestion.applicability)), + je, + ) + }) + }) + .collect() } } impl DiagnosticSpanLine { - fn line_from_source_file(fm: &syntax_pos::SourceFile, - index: usize, - h_start: usize, - h_end: usize) - -> DiagnosticSpanLine { + fn line_from_source_file( + fm: &syntax_pos::SourceFile, + index: usize, + h_start: usize, + h_end: usize, + ) -> DiagnosticSpanLine { DiagnosticSpanLine { text: fm.get_line(index).map_or(String::new(), |l| l.into_owned()), highlight_start: h_start, @@ -399,18 +394,24 @@ impl DiagnosticSpanLine { /// of `span` gets a DiagnosticSpanLine, with the highlight indicating the /// `span` within the line. fn from_span(span: Span, je: &JsonEmitter) -> Vec { - je.sm.span_to_lines(span) + je.sm + .span_to_lines(span) .map(|lines| { let fm = &*lines.file; - lines.lines + lines + .lines .iter() - .map(|line| DiagnosticSpanLine::line_from_source_file( - fm, - line.line_index, - line.start_col.0 + 1, - line.end_col.0 + 1, - )).collect() - }).unwrap_or_else(|_| vec![]) + .map(|line| { + DiagnosticSpanLine::line_from_source_file( + fm, + line.line_index, + line.start_col.0 + 1, + line.end_col.0 + 1, + ) + }) + .collect() + }) + .unwrap_or_else(|_| vec![]) } } @@ -421,14 +422,10 @@ impl DiagnosticCode { DiagnosticId::Error(s) => s, DiagnosticId::Lint(s) => s, }; - let explanation = je.registry - .as_ref() - .and_then(|registry| registry.find_description(&s)); + let explanation = + je.registry.as_ref().and_then(|registry| registry.find_description(&s)); - DiagnosticCode { - code: s, - explanation, - } + DiagnosticCode { code: s, explanation } }) } } diff --git a/src/librustc_errors/json/tests.rs b/src/librustc_errors/json/tests.rs index 4ab5cd21b0b00..a96bf715858f3 100644 --- a/src/librustc_errors/json/tests.rs +++ b/src/librustc_errors/json/tests.rs @@ -41,9 +41,7 @@ impl Write for Shared { fn with_default_globals(f: impl FnOnce()) { let globals = syntax_pos::Globals::new(syntax_pos::edition::DEFAULT_EDITION); - syntax_pos::GLOBALS.set(&globals, || { - syntax_pos::GLOBALS.set(&globals, f) - }) + syntax_pos::GLOBALS.set(&globals, || syntax_pos::GLOBALS.set(&globals, f)) } /// Test the span yields correct positions in JSON. diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index ae5876848185b..8f1437ee49cc3 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -3,7 +3,6 @@ //! This module contains the code for creating and emitting diagnostics. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] - #![feature(crate_visibility_modifier)] #![cfg_attr(unix, feature(libc))] #![feature(nll)] @@ -13,31 +12,31 @@ pub use emitter::ColorConfig; use Level::*; -use emitter::{Emitter, EmitterWriter, is_case_difference}; +use emitter::{is_case_difference, Emitter, EmitterWriter}; use registry::Registry; -use rustc_data_structures::sync::{self, Lrc, Lock}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::stable_hasher::StableHasher; +use rustc_data_structures::sync::{self, Lock, Lrc}; use syntax_pos::source_map::SourceMap; -use syntax_pos::{Loc, Span, MultiSpan}; +use syntax_pos::{Loc, MultiSpan, Span}; use std::borrow::Cow; use std::cell::Cell; -use std::{error, fmt}; use std::panic; use std::path::Path; +use std::{error, fmt}; -use termcolor::{ColorSpec, Color}; +use termcolor::{Color, ColorSpec}; +pub mod annotate_snippet_emitter_writer; mod diagnostic; mod diagnostic_builder; pub mod emitter; -pub mod annotate_snippet_emitter_writer; -mod snippet; +pub mod json; +mod lock; pub mod registry; +mod snippet; mod styled_buffer; -mod lock; -pub mod json; pub use snippet::Style; pub type PResult<'a, T> = Result>; @@ -146,16 +145,15 @@ pub struct SubstitutionPart { impl CodeSuggestion { /// Returns the assembled code suggestions, whether they should be shown with an underline /// and whether the substitution only differs in capitalization. - pub fn splice_lines( - &self, - cm: &SourceMap, - ) -> Vec<(String, Vec, bool)> { + pub fn splice_lines(&self, cm: &SourceMap) -> Vec<(String, Vec, bool)> { use syntax_pos::{CharPos, Pos}; - fn push_trailing(buf: &mut String, - line_opt: Option<&Cow<'_, str>>, - lo: &Loc, - hi_opt: Option<&Loc>) { + fn push_trailing( + buf: &mut String, + line_opt: Option<&Cow<'_, str>>, + lo: &Loc, + hi_opt: Option<&Loc>, + ) { let (lo, hi_opt) = (lo.col.to_usize(), hi_opt.map(|hi| hi.col.to_usize())); if let Some(line) = line_opt { if let Some(lo) = line.char_indices().map(|(i, _)| i).nth(lo) { @@ -174,67 +172,71 @@ impl CodeSuggestion { assert!(!self.substitutions.is_empty()); - self.substitutions.iter().cloned().map(|mut substitution| { - // Assumption: all spans are in the same file, and all spans - // are disjoint. Sort in ascending order. - substitution.parts.sort_by_key(|part| part.span.lo()); - - // Find the bounding span. - let lo = substitution.parts.iter().map(|part| part.span.lo()).min().unwrap(); - let hi = substitution.parts.iter().map(|part| part.span.hi()).min().unwrap(); - let bounding_span = Span::with_root_ctxt(lo, hi); - let lines = cm.span_to_lines(bounding_span).unwrap(); - assert!(!lines.lines.is_empty()); - - // To build up the result, we do this for each span: - // - push the line segment trailing the previous span - // (at the beginning a "phantom" span pointing at the start of the line) - // - push lines between the previous and current span (if any) - // - if the previous and current span are not on the same line - // push the line segment leading up to the current span - // - splice in the span substitution - // - // Finally push the trailing line segment of the last span - let fm = &lines.file; - let mut prev_hi = cm.lookup_char_pos(bounding_span.lo()); - prev_hi.col = CharPos::from_usize(0); - - let mut prev_line = fm.get_line(lines.lines[0].line_index); - let mut buf = String::new(); - - for part in &substitution.parts { - let cur_lo = cm.lookup_char_pos(part.span.lo()); - if prev_hi.line == cur_lo.line { - push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, Some(&cur_lo)); - } else { - push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None); - // push lines between the previous and current span (if any) - for idx in prev_hi.line..(cur_lo.line - 1) { - if let Some(line) = fm.get_line(idx) { - buf.push_str(line.as_ref()); - buf.push('\n'); + self.substitutions + .iter() + .cloned() + .map(|mut substitution| { + // Assumption: all spans are in the same file, and all spans + // are disjoint. Sort in ascending order. + substitution.parts.sort_by_key(|part| part.span.lo()); + + // Find the bounding span. + let lo = substitution.parts.iter().map(|part| part.span.lo()).min().unwrap(); + let hi = substitution.parts.iter().map(|part| part.span.hi()).min().unwrap(); + let bounding_span = Span::with_root_ctxt(lo, hi); + let lines = cm.span_to_lines(bounding_span).unwrap(); + assert!(!lines.lines.is_empty()); + + // To build up the result, we do this for each span: + // - push the line segment trailing the previous span + // (at the beginning a "phantom" span pointing at the start of the line) + // - push lines between the previous and current span (if any) + // - if the previous and current span are not on the same line + // push the line segment leading up to the current span + // - splice in the span substitution + // + // Finally push the trailing line segment of the last span + let fm = &lines.file; + let mut prev_hi = cm.lookup_char_pos(bounding_span.lo()); + prev_hi.col = CharPos::from_usize(0); + + let mut prev_line = fm.get_line(lines.lines[0].line_index); + let mut buf = String::new(); + + for part in &substitution.parts { + let cur_lo = cm.lookup_char_pos(part.span.lo()); + if prev_hi.line == cur_lo.line { + push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, Some(&cur_lo)); + } else { + push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None); + // push lines between the previous and current span (if any) + for idx in prev_hi.line..(cur_lo.line - 1) { + if let Some(line) = fm.get_line(idx) { + buf.push_str(line.as_ref()); + buf.push('\n'); + } + } + if let Some(cur_line) = fm.get_line(cur_lo.line - 1) { + let end = std::cmp::min(cur_line.len(), cur_lo.col.to_usize()); + buf.push_str(&cur_line[..end]); } } - if let Some(cur_line) = fm.get_line(cur_lo.line - 1) { - let end = std::cmp::min(cur_line.len(), cur_lo.col.to_usize()); - buf.push_str(&cur_line[..end]); - } + buf.push_str(&part.snippet); + prev_hi = cm.lookup_char_pos(part.span.hi()); + prev_line = fm.get_line(prev_hi.line - 1); } - buf.push_str(&part.snippet); - prev_hi = cm.lookup_char_pos(part.span.hi()); - prev_line = fm.get_line(prev_hi.line - 1); - } - let only_capitalization = is_case_difference(cm, &buf, bounding_span); - // if the replacement already ends with a newline, don't print the next line - if !buf.ends_with('\n') { - push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None); - } - // remove trailing newlines - while buf.ends_with('\n') { - buf.pop(); - } - (buf, substitution.parts, only_capitalization) - }).collect() + let only_capitalization = is_case_difference(cm, &buf, bounding_span); + // if the replacement already ends with a newline, don't print the next line + if !buf.ends_with('\n') { + push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None); + } + // remove trailing newlines + while buf.ends_with('\n') { + buf.pop(); + } + (buf, substitution.parts, only_capitalization) + }) + .collect() } } @@ -257,7 +259,7 @@ impl error::Error for ExplicitBug { } } -pub use diagnostic::{Diagnostic, SubDiagnostic, DiagnosticStyledString, DiagnosticId}; +pub use diagnostic::{Diagnostic, DiagnosticId, DiagnosticStyledString, SubDiagnostic}; pub use diagnostic_builder::DiagnosticBuilder; /// A handler deals with errors and other compiler output. @@ -360,11 +362,7 @@ impl Handler { Self::with_tty_emitter_and_flags( color_config, cm, - HandlerFlags { - can_emit_warnings, - treat_err_as_bug, - .. Default::default() - }, + HandlerFlags { can_emit_warnings, treat_err_as_bug, ..Default::default() }, ) } @@ -391,17 +389,13 @@ impl Handler { ) -> Self { Handler::with_emitter_and_flags( emitter, - HandlerFlags { - can_emit_warnings, - treat_err_as_bug, - .. Default::default() - }, + HandlerFlags { can_emit_warnings, treat_err_as_bug, ..Default::default() }, ) } pub fn with_emitter_and_flags( emitter: Box, - flags: HandlerFlags + flags: HandlerFlags, ) -> Self { Self { flags, @@ -457,7 +451,10 @@ impl Handler { old_diag.level = Bug; old_diag.note(&format!( "{}:{}: already existing stashed diagnostic with (span = {:?}, key = {:?})", - file!(), line!(), span, key + file!(), + line!(), + span, + key )); inner.emit_diag_at_span(old_diag, span); panic!(ExplicitBug); @@ -779,7 +776,7 @@ impl HandlerInner { let s = match self.deduplicated_err_count { 0 => return, 1 => "aborting due to previous error".to_string(), - count => format!("aborting due to {} previous errors", count) + count => format!("aborting due to {} previous errors", count), }; if self.treat_err_as_bug() { return; @@ -804,16 +801,22 @@ impl HandlerInner { error_codes.sort(); if error_codes.len() > 1 { let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() }; - self.failure(&format!("Some errors have detailed explanations: {}{}", - error_codes[..limit].join(", "), - if error_codes.len() > 9 { "..." } else { "." })); - self.failure(&format!("For more information about an error, try \ + self.failure(&format!( + "Some errors have detailed explanations: {}{}", + error_codes[..limit].join(", "), + if error_codes.len() > 9 { "..." } else { "." } + )); + self.failure(&format!( + "For more information about an error, try \ `rustc --explain {}`.", - &error_codes[0])); + &error_codes[0] + )); } else { - self.failure(&format!("For more information about this error, try \ + self.failure(&format!( + "For more information about this error, try \ `rustc --explain {}`.", - &error_codes[0])); + &error_codes[0] + )); } } } @@ -880,7 +883,7 @@ impl HandlerInner { } /// Emit an error; level should be `Error` or `Fatal`. - fn emit_error(&mut self, level: Level, msg: &str,) { + fn emit_error(&mut self, level: Level, msg: &str) { if self.treat_err_as_bug() { self.bug(msg); } @@ -910,13 +913,10 @@ impl HandlerInner { (0, _) => return, (1, 1) => "aborting due to `-Z treat-err-as-bug=1`".to_string(), (1, _) => return, - (count, as_bug) => { - format!( - "aborting after {} errors due to `-Z treat-err-as-bug={}`", - count, - as_bug, - ) - } + (count, as_bug) => format!( + "aborting after {} errors due to `-Z treat-err-as-bug={}`", + count, as_bug, + ), }; panic!(s); } @@ -946,20 +946,16 @@ impl Level { let mut spec = ColorSpec::new(); match self { Bug | Fatal | Error => { - spec.set_fg(Some(Color::Red)) - .set_intense(true); + spec.set_fg(Some(Color::Red)).set_intense(true); } Warning => { - spec.set_fg(Some(Color::Yellow)) - .set_intense(cfg!(windows)); + spec.set_fg(Some(Color::Yellow)).set_intense(cfg!(windows)); } Note => { - spec.set_fg(Some(Color::Green)) - .set_intense(true); + spec.set_fg(Some(Color::Green)).set_intense(true); } Help => { - spec.set_fg(Some(Color::Cyan)) - .set_intense(true); + spec.set_fg(Some(Color::Cyan)).set_intense(true); } FailureNote => {} Cancelled => unreachable!(), diff --git a/src/librustc_errors/lock.rs b/src/librustc_errors/lock.rs index 25a27d2cbd884..198a9c12406e5 100644 --- a/src/librustc_errors/lock.rs +++ b/src/librustc_errors/lock.rs @@ -28,10 +28,11 @@ pub fn acquire_global_lock(name: &str) -> Box { const WAIT_ABANDONED: DWORD = 0x00000080; extern "system" { - fn CreateMutexA(lpMutexAttributes: LPSECURITY_ATTRIBUTES, - bInitialOwner: BOOL, - lpName: LPCSTR) - -> HANDLE; + fn CreateMutexA( + lpMutexAttributes: LPSECURITY_ATTRIBUTES, + bInitialOwner: BOOL, + lpName: LPCSTR, + ) -> HANDLE; fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD; fn ReleaseMutex(hMutex: HANDLE) -> BOOL; fn CloseHandle(hObject: HANDLE) -> BOOL; @@ -66,9 +67,11 @@ pub fn acquire_global_lock(name: &str) -> Box { // open up a handle to one if it already exists. let mutex = CreateMutexA(std::ptr::null_mut(), 0, cname.as_ptr() as *const u8); if mutex.is_null() { - panic!("failed to create global mutex named `{}`: {}", - name, - io::Error::last_os_error()); + panic!( + "failed to create global mutex named `{}`: {}", + name, + io::Error::last_os_error() + ); } let mutex = Handle(mutex); @@ -86,11 +89,13 @@ pub fn acquire_global_lock(name: &str) -> Box { match WaitForSingleObject(mutex.0, INFINITE) { WAIT_OBJECT_0 | WAIT_ABANDONED => {} code => { - panic!("WaitForSingleObject failed on global mutex named \ + panic!( + "WaitForSingleObject failed on global mutex named \ `{}`: {} (ret={:x})", - name, - io::Error::last_os_error(), - code); + name, + io::Error::last_os_error(), + code + ); } } diff --git a/src/librustc_errors/snippet.rs b/src/librustc_errors/snippet.rs index 47ba22d3d25af..a39e19f0bf75b 100644 --- a/src/librustc_errors/snippet.rs +++ b/src/librustc_errors/snippet.rs @@ -8,7 +8,6 @@ pub struct Line { pub annotations: Vec, } - #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct MultilineAnnotation { pub depth: usize, @@ -28,8 +27,10 @@ impl MultilineAnnotation { /// Compare two `MultilineAnnotation`s considering only the `Span` they cover. pub fn same_span(&self, other: &MultilineAnnotation) -> bool { - self.line_start == other.line_start && self.line_end == other.line_end - && self.start_col == other.start_col && self.end_col == other.end_col + self.line_start == other.line_start + && self.line_end == other.line_end + && self.start_col == other.start_col + && self.end_col == other.end_col } pub fn as_start(&self) -> Annotation { @@ -38,7 +39,7 @@ impl MultilineAnnotation { end_col: self.start_col + 1, is_primary: self.is_primary, label: None, - annotation_type: AnnotationType::MultilineStart(self.depth) + annotation_type: AnnotationType::MultilineStart(self.depth), } } @@ -48,7 +49,7 @@ impl MultilineAnnotation { end_col: self.end_col, is_primary: self.is_primary, label: self.label.clone(), - annotation_type: AnnotationType::MultilineEnd(self.depth) + annotation_type: AnnotationType::MultilineEnd(self.depth), } } @@ -58,7 +59,7 @@ impl MultilineAnnotation { end_col: 0, is_primary: self.is_primary, label: None, - annotation_type: AnnotationType::MultilineLine(self.depth) + annotation_type: AnnotationType::MultilineLine(self.depth), } } } @@ -117,19 +118,15 @@ pub struct Annotation { impl Annotation { /// Whether this annotation is a vertical line placeholder. pub fn is_line(&self) -> bool { - if let AnnotationType::MultilineLine(_) = self.annotation_type { - true - } else { - false - } + if let AnnotationType::MultilineLine(_) = self.annotation_type { true } else { false } } pub fn is_multiline(&self) -> bool { match self.annotation_type { - AnnotationType::Multiline(_) | - AnnotationType::MultilineStart(_) | - AnnotationType::MultilineLine(_) | - AnnotationType::MultilineEnd(_) => true, + AnnotationType::Multiline(_) + | AnnotationType::MultilineStart(_) + | AnnotationType::MultilineLine(_) + | AnnotationType::MultilineEnd(_) => true, _ => false, } } @@ -164,8 +161,7 @@ impl Annotation { pub fn takes_space(&self) -> bool { // Multiline annotations always have to keep vertical space. match self.annotation_type { - AnnotationType::MultilineStart(_) | - AnnotationType::MultilineEnd(_) => true, + AnnotationType::MultilineStart(_) | AnnotationType::MultilineEnd(_) => true, _ => false, } } diff --git a/src/librustc_errors/styled_buffer.rs b/src/librustc_errors/styled_buffer.rs index b12ab9e457602..f2d255d7d9524 100644 --- a/src/librustc_errors/styled_buffer.rs +++ b/src/librustc_errors/styled_buffer.rs @@ -10,10 +10,7 @@ pub struct StyledBuffer { impl StyledBuffer { pub fn new() -> StyledBuffer { - StyledBuffer { - text: vec![], - styles: vec![], - } + StyledBuffer { text: vec![], styles: vec![] } } fn replace_tabs(&mut self) { @@ -51,10 +48,7 @@ impl StyledBuffer { for (&c, &s) in row.iter().zip(row_style) { if s != current_style { if !current_text.is_empty() { - styled_vec.push(StyledString { - text: current_text, - style: current_style, - }); + styled_vec.push(StyledString { text: current_text, style: current_style }); } current_style = s; current_text = String::new(); @@ -62,10 +56,7 @@ impl StyledBuffer { current_text.push(c); } if !current_text.is_empty() { - styled_vec.push(StyledString { - text: current_text, - style: current_style, - }); + styled_vec.push(StyledString { text: current_text, style: current_style }); } // We're done with the row, push and keep going @@ -135,12 +126,14 @@ impl StyledBuffer { self.text.len() } - pub fn set_style_range(&mut self, - line: usize, - col_start: usize, - col_end: usize, - style: Style, - overwrite: bool) { + pub fn set_style_range( + &mut self, + line: usize, + col_start: usize, + col_end: usize, + style: Style, + overwrite: bool, + ) { for col in col_start..col_end { self.set_style(line, col, style, overwrite); } diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs index 44b610e487bee..4b6244bb6e2c6 100644 --- a/src/librustc_incremental/assert_dep_graph.rs +++ b/src/librustc_incremental/assert_dep_graph.rs @@ -34,16 +34,14 @@ //! ``` use graphviz as dot; -use rustc::dep_graph::{DepGraphQuery, DepNode, DepKind}; use rustc::dep_graph::debug::{DepNodeFilter, EdgeFilter}; +use rustc::dep_graph::{DepGraphQuery, DepKind, DepNode}; +use rustc::hir; use rustc::hir::def_id::DefId; +use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc::ty::TyCtxt; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::graph::implementation::{ - Direction, INCOMING, OUTGOING, NodeIndex -}; -use rustc::hir; -use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; +use rustc_data_structures::graph::implementation::{Direction, NodeIndex, INCOMING, OUTGOING}; use std::env; use std::fs::{self, File}; use std::io::Write; @@ -65,19 +63,21 @@ pub fn assert_dep_graph(tcx: TyCtxt<'_>) { // Find annotations supplied by user (if any). let (if_this_changed, then_this_would_need) = { - let mut visitor = IfThisChanged { tcx, - if_this_changed: vec![], - then_this_would_need: vec![] }; + let mut visitor = + IfThisChanged { tcx, if_this_changed: vec![], then_this_would_need: vec![] }; visitor.process_attrs(hir::CRATE_HIR_ID, &tcx.hir().krate().attrs); tcx.hir().krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); (visitor.if_this_changed, visitor.then_this_would_need) }; if !if_this_changed.is_empty() || !then_this_would_need.is_empty() { - assert!(tcx.sess.opts.debugging_opts.query_dep_graph, - "cannot use the `#[{}]` or `#[{}]` annotations \ + assert!( + tcx.sess.opts.debugging_opts.query_dep_graph, + "cannot use the `#[{}]` or `#[{}]` annotations \ without supplying `-Z query-dep-graph`", - sym::rustc_if_this_changed, sym::rustc_then_this_would_need); + sym::rustc_if_this_changed, + sym::rustc_then_this_would_need + ); } // Check paths. @@ -99,11 +99,12 @@ impl IfThisChanged<'tcx> { let mut value = None; for list_item in attr.meta_item_list().unwrap_or_default() { match list_item.ident() { - Some(ident) if list_item.is_word() && value.is_none() => - value = Some(ident.name), + Some(ident) if list_item.is_word() && value.is_none() => value = Some(ident.name), _ => - // FIXME better-encapsulate meta_item (don't directly access `node`) - span_bug!(list_item.span(), "unexpected meta-item {:?}", list_item), + // FIXME better-encapsulate meta_item (don't directly access `node`) + { + span_bug!(list_item.span(), "unexpected meta-item {:?}", list_item) + } } } value @@ -117,41 +118,39 @@ impl IfThisChanged<'tcx> { let dep_node_interned = self.argument(attr); let dep_node = match dep_node_interned { None => def_path_hash.to_dep_node(DepKind::Hir), - Some(n) => { - match DepNode::from_label_string(&n.as_str(), def_path_hash) { - Ok(n) => n, - Err(()) => { - self.tcx.sess.span_fatal( - attr.span, - &format!("unrecognized DepNode variant {:?}", n)); - } + Some(n) => match DepNode::from_label_string(&n.as_str(), def_path_hash) { + Ok(n) => n, + Err(()) => { + self.tcx.sess.span_fatal( + attr.span, + &format!("unrecognized DepNode variant {:?}", n), + ); } - } + }, }; self.if_this_changed.push((attr.span, def_id, dep_node)); } else if attr.check_name(sym::rustc_then_this_would_need) { let dep_node_interned = self.argument(attr); let dep_node = match dep_node_interned { - Some(n) => { - match DepNode::from_label_string(&n.as_str(), def_path_hash) { - Ok(n) => n, - Err(()) => { - self.tcx.sess.span_fatal( - attr.span, - &format!("unrecognized DepNode variant {:?}", n)); - } + Some(n) => match DepNode::from_label_string(&n.as_str(), def_path_hash) { + Ok(n) => n, + Err(()) => { + self.tcx.sess.span_fatal( + attr.span, + &format!("unrecognized DepNode variant {:?}", n), + ); } - } + }, None => { - self.tcx.sess.span_fatal( - attr.span, - "missing DepNode variant"); + self.tcx.sess.span_fatal(attr.span, "missing DepNode variant"); } }; - self.then_this_would_need.push((attr.span, - dep_node_interned.unwrap(), - hir_id, - dep_node)); + self.then_this_would_need.push(( + attr.span, + dep_node_interned.unwrap(), + hir_id, + dep_node, + )); } } } @@ -187,10 +186,7 @@ fn check_paths<'tcx>(tcx: TyCtxt<'tcx>, if_this_changed: &Sources, then_this_wou // Return early here so as not to construct the query, which is not cheap. if if_this_changed.is_empty() { for &(target_span, _, _, _) in then_this_would_need { - tcx.sess.span_err( - target_span, - "no `#[rustc_if_this_changed]` annotation detected"); - + tcx.sess.span_err(target_span, "no `#[rustc_if_this_changed]` annotation detected"); } return; } @@ -201,13 +197,14 @@ fn check_paths<'tcx>(tcx: TyCtxt<'tcx>, if_this_changed: &Sources, then_this_wou if !dependents.contains(&target_dep_node) { tcx.sess.span_err( target_span, - &format!("no path from `{}` to `{}`", - tcx.def_path_str(source_def_id), - target_pass)); + &format!( + "no path from `{}` to `{}`", + tcx.def_path_str(source_def_id), + target_pass + ), + ); } else { - tcx.sess.span_err( - target_span, - "OK"); + tcx.sess.span_err(target_span, "OK"); } } } @@ -220,22 +217,18 @@ fn dump_graph(tcx: TyCtxt<'_>) { let nodes = match env::var("RUST_DEP_GRAPH_FILTER") { Ok(string) => { // Expect one of: "-> target", "source -> target", or "source ->". - let edge_filter = EdgeFilter::new(&string).unwrap_or_else(|e| { - bug!("invalid filter: {}", e) - }); + let edge_filter = + EdgeFilter::new(&string).unwrap_or_else(|e| bug!("invalid filter: {}", e)); let sources = node_set(&query, &edge_filter.source); let targets = node_set(&query, &edge_filter.target); filter_nodes(&query, &sources, &targets) } - Err(_) => { - query.nodes() - .into_iter() - .collect() - } + Err(_) => query.nodes().into_iter().collect(), }; let edges = filter_edges(&query, &nodes); - { // dump a .txt file with just the edges: + { + // dump a .txt file with just the edges: let txt_path = format!("{}.txt", path); let mut file = File::create(&txt_path).unwrap(); for &(ref source, ref target) in &edges { @@ -243,7 +236,8 @@ fn dump_graph(tcx: TyCtxt<'_>) { } } - { // dump a .dot file in graphviz format: + { + // dump a .dot file in graphviz format: let dot_path = format!("{}.dot", path); let mut v = Vec::new(); dot::render(&GraphvizDepGraph(nodes, edges), &mut v).unwrap(); @@ -251,8 +245,7 @@ fn dump_graph(tcx: TyCtxt<'_>) { } } -pub struct GraphvizDepGraph<'q>(FxHashSet<&'q DepNode>, - Vec<(&'q DepNode, &'q DepNode)>); +pub struct GraphvizDepGraph<'q>(FxHashSet<&'q DepNode>, Vec<(&'q DepNode, &'q DepNode)>); impl<'a, 'q> dot::GraphWalk<'a> for GraphvizDepGraph<'q> { type Node = &'q DepNode; @@ -279,10 +272,10 @@ impl<'a, 'q> dot::Labeller<'a> for GraphvizDepGraph<'q> { dot::Id::new("DependencyGraph").unwrap() } fn node_id(&self, n: &&'q DepNode) -> dot::Id<'_> { - let s: String = - format!("{:?}", n).chars() - .map(|c| if c == '_' || c.is_alphanumeric() { c } else { '_' }) - .collect(); + let s: String = format!("{:?}", n) + .chars() + .map(|c| if c == '_' || c.is_alphanumeric() { c } else { '_' }) + .collect(); debug!("n={:?} s={:?}", n, s); dot::Id::new(s).unwrap() } @@ -294,9 +287,10 @@ impl<'a, 'q> dot::Labeller<'a> for GraphvizDepGraph<'q> { // Given an optional filter like `"x,y,z"`, returns either `None` (no // filter) or the set of nodes whose labels contain all of those // substrings. -fn node_set<'q>(query: &'q DepGraphQuery, filter: &DepNodeFilter) - -> Option> -{ +fn node_set<'q>( + query: &'q DepGraphQuery, + filter: &DepNodeFilter, +) -> Option> { debug!("node_set(filter={:?})", filter); if filter.accepts_all() { @@ -306,11 +300,11 @@ fn node_set<'q>(query: &'q DepGraphQuery, filter: &DepNodeFilter) Some(query.nodes().into_iter().filter(|n| filter.test(n)).collect()) } -fn filter_nodes<'q>(query: &'q DepGraphQuery, - sources: &Option>, - targets: &Option>) - -> FxHashSet<&'q DepNode> -{ +fn filter_nodes<'q>( + query: &'q DepGraphQuery, + sources: &Option>, + targets: &Option>, +) -> FxHashSet<&'q DepNode> { if let &Some(ref sources) = sources { if let &Some(ref targets) = targets { walk_between(query, sources, targets) @@ -324,11 +318,11 @@ fn filter_nodes<'q>(query: &'q DepGraphQuery, } } -fn walk_nodes<'q>(query: &'q DepGraphQuery, - starts: &FxHashSet<&'q DepNode>, - direction: Direction) - -> FxHashSet<&'q DepNode> -{ +fn walk_nodes<'q>( + query: &'q DepGraphQuery, + starts: &FxHashSet<&'q DepNode>, + direction: Direction, +) -> FxHashSet<&'q DepNode> { let mut set = FxHashSet::default(); for &start in starts { debug!("walk_nodes: start={:?} outgoing?={:?}", start, direction == OUTGOING); @@ -348,18 +342,23 @@ fn walk_nodes<'q>(query: &'q DepGraphQuery, set } -fn walk_between<'q>(query: &'q DepGraphQuery, - sources: &FxHashSet<&'q DepNode>, - targets: &FxHashSet<&'q DepNode>) - -> FxHashSet<&'q DepNode> -{ +fn walk_between<'q>( + query: &'q DepGraphQuery, + sources: &FxHashSet<&'q DepNode>, + targets: &FxHashSet<&'q DepNode>, +) -> FxHashSet<&'q DepNode> { // This is a bit tricky. We want to include a node only if it is: // (a) reachable from a source and (b) will reach a target. And we // have to be careful about cycles etc. Luckily efficiency is not // a big concern! #[derive(Copy, Clone, PartialEq)] - enum State { Undecided, Deciding, Included, Excluded } + enum State { + Undecided, + Deciding, + Included, + Excluded, + } let mut node_states = vec![State::Undecided; query.graph.len_nodes()]; @@ -371,19 +370,16 @@ fn walk_between<'q>(query: &'q DepGraphQuery, recurse(query, &mut node_states, source); } - return query.nodes() - .into_iter() - .filter(|&n| { - let index = query.indices[n]; - node_states[index.0] == State::Included - }) - .collect(); - - fn recurse(query: &DepGraphQuery, - node_states: &mut [State], - node: NodeIndex) - -> bool - { + return query + .nodes() + .into_iter() + .filter(|&n| { + let index = query.indices[n]; + node_states[index.0] == State::Included + }) + .collect(); + + fn recurse(query: &DepGraphQuery, node_states: &mut [State], node: NodeIndex) -> bool { match node_states[node.0] { // known to reach a target State::Included => return true, @@ -394,7 +390,7 @@ fn walk_between<'q>(query: &'q DepGraphQuery, // backedge, not yet known, say false State::Deciding => return false, - State::Undecided => { } + State::Undecided => {} } node_states[node.0] = State::Deciding; @@ -416,12 +412,13 @@ fn walk_between<'q>(query: &'q DepGraphQuery, } } -fn filter_edges<'q>(query: &'q DepGraphQuery, - nodes: &FxHashSet<&'q DepNode>) - -> Vec<(&'q DepNode, &'q DepNode)> -{ - query.edges() - .into_iter() - .filter(|&(source, target)| nodes.contains(source) && nodes.contains(target)) - .collect() +fn filter_edges<'q>( + query: &'q DepGraphQuery, + nodes: &FxHashSet<&'q DepNode>, +) -> Vec<(&'q DepNode, &'q DepNode)> { + query + .edges() + .into_iter() + .filter(|&(source, target)| nodes.contains(source) && nodes.contains(target)) + .collect() } diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index 8b692d84b11f3..c08deb6dfd5b5 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -22,12 +22,12 @@ //! was re-used. use rustc::hir::def_id::LOCAL_CRATE; -use rustc_session::cgu_reuse_tracker::*; use rustc::mir::mono::CodegenUnitNameBuilder; use rustc::ty::TyCtxt; +use rustc_session::cgu_reuse_tracker::*; use std::collections::BTreeSet; use syntax::ast; -use syntax::symbol::{Symbol, sym}; +use syntax::symbol::{sym, Symbol}; pub fn assert_module_sources(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { @@ -42,10 +42,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) { .map(|cgu| cgu.name()) .collect::>(); - let ams = AssertModuleSource { - tcx, - available_cgus - }; + let ams = AssertModuleSource { tcx, available_cgus }; for attr in tcx.hir().krate().attrs { ams.check_attr(attr); @@ -73,7 +70,8 @@ impl AssertModuleSource<'tcx> { other => { self.tcx.sess.span_fatal( attr.span, - &format!("unknown cgu-reuse-kind `{}` specified", other)); + &format!("unknown cgu-reuse-kind `{}` specified", other), + ); } } } else { @@ -83,8 +81,11 @@ impl AssertModuleSource<'tcx> { if !self.tcx.sess.opts.debugging_opts.query_dep_graph { self.tcx.sess.span_fatal( attr.span, - &format!("found CGU-reuse attribute but `-Zquery-dep-graph` \ - was not specified")); + &format!( + "found CGU-reuse attribute but `-Zquery-dep-graph` \ + was not specified" + ), + ); } if !self.check_config(attr) { @@ -96,15 +97,18 @@ impl AssertModuleSource<'tcx> { let crate_name = self.tcx.crate_name(LOCAL_CRATE).to_string(); if !user_path.starts_with(&crate_name) { - let msg = format!("Found malformed codegen unit name `{}`. \ + let msg = format!( + "Found malformed codegen unit name `{}`. \ Codegen units names must always start with the name of the \ - crate (`{}` in this case).", user_path, crate_name); + crate (`{}` in this case).", + user_path, crate_name + ); self.tcx.sess.span_fatal(attr.span, &msg); } // Split of the "special suffix" if there is one. let (user_path, cgu_special_suffix) = if let Some(index) = user_path.rfind(".") { - (&user_path[..index], Some(&user_path[index + 1 ..])) + (&user_path[..index], Some(&user_path[index + 1..])) } else { (&user_path[..], None) }; @@ -115,15 +119,16 @@ impl AssertModuleSource<'tcx> { assert_eq!(cgu_path_components.remove(0), crate_name); let cgu_name_builder = &mut CodegenUnitNameBuilder::new(self.tcx); - let cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE, - cgu_path_components, - cgu_special_suffix); + let cgu_name = + cgu_name_builder.build_cgu_name(LOCAL_CRATE, cgu_path_components, cgu_special_suffix); debug!("mapping '{}' to cgu name '{}'", self.field(attr, sym::module), cgu_name); if !self.available_cgus.contains(&cgu_name) { - self.tcx.sess.span_err(attr.span, - &format!("no module named `{}` (mangled: {}). \ + self.tcx.sess.span_err( + attr.span, + &format!( + "no module named `{}` (mangled: {}). \ Available modules: {}", user_path, cgu_name, @@ -131,14 +136,18 @@ impl AssertModuleSource<'tcx> { .iter() .map(|cgu| cgu.to_string()) .collect::>() - .join(", "))); + .join(", ") + ), + ); } - self.tcx.sess.cgu_reuse_tracker.set_expectation(&cgu_name.as_str(), - &user_path, - attr.span, - expected_reuse, - comp_kind); + self.tcx.sess.cgu_reuse_tracker.set_expectation( + &cgu_name.as_str(), + &user_path, + attr.span, + expected_reuse, + comp_kind, + ); } fn field(&self, attr: &ast::Attribute, name: Symbol) -> ast::Name { @@ -149,14 +158,13 @@ impl AssertModuleSource<'tcx> { } else { self.tcx.sess.span_fatal( item.span(), - &format!("associated value expected for `{}`", name)); + &format!("associated value expected for `{}`", name), + ); } } } - self.tcx.sess.span_fatal( - attr.span, - &format!("no field `{}`", name)); + self.tcx.sess.span_fatal(attr.span, &format!("no field `{}`", name)); } /// Scan for a `cfg="foo"` attribute and check whether we have a diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index b257311138587..7ce4def2886b8 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -1,31 +1,31 @@ //! Support for serializing the dep-graph and reloading it. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] - #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(specialization)] +#![recursion_limit = "256"] -#![recursion_limit="256"] - -#[macro_use] extern crate rustc; -#[macro_use] extern crate log; +#[macro_use] +extern crate rustc; +#[macro_use] +extern crate log; mod assert_dep_graph; pub mod assert_module_sources; mod persist; pub use assert_dep_graph::assert_dep_graph; -pub use persist::dep_graph_tcx_init; -pub use persist::{DepGraphFuture, load_dep_graph}; -pub use persist::load_query_result_cache; -pub use persist::LoadResult; pub use persist::copy_cgu_workproducts_to_incr_comp_cache_dir; -pub use persist::save_dep_graph; -pub use persist::save_work_product_index; +pub use persist::delete_workproduct_files; +pub use persist::dep_graph_tcx_init; +pub use persist::finalize_session_directory; +pub use persist::garbage_collect_session_directories; pub use persist::in_incr_comp_dir; pub use persist::in_incr_comp_dir_sess; +pub use persist::load_query_result_cache; pub use persist::prepare_session_directory; -pub use persist::finalize_session_directory; -pub use persist::delete_workproduct_files; -pub use persist::garbage_collect_session_directories; +pub use persist::save_dep_graph; +pub use persist::save_work_product_index; +pub use persist::LoadResult; +pub use persist::{load_dep_graph, DepGraphFuture}; diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 7c9ed24f53b02..2f67dbd69c4da 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -13,20 +13,20 @@ //! Errors are reported if we are in the suitable configuration but //! the required condition is not met. -use std::iter::FromIterator; -use std::vec::Vec; -use rustc::dep_graph::{DepNode, label_strs}; +use rustc::dep_graph::{label_strs, DepNode}; use rustc::hir; -use rustc::hir::{ItemKind as HirItem, ImplItemKind, TraitItemKind}; -use rustc::hir::Node as HirNode; use rustc::hir::def_id::DefId; -use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::intravisit; +use rustc::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir::Node as HirNode; +use rustc::hir::{ImplItemKind, ItemKind as HirItem, TraitItemKind}; use rustc::ty::TyCtxt; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashSet; +use std::iter::FromIterator; +use std::vec::Vec; use syntax::ast::{self, Attribute, NestedMetaItem}; -use syntax::symbol::{Symbol, sym}; +use syntax::symbol::{sym, Symbol}; use syntax_pos::Span; const EXCEPT: Symbol = sym::except; @@ -36,9 +36,7 @@ const CFG: Symbol = sym::cfg; // Base and Extra labels to build up the labels /// For typedef, constants, and statics -const BASE_CONST: &[&str] = &[ - label_strs::type_of, -]; +const BASE_CONST: &[&str] = &[label_strs::type_of]; /// DepNodes for functions + methods const BASE_FN: &[&str] = &[ @@ -47,7 +45,6 @@ const BASE_FN: &[&str] = &[ label_strs::generics_of, label_strs::predicates_of, label_strs::type_of, - // And a big part of compilation (that we eventually want to cache) is type inference // information: label_strs::typeck_tables_of, @@ -61,29 +58,20 @@ const BASE_HIR: &[&str] = &[ ]; /// `impl` implementation of struct/trait -const BASE_IMPL: &[&str] = &[ - label_strs::associated_item_def_ids, - label_strs::generics_of, - label_strs::impl_trait_ref, -]; +const BASE_IMPL: &[&str] = + &[label_strs::associated_item_def_ids, label_strs::generics_of, label_strs::impl_trait_ref]; /// DepNodes for mir_built/Optimized, which is relevant in "executable" /// code, i.e., functions+methods -const BASE_MIR: &[&str] = &[ - label_strs::optimized_mir, - label_strs::promoted_mir, - label_strs::mir_built, -]; +const BASE_MIR: &[&str] = + &[label_strs::optimized_mir, label_strs::promoted_mir, label_strs::mir_built]; /// Struct, Enum and Union DepNodes /// /// Note that changing the type of a field does not change the type of the struct or enum, but /// adding/removing fields or changing a fields name or visibility does. -const BASE_STRUCT: &[&str] = &[ - label_strs::generics_of, - label_strs::predicates_of, - label_strs::type_of, -]; +const BASE_STRUCT: &[&str] = + &[label_strs::generics_of, label_strs::predicates_of, label_strs::type_of]; /// Trait definition `DepNode`s. const BASE_TRAIT_DEF: &[&str] = &[ @@ -97,84 +85,42 @@ const BASE_TRAIT_DEF: &[&str] = &[ ]; /// Extra `DepNode`s for functions and methods. -const EXTRA_ASSOCIATED: &[&str] = &[ - label_strs::associated_item, -]; +const EXTRA_ASSOCIATED: &[&str] = &[label_strs::associated_item]; -const EXTRA_TRAIT: &[&str] = &[ - label_strs::trait_of_item, -]; +const EXTRA_TRAIT: &[&str] = &[label_strs::trait_of_item]; // Fully Built Labels -const LABELS_CONST: &[&[&str]] = &[ - BASE_HIR, - BASE_CONST, -]; +const LABELS_CONST: &[&[&str]] = &[BASE_HIR, BASE_CONST]; /// Constant/Typedef in an impl -const LABELS_CONST_IN_IMPL: &[&[&str]] = &[ - BASE_HIR, - BASE_CONST, - EXTRA_ASSOCIATED, -]; +const LABELS_CONST_IN_IMPL: &[&[&str]] = &[BASE_HIR, BASE_CONST, EXTRA_ASSOCIATED]; /// Trait-Const/Typedef DepNodes -const LABELS_CONST_IN_TRAIT: &[&[&str]] = &[ - BASE_HIR, - BASE_CONST, - EXTRA_ASSOCIATED, - EXTRA_TRAIT, -]; +const LABELS_CONST_IN_TRAIT: &[&[&str]] = &[BASE_HIR, BASE_CONST, EXTRA_ASSOCIATED, EXTRA_TRAIT]; /// Function `DepNode`s. -const LABELS_FN: &[&[&str]] = &[ - BASE_HIR, - BASE_MIR, - BASE_FN, -]; +const LABELS_FN: &[&[&str]] = &[BASE_HIR, BASE_MIR, BASE_FN]; /// Method `DepNode`s. -const LABELS_FN_IN_IMPL: &[&[&str]] = &[ - BASE_HIR, - BASE_MIR, - BASE_FN, - EXTRA_ASSOCIATED, -]; +const LABELS_FN_IN_IMPL: &[&[&str]] = &[BASE_HIR, BASE_MIR, BASE_FN, EXTRA_ASSOCIATED]; /// Trait method `DepNode`s. -const LABELS_FN_IN_TRAIT: &[&[&str]] = &[ - BASE_HIR, - BASE_MIR, - BASE_FN, - EXTRA_ASSOCIATED, - EXTRA_TRAIT, -]; +const LABELS_FN_IN_TRAIT: &[&[&str]] = + &[BASE_HIR, BASE_MIR, BASE_FN, EXTRA_ASSOCIATED, EXTRA_TRAIT]; /// For generic cases like inline-assembly, modules, etc. -const LABELS_HIR_ONLY: &[&[&str]] = &[ - BASE_HIR, -]; +const LABELS_HIR_ONLY: &[&[&str]] = &[BASE_HIR]; /// Impl `DepNode`s. -const LABELS_IMPL: &[&[&str]] = &[ - BASE_HIR, - BASE_IMPL, -]; +const LABELS_IMPL: &[&[&str]] = &[BASE_HIR, BASE_IMPL]; /// Abstract data type (struct, enum, union) `DepNode`s. -const LABELS_ADT: &[&[&str]] = &[ - BASE_HIR, - BASE_STRUCT, -]; +const LABELS_ADT: &[&[&str]] = &[BASE_HIR, BASE_STRUCT]; /// Trait definition `DepNode`s. #[allow(dead_code)] -const LABELS_TRAIT: &[&[&str]] = &[ - BASE_HIR, - BASE_TRAIT_DEF, -]; - +const LABELS_TRAIT: &[&[&str]] = &[BASE_HIR, BASE_TRAIT_DEF]; // FIXME: Struct/Enum/Unions Fields (there is currently no way to attach these) // @@ -193,17 +139,11 @@ struct Assertion { impl Assertion { fn from_clean_labels(labels: Labels) -> Assertion { - Assertion { - clean: labels, - dirty: Labels::default(), - } + Assertion { clean: labels, dirty: Labels::default() } } fn from_dirty_labels(labels: Labels) -> Assertion { - Assertion { - clean: Labels::default(), - dirty: labels, - } + Assertion { clean: Labels::default(), dirty: labels } } } @@ -215,10 +155,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { let krate = tcx.hir().krate(); - let mut dirty_clean_visitor = DirtyCleanVisitor { - tcx, - checked_attrs: Default::default(), - }; + let mut dirty_clean_visitor = DirtyCleanVisitor { tcx, checked_attrs: Default::default() }; krate.visit_all_item_likes(&mut dirty_clean_visitor); let mut all_attrs = FindAllAttrs { @@ -242,16 +179,14 @@ pub struct DirtyCleanVisitor<'tcx> { impl DirtyCleanVisitor<'tcx> { /// Possibly "deserialize" the attribute into a clean/dirty assertion - fn assertion_maybe(&mut self, item_id: hir::HirId, attr: &Attribute) - -> Option - { + fn assertion_maybe(&mut self, item_id: hir::HirId, attr: &Attribute) -> Option { let is_clean = if attr.check_name(sym::rustc_dirty) { false } else if attr.check_name(sym::rustc_clean) { true } else { // skip: not rustc_clean/dirty - return None + return None; }; if !check_config(self.tcx, attr) { // skip: not the correct `cfg=` @@ -270,31 +205,27 @@ impl DirtyCleanVisitor<'tcx> { } /// Gets the "auto" assertion on pre-validated attr, along with the `except` labels. - fn assertion_auto(&mut self, item_id: hir::HirId, attr: &Attribute, is_clean: bool) - -> Assertion - { + fn assertion_auto( + &mut self, + item_id: hir::HirId, + attr: &Attribute, + is_clean: bool, + ) -> Assertion { let (name, mut auto) = self.auto_labels(item_id, attr); let except = self.except(attr); for e in except.iter() { if !auto.remove(e) { let msg = format!( "`except` specified DepNodes that can not be affected for \"{}\": \"{}\"", - name, - e + name, e ); self.tcx.sess.span_fatal(attr.span, &msg); } } if is_clean { - Assertion { - clean: auto, - dirty: except, - } + Assertion { clean: auto, dirty: except } } else { - Assertion { - clean: except, - dirty: auto, - } + Assertion { clean: except, dirty: auto } } } @@ -346,7 +277,7 @@ impl DirtyCleanVisitor<'tcx> { HirItem::Fn(..) => ("ItemFn", LABELS_FN), // // A module - HirItem::Mod(..) =>("ItemMod", LABELS_HIR_ONLY), + HirItem::Mod(..) => ("ItemMod", LABELS_HIR_ONLY), // // An external module HirItem::ForeignMod(..) => ("ItemForeignMod", LABELS_HIR_ONLY), @@ -391,36 +322,27 @@ impl DirtyCleanVisitor<'tcx> { "clean/dirty auto-assertions not yet defined \ for Node::Item.node={:?}", item.kind - ) + ), ), } + } + HirNode::TraitItem(item) => match item.kind { + TraitItemKind::Method(..) => ("Node::TraitItem", LABELS_FN_IN_TRAIT), + TraitItemKind::Const(..) => ("NodeTraitConst", LABELS_CONST_IN_TRAIT), + TraitItemKind::Type(..) => ("NodeTraitType", LABELS_CONST_IN_TRAIT), }, - HirNode::TraitItem(item) => { - match item.kind { - TraitItemKind::Method(..) => ("Node::TraitItem", LABELS_FN_IN_TRAIT), - TraitItemKind::Const(..) => ("NodeTraitConst", LABELS_CONST_IN_TRAIT), - TraitItemKind::Type(..) => ("NodeTraitType", LABELS_CONST_IN_TRAIT), - } - }, - HirNode::ImplItem(item) => { - match item.kind { - ImplItemKind::Method(..) => ("Node::ImplItem", LABELS_FN_IN_IMPL), - ImplItemKind::Const(..) => ("NodeImplConst", LABELS_CONST_IN_IMPL), - ImplItemKind::TyAlias(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), - ImplItemKind::OpaqueTy(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), - } + HirNode::ImplItem(item) => match item.kind { + ImplItemKind::Method(..) => ("Node::ImplItem", LABELS_FN_IN_IMPL), + ImplItemKind::Const(..) => ("NodeImplConst", LABELS_CONST_IN_IMPL), + ImplItemKind::TyAlias(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), + ImplItemKind::OpaqueTy(..) => ("NodeImplType", LABELS_CONST_IN_IMPL), }, _ => self.tcx.sess.span_fatal( attr.span, - &format!( - "clean/dirty auto-assertions not yet defined for {:?}", - node - ) + &format!("clean/dirty auto-assertions not yet defined for {:?}", node), ), }; - let labels = Labels::from_iter( - labels.iter().flat_map(|s| s.iter().map(|l| l.to_string())) - ); + let labels = Labels::from_iter(labels.iter().flat_map(|s| s.iter().map(|l| l.to_string()))); (name, labels) } @@ -432,13 +354,14 @@ impl DirtyCleanVisitor<'tcx> { if out.contains(label) { self.tcx.sess.span_fatal( item.span(), - &format!("dep-node label `{}` is repeated", label)); + &format!("dep-node label `{}` is repeated", label), + ); } out.insert(label.to_string()); } else { - self.tcx.sess.span_fatal( - item.span(), - &format!("dep-node label `{}` not recognized", label)); + self.tcx + .sess + .span_fatal(item.span(), &format!("dep-node label `{}` not recognized", label)); } } out @@ -447,24 +370,18 @@ impl DirtyCleanVisitor<'tcx> { fn dep_nodes<'l>( &self, labels: &'l Labels, - def_id: DefId + def_id: DefId, ) -> impl Iterator + 'l { let def_path_hash = self.tcx.def_path_hash(def_id); - labels - .iter() - .map(move |label| { - match DepNode::from_label_string(label, def_path_hash) { - Ok(dep_node) => dep_node, - Err(()) => unreachable!(), - } - }) + labels.iter().map(move |label| match DepNode::from_label_string(label, def_path_hash) { + Ok(dep_node) => dep_node, + Err(()) => unreachable!(), + }) } fn dep_node_str(&self, dep_node: &DepNode) -> String { if let Some(def_id) = dep_node.extract_def_id(self.tcx) { - format!("{:?}({})", - dep_node.kind, - self.tcx.def_path_str(def_id)) + format!("{:?}({})", dep_node.kind, self.tcx.def_path_str(def_id)) } else { format!("{:?}({:?})", dep_node.kind, dep_node.hash) } @@ -478,9 +395,9 @@ impl DirtyCleanVisitor<'tcx> { if current_fingerprint == prev_fingerprint { let dep_node_str = self.dep_node_str(&dep_node); - self.tcx.sess.span_err( - item_span, - &format!("`{}` should be dirty but is not", dep_node_str)); + self.tcx + .sess + .span_err(item_span, &format!("`{}` should be dirty but is not", dep_node_str)); } } @@ -507,9 +424,9 @@ impl DirtyCleanVisitor<'tcx> { if current_fingerprint != prev_fingerprint { let dep_node_str = self.dep_node_str(&dep_node); - self.tcx.sess.span_err( - item_span, - &format!("`{}` should be clean but is not", dep_node_str)); + self.tcx + .sess + .span_err(item_span, &format!("`{}` should be clean but is not", dep_node_str)); } } @@ -571,17 +488,11 @@ fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool { } if label && except { - tcx.sess.span_fatal( - attr.span, - "must specify only one of: `label`, `except`" - ); + tcx.sess.span_fatal(attr.span, "must specify only one of: `label`, `except`"); } match cfg { - None => tcx.sess.span_fatal( - attr.span, - "no cfg attribute" - ), + None => tcx.sess.span_fatal(attr.span, "no cfg attribute"), Some(c) => c, } } @@ -623,8 +534,13 @@ impl FindAllAttrs<'tcx> { fn report_unchecked_attrs(&self, checked_attrs: &FxHashSet) { for attr in &self.found_attrs { if !checked_attrs.contains(&attr.id) { - self.tcx.sess.span_err(attr.span, &format!("found unchecked \ - `#[rustc_dirty]` / `#[rustc_clean]` attribute")); + self.tcx.sess.span_err( + attr.span, + &format!( + "found unchecked \ + `#[rustc_dirty]` / `#[rustc_clean]` attribute" + ), + ); } } } diff --git a/src/librustc_incremental/persist/file_format.rs b/src/librustc_incremental/persist/file_format.rs index f363f718496fa..7534b7e9ef429 100644 --- a/src/librustc_incremental/persist/file_format.rs +++ b/src/librustc_incremental/persist/file_format.rs @@ -9,10 +9,10 @@ //! compiler versions don't change frequently for the typical user, being //! conservative here practically has no downside. +use std::env; +use std::fs; use std::io::{self, Read}; use std::path::Path; -use std::fs; -use std::env; use rustc::session::config::nightly_options; use rustc_serialize::opaque::Encoder; @@ -30,8 +30,8 @@ const RUSTC_VERSION: Option<&str> = option_env!("CFG_VERSION"); pub fn write_file_header(stream: &mut Encoder) { stream.emit_raw_bytes(FILE_MAGIC); - stream.emit_raw_bytes(&[(HEADER_FORMAT_VERSION >> 0) as u8, - (HEADER_FORMAT_VERSION >> 8) as u8]); + stream + .emit_raw_bytes(&[(HEADER_FORMAT_VERSION >> 0) as u8, (HEADER_FORMAT_VERSION >> 8) as u8]); let rustc_version = rustc_version(); assert_eq!(rustc_version.len(), (rustc_version.len() as u8) as usize); @@ -48,9 +48,10 @@ pub fn write_file_header(stream: &mut Encoder) { /// incompatible version of the compiler. /// - Returns `Err(..)` if some kind of IO error occurred while reading the /// file. -pub fn read_file(report_incremental_info: bool, path: &Path) - -> io::Result, usize)>> -{ +pub fn read_file( + report_incremental_info: bool, + path: &Path, +) -> io::Result, usize)>> { if !path.exists() { return Ok(None); } @@ -66,7 +67,7 @@ pub fn read_file(report_incremental_info: bool, path: &Path) file.read_exact(&mut file_magic)?; if file_magic != FILE_MAGIC { report_format_mismatch(report_incremental_info, path, "Wrong FILE_MAGIC"); - return Ok(None) + return Ok(None); } } @@ -75,12 +76,12 @@ pub fn read_file(report_incremental_info: bool, path: &Path) debug_assert!(::std::mem::size_of_val(&HEADER_FORMAT_VERSION) == 2); let mut header_format_version = [0u8; 2]; file.read_exact(&mut header_format_version)?; - let header_format_version = (header_format_version[0] as u16) | - ((header_format_version[1] as u16) << 8); + let header_format_version = + (header_format_version[0] as u16) | ((header_format_version[1] as u16) << 8); if header_format_version != HEADER_FORMAT_VERSION { report_format_mismatch(report_incremental_info, path, "Wrong HEADER_FORMAT_VERSION"); - return Ok(None) + return Ok(None); } } @@ -107,20 +108,25 @@ fn report_format_mismatch(report_incremental_info: bool, file: &Path, message: & debug!("read_file: {}", message); if report_incremental_info { - println!("[incremental] ignoring cache artifact `{}`: {}", - file.file_name().unwrap().to_string_lossy(), - message); + println!( + "[incremental] ignoring cache artifact `{}`: {}", + file.file_name().unwrap().to_string_lossy(), + message + ); } } fn rustc_version() -> String { if nightly_options::is_nightly_build() { if let Some(val) = env::var_os("RUSTC_FORCE_INCR_COMP_ARTIFACT_HEADER") { - return val.to_string_lossy().into_owned() + return val.to_string_lossy().into_owned(); } } - RUSTC_VERSION.expect("Cannot use rustc without explicit version for \ - incremental compilation") - .to_string() + RUSTC_VERSION + .expect( + "Cannot use rustc without explicit version for \ + incremental compilation", + ) + .to_string() } diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs index cbebdeb602cc0..adf8f57f01d08 100644 --- a/src/librustc_incremental/persist/fs.rs +++ b/src/librustc_incremental/persist/fs.rs @@ -103,19 +103,19 @@ //! unsupported file system and emit a warning in that case. This is not yet //! implemented. -use rustc::session::{Session, CrateDisambiguator}; -use rustc_fs_util::{link_or_copy, LinkOrCopy}; -use rustc_data_structures::{flock, base_n}; -use rustc_data_structures::fx::{FxHashSet, FxHashMap}; +use rustc::session::{CrateDisambiguator, Session}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::svh::Svh; +use rustc_data_structures::{base_n, flock}; +use rustc_fs_util::{link_or_copy, LinkOrCopy}; use std::fs as std_fs; use std::io; use std::mem; use std::path::{Path, PathBuf}; -use std::time::{UNIX_EPOCH, SystemTime, Duration}; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use rand::{RngCore, thread_rng}; +use rand::{thread_rng, RngCore}; #[cfg(test)] mod tests; @@ -152,17 +152,16 @@ pub fn lock_file_path(session_dir: &Path) -> PathBuf { let directory_name = session_dir.file_name().unwrap().to_string_lossy(); assert_no_characters_lost(&directory_name); - let dash_indices: Vec<_> = directory_name.match_indices("-") - .map(|(idx, _)| idx) - .collect(); + let dash_indices: Vec<_> = directory_name.match_indices("-").map(|(idx, _)| idx).collect(); if dash_indices.len() != 3 { - bug!("Encountered incremental compilation session directory with \ + bug!( + "Encountered incremental compilation session directory with \ malformed name: {}", - session_dir.display()) + session_dir.display() + ) } - crate_dir.join(&directory_name[0 .. dash_indices[2]]) - .with_extension(&LOCK_FILE_EXT[1..]) + crate_dir.join(&directory_name[0..dash_indices[2]]).with_extension(&LOCK_FILE_EXT[1..]) } pub fn in_incr_comp_dir_sess(sess: &Session, file_name: &str) -> PathBuf { @@ -182,11 +181,13 @@ pub fn in_incr_comp_dir(incr_comp_session_dir: &Path, file_name: &str) -> PathBu /// a dep-graph and work products from a previous session. /// If the call fails, the fn may leave behind an invalid session directory. /// The garbage collection will take care of it. -pub fn prepare_session_directory(sess: &Session, - crate_name: &str, - crate_disambiguator: CrateDisambiguator) { +pub fn prepare_session_directory( + sess: &Session, + crate_name: &str, + crate_disambiguator: CrateDisambiguator, +) { if sess.opts.incremental.is_none() { - return + return; } debug!("prepare_session_directory"); @@ -195,7 +196,7 @@ pub fn prepare_session_directory(sess: &Session, let crate_dir = crate_path(sess, crate_name, crate_disambiguator); debug!("crate-dir: {}", crate_dir.display()); if create_dir(sess, &crate_dir, "crate").is_err() { - return + return; } // Hack: canonicalize the path *after creating the directory* @@ -205,9 +206,12 @@ pub fn prepare_session_directory(sess: &Session, let crate_dir = match crate_dir.canonicalize() { Ok(v) => v, Err(err) => { - sess.err(&format!("incremental compilation: error canonicalizing path `{}`: {}", - crate_dir.display(), err)); - return + sess.err(&format!( + "incremental compilation: error canonicalizing path `{}`: {}", + crate_dir.display(), + err + )); + return; } }; @@ -230,51 +234,47 @@ pub fn prepare_session_directory(sess: &Session, // Now that we have the lock, we can actually create the session // directory if create_dir(sess, &session_dir, "session").is_err() { - return + return; } // Find a suitable source directory to copy from. Ignore those that we // have already tried before. - let source_directory = find_source_directory(&crate_dir, - &source_directories_already_tried); + let source_directory = find_source_directory(&crate_dir, &source_directories_already_tried); let source_directory = if let Some(dir) = source_directory { dir } else { // There's nowhere to copy from, we're done - debug!("no source directory found. Continuing with empty session \ - directory."); + debug!( + "no source directory found. Continuing with empty session \ + directory." + ); sess.init_incr_comp_session(session_dir, directory_lock, false); - return + return; }; - debug!("attempting to copy data from source: {}", - source_directory.display()); - - + debug!("attempting to copy data from source: {}", source_directory.display()); // Try copying over all files from the source directory - if let Ok(allows_links) = copy_files(sess, - &session_dir, - &source_directory) { - debug!("successfully copied data from: {}", - source_directory.display()); + if let Ok(allows_links) = copy_files(sess, &session_dir, &source_directory) { + debug!("successfully copied data from: {}", source_directory.display()); if !allows_links { - sess.warn(&format!("Hard linking files in the incremental \ + sess.warn(&format!( + "Hard linking files in the incremental \ compilation cache failed. Copying files \ instead. Consider moving the cache \ directory to a file system which supports \ hard linking in session dir `{}`", - session_dir.display()) - ); + session_dir.display() + )); } sess.init_incr_comp_session(session_dir, directory_lock, true); - return + return; } else { - debug!("copying failed - trying next directory"); + debug!("copying failed - trying next directory"); // Something went wrong while trying to copy/link files from the // source directory. Try again with a different one. @@ -283,10 +283,12 @@ pub fn prepare_session_directory(sess: &Session, // Try to remove the session directory we just allocated. We don't // know if there's any garbage in it from the failed copy action. if let Err(err) = safe_remove_dir_all(&session_dir) { - sess.warn(&format!("Failed to delete partly initialized \ + sess.warn(&format!( + "Failed to delete partly initialized \ session dir `{}`: {}", - session_dir.display(), - err)); + session_dir.display(), + err + )); } delete_session_dir_lock_file(sess, &lock_file_path); @@ -295,7 +297,6 @@ pub fn prepare_session_directory(sess: &Session, } } - /// This function finalizes and thus 'publishes' the session directory by /// renaming it to `s-{timestamp}-{svh}` and releasing the file lock. /// If there have been compilation errors, however, this function will just @@ -311,14 +312,18 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) { // If there have been any errors during compilation, we don't want to // publish this session directory. Rather, we'll just delete it. - debug!("finalize_session_directory() - invalidating session directory: {}", - incr_comp_session_dir.display()); + debug!( + "finalize_session_directory() - invalidating session directory: {}", + incr_comp_session_dir.display() + ); if let Err(err) = safe_remove_dir_all(&*incr_comp_session_dir) { - sess.warn(&format!("Error deleting incremental compilation \ + sess.warn(&format!( + "Error deleting incremental compilation \ session directory `{}`: {}", - incr_comp_session_dir.display(), - err)); + incr_comp_session_dir.display(), + err + )); } let lock_file_path = lock_file_path(&*incr_comp_session_dir); @@ -326,27 +331,24 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) { sess.mark_incr_comp_session_as_invalid(); } - debug!("finalize_session_directory() - session directory: {}", - incr_comp_session_dir.display()); + debug!("finalize_session_directory() - session directory: {}", incr_comp_session_dir.display()); - let old_sub_dir_name = incr_comp_session_dir.file_name() - .unwrap() - .to_string_lossy(); + let old_sub_dir_name = incr_comp_session_dir.file_name().unwrap().to_string_lossy(); assert_no_characters_lost(&old_sub_dir_name); // Keep the 's-{timestamp}-{random-number}' prefix, but replace the // '-working' part with the SVH of the crate - let dash_indices: Vec<_> = old_sub_dir_name.match_indices("-") - .map(|(idx, _)| idx) - .collect(); + let dash_indices: Vec<_> = old_sub_dir_name.match_indices("-").map(|(idx, _)| idx).collect(); if dash_indices.len() != 3 { - bug!("Encountered incremental compilation session directory with \ + bug!( + "Encountered incremental compilation session directory with \ malformed name: {}", - incr_comp_session_dir.display()) + incr_comp_session_dir.display() + ) } // State: "s-{timestamp}-{random-number}-" - let mut new_sub_dir_name = String::from(&old_sub_dir_name[..= dash_indices[2]]); + let mut new_sub_dir_name = String::from(&old_sub_dir_name[..=dash_indices[2]]); // Append the svh base_n::push_str(svh.as_u64() as u128, INT_ENCODE_BASE, &mut new_sub_dir_name); @@ -364,10 +366,12 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) { } Err(e) => { // Warn about the error. However, no need to abort compilation now. - sess.warn(&format!("Error finalizing incremental compilation \ + sess.warn(&format!( + "Error finalizing incremental compilation \ session directory `{}`: {}", - incr_comp_session_dir.display(), - e)); + incr_comp_session_dir.display(), + e + )); debug!("finalize_session_directory() - error, marking as invalid"); // Drop the file lock, so we can garage collect @@ -387,26 +391,26 @@ pub fn delete_all_session_dir_contents(sess: &Session) -> io::Result<()> { Ok(()) } -fn copy_files(sess: &Session, - target_dir: &Path, - source_dir: &Path) - -> Result { +fn copy_files(sess: &Session, target_dir: &Path, source_dir: &Path) -> Result { // We acquire a shared lock on the lock file of the directory, so that // nobody deletes it out from under us while we are reading from it. let lock_file_path = lock_file_path(source_dir); - let _lock = if let Ok(lock) = flock::Lock::new(&lock_file_path, - false, // don't wait, - false, // don't create - false) { // not exclusive + let _lock = if let Ok(lock) = flock::Lock::new( + &lock_file_path, + false, // don't wait, + false, // don't create + false, + ) { + // not exclusive lock } else { // Could not acquire the lock, don't try to copy from here - return Err(()) + return Err(()); }; let source_dir_iterator = match source_dir.read_dir() { Ok(it) => it, - Err(_) => return Err(()) + Err(_) => return Err(()), }; let mut files_linked = 0; @@ -422,26 +426,26 @@ fn copy_files(sess: &Session, debug!("copying into session dir: {}", source_path.display()); match link_or_copy(source_path, target_file_path) { - Ok(LinkOrCopy::Link) => { - files_linked += 1 - } - Ok(LinkOrCopy::Copy) => { - files_copied += 1 - } - Err(_) => return Err(()) + Ok(LinkOrCopy::Link) => files_linked += 1, + Ok(LinkOrCopy::Copy) => files_copied += 1, + Err(_) => return Err(()), } } - Err(_) => { - return Err(()) - } + Err(_) => return Err(()), } } if sess.opts.debugging_opts.incremental_info { - println!("[incremental] session directory: \ - {} files hard-linked", files_linked); - println!("[incremental] session directory: \ - {} files copied", files_copied); + println!( + "[incremental] session directory: \ + {} files hard-linked", + files_linked + ); + println!( + "[incremental] session directory: \ + {} files copied", + files_copied + ); } Ok(files_linked > 0 || files_copied == 0) @@ -455,100 +459,111 @@ fn generate_session_dir_path(crate_dir: &Path) -> PathBuf { let random_number = thread_rng().next_u32(); debug!("generate_session_dir_path: random_number = {}", random_number); - let directory_name = format!("s-{}-{}-working", - timestamp, - base_n::encode(random_number as u128, - INT_ENCODE_BASE)); + let directory_name = format!( + "s-{}-{}-working", + timestamp, + base_n::encode(random_number as u128, INT_ENCODE_BASE) + ); debug!("generate_session_dir_path: directory_name = {}", directory_name); let directory_path = crate_dir.join(directory_name); debug!("generate_session_dir_path: directory_path = {}", directory_path.display()); directory_path } -fn create_dir(sess: &Session, path: &Path, dir_tag: &str) -> Result<(),()> { +fn create_dir(sess: &Session, path: &Path, dir_tag: &str) -> Result<(), ()> { match std_fs::create_dir_all(path) { Ok(()) => { debug!("{} directory created successfully", dir_tag); Ok(()) } Err(err) => { - sess.err(&format!("Could not create incremental compilation {} \ + sess.err(&format!( + "Could not create incremental compilation {} \ directory `{}`: {}", - dir_tag, - path.display(), - err)); + dir_tag, + path.display(), + err + )); Err(()) } } } /// Allocate the lock-file and lock it. -fn lock_directory(sess: &Session, - session_dir: &Path) - -> Result<(flock::Lock, PathBuf), ()> { +fn lock_directory(sess: &Session, session_dir: &Path) -> Result<(flock::Lock, PathBuf), ()> { let lock_file_path = lock_file_path(session_dir); debug!("lock_directory() - lock_file: {}", lock_file_path.display()); - match flock::Lock::new(&lock_file_path, - false, // don't wait - true, // create the lock file - true) { // the lock should be exclusive + match flock::Lock::new( + &lock_file_path, + false, // don't wait + true, // create the lock file + true, + ) { + // the lock should be exclusive Ok(lock) => Ok((lock, lock_file_path)), Err(err) => { - sess.err(&format!("incremental compilation: could not create \ - session directory lock file: {}", err)); + sess.err(&format!( + "incremental compilation: could not create \ + session directory lock file: {}", + err + )); Err(()) } } } -fn delete_session_dir_lock_file(sess: &Session, - lock_file_path: &Path) { +fn delete_session_dir_lock_file(sess: &Session, lock_file_path: &Path) { if let Err(err) = safe_remove_file(&lock_file_path) { - sess.warn(&format!("Error deleting lock file for incremental \ + sess.warn(&format!( + "Error deleting lock file for incremental \ compilation session directory `{}`: {}", - lock_file_path.display(), - err)); + lock_file_path.display(), + err + )); } } /// Finds the most recent published session directory that is not in the /// ignore-list. -fn find_source_directory(crate_dir: &Path, - source_directories_already_tried: &FxHashSet) - -> Option { - let iter = crate_dir.read_dir() - .unwrap() // FIXME - .filter_map(|e| e.ok().map(|e| e.path())); +fn find_source_directory( + crate_dir: &Path, + source_directories_already_tried: &FxHashSet, +) -> Option { + let iter = crate_dir + .read_dir() + .unwrap() // FIXME + .filter_map(|e| e.ok().map(|e| e.path())); find_source_directory_in_iter(iter, source_directories_already_tried) } -fn find_source_directory_in_iter(iter: I, - source_directories_already_tried: &FxHashSet) - -> Option - where I: Iterator +fn find_source_directory_in_iter( + iter: I, + source_directories_already_tried: &FxHashSet, +) -> Option +where + I: Iterator, { let mut best_candidate = (UNIX_EPOCH, None); for session_dir in iter { - debug!("find_source_directory_in_iter - inspecting `{}`", - session_dir.display()); + debug!("find_source_directory_in_iter - inspecting `{}`", session_dir.display()); let directory_name = session_dir.file_name().unwrap().to_string_lossy(); assert_no_characters_lost(&directory_name); - if source_directories_already_tried.contains(&session_dir) || - !is_session_directory(&directory_name) || - !is_finalized(&directory_name) { + if source_directories_already_tried.contains(&session_dir) + || !is_session_directory(&directory_name) + || !is_finalized(&directory_name) + { debug!("find_source_directory_in_iter - ignoring"); - continue + continue; } - let timestamp = extract_timestamp_from_session_dir(&directory_name) - .unwrap_or_else(|_| { - bug!("unexpected incr-comp session dir: {}", session_dir.display()) - }); + let timestamp = extract_timestamp_from_session_dir(&directory_name).unwrap_or_else(|_| { + bug!("unexpected incr-comp session dir: {}", session_dir.display()) + }); if timestamp > best_candidate.0 { best_candidate = (timestamp, Some(session_dir.clone())); @@ -563,34 +578,29 @@ fn is_finalized(directory_name: &str) -> bool { } fn is_session_directory(directory_name: &str) -> bool { - directory_name.starts_with("s-") && - !directory_name.ends_with(LOCK_FILE_EXT) + directory_name.starts_with("s-") && !directory_name.ends_with(LOCK_FILE_EXT) } fn is_session_directory_lock_file(file_name: &str) -> bool { file_name.starts_with("s-") && file_name.ends_with(LOCK_FILE_EXT) } -fn extract_timestamp_from_session_dir(directory_name: &str) - -> Result { +fn extract_timestamp_from_session_dir(directory_name: &str) -> Result { if !is_session_directory(directory_name) { - return Err(()) + return Err(()); } - let dash_indices: Vec<_> = directory_name.match_indices("-") - .map(|(idx, _)| idx) - .collect(); + let dash_indices: Vec<_> = directory_name.match_indices("-").map(|(idx, _)| idx).collect(); if dash_indices.len() != 3 { - return Err(()) + return Err(()); } - string_to_timestamp(&directory_name[dash_indices[0]+1 .. dash_indices[1]]) + string_to_timestamp(&directory_name[dash_indices[0] + 1..dash_indices[1]]) } fn timestamp_to_string(timestamp: SystemTime) -> String { let duration = timestamp.duration_since(UNIX_EPOCH).unwrap(); - let micros = duration.as_secs() * 1_000_000 + - (duration.subsec_nanos() as u64) / 1000; + let micros = duration.as_secs() * 1_000_000 + (duration.subsec_nanos() as u64) / 1000; base_n::encode(micros as u128, INT_ENCODE_BASE) } @@ -598,28 +608,29 @@ fn string_to_timestamp(s: &str) -> Result { let micros_since_unix_epoch = u64::from_str_radix(s, INT_ENCODE_BASE as u32); if micros_since_unix_epoch.is_err() { - return Err(()) + return Err(()); } let micros_since_unix_epoch = micros_since_unix_epoch.unwrap(); - let duration = Duration::new(micros_since_unix_epoch / 1_000_000, - 1000 * (micros_since_unix_epoch % 1_000_000) as u32); + let duration = Duration::new( + micros_since_unix_epoch / 1_000_000, + 1000 * (micros_since_unix_epoch % 1_000_000) as u32, + ); Ok(UNIX_EPOCH + duration) } -fn crate_path(sess: &Session, - crate_name: &str, - crate_disambiguator: CrateDisambiguator) - -> PathBuf { - +fn crate_path( + sess: &Session, + crate_name: &str, + crate_disambiguator: CrateDisambiguator, +) -> PathBuf { let incr_dir = sess.opts.incremental.as_ref().unwrap().clone(); // The full crate disambiguator is really long. 64 bits of it should be // sufficient. let crate_disambiguator = crate_disambiguator.to_fingerprint().to_smaller_hash(); - let crate_disambiguator = base_n::encode(crate_disambiguator as u128, - INT_ENCODE_BASE); + let crate_disambiguator = base_n::encode(crate_disambiguator as u128, INT_ENCODE_BASE); let crate_name = format!("{}-{}", crate_name, crate_disambiguator); incr_dir.join(crate_name) @@ -639,12 +650,16 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { debug!("garbage_collect_session_directories() - begin"); let session_directory = sess.incr_comp_session_dir(); - debug!("garbage_collect_session_directories() - session directory: {}", - session_directory.display()); + debug!( + "garbage_collect_session_directories() - session directory: {}", + session_directory.display() + ); let crate_directory = session_directory.parent().unwrap(); - debug!("garbage_collect_session_directories() - crate directory: {}", - crate_directory.display()); + debug!( + "garbage_collect_session_directories() - crate directory: {}", + crate_directory.display() + ); // First do a pass over the crate directory, collecting lock files and // session directories @@ -656,7 +671,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { Ok(dir_entry) => dir_entry, _ => { // Ignore any errors - continue + continue; } }; @@ -675,19 +690,18 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { } // Now map from lock files to session directories - let lock_file_to_session_dir: FxHashMap> = - lock_files.into_iter() - .map(|lock_file_name| { - assert!(lock_file_name.ends_with(LOCK_FILE_EXT)); - let dir_prefix_end = lock_file_name.len() - LOCK_FILE_EXT.len(); - let session_dir = { - let dir_prefix = &lock_file_name[0 .. dir_prefix_end]; - session_directories.iter() - .find(|dir_name| dir_name.starts_with(dir_prefix)) - }; - (lock_file_name, session_dir.map(String::clone)) - }) - .collect(); + let lock_file_to_session_dir: FxHashMap> = lock_files + .into_iter() + .map(|lock_file_name| { + assert!(lock_file_name.ends_with(LOCK_FILE_EXT)); + let dir_prefix_end = lock_file_name.len() - LOCK_FILE_EXT.len(); + let session_dir = { + let dir_prefix = &lock_file_name[0..dir_prefix_end]; + session_directories.iter().find(|dir_name| dir_name.starts_with(dir_prefix)) + }; + (lock_file_name, session_dir.map(String::clone)) + }) + .collect(); // Delete all lock files, that don't have an associated directory. They must // be some kind of leftover @@ -696,44 +710,51 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { let timestamp = match extract_timestamp_from_session_dir(lock_file_name) { Ok(timestamp) => timestamp, Err(()) => { - debug!("found lock-file with malformed timestamp: {}", - crate_directory.join(&lock_file_name).display()); + debug!( + "found lock-file with malformed timestamp: {}", + crate_directory.join(&lock_file_name).display() + ); // Ignore it - continue + continue; } }; let lock_file_path = crate_directory.join(&**lock_file_name); if is_old_enough_to_be_collected(timestamp) { - debug!("garbage_collect_session_directories() - deleting \ - garbage lock file: {}", lock_file_path.display()); + debug!( + "garbage_collect_session_directories() - deleting \ + garbage lock file: {}", + lock_file_path.display() + ); delete_session_dir_lock_file(sess, &lock_file_path); } else { - debug!("garbage_collect_session_directories() - lock file with \ + debug!( + "garbage_collect_session_directories() - lock file with \ no session dir not old enough to be collected: {}", - lock_file_path.display()); + lock_file_path.display() + ); } } } // Filter out `None` directories - let lock_file_to_session_dir: FxHashMap = - lock_file_to_session_dir.into_iter() - .filter_map(|(lock_file_name, directory_name)| { - directory_name.map(|n| (lock_file_name, n)) - }) - .collect(); + let lock_file_to_session_dir: FxHashMap = lock_file_to_session_dir + .into_iter() + .filter_map(|(lock_file_name, directory_name)| directory_name.map(|n| (lock_file_name, n))) + .collect(); // Delete all session directories that don't have a lock file. for directory_name in session_directories { if !lock_file_to_session_dir.values().any(|dir| *dir == directory_name) { let path = crate_directory.join(directory_name); if let Err(err) = safe_remove_dir_all(&path) { - sess.warn(&format!("Failed to garbage collect invalid incremental \ + sess.warn(&format!( + "Failed to garbage collect invalid incremental \ compilation session directory `{}`: {}", - path.display(), - err)); + path.display(), + err + )); } } } @@ -743,39 +764,52 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { let mut definitely_delete = vec![]; for (lock_file_name, directory_name) in &lock_file_to_session_dir { - debug!("garbage_collect_session_directories() - inspecting: {}", - directory_name); + debug!("garbage_collect_session_directories() - inspecting: {}", directory_name); let timestamp = match extract_timestamp_from_session_dir(directory_name) { Ok(timestamp) => timestamp, Err(()) => { - debug!("found session-dir with malformed timestamp: {}", - crate_directory.join(directory_name).display()); + debug!( + "found session-dir with malformed timestamp: {}", + crate_directory.join(directory_name).display() + ); // Ignore it - continue + continue; } }; if is_finalized(directory_name) { let lock_file_path = crate_directory.join(lock_file_name); - match flock::Lock::new(&lock_file_path, - false, // don't wait - false, // don't create the lock-file - true) { // get an exclusive lock + match flock::Lock::new( + &lock_file_path, + false, // don't wait + false, // don't create the lock-file + true, + ) { + // get an exclusive lock Ok(lock) => { - debug!("garbage_collect_session_directories() - \ - successfully acquired lock"); - debug!("garbage_collect_session_directories() - adding \ - deletion candidate: {}", directory_name); + debug!( + "garbage_collect_session_directories() - \ + successfully acquired lock" + ); + debug!( + "garbage_collect_session_directories() - adding \ + deletion candidate: {}", + directory_name + ); // Note that we are holding on to the lock - deletion_candidates.push((timestamp, - crate_directory.join(directory_name), - Some(lock))); + deletion_candidates.push(( + timestamp, + crate_directory.join(directory_name), + Some(lock), + )); } Err(_) => { - debug!("garbage_collect_session_directories() - \ - not collecting, still in use"); + debug!( + "garbage_collect_session_directories() - \ + not collecting, still in use" + ); } } } else if is_old_enough_to_be_collected(timestamp) { @@ -791,58 +825,67 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { // means that the owning process is still alive and we // leave this directory alone. let lock_file_path = crate_directory.join(lock_file_name); - match flock::Lock::new(&lock_file_path, - false, // don't wait - false, // don't create the lock-file - true) { // get an exclusive lock + match flock::Lock::new( + &lock_file_path, + false, // don't wait + false, // don't create the lock-file + true, + ) { + // get an exclusive lock Ok(lock) => { - debug!("garbage_collect_session_directories() - \ - successfully acquired lock"); + debug!( + "garbage_collect_session_directories() - \ + successfully acquired lock" + ); // Note that we are holding on to the lock - definitely_delete.push((crate_directory.join(directory_name), - Some(lock))); + definitely_delete.push((crate_directory.join(directory_name), Some(lock))); } Err(_) => { - debug!("garbage_collect_session_directories() - \ - not collecting, still in use"); + debug!( + "garbage_collect_session_directories() - \ + not collecting, still in use" + ); } } } else { - debug!("garbage_collect_session_directories() - not finalized, not \ - old enough"); + debug!( + "garbage_collect_session_directories() - not finalized, not \ + old enough" + ); } } // Delete all but the most recent of the candidates for (path, lock) in all_except_most_recent(deletion_candidates) { - debug!("garbage_collect_session_directories() - deleting `{}`", - path.display()); + debug!("garbage_collect_session_directories() - deleting `{}`", path.display()); if let Err(err) = safe_remove_dir_all(&path) { - sess.warn(&format!("Failed to garbage collect finalized incremental \ + sess.warn(&format!( + "Failed to garbage collect finalized incremental \ compilation session directory `{}`: {}", - path.display(), - err)); + path.display(), + err + )); } else { delete_session_dir_lock_file(sess, &lock_file_path(&path)); } - // Let's make it explicit that the file lock is released at this point, // or rather, that we held on to it until here mem::drop(lock); } for (path, lock) in definitely_delete { - debug!("garbage_collect_session_directories() - deleting `{}`", - path.display()); + debug!("garbage_collect_session_directories() - deleting `{}`", path.display()); if let Err(err) = safe_remove_dir_all(&path) { - sess.warn(&format!("Failed to garbage collect incremental \ + sess.warn(&format!( + "Failed to garbage collect incremental \ compilation session directory `{}`: {}", - path.display(), - err)); + path.display(), + err + )); } else { delete_session_dir_lock_file(sess, &lock_file_path(&path)); } @@ -855,17 +898,17 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { Ok(()) } -fn all_except_most_recent(deletion_candidates: Vec<(SystemTime, PathBuf, Option)>) - -> FxHashMap> { - let most_recent = deletion_candidates.iter() - .map(|&(timestamp, ..)| timestamp) - .max(); +fn all_except_most_recent( + deletion_candidates: Vec<(SystemTime, PathBuf, Option)>, +) -> FxHashMap> { + let most_recent = deletion_candidates.iter().map(|&(timestamp, ..)| timestamp).max(); if let Some(most_recent) = most_recent { - deletion_candidates.into_iter() - .filter(|&(timestamp, ..)| timestamp != most_recent) - .map(|(_, path, lock)| (path, lock)) - .collect() + deletion_candidates + .into_iter() + .filter(|&(timestamp, ..)| timestamp != most_recent) + .map(|(_, path, lock)| (path, lock)) + .collect() } else { FxHashMap::default() } diff --git a/src/librustc_incremental/persist/fs/tests.rs b/src/librustc_incremental/persist/fs/tests.rs index 09c2fc1463836..652ef6bcdced2 100644 --- a/src/librustc_incremental/persist/fs/tests.rs +++ b/src/librustc_incremental/persist/fs/tests.rs @@ -2,32 +2,31 @@ use super::*; #[test] fn test_all_except_most_recent() { - assert_eq!(all_except_most_recent( - vec![ + assert_eq!( + all_except_most_recent(vec![ (UNIX_EPOCH + Duration::new(4, 0), PathBuf::from("4"), None), (UNIX_EPOCH + Duration::new(1, 0), PathBuf::from("1"), None), (UNIX_EPOCH + Duration::new(5, 0), PathBuf::from("5"), None), (UNIX_EPOCH + Duration::new(3, 0), PathBuf::from("3"), None), (UNIX_EPOCH + Duration::new(2, 0), PathBuf::from("2"), None), - ]).keys().cloned().collect::>(), - vec![ - PathBuf::from("1"), - PathBuf::from("2"), - PathBuf::from("3"), - PathBuf::from("4"), - ].into_iter().collect::>() + ]) + .keys() + .cloned() + .collect::>(), + vec![PathBuf::from("1"), PathBuf::from("2"), PathBuf::from("3"), PathBuf::from("4"),] + .into_iter() + .collect::>() ); - assert_eq!(all_except_most_recent( - vec![ - ]).keys().cloned().collect::>(), + assert_eq!( + all_except_most_recent(vec![]).keys().cloned().collect::>(), FxHashSet::default() ); } #[test] fn test_timestamp_serialization() { - for i in 0 .. 1_000u64 { + for i in 0..1_000u64 { let time = UNIX_EPOCH + Duration::new(i * 1_434_578, (i as u32) * 239_000); let s = timestamp_to_string(time); assert_eq!(Ok(time), string_to_timestamp(&s)); @@ -39,27 +38,47 @@ fn test_find_source_directory_in_iter() { let already_visited = FxHashSet::default(); // Find newest - assert_eq!(find_source_directory_in_iter( - vec![PathBuf::from("crate-dir/s-3234-0000-svh"), - PathBuf::from("crate-dir/s-2234-0000-svh"), - PathBuf::from("crate-dir/s-1234-0000-svh")].into_iter(), &already_visited), - Some(PathBuf::from("crate-dir/s-3234-0000-svh"))); + assert_eq!( + find_source_directory_in_iter( + vec![ + PathBuf::from("crate-dir/s-3234-0000-svh"), + PathBuf::from("crate-dir/s-2234-0000-svh"), + PathBuf::from("crate-dir/s-1234-0000-svh") + ] + .into_iter(), + &already_visited + ), + Some(PathBuf::from("crate-dir/s-3234-0000-svh")) + ); // Filter out "-working" - assert_eq!(find_source_directory_in_iter( - vec![PathBuf::from("crate-dir/s-3234-0000-working"), - PathBuf::from("crate-dir/s-2234-0000-svh"), - PathBuf::from("crate-dir/s-1234-0000-svh")].into_iter(), &already_visited), - Some(PathBuf::from("crate-dir/s-2234-0000-svh"))); + assert_eq!( + find_source_directory_in_iter( + vec![ + PathBuf::from("crate-dir/s-3234-0000-working"), + PathBuf::from("crate-dir/s-2234-0000-svh"), + PathBuf::from("crate-dir/s-1234-0000-svh") + ] + .into_iter(), + &already_visited + ), + Some(PathBuf::from("crate-dir/s-2234-0000-svh")) + ); // Handle empty - assert_eq!(find_source_directory_in_iter(vec![].into_iter(), &already_visited), - None); + assert_eq!(find_source_directory_in_iter(vec![].into_iter(), &already_visited), None); // Handle only working - assert_eq!(find_source_directory_in_iter( - vec![PathBuf::from("crate-dir/s-3234-0000-working"), - PathBuf::from("crate-dir/s-2234-0000-working"), - PathBuf::from("crate-dir/s-1234-0000-working")].into_iter(), &already_visited), - None); + assert_eq!( + find_source_directory_in_iter( + vec![ + PathBuf::from("crate-dir/s-3234-0000-working"), + PathBuf::from("crate-dir/s-2234-0000-working"), + PathBuf::from("crate-dir/s-1234-0000-working") + ] + .into_iter(), + &already_visited + ), + None + ); } diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs index 673da52c3250e..770137863bda1 100644 --- a/src/librustc_incremental/persist/load.rs +++ b/src/librustc_incremental/persist/load.rs @@ -1,23 +1,23 @@ //! Code to save/load the dep-graph from files. -use rustc_data_structures::fx::FxHashMap; use rustc::dep_graph::{PreviousDepGraph, SerializedDepGraph, WorkProduct, WorkProductId}; use rustc::session::Session; -use rustc::ty::TyCtxt; use rustc::ty::query::OnDiskCache; +use rustc::ty::TyCtxt; use rustc::util::common::time_ext; -use rustc_serialize::Decodable as RustcDecodable; +use rustc_data_structures::fx::FxHashMap; use rustc_serialize::opaque::Decoder; +use rustc_serialize::Decodable as RustcDecodable; use std::path::Path; use super::data::*; -use super::fs::*; use super::file_format; +use super::fs::*; use super::work_product; pub fn dep_graph_tcx_init(tcx: TyCtxt<'_>) { if !tcx.dep_graph.is_fully_enabled() { - return + return; } tcx.allocate_metadata_dep_nodes(); @@ -37,42 +37,38 @@ impl LoadResult<(PreviousDepGraph, WorkProductMap)> { LoadResult::Error { message } => { sess.warn(&message); Default::default() - }, + } LoadResult::DataOutOfDate => { if let Err(err) = delete_all_session_dir_contents(sess) { - sess.err(&format!("Failed to delete invalidated or incompatible \ + sess.err(&format!( + "Failed to delete invalidated or incompatible \ incremental compilation session directory contents `{}`: {}.", - dep_graph_path(sess).display(), err)); + dep_graph_path(sess).display(), + err + )); } Default::default() } - LoadResult::Ok { data } => data + LoadResult::Ok { data } => data, } } } - fn load_data(report_incremental_info: bool, path: &Path) -> LoadResult<(Vec, usize)> { match file_format::read_file(report_incremental_info, path) { - Ok(Some(data_and_pos)) => LoadResult::Ok { - data: data_and_pos - }, + Ok(Some(data_and_pos)) => LoadResult::Ok { data: data_and_pos }, Ok(None) => { // The file either didn't exist or was produced by an incompatible // compiler version. Neither is an error. LoadResult::DataOutOfDate } - Err(err) => { - LoadResult::Error { - message: format!("could not load dep-graph from `{}`: {}", - path.display(), err) - } - } + Err(err) => LoadResult::Error { + message: format!("could not load dep-graph from `{}`: {}", path.display(), err), + }, } } -fn delete_dirty_work_product(sess: &Session, - swp: SerializedWorkProduct) { +fn delete_dirty_work_product(sess: &Session, swp: SerializedWorkProduct) { debug!("delete_dirty_work_product({:?})", swp); work_product::delete_workproduct_files(sess, &swp.work_product); } @@ -82,13 +78,13 @@ fn delete_dirty_work_product(sess: &Session, /// by a background thread. pub enum MaybeAsync { Sync(T), - Async(std::thread::JoinHandle) + Async(std::thread::JoinHandle), } impl MaybeAsync { pub fn open(self) -> std::thread::Result { match self { MaybeAsync::Sync(result) => Ok(result), - MaybeAsync::Async(handle) => handle.join() + MaybeAsync::Async(handle) => handle.join(), } } } @@ -105,9 +101,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { if sess.opts.incremental.is_none() { // No incremental compilation. - return MaybeAsync::Sync(LoadResult::Ok { - data: Default::default(), - }); + return MaybeAsync::Sync(LoadResult::Ok { data: Default::default() }); } // Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`. @@ -130,8 +124,11 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { let mut work_product_decoder = Decoder::new(&work_products_data[..], start_pos); let work_products: Vec = RustcDecodable::decode(&mut work_product_decoder).unwrap_or_else(|e| { - let msg = format!("Error decoding `work-products` from incremental \ - compilation session directory: {}", e); + let msg = format!( + "Error decoding `work-products` from incremental \ + compilation session directory: {}", + e + ); sess.fatal(&msg[..]) }); @@ -143,8 +140,11 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { all_files_exist = false; if sess.opts.debugging_opts.incremental_info { - eprintln!("incremental: could not find file for work \ - product: {}", path.display()); + eprintln!( + "incremental: could not find file for work \ + product: {}", + path.display() + ); } } } @@ -168,15 +168,16 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { LoadResult::DataOutOfDate => LoadResult::DataOutOfDate, LoadResult::Error { message } => LoadResult::Error { message }, LoadResult::Ok { data: (bytes, start_pos) } => { - let mut decoder = Decoder::new(&bytes, start_pos); let prev_commandline_args_hash = u64::decode(&mut decoder) .expect("Error reading commandline arg hash from cached dep-graph"); if prev_commandline_args_hash != expected_hash { if report_incremental_info { - println!("[incremental] completely ignoring cache because of \ - differing commandline arguments"); + println!( + "[incremental] completely ignoring cache because of \ + differing commandline arguments" + ); } // We can't reuse the cache, purge it. debug!("load_dep_graph_new: differing commandline arg hashes"); @@ -196,15 +197,14 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { } pub fn load_query_result_cache(sess: &Session) -> OnDiskCache<'_> { - if sess.opts.incremental.is_none() || - !sess.opts.debugging_opts.incremental_queries { + if sess.opts.incremental.is_none() || !sess.opts.debugging_opts.incremental_queries { return OnDiskCache::new_empty(sess.source_map()); } let _prof_timer = sess.prof.generic_activity("incr_comp_load_query_result_cache"); match load_data(sess.opts.debugging_opts.incremental_info, &query_cache_path(sess)) { - LoadResult::Ok{ data: (bytes, start_pos) } => OnDiskCache::new(sess, bytes, start_pos), - _ => OnDiskCache::new_empty(sess.source_map()) + LoadResult::Ok { data: (bytes, start_pos) } => OnDiskCache::new(sess, bytes, start_pos), + _ => OnDiskCache::new_empty(sess.source_map()), } } diff --git a/src/librustc_incremental/persist/mod.rs b/src/librustc_incremental/persist/mod.rs index bf404140f18d5..6a03a01430b0f 100644 --- a/src/librustc_incremental/persist/mod.rs +++ b/src/librustc_incremental/persist/mod.rs @@ -4,11 +4,11 @@ mod data; mod dirty_clean; +mod file_format; mod fs; mod load; mod save; mod work_product; -mod file_format; pub use fs::finalize_session_directory; pub use fs::garbage_collect_session_directories; @@ -16,9 +16,9 @@ pub use fs::in_incr_comp_dir; pub use fs::in_incr_comp_dir_sess; pub use fs::prepare_session_directory; pub use load::dep_graph_tcx_init; -pub use load::{DepGraphFuture, load_dep_graph}; pub use load::load_query_result_cache; pub use load::LoadResult; +pub use load::{load_dep_graph, DepGraphFuture}; pub use save::save_dep_graph; pub use save::save_work_product_index; pub use work_product::copy_cgu_workproducts_to_incr_comp_cache_dir; diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index ecc66e60175f0..3abda32b3ea9b 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -4,15 +4,15 @@ use rustc::ty::TyCtxt; use rustc::util::common::time; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::join; -use rustc_serialize::Encodable as RustcEncodable; use rustc_serialize::opaque::Encoder; +use rustc_serialize::Encodable as RustcEncodable; use std::fs; use std::path::PathBuf; use super::data::*; -use super::fs::*; use super::dirty_clean; use super::file_format; +use super::fs::*; use super::work_product; pub fn save_dep_graph(tcx: TyCtxt<'_>) { @@ -30,43 +30,42 @@ pub fn save_dep_graph(tcx: TyCtxt<'_>) { let query_cache_path = query_cache_path(sess); let dep_graph_path = dep_graph_path(sess); - join(move || { - if tcx.sess.opts.debugging_opts.incremental_queries { - let _timer = tcx.prof.generic_activity("incr_comp_persist_result_cache"); - - time(sess, "persist query result cache", || { - save_in(sess, - query_cache_path, - |e| encode_query_cache(tcx, e)); + join( + move || { + if tcx.sess.opts.debugging_opts.incremental_queries { + let _timer = tcx.prof.generic_activity("incr_comp_persist_result_cache"); + + time(sess, "persist query result cache", || { + save_in(sess, query_cache_path, |e| encode_query_cache(tcx, e)); + }); + } + }, + || { + time(sess, "persist dep-graph", || { + let _timer = tcx.prof.generic_activity("incr_comp_persist_dep_graph"); + + save_in(sess, dep_graph_path, |e| { + time(sess, "encode dep-graph", || encode_dep_graph(tcx, e)) + }); }); - } - }, || { - time(sess, "persist dep-graph", || { - let _timer = tcx.prof.generic_activity("incr_comp_persist_dep_graph"); - - save_in(sess, - dep_graph_path, - |e| { - time(sess, "encode dep-graph", || { - encode_dep_graph(tcx, e) - }) - }); - }); - }); + }, + ); dirty_clean::check_dirty_clean_annotations(tcx); }) } -pub fn save_work_product_index(sess: &Session, - dep_graph: &DepGraph, - new_work_products: FxHashMap) { +pub fn save_work_product_index( + sess: &Session, + dep_graph: &DepGraph, + new_work_products: FxHashMap, +) { if sess.opts.incremental.is_none() { return; } // This is going to be deleted in finalize_session_directory, so let's not create it if sess.has_errors_or_delayed_span_bugs() { - return; + return; } debug!("save_work_product_index()"); @@ -81,25 +80,27 @@ pub fn save_work_product_index(sess: &Session, for (id, wp) in previous_work_products.iter() { if !new_work_products.contains_key(id) { work_product::delete_workproduct_files(sess, wp); - debug_assert!(wp.saved_files.iter().all(|&(_, ref file_name)| { - !in_incr_comp_dir_sess(sess, file_name).exists() - })); + debug_assert!( + wp.saved_files.iter().all(|&(_, ref file_name)| { + !in_incr_comp_dir_sess(sess, file_name).exists() + }) + ); } } // Check that we did not delete one of the current work-products: debug_assert!({ - new_work_products.iter() - .flat_map(|(_, wp)| wp.saved_files - .iter() - .map(|&(_, ref name)| name)) - .map(|name| in_incr_comp_dir_sess(sess, name)) - .all(|path| path.exists()) + new_work_products + .iter() + .flat_map(|(_, wp)| wp.saved_files.iter().map(|&(_, ref name)| name)) + .map(|name| in_incr_comp_dir_sess(sess, name)) + .all(|path| path.exists()) }); } fn save_in(sess: &Session, path_buf: PathBuf, encode: F) - where F: FnOnce(&mut Encoder) +where + F: FnOnce(&mut Encoder), { debug!("save: storing data in {}", path_buf.display()); @@ -113,9 +114,11 @@ fn save_in(sess: &Session, path_buf: PathBuf, encode: F) debug!("save: remove old file"); } Err(err) => { - sess.err(&format!("unable to delete old dep-graph at `{}`: {}", - path_buf.display(), - err)); + sess.err(&format!( + "unable to delete old dep-graph at `{}`: {}", + path_buf.display(), + err + )); return; } } @@ -133,9 +136,7 @@ fn save_in(sess: &Session, path_buf: PathBuf, encode: F) debug!("save: data written to disk successfully"); } Err(err) => { - sess.err(&format!("failed to write dep-graph to `{}`: {}", - path_buf.display(), - err)); + sess.err(&format!("failed to write dep-graph to `{}`: {}", path_buf.display(), err)); return; } } @@ -179,13 +180,13 @@ fn encode_dep_graph(tcx: TyCtxt<'_>, encoder: &mut Encoder) { let mut counts: Vec<_> = counts.values().cloned().collect(); counts.sort_by_key(|s| -(s.node_counter as i64)); - let percentage_of_all_nodes: Vec = counts.iter().map(|s| { - (100.0 * (s.node_counter as f64)) / (total_node_count as f64) - }).collect(); + let percentage_of_all_nodes: Vec = counts + .iter() + .map(|s| (100.0 * (s.node_counter as f64)) / (total_node_count as f64)) + .collect(); - let average_edges_per_kind: Vec = counts.iter().map(|s| { - (s.edge_counter as f64) / (s.node_counter as f64) - }).collect(); + let average_edges_per_kind: Vec = + counts.iter().map(|s| (s.edge_counter as f64) / (s.node_counter as f64)).collect(); println!("[incremental]"); println!("[incremental] DepGraph Statistics"); @@ -198,28 +199,32 @@ fn encode_dep_graph(tcx: TyCtxt<'_>, encoder: &mut Encoder) { println!("[incremental]"); println!("[incremental] Total Node Count: {}", total_node_count); println!("[incremental] Total Edge Count: {}", total_edge_count); - if let Some((total_edge_reads, - total_duplicate_edge_reads)) = tcx.dep_graph.edge_deduplication_data() { + if let Some((total_edge_reads, total_duplicate_edge_reads)) = + tcx.dep_graph.edge_deduplication_data() + { println!("[incremental] Total Edge Reads: {}", total_edge_reads); println!("[incremental] Total Duplicate Edge Reads: {}", total_duplicate_edge_reads); } println!("[incremental]"); - println!("[incremental] {:<36}| {:<17}| {:<12}| {:<17}|", - "Node Kind", - "Node Frequency", - "Node Count", - "Avg. Edge Count"); - println!("[incremental] -------------------------------------\ + println!( + "[incremental] {:<36}| {:<17}| {:<12}| {:<17}|", + "Node Kind", "Node Frequency", "Node Count", "Avg. Edge Count" + ); + println!( + "[incremental] -------------------------------------\ |------------------\ |-------------\ - |------------------|"); + |------------------|" + ); for (i, stat) in counts.iter().enumerate() { - println!("[incremental] {:<36}|{:>16.1}% |{:>12} |{:>17.1} |", + println!( + "[incremental] {:<36}|{:>16.1}% |{:>12} |{:>17.1} |", format!("{:?}", stat.kind), percentage_of_all_nodes[i], stat.node_counter, - average_edges_per_kind[i]); + average_edges_per_kind[i] + ); } println!("{}", SEPARATOR); @@ -232,15 +237,15 @@ fn encode_dep_graph(tcx: TyCtxt<'_>, encoder: &mut Encoder) { }); } -fn encode_work_product_index(work_products: &FxHashMap, - encoder: &mut Encoder) { +fn encode_work_product_index( + work_products: &FxHashMap, + encoder: &mut Encoder, +) { let serialized_products: Vec<_> = work_products .iter() - .map(|(id, work_product)| { - SerializedWorkProduct { - id: id.clone(), - work_product: work_product.clone(), - } + .map(|(id, work_product)| SerializedWorkProduct { + id: id.clone(), + work_product: work_product.clone(), }) .collect(); diff --git a/src/librustc_incremental/persist/work_product.rs b/src/librustc_incremental/persist/work_product.rs index 3495b27c5ebca..65a742a202ddd 100644 --- a/src/librustc_incremental/persist/work_product.rs +++ b/src/librustc_incremental/persist/work_product.rs @@ -1,52 +1,49 @@ //! This module contains files for saving intermediate work-products. use crate::persist::fs::*; -use rustc::dep_graph::{WorkProduct, WorkProductId, WorkProductFileKind}; +use rustc::dep_graph::{WorkProduct, WorkProductFileKind, WorkProductId}; use rustc::session::Session; use rustc_fs_util::link_or_copy; -use std::path::PathBuf; use std::fs as std_fs; +use std::path::PathBuf; pub fn copy_cgu_workproducts_to_incr_comp_cache_dir( sess: &Session, cgu_name: &str, - files: &[(WorkProductFileKind, PathBuf)] + files: &[(WorkProductFileKind, PathBuf)], ) -> Option<(WorkProductId, WorkProduct)> { - debug!("copy_cgu_workproducts_to_incr_comp_cache_dir({:?},{:?})", - cgu_name, - files); + debug!("copy_cgu_workproducts_to_incr_comp_cache_dir({:?},{:?})", cgu_name, files); if sess.opts.incremental.is_none() { - return None + return None; } - let saved_files = - files.iter() - .map(|&(kind, ref path)| { - let extension = match kind { - WorkProductFileKind::Object => "o", - WorkProductFileKind::Bytecode => "bc", - WorkProductFileKind::BytecodeCompressed => "bc.z", - }; - let file_name = format!("{}.{}", cgu_name, extension); - let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name); - match link_or_copy(path, &path_in_incr_dir) { - Ok(_) => Some((kind, file_name)), - Err(err) => { - sess.warn(&format!("error copying object file `{}` \ + let saved_files = files + .iter() + .map(|&(kind, ref path)| { + let extension = match kind { + WorkProductFileKind::Object => "o", + WorkProductFileKind::Bytecode => "bc", + WorkProductFileKind::BytecodeCompressed => "bc.z", + }; + let file_name = format!("{}.{}", cgu_name, extension); + let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name); + match link_or_copy(path, &path_in_incr_dir) { + Ok(_) => Some((kind, file_name)), + Err(err) => { + sess.warn(&format!( + "error copying object file `{}` \ to incremental directory as `{}`: {}", - path.display(), - path_in_incr_dir.display(), - err)); - None - } - } - }) - .collect::>>()?; + path.display(), + path_in_incr_dir.display(), + err + )); + None + } + } + }) + .collect::>>()?; - let work_product = WorkProduct { - cgu_name: cgu_name.to_string(), - saved_files, - }; + let work_product = WorkProduct { cgu_name: cgu_name.to_string(), saved_files }; let work_product_id = WorkProductId::from_cgu_name(cgu_name); Some((work_product_id, work_product)) @@ -56,11 +53,13 @@ pub fn delete_workproduct_files(sess: &Session, work_product: &WorkProduct) { for &(_, ref file_name) in &work_product.saved_files { let path = in_incr_comp_dir_sess(sess, file_name); match std_fs::remove_file(&path) { - Ok(()) => { } + Ok(()) => {} Err(err) => { - sess.warn( - &format!("file-system error deleting outdated file `{}`: {}", - path.display(), err)); + sess.warn(&format!( + "file-system error deleting outdated file `{}`: {}", + path.display(), + err + )); } } } diff --git a/src/librustc_index/bit_set.rs b/src/librustc_index/bit_set.rs index 9ed5ef5a539a1..2a1a56076728e 100644 --- a/src/librustc_index/bit_set.rs +++ b/src/librustc_index/bit_set.rs @@ -37,22 +37,14 @@ impl BitSet { #[inline] pub fn new_empty(domain_size: usize) -> BitSet { let num_words = num_words(domain_size); - BitSet { - domain_size, - words: vec![0; num_words], - marker: PhantomData, - } + BitSet { domain_size, words: vec![0; num_words], marker: PhantomData } } /// Creates a new, filled bitset with a given `domain_size`. #[inline] pub fn new_filled(domain_size: usize) -> BitSet { let num_words = num_words(domain_size); - let mut result = BitSet { - domain_size, - words: vec![!0; num_words], - marker: PhantomData, - }; + let mut result = BitSet { domain_size, words: vec![!0; num_words], marker: PhantomData }; result.clear_excess_bits(); result } @@ -160,7 +152,7 @@ impl BitSet { /// (i.e., if any bits were removed). pub fn intersect(&mut self, other: &BitSet) -> bool { assert_eq!(self.domain_size, other.domain_size); - bitwise(&mut self.words, &other.words, |a, b| { a & b }) + bitwise(&mut self.words, &other.words, |a, b| a & b) } /// Gets a slice of the underlying words. @@ -200,7 +192,7 @@ impl BitSet { // Were there any bits in the old word that did not occur in the sparse set? not_already |= (self.words[current_index] ^ new_bit_mask) != 0; // Check all words we skipped for any set bit. - not_already |= self.words[current_index+1..word_index].iter().any(|&x| x != 0); + not_already |= self.words[current_index + 1..word_index].iter().any(|&x| x != 0); // Update next word. current_index = word_index; // Reset bit mask, no bits have been merged yet. @@ -214,7 +206,7 @@ impl BitSet { // Any bits in the last inspected word that were not in the sparse set? not_already |= (self.words[current_index] ^ new_bit_mask) != 0; // Any bits in the tail? Note `clear_excess_bits` before. - not_already |= self.words[current_index+1..].iter().any(|&x| x != 0); + not_already |= self.words[current_index + 1..].iter().any(|&x| x != 0); not_already } @@ -237,22 +229,20 @@ pub trait SubtractFromBitSet { impl UnionIntoBitSet for BitSet { fn union_into(&self, other: &mut BitSet) -> bool { assert_eq!(self.domain_size, other.domain_size); - bitwise(&mut other.words, &self.words, |a, b| { a | b }) + bitwise(&mut other.words, &self.words, |a, b| a | b) } } impl SubtractFromBitSet for BitSet { fn subtract_from(&self, other: &mut BitSet) -> bool { assert_eq!(self.domain_size, other.domain_size); - bitwise(&mut other.words, &self.words, |a, b| { a & !b }) + bitwise(&mut other.words, &self.words, |a, b| a & !b) } } impl fmt::Debug for BitSet { fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { - w.debug_list() - .entries(self.iter()) - .finish() + w.debug_list().entries(self.iter()).finish() } } @@ -267,7 +257,8 @@ impl ToString for BitSet { let mut i = 0; for word in &self.words { let mut word = *word; - for _ in 0..WORD_BYTES { // for each byte in `word`: + for _ in 0..WORD_BYTES { + // for each byte in `word`: let remain = self.domain_size - i; // If less than a byte remains, then mask just that many bits. let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF }; @@ -276,7 +267,9 @@ impl ToString for BitSet { result.push_str(&format!("{}{:02x}", sep, byte)); - if remain <= 8 { break; } + if remain <= 8 { + break; + } word >>= 8; i += 8; sep = '-'; @@ -301,7 +294,7 @@ pub struct BitIter<'a, T: Idx> { /// Underlying iterator over the words. iter: slice::Iter<'a, Word>, - marker: PhantomData + marker: PhantomData, } impl<'a, T: Idx> BitIter<'a, T> { @@ -331,7 +324,7 @@ impl<'a, T: Idx> Iterator for BitIter<'a, T> { let bit_pos = self.word.trailing_zeros() as usize; let bit = 1 << bit_pos; self.word ^= bit; - return Some(T::new(bit_pos + self.offset)) + return Some(T::new(bit_pos + self.offset)); } // Move onto the next word. `wrapping_add()` is needed to handle @@ -345,7 +338,8 @@ impl<'a, T: Idx> Iterator for BitIter<'a, T> { #[inline] fn bitwise(out_vec: &mut [Word], in_vec: &[Word], op: Op) -> bool - where Op: Fn(Word, Word) -> Word +where + Op: Fn(Word, Word) -> Word, { assert_eq!(out_vec.len(), in_vec.len()); let mut changed = false; @@ -374,10 +368,7 @@ pub struct SparseBitSet { impl SparseBitSet { fn new_empty(domain_size: usize) -> Self { - SparseBitSet { - domain_size, - elems: SmallVec::new() - } + SparseBitSet { domain_size, elems: SmallVec::new() } } fn len(&self) -> usize { @@ -698,11 +689,7 @@ impl GrowableBitSet { #[inline] pub fn contains(&self, elem: T) -> bool { let (word_index, mask) = word_index_and_mask(elem); - if let Some(word) = self.bit_set.words.get(word_index) { - (word & mask) != 0 - } else { - false - } + if let Some(word) = self.bit_set.words.get(word_index) { (word & mask) != 0 } else { false } } } @@ -913,10 +900,7 @@ where impl SparseBitMatrix { /// Creates a new empty sparse bit matrix with no rows or columns. pub fn new(num_columns: usize) -> Self { - Self { - num_columns, - rows: IndexVec::new(), - } + Self { num_columns, rows: IndexVec::new() } } fn ensure_row(&mut self, row: R) -> &mut HybridBitSet { @@ -986,11 +970,7 @@ impl SparseBitMatrix { } pub fn row(&self, row: R) -> Option<&HybridBitSet> { - if let Some(Some(row)) = self.rows.get(row) { - Some(row) - } else { - None - } + if let Some(Some(row)) = self.rows.get(row) { Some(row) } else { None } } } diff --git a/src/librustc_index/bit_set/tests.rs b/src/librustc_index/bit_set/tests.rs index ac7913815ffd4..6cc3e9427d1a7 100644 --- a/src/librustc_index/bit_set/tests.rs +++ b/src/librustc_index/bit_set/tests.rs @@ -25,10 +25,7 @@ fn bitset_iter_works() { bitset.insert(65); bitset.insert(66); bitset.insert(99); - assert_eq!( - bitset.iter().collect::>(), - [1, 10, 19, 62, 63, 64, 65, 66, 99] - ); + assert_eq!(bitset.iter().collect::>(), [1, 10, 19, 62, 63, 64, 65, 66, 99]); } #[test] @@ -100,14 +97,14 @@ fn hybrid_bitset() { assert!(dense256.contains(i)); } - assert!(sparse038.superset(&sparse038)); // sparse + sparse (self) - assert!(sparse01358.superset(&sparse038)); // sparse + sparse - assert!(dense10.superset(&sparse038)); // dense + sparse - assert!(dense10.superset(&dense10)); // dense + dense (self) - assert!(dense256.superset(&dense10)); // dense + dense + assert!(sparse038.superset(&sparse038)); // sparse + sparse (self) + assert!(sparse01358.superset(&sparse038)); // sparse + sparse + assert!(dense10.superset(&sparse038)); // dense + sparse + assert!(dense10.superset(&dense10)); // dense + dense (self) + assert!(dense256.superset(&dense10)); // dense + dense let mut hybrid = sparse038; - assert!(!sparse01358.union(&hybrid)); // no change + assert!(!sparse01358.union(&hybrid)); // no change assert!(hybrid.union(&sparse01358)); assert!(hybrid.superset(&sparse01358) && sparse01358.superset(&hybrid)); assert!(!dense10.union(&sparse01358)); @@ -320,13 +317,13 @@ fn union_hybrid_sparse_full_to_dense(b: &mut Bencher) { /// Merge dense hybrid set into full hybrid set with indices over the whole domain. #[bench] fn union_hybrid_sparse_domain_to_dense(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX*64); + let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX * 64); for i in 0..10 { assert!(pre_dense.insert(i)); } - let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX*64); + let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX * 64); for i in 0..SPARSE_MAX { - assert!(pre_sparse.insert(i*64)); + assert!(pre_sparse.insert(i * 64)); } b.iter(|| { let dense = pre_dense.clone(); diff --git a/src/librustc_index/lib.rs b/src/librustc_index/lib.rs index ad242dfd2e0c1..86dd1a29d0ce3 100644 --- a/src/librustc_index/lib.rs +++ b/src/librustc_index/lib.rs @@ -3,5 +3,5 @@ #![feature(test)] #![feature(fn_traits)] -pub mod vec; pub mod bit_set; +pub mod vec; diff --git a/src/librustc_index/vec.rs b/src/librustc_index/vec.rs index 6e80b48a68560..1f6a330cdc235 100644 --- a/src/librustc_index/vec.rs +++ b/src/librustc_index/vec.rs @@ -1,14 +1,14 @@ -use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; +use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; +use std::fmt; use std::fmt::Debug; +use std::hash::Hash; use std::iter::{self, FromIterator}; -use std::slice; use std::marker::PhantomData; use std::ops::{Index, IndexMut, Range, RangeBounds}; -use std::fmt; -use std::hash::Hash; -use std::vec; +use std::slice; use std::u32; +use std::vec; /// Represents some newtyped `usize` wrapper. /// @@ -29,16 +29,25 @@ pub trait Idx: Copy + 'static + Ord + Debug + Hash { impl Idx for usize { #[inline] - fn new(idx: usize) -> Self { idx } + fn new(idx: usize) -> Self { + idx + } #[inline] - fn index(self) -> usize { self } + fn index(self) -> usize { + self + } } impl Idx for u32 { #[inline] - fn new(idx: usize) -> Self { assert!(idx <= u32::MAX as usize); idx as u32 } + fn new(idx: usize) -> Self { + assert!(idx <= u32::MAX as usize); + idx as u32 + } #[inline] - fn index(self) -> usize { self as usize } + fn index(self) -> usize { + self as usize + } } /// Creates a struct type `S` that can be used as an index with @@ -506,7 +515,7 @@ macro_rules! newtype_index { #[derive(Clone, PartialEq, Eq, Hash)] pub struct IndexVec { pub raw: Vec, - _marker: PhantomData + _marker: PhantomData, } // Whether `IndexVec` is `Send` depends only on the data, @@ -521,9 +530,7 @@ impl Encodable for IndexVec { impl Decodable for IndexVec { fn decode(d: &mut D) -> Result { - Decodable::decode(d).map(|v| { - IndexVec { raw: v, _marker: PhantomData } - }) + Decodable::decode(d).map(|v| IndexVec { raw: v, _marker: PhantomData }) } } @@ -553,14 +560,16 @@ impl IndexVec { #[inline] pub fn from_elem(elem: T, universe: &IndexVec) -> Self - where T: Clone + where + T: Clone, { IndexVec { raw: vec![elem; universe.len()], _marker: PhantomData } } #[inline] pub fn from_elem_n(elem: T, n: usize) -> Self - where T: Clone + where + T: Clone, { IndexVec { raw: vec![elem; n], _marker: PhantomData } } @@ -600,8 +609,7 @@ impl IndexVec { } #[inline] - pub fn into_iter_enumerated(self) -> Enumerated> - { + pub fn into_iter_enumerated(self) -> Enumerated> { self.raw.into_iter().enumerate().map(IntoIdx { _marker: PhantomData }) } @@ -611,8 +619,7 @@ impl IndexVec { } #[inline] - pub fn iter_enumerated(&self) -> Enumerated> - { + pub fn iter_enumerated(&self) -> Enumerated> { self.raw.iter().enumerate().map(IntoIdx { _marker: PhantomData }) } @@ -627,20 +634,23 @@ impl IndexVec { } #[inline] - pub fn iter_enumerated_mut(&mut self) -> Enumerated> - { + pub fn iter_enumerated_mut(&mut self) -> Enumerated> { self.raw.iter_mut().enumerate().map(IntoIdx { _marker: PhantomData }) } #[inline] pub fn drain<'a, R: RangeBounds>( - &'a mut self, range: R) -> impl Iterator + 'a { + &'a mut self, + range: R, + ) -> impl Iterator + 'a { self.raw.drain(range) } #[inline] pub fn drain_enumerated<'a, R: RangeBounds>( - &'a mut self, range: R) -> impl Iterator + 'a { + &'a mut self, + range: R, + ) -> impl Iterator + 'a { self.raw.drain(range).enumerate().map(IntoIdx { _marker: PhantomData }) } @@ -690,10 +700,7 @@ impl IndexVec { } pub fn convert_index_type(self) -> IndexVec { - IndexVec { - raw: self.raw, - _marker: PhantomData, - } + IndexVec { raw: self.raw, _marker: PhantomData } } } @@ -764,7 +771,10 @@ impl Extend for IndexVec { impl FromIterator for IndexVec { #[inline] - fn from_iter(iter: J) -> Self where J: IntoIterator { + fn from_iter(iter: J) -> Self + where + J: IntoIterator, + { IndexVec { raw: FromIterator::from_iter(iter), _marker: PhantomData } } } @@ -777,7 +787,6 @@ impl IntoIterator for IndexVec { fn into_iter(self) -> vec::IntoIter { self.raw.into_iter() } - } impl<'a, I: Idx, T> IntoIterator for &'a IndexVec { @@ -800,7 +809,9 @@ impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec { } } -pub struct IntoIdx { _marker: PhantomData } +pub struct IntoIdx { + _marker: PhantomData, +} impl FnOnce<((usize, T),)> for IntoIdx { type Output = (I, T); diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 2365fc3ee2e4d..62dd2db709965 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -1,25 +1,25 @@ -use crate::util; pub use crate::passes::BoxedResolver; +use crate::util; use rustc::lint; +use rustc::session::config::{self, ErrorOutputType, Input}; use rustc::session::early_error; -use rustc::session::config::{self, Input, ErrorOutputType}; use rustc::session::{DiagnosticOutput, Session}; +use rustc::ty; use rustc::util::common::ErrorReported; use rustc_codegen_utils::codegen_backend::CodegenBackend; -use rustc_data_structures::OnDrop; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; -use rustc_data_structures::fx::{FxHashSet, FxHashMap}; +use rustc_data_structures::OnDrop; use rustc_errors::registry::Registry; use rustc_parse::new_parser_from_source_str; -use rustc::ty; use std::path::PathBuf; use std::result; use std::sync::{Arc, Mutex}; use syntax::ast::{self, MetaItemKind}; -use syntax::token; -use syntax::source_map::{FileName, FileLoader, SourceMap}; use syntax::sess::ParseSess; +use syntax::source_map::{FileLoader, FileName, SourceMap}; +use syntax::token; use syntax_pos::edition; pub type Result = result::Result; @@ -65,43 +65,48 @@ impl Compiler { /// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`. pub fn parse_cfgspecs(cfgspecs: Vec) -> FxHashSet<(String, Option)> { syntax::with_default_globals(move || { - let cfg = cfgspecs.into_iter().map(|s| { - let sess = ParseSess::with_silent_emitter(); - let filename = FileName::cfg_spec_source_code(&s); - let mut parser = new_parser_from_source_str(&sess, filename, s.to_string()); - - macro_rules! error {($reason: expr) => { - early_error(ErrorOutputType::default(), - &format!(concat!("invalid `--cfg` argument: `{}` (", $reason, ")"), s)); - }} - - match &mut parser.parse_meta_item() { - Ok(meta_item) if parser.token == token::Eof => { - if meta_item.path.segments.len() != 1 { - error!("argument key must be an identifier"); - } - match &meta_item.kind { - MetaItemKind::List(..) => { - error!(r#"expected `key` or `key="value"`"#); - } - MetaItemKind::NameValue(lit) if !lit.kind.is_str() => { - error!("argument value must be a string"); + let cfg = cfgspecs + .into_iter() + .map(|s| { + let sess = ParseSess::with_silent_emitter(); + let filename = FileName::cfg_spec_source_code(&s); + let mut parser = new_parser_from_source_str(&sess, filename, s.to_string()); + + macro_rules! error { + ($reason: expr) => { + early_error( + ErrorOutputType::default(), + &format!(concat!("invalid `--cfg` argument: `{}` (", $reason, ")"), s), + ); + }; + } + + match &mut parser.parse_meta_item() { + Ok(meta_item) if parser.token == token::Eof => { + if meta_item.path.segments.len() != 1 { + error!("argument key must be an identifier"); } - MetaItemKind::NameValue(..) | MetaItemKind::Word => { - let ident = meta_item.ident().expect("multi-segment cfg key"); - return (ident.name, meta_item.value_str()); + match &meta_item.kind { + MetaItemKind::List(..) => { + error!(r#"expected `key` or `key="value"`"#); + } + MetaItemKind::NameValue(lit) if !lit.kind.is_str() => { + error!("argument value must be a string"); + } + MetaItemKind::NameValue(..) | MetaItemKind::Word => { + let ident = meta_item.ident().expect("multi-segment cfg key"); + return (ident.name, meta_item.value_str()); + } } } + Ok(..) => {} + Err(err) => err.cancel(), } - Ok(..) => {} - Err(err) => err.cancel(), - } - - error!(r#"expected `key` or `key="value"`"#); - }).collect::(); - cfg.into_iter().map(|(a, b)| { - (a.to_string(), b.map(|b| b.to_string())) - }).collect() + + error!(r#"expected `key` or `key="value"`"#); + }) + .collect::(); + cfg.into_iter().map(|(a, b)| (a.to_string(), b.map(|b| b.to_string()))).collect() }) } diff --git a/src/librustc_interface/lib.rs b/src/librustc_interface/lib.rs index 9bb18788171b4..3d79661978811 100644 --- a/src/librustc_interface/lib.rs +++ b/src/librustc_interface/lib.rs @@ -6,17 +6,16 @@ #![feature(generator_trait)] #![feature(generators)] #![cfg_attr(unix, feature(libc))] - -#![recursion_limit="256"] +#![recursion_limit = "256"] #[cfg(unix)] extern crate libc; pub mod interface; mod passes; +mod proc_macro_decls; mod queries; pub mod util; -mod proc_macro_decls; pub use interface::{run_compiler, Config}; pub use queries::Queries; diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index e1c4c86d9d6aa..9d0ec585c203b 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -1,29 +1,29 @@ use crate::interface::{Compiler, Result}; -use crate::util; use crate::proc_macro_decls; +use crate::util; -use log::{info, warn, log_enabled}; +use log::{info, log_enabled, warn}; use rustc::arena::Arena; use rustc::dep_graph::DepGraph; use rustc::hir; -use rustc::hir::lowering::lower_crate; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; +use rustc::hir::lowering::lower_crate; use rustc::lint; -use rustc::middle::{self, reachable, resolve_lifetime, stability}; use rustc::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn}; -use rustc::ty::{self, AllArenas, ResolverOutputs, TyCtxt, GlobalCtxt}; -use rustc::ty::steal::Steal; -use rustc::traits; -use rustc::util::common::{time, ErrorReported}; -use rustc::session::Session; +use rustc::middle::{self, reachable, resolve_lifetime, stability}; use rustc::session::config::{self, CrateType, Input, OutputFilenames, OutputType}; use rustc::session::config::{PpMode, PpSourceMode}; use rustc::session::search_paths::PathKind; +use rustc::session::Session; +use rustc::traits; +use rustc::ty::steal::Steal; +use rustc::ty::{self, AllArenas, GlobalCtxt, ResolverOutputs, TyCtxt}; +use rustc::util::common::{time, ErrorReported}; use rustc_codegen_ssa::back::link::emit_metadata; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_codegen_utils::link::filename_for_metadata; +use rustc_data_structures::sync::{par_iter, Lrc, Once, ParallelIterator, WorkerLocal}; use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel}; -use rustc_data_structures::sync::{Lrc, Once, ParallelIterator, par_iter, WorkerLocal}; use rustc_errors::PResult; use rustc_incremental; use rustc_mir as mir; @@ -34,29 +34,28 @@ use rustc_privacy; use rustc_resolve::{Resolver, ResolverArenas}; use rustc_traits; use rustc_typeck as typeck; -use syntax::{self, ast, visit}; use syntax::early_buffered_lints::BufferedEarlyLint; -use syntax_expand::base::ExtCtxt; use syntax::mut_visit::MutVisitor; -use syntax::util::node_count::NodeCounter; use syntax::symbol::Symbol; -use syntax_pos::FileName; +use syntax::util::node_count::NodeCounter; +use syntax::{self, ast, visit}; +use syntax_expand::base::ExtCtxt; use syntax_ext; +use syntax_pos::FileName; use rustc_serialize::json; use tempfile::Builder as TempFileBuilder; -use std::{env, fs, iter, mem}; use std::any::Any; +use std::cell::RefCell; use std::ffi::OsString; use std::io::{self, Write}; use std::path::PathBuf; -use std::cell::RefCell; use std::rc::Rc; +use std::{env, fs, iter, mem}; pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { - sess.diagnostic() - .set_continue_after_error(sess.opts.debugging_opts.continue_parse_after_error); + sess.diagnostic().set_continue_after_error(sess.opts.debugging_opts.continue_parse_after_error); let krate = time(sess, "parsing", || { let _prof_timer = sess.prof.generic_activity("parse_crate"); @@ -75,10 +74,7 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { } if sess.opts.debugging_opts.input_stats { - println!( - "Lines of code: {}", - sess.source_map().count_lines() - ); + println!("Lines of code: {}", sess.source_map().count_lines()); println!("Pre-expansion node count: {}", count_nodes(&krate)); } @@ -169,7 +165,9 @@ pub fn register_plugins<'a>( ) -> Result<(ast::Crate, Lrc)> { krate = time(sess, "attributes injection", || { syntax_ext::cmdline_attrs::inject( - krate, &sess.parse_sess, &sess.opts.debugging_opts.crate_attr + krate, + &sess.parse_sess, + &sess.opts.debugging_opts.crate_attr, ) }); @@ -213,9 +211,8 @@ pub fn register_plugins<'a>( ); register_lints(&sess, &mut lint_store); - let registrars = time(sess, "plugin loading", || { - plugin::load::load_plugins(sess, metadata_loader, &krate) - }); + let registrars = + time(sess, "plugin loading", || plugin::load::load_plugins(sess, metadata_loader, &krate)); time(sess, "plugin registration", || { let mut registry = plugin::Registry { lint_store: &mut lint_store }; for registrar in registrars { @@ -241,16 +238,11 @@ fn configure_and_expand_inner<'a>( &krate, true, None, - rustc_lint::BuiltinCombinedPreExpansionLintPass::new()); + rustc_lint::BuiltinCombinedPreExpansionLintPass::new(), + ); }); - let mut resolver = Resolver::new( - sess, - &krate, - crate_name, - metadata_loader, - &resolver_arenas, - ); + let mut resolver = Resolver::new(sess, &krate, crate_name, metadata_loader, &resolver_arenas); syntax_ext::register_builtin_macros(&mut resolver, sess.edition()); krate = time(sess, "crate injection", || { @@ -297,10 +289,9 @@ fn configure_and_expand_inner<'a>( env::set_var( "PATH", &env::join_paths( - new_path - .iter() - .filter(|p| env::join_paths(iter::once(p)).is_ok()), - ).unwrap(), + new_path.iter().filter(|p| env::join_paths(iter::once(p)).is_ok()), + ) + .unwrap(), ); } @@ -317,9 +308,7 @@ fn configure_and_expand_inner<'a>( let mut ecx = ExtCtxt::new(&sess.parse_sess, cfg, &mut resolver); // Expand macros now! - let krate = time(sess, "expand crate", || { - ecx.monotonic_expander().expand_crate(krate) - }); + let krate = time(sess, "expand crate", || ecx.monotonic_expander().expand_crate(krate)); // The rest is error reporting @@ -327,12 +316,8 @@ fn configure_and_expand_inner<'a>( ecx.check_unused_macros(); }); - let mut missing_fragment_specifiers: Vec<_> = ecx.parse_sess - .missing_fragment_specifiers - .borrow() - .iter() - .cloned() - .collect(); + let mut missing_fragment_specifiers: Vec<_> = + ecx.parse_sess.missing_fragment_specifiers.borrow().iter().cloned().collect(); missing_fragment_specifiers.sort(); for span in missing_fragment_specifiers { @@ -374,7 +359,6 @@ fn configure_and_expand_inner<'a>( ast_validation::check_crate(sess, &krate, &mut resolver.lint_buffer()) }); - let crate_types = sess.crate_types.borrow(); let is_proc_macro_crate = crate_types.contains(&config::CrateType::ProcMacro); @@ -385,8 +369,10 @@ fn configure_and_expand_inner<'a>( // However, we do emit a warning, to let such users know that they should // start passing '--crate-type proc-macro' if has_proc_macro_decls && sess.opts.actually_rustdoc && !is_proc_macro_crate { - let mut msg = sess.diagnostic().struct_warn(&"Trying to document proc macro crate \ - without passing '--crate-type proc-macro to rustdoc"); + let mut msg = sess.diagnostic().struct_warn( + &"Trying to document proc macro crate \ + without passing '--crate-type proc-macro to rustdoc", + ); msg.warn("The generated documentation may be incorrect"); msg.emit() @@ -438,7 +424,7 @@ fn configure_and_expand_inner<'a>( // Add all buffered lints from the `ParseSess` to the `Session`. sess.parse_sess.buffered_lints.with_lock(|buffered_lints| { info!("{} parse sess buffered_lints", buffered_lints.len()); - for BufferedEarlyLint{id, span, msg, lint_id} in buffered_lints.drain(..) { + for BufferedEarlyLint { id, span, msg, lint_id } in buffered_lints.drain(..) { resolver.lint_buffer().buffer_lint(lint_id, id, span, &msg); } }); @@ -498,15 +484,17 @@ fn generated_output_paths( match *output_type { // If the filename has been overridden using `-o`, it will not be modified // by appending `.rlib`, `.exe`, etc., so we can skip this transformation. - OutputType::Exe if !exact_name => for crate_type in sess.crate_types.borrow().iter() { - let p = ::rustc_codegen_utils::link::filename_for_input( - sess, - *crate_type, - crate_name, - outputs, - ); - out_filenames.push(p); - }, + OutputType::Exe if !exact_name => { + for crate_type in sess.crate_types.borrow().iter() { + let p = ::rustc_codegen_utils::link::filename_for_input( + sess, + *crate_type, + crate_name, + outputs, + ); + out_filenames.push(p); + } + } OutputType::DepInfo if sess.opts.debugging_opts.dep_info_omit_d_target => { // Don't add the dep-info output when omitting it from dep-info targets } @@ -538,11 +526,7 @@ fn output_contains_path(output_paths: &[PathBuf], input_path: &PathBuf) -> bool return false; } let check = |output_path: &PathBuf| { - if output_path.canonicalize().ok() == input_path { - Some(()) - } else { - None - } + if output_path.canonicalize().ok() == input_path { Some(()) } else { None } }; check_output(output_paths, check).is_some() } @@ -573,7 +557,8 @@ fn write_out_deps( let result = (|| -> io::Result<()> { // Build a list of files used to compile the output and // write Makefile-compatible dependency rules - let mut files: Vec = sess.source_map() + let mut files: Vec = sess + .source_map() .files() .iter() .filter(|fmap| fmap.is_real_file()) @@ -615,17 +600,16 @@ fn write_out_deps( match result { Ok(_) => { if sess.opts.json_artifact_notifications { - sess.parse_sess.span_diagnostic + sess.parse_sess + .span_diagnostic .emit_artifact_notification(&deps_filename, "dep-info"); } - }, - Err(e) => { - sess.fatal(&format!( - "error writing dependencies to `{}`: {}", - deps_filename.display(), - e - )) } + Err(e) => sess.fatal(&format!( + "error writing dependencies to `{}`: {}", + deps_filename.display(), + e + )), } } @@ -634,7 +618,7 @@ pub fn prepare_outputs( compiler: &Compiler, krate: &ast::Crate, boxed_resolver: &Steal>>, - crate_name: &str + crate_name: &str, ) -> Result { // FIXME: rustdoc passes &[] instead of &krate.attrs here let outputs = util::build_output_filenames( @@ -642,16 +626,12 @@ pub fn prepare_outputs( &compiler.output_dir, &compiler.output_file, &krate.attrs, - sess - ); - - let output_paths = generated_output_paths( sess, - &outputs, - compiler.output_file.is_some(), - &crate_name, ); + let output_paths = + generated_output_paths(sess, &outputs, compiler.output_file.is_some(), &crate_name); + // Ensure the source file isn't accidentally overwritten during compilation. if let Some(ref input_path) = compiler.input_path { if sess.opts.will_create_output_file() { @@ -755,9 +735,8 @@ pub fn create_global_ctxt<'tcx>( hir::map::map_crate(sess, &*resolver_outputs.cstore, &hir_forest, defs) }); - let query_result_on_disk_cache = time(sess, "load query result cache", || { - rustc_incremental::load_query_result_cache(sess) - }); + let query_result_on_disk_cache = + time(sess, "load query result cache", || rustc_incremental::load_query_result_cache(sess)); let codegen_backend = compiler.codegen_backend(); let mut local_providers = ty::query::Providers::default(); @@ -772,19 +751,21 @@ pub fn create_global_ctxt<'tcx>( callback(sess, &mut local_providers, &mut extern_providers); } - let gcx = global_ctxt.init_locking(|| TyCtxt::create_global_ctxt( - sess, - lint_store, - local_providers, - extern_providers, - &all_arenas, - arena, - resolver_outputs, - hir_map, - query_result_on_disk_cache, - &crate_name, - &outputs - )); + let gcx = global_ctxt.init_locking(|| { + TyCtxt::create_global_ctxt( + sess, + lint_store, + local_providers, + extern_providers, + &all_arenas, + arena, + resolver_outputs, + hir_map, + query_result_on_disk_cache, + &crate_name, + &outputs, + ) + }); // Do some initialization of the DepGraph that can only be done with the tcx available. ty::tls::enter_global(&gcx, |tcx| { @@ -803,53 +784,57 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { let mut entry_point = None; time(sess, "misc checking 1", || { - parallel!({ - entry_point = time(sess, "looking for entry point", || { - rustc_passes::entry::find_entry_point(tcx) - }); + parallel!( + { + entry_point = time(sess, "looking for entry point", || { + rustc_passes::entry::find_entry_point(tcx) + }); - time(sess, "looking for plugin registrar", || { - plugin::build::find_plugin_registrar(tcx) - }); + time(sess, "looking for plugin registrar", || { + plugin::build::find_plugin_registrar(tcx) + }); - time(sess, "looking for derive registrar", || { - proc_macro_decls::find(tcx) - }); - }, { - par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { - let local_def_id = tcx.hir().local_def_id(module); - tcx.ensure().check_mod_loops(local_def_id); - tcx.ensure().check_mod_attrs(local_def_id); - tcx.ensure().check_mod_unstable_api_usage(local_def_id); - tcx.ensure().check_mod_const_bodies(local_def_id); - }); - }); + time(sess, "looking for derive registrar", || proc_macro_decls::find(tcx)); + }, + { + par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { + let local_def_id = tcx.hir().local_def_id(module); + tcx.ensure().check_mod_loops(local_def_id); + tcx.ensure().check_mod_attrs(local_def_id); + tcx.ensure().check_mod_unstable_api_usage(local_def_id); + tcx.ensure().check_mod_const_bodies(local_def_id); + }); + } + ); }); // passes are timed inside typeck typeck::check_crate(tcx)?; time(sess, "misc checking 2", || { - parallel!({ - time(sess, "match checking", || { - tcx.par_body_owners(|def_id| { - tcx.ensure().check_match(def_id); + parallel!( + { + time(sess, "match checking", || { + tcx.par_body_owners(|def_id| { + tcx.ensure().check_match(def_id); + }); }); - }); - }, { - time(sess, "liveness checking + intrinsic checking", || { - par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { - // this must run before MIR dump, because - // "not all control paths return a value" is reported here. - // - // maybe move the check to a MIR pass? - let local_def_id = tcx.hir().local_def_id(module); - - tcx.ensure().check_mod_liveness(local_def_id); - tcx.ensure().check_mod_intrinsics(local_def_id); + }, + { + time(sess, "liveness checking + intrinsic checking", || { + par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { + // this must run before MIR dump, because + // "not all control paths return a value" is reported here. + // + // maybe move the check to a MIR pass? + let local_def_id = tcx.hir().local_def_id(module); + + tcx.ensure().check_mod_liveness(local_def_id); + tcx.ensure().check_mod_intrinsics(local_def_id); + }); }); - }); - }); + } + ); }); time(sess, "MIR borrow checking", || { @@ -878,32 +863,42 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { } time(sess, "misc checking 3", || { - parallel!({ - time(sess, "privacy access levels", || { - tcx.ensure().privacy_access_levels(LOCAL_CRATE); - }); - parallel!({ - time(sess, "private in public", || { - tcx.ensure().check_private_in_public(LOCAL_CRATE); - }); - }, { - time(sess, "death checking", || rustc_passes::dead::check_crate(tcx)); - }, { - time(sess, "unused lib feature checking", || { - stability::check_unused_or_stable_features(tcx) + parallel!( + { + time(sess, "privacy access levels", || { + tcx.ensure().privacy_access_levels(LOCAL_CRATE); }); - }, { - time(sess, "lint checking", || { - lint::check_crate(tcx, || rustc_lint::BuiltinCombinedLateLintPass::new()); - }); - }); - }, { - time(sess, "privacy checking modules", || { - par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { - tcx.ensure().check_mod_privacy(tcx.hir().local_def_id(module)); + parallel!( + { + time(sess, "private in public", || { + tcx.ensure().check_private_in_public(LOCAL_CRATE); + }); + }, + { + time(sess, "death checking", || rustc_passes::dead::check_crate(tcx)); + }, + { + time(sess, "unused lib feature checking", || { + stability::check_unused_or_stable_features(tcx) + }); + }, + { + time(sess, "lint checking", || { + lint::check_crate(tcx, || { + rustc_lint::BuiltinCombinedLateLintPass::new() + }); + }); + } + ); + }, + { + time(sess, "privacy checking modules", || { + par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { + tcx.ensure().check_mod_privacy(tcx.hir().local_def_id(module)); + }); }); - }); - }); + } + ); }); Ok(()) @@ -917,26 +912,27 @@ fn encode_and_write_metadata( enum MetadataKind { None, Uncompressed, - Compressed + Compressed, } - let metadata_kind = tcx.sess.crate_types.borrow().iter().map(|ty| { - match *ty { - CrateType::Executable | - CrateType::Staticlib | - CrateType::Cdylib => MetadataKind::None, + let metadata_kind = tcx + .sess + .crate_types + .borrow() + .iter() + .map(|ty| match *ty { + CrateType::Executable | CrateType::Staticlib | CrateType::Cdylib => MetadataKind::None, CrateType::Rlib => MetadataKind::Uncompressed, - CrateType::Dylib | - CrateType::ProcMacro => MetadataKind::Compressed, - } - }).max().unwrap_or(MetadataKind::None); + CrateType::Dylib | CrateType::ProcMacro => MetadataKind::Compressed, + }) + .max() + .unwrap_or(MetadataKind::None); let metadata = match metadata_kind { MetadataKind::None => middle::cstore::EncodedMetadata::new(), - MetadataKind::Uncompressed | - MetadataKind::Compressed => tcx.encode_metadata(), + MetadataKind::Uncompressed | MetadataKind::Compressed => tcx.encode_metadata(), }; let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata); @@ -951,15 +947,15 @@ fn encode_and_write_metadata( let metadata_tmpdir = TempFileBuilder::new() .prefix("rmeta") .tempdir_in(out_filename.parent().unwrap()) - .unwrap_or_else(|err| { - tcx.sess.fatal(&format!("couldn't create a temp dir: {}", err)) - }); + .unwrap_or_else(|err| tcx.sess.fatal(&format!("couldn't create a temp dir: {}", err))); let metadata_filename = emit_metadata(tcx.sess, &metadata, &metadata_tmpdir); if let Err(e) = fs::rename(&metadata_filename, &out_filename) { tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e)); } if tcx.sess.opts.json_artifact_notifications { - tcx.sess.parse_sess.span_diagnostic + tcx.sess + .parse_sess + .span_diagnostic .emit_artifact_notification(&out_filename, "metadata"); } } @@ -981,9 +977,8 @@ pub fn start_codegen<'tcx>( tcx.print_debug_stats(); } - let (metadata, need_metadata_module) = time(tcx.sess, "metadata encoding and writing", || { - encode_and_write_metadata(tcx, outputs) - }); + let (metadata, need_metadata_module) = + time(tcx.sess, "metadata encoding and writing", || encode_and_write_metadata(tcx, outputs)); let codegen = time(tcx.sess, "codegen", move || { let _prof_timer = tcx.prof.generic_activity("codegen_crate"); diff --git a/src/librustc_interface/proc_macro_decls.rs b/src/librustc_interface/proc_macro_decls.rs index e3def1756267c..5bf35124a70e2 100644 --- a/src/librustc_interface/proc_macro_decls.rs +++ b/src/librustc_interface/proc_macro_decls.rs @@ -1,8 +1,8 @@ -use rustc::hir::itemlikevisit::ItemLikeVisitor; -use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir; -use rustc::ty::TyCtxt; +use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; +use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::query::Providers; +use rustc::ty::TyCtxt; use syntax::attr; use syntax::symbol::sym; @@ -30,16 +30,11 @@ impl<'v> ItemLikeVisitor<'v> for Finder { } } - fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) { - } + fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {} - fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) { - } + fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {} } pub(crate) fn provide(providers: &mut Providers<'_>) { - *providers = Providers { - proc_macro_decls_static, - ..*providers - }; + *providers = Providers { proc_macro_decls_static, ..*providers }; } diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index d6de9d5f4e43c..4318f99e69071 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -1,24 +1,24 @@ use crate::interface::{Compiler, Result}; use crate::passes::{self, BoxedResolver, QueryContext}; -use rustc_incremental::DepGraphFuture; -use rustc_data_structures::sync::{Lrc, Once, WorkerLocal}; -use rustc_codegen_utils::codegen_backend::CodegenBackend; -use rustc::session::config::{OutputFilenames, OutputType}; -use rustc::util::common::{time, ErrorReported}; use rustc::arena::Arena; +use rustc::dep_graph::DepGraph; use rustc::hir; +use rustc::hir::def_id::LOCAL_CRATE; use rustc::lint; -use rustc::session::Session; use rustc::lint::LintStore; -use rustc::hir::def_id::LOCAL_CRATE; +use rustc::session::config::{OutputFilenames, OutputType}; +use rustc::session::Session; use rustc::ty::steal::Steal; -use rustc::ty::{AllArenas, ResolverOutputs, GlobalCtxt}; -use rustc::dep_graph::DepGraph; -use std::cell::{Ref, RefMut, RefCell}; -use std::rc::Rc; +use rustc::ty::{AllArenas, GlobalCtxt, ResolverOutputs}; +use rustc::util::common::{time, ErrorReported}; +use rustc_codegen_utils::codegen_backend::CodegenBackend; +use rustc_data_structures::sync::{Lrc, Once, WorkerLocal}; +use rustc_incremental::DepGraphFuture; use std::any::Any; +use std::cell::{Ref, RefCell, RefMut}; use std::mem; +use std::rc::Rc; use syntax::{self, ast}; /// Represent the result of a query. @@ -39,11 +39,7 @@ impl Query { /// Takes ownership of the query result. Further attempts to take or peek the query /// result will panic unless it is generated by calling the `compute` method. pub fn take(&self) -> T { - self.result - .borrow_mut() - .take() - .expect("missing query result") - .unwrap() + self.result.borrow_mut().take().expect("missing query result").unwrap() } /// Borrows the query result using the RefCell. Panics if the result is stolen. @@ -63,9 +59,7 @@ impl Query { impl Default for Query { fn default() -> Self { - Query { - result: RefCell::new(None), - } + Query { result: RefCell::new(None) } } } @@ -117,20 +111,20 @@ impl<'tcx> Queries<'tcx> { pub fn dep_graph_future(&self) -> Result<&Query>> { self.dep_graph_future.compute(|| { - Ok(self.session().opts.build_dep_graph().then(|| { - rustc_incremental::load_dep_graph(self.session()) - })) + Ok(self + .session() + .opts + .build_dep_graph() + .then(|| rustc_incremental::load_dep_graph(self.session()))) }) } pub fn parse(&self) -> Result<&Query> { self.parse.compute(|| { - passes::parse(self.session(), &self.compiler.input).map_err( - |mut parse_error| { - parse_error.emit(); - ErrorReported - }, - ) + passes::parse(self.session(), &self.compiler.input).map_err(|mut parse_error| { + parse_error.emit(); + ErrorReported + }) }) } @@ -143,10 +137,7 @@ impl<'tcx> Queries<'tcx> { let result = passes::register_plugins( self.session(), &*self.codegen_backend().metadata_loader(), - self.compiler.register_lints - .as_ref() - .map(|p| &**p) - .unwrap_or_else(|| empty), + self.compiler.register_lints.as_ref().map(|p| &**p).unwrap_or_else(|| empty), krate, &crate_name, ); @@ -172,7 +163,7 @@ impl<'tcx> Queries<'tcx> { rustc_codegen_utils::link::find_crate_name( Some(self.session()), &krate.attrs, - &self.compiler.input + &self.compiler.input, ) } }) @@ -180,7 +171,7 @@ impl<'tcx> Queries<'tcx> { } pub fn expansion( - &self + &self, ) -> Result<&Query<(ast::Crate, Steal>>, Lrc)>> { self.expansion.compute(|| { let crate_name = self.crate_name()?.peek().clone(); @@ -191,7 +182,8 @@ impl<'tcx> Queries<'tcx> { self.codegen_backend().metadata_loader(), krate, &crate_name, - ).map(|(krate, resolver)| { + ) + .map(|(krate, resolver)| { (krate, Steal::new(Rc::new(RefCell::new(resolver))), lint_store) }) }) @@ -204,9 +196,12 @@ impl<'tcx> Queries<'tcx> { Some(future) => { let (prev_graph, prev_work_products) = time(self.session(), "blocked while dep-graph loading finishes", || { - future.open().unwrap_or_else(|e| rustc_incremental::LoadResult::Error { - message: format!("could not decode incremental cache: {:?}", e), - }).open(self.session()) + future + .open() + .unwrap_or_else(|e| rustc_incremental::LoadResult::Error { + message: format!("could not decode incremental cache: {:?}", e), + }) + .open(self.session()) }); DepGraph::new(prev_graph, prev_work_products) } @@ -245,7 +240,11 @@ impl<'tcx> Queries<'tcx> { let crate_name = self.crate_name()?; let crate_name = crate_name.peek(); passes::prepare_outputs( - self.session(), self.compiler, &krate, &boxed_resolver, &crate_name + self.session(), + self.compiler, + &krate, + &boxed_resolver, + &crate_name, ) }) } @@ -280,11 +279,7 @@ impl<'tcx> Queries<'tcx> { // Don't do code generation if there were any errors self.session().compile_status()?; - Ok(passes::start_codegen( - &***self.codegen_backend(), - tcx, - &*outputs.peek() - )) + Ok(passes::start_codegen(&***self.codegen_backend(), tcx, &*outputs.peek())) }) }) } @@ -317,18 +312,21 @@ pub struct Linker { impl Linker { pub fn link(self) -> Result<()> { - self.codegen_backend.join_codegen_and_link( - self.ongoing_codegen, - &self.sess, - &self.dep_graph, - &self.prepare_outputs, - ).map_err(|_| ErrorReported) + self.codegen_backend + .join_codegen_and_link( + self.ongoing_codegen, + &self.sess, + &self.dep_graph, + &self.prepare_outputs, + ) + .map_err(|_| ErrorReported) } } impl Compiler { pub fn enter(&self, f: F) -> T - where F: for<'tcx> FnOnce(&'tcx Queries<'tcx>) -> T + where + F: for<'tcx> FnOnce(&'tcx Queries<'tcx>) -> T, { let queries = Queries::new(&self); let ret = f(&queries); @@ -354,7 +352,7 @@ impl Compiler { if self.session().opts.output_types.contains_key(&OutputType::DepInfo) && self.session().opts.output_types.len() == 1 { - return Ok(None) + return Ok(None); } queries.global_ctxt()?; diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs index d4b5e833dfb23..4ae579cfca26d 100644 --- a/src/librustc_interface/tests.rs +++ b/src/librustc_interface/tests.rs @@ -5,20 +5,20 @@ use crate::interface::parse_cfgspecs; use rustc::lint; use rustc::middle::cstore; use rustc::session::config::{build_configuration, build_session_options, to_crate_config}; -use rustc::session::config::{LtoCli, LinkerPluginLto, SwitchWithOptPath, ExternEntry}; +use rustc::session::config::{rustc_optgroups, ErrorOutputType, ExternLocation, Options, Passes}; +use rustc::session::config::{ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath}; use rustc::session::config::{Externs, OutputType, OutputTypes, SymbolManglingVersion}; -use rustc::session::config::{rustc_optgroups, Options, ErrorOutputType, Passes, ExternLocation}; -use rustc::session::{build_session, Session}; use rustc::session::search_paths::SearchPath; +use rustc::session::{build_session, Session}; +use rustc_data_structures::fx::FxHashSet; +use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; +use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel}; use std::collections::{BTreeMap, BTreeSet}; use std::iter::FromIterator; use std::path::PathBuf; -use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel}; -use syntax::symbol::sym; -use syntax::edition::{Edition, DEFAULT_EDITION}; use syntax; -use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{ColorConfig, emitter::HumanReadableErrorType, registry}; +use syntax::edition::{Edition, DEFAULT_EDITION}; +use syntax::symbol::sym; type CfgSpecs = FxHashSet<(String, Option)>; @@ -40,8 +40,7 @@ where S: Into, I: IntoIterator, { - let locations: BTreeSet<_> = locations.into_iter().map(|s| s.into()) - .collect(); + let locations: BTreeSet<_> = locations.into_iter().map(|s| s.into()).collect(); ExternEntry { location: ExternLocation::ExactPaths(locations), @@ -95,9 +94,8 @@ fn test_can_print_warnings() { }); syntax::with_default_globals(|| { - let matches = optgroups() - .parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]) - .unwrap(); + let matches = + optgroups().parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]).unwrap(); let (sess, _) = mk_session(matches); assert!(sess.diagnostic().can_emit_warnings()); }); @@ -115,10 +113,8 @@ fn test_output_types_tracking_hash_different_paths() { let mut v2 = Options::default(); let mut v3 = Options::default(); - v1.output_types = - OutputTypes::new(&[(OutputType::Exe, Some(PathBuf::from("./some/thing")))]); - v2.output_types = - OutputTypes::new(&[(OutputType::Exe, Some(PathBuf::from("/some/thing")))]); + v1.output_types = OutputTypes::new(&[(OutputType::Exe, Some(PathBuf::from("./some/thing")))]); + v2.output_types = OutputTypes::new(&[(OutputType::Exe, Some(PathBuf::from("/some/thing")))]); v3.output_types = OutputTypes::new(&[(OutputType::Exe, None)]); assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash()); @@ -159,36 +155,18 @@ fn test_externs_tracking_hash_different_construction_order() { let mut v3 = Options::default(); v1.externs = Externs::new(mk_map(vec![ - ( - String::from("a"), - new_public_extern_entry(vec!["b", "c"]) - ), - ( - String::from("d"), - new_public_extern_entry(vec!["e", "f"]) - ), + (String::from("a"), new_public_extern_entry(vec!["b", "c"])), + (String::from("d"), new_public_extern_entry(vec!["e", "f"])), ])); v2.externs = Externs::new(mk_map(vec![ - ( - String::from("d"), - new_public_extern_entry(vec!["e", "f"]) - ), - ( - String::from("a"), - new_public_extern_entry(vec!["b", "c"]) - ), + (String::from("d"), new_public_extern_entry(vec!["e", "f"])), + (String::from("a"), new_public_extern_entry(vec!["b", "c"])), ])); v3.externs = Externs::new(mk_map(vec![ - ( - String::from("a"), - new_public_extern_entry(vec!["b", "c"]) - ), - ( - String::from("d"), - new_public_extern_entry(vec!["f", "e"]) - ), + (String::from("a"), new_public_extern_entry(vec!["b", "c"])), + (String::from("d"), new_public_extern_entry(vec!["f", "e"])), ])); assert_eq!(v1.dep_tracking_hash(), v2.dep_tracking_hash()); @@ -277,49 +255,29 @@ fn test_search_paths_tracking_hash_different_order() { }; // Reference - v1.search_paths - .push(SearchPath::from_cli_opt("native=abc", JSON)); - v1.search_paths - .push(SearchPath::from_cli_opt("crate=def", JSON)); - v1.search_paths - .push(SearchPath::from_cli_opt("dependency=ghi", JSON)); - v1.search_paths - .push(SearchPath::from_cli_opt("framework=jkl", JSON)); - v1.search_paths - .push(SearchPath::from_cli_opt("all=mno", JSON)); - - v2.search_paths - .push(SearchPath::from_cli_opt("native=abc", JSON)); - v2.search_paths - .push(SearchPath::from_cli_opt("dependency=ghi", JSON)); - v2.search_paths - .push(SearchPath::from_cli_opt("crate=def", JSON)); - v2.search_paths - .push(SearchPath::from_cli_opt("framework=jkl", JSON)); - v2.search_paths - .push(SearchPath::from_cli_opt("all=mno", JSON)); - - v3.search_paths - .push(SearchPath::from_cli_opt("crate=def", JSON)); - v3.search_paths - .push(SearchPath::from_cli_opt("framework=jkl", JSON)); - v3.search_paths - .push(SearchPath::from_cli_opt("native=abc", JSON)); - v3.search_paths - .push(SearchPath::from_cli_opt("dependency=ghi", JSON)); - v3.search_paths - .push(SearchPath::from_cli_opt("all=mno", JSON)); - - v4.search_paths - .push(SearchPath::from_cli_opt("all=mno", JSON)); - v4.search_paths - .push(SearchPath::from_cli_opt("native=abc", JSON)); - v4.search_paths - .push(SearchPath::from_cli_opt("crate=def", JSON)); - v4.search_paths - .push(SearchPath::from_cli_opt("dependency=ghi", JSON)); - v4.search_paths - .push(SearchPath::from_cli_opt("framework=jkl", JSON)); + v1.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON)); + v1.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON)); + v1.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON)); + v1.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON)); + v1.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON)); + + v2.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON)); + v2.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON)); + v2.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON)); + v2.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON)); + v2.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON)); + + v3.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON)); + v3.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON)); + v3.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON)); + v3.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON)); + v3.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON)); + + v4.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON)); + v4.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON)); + v4.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON)); + v4.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON)); + v4.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON)); assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash()); assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash()); @@ -363,11 +321,7 @@ fn test_native_libs_tracking_hash_different_values() { // Change new-name v4.libs = vec![ (String::from("a"), None, Some(cstore::NativeStatic)), - ( - String::from("b"), - Some(String::from("X")), - Some(cstore::NativeFramework), - ), + (String::from("b"), Some(String::from("X")), Some(cstore::NativeFramework)), (String::from("c"), None, Some(cstore::NativeUnknown)), ]; @@ -686,9 +640,7 @@ fn test_edition_parsing() { let options = Options::default(); assert!(options.edition == DEFAULT_EDITION); - let matches = optgroups() - .parse(&["--edition=2018".to_string()]) - .unwrap(); + let matches = optgroups().parse(&["--edition=2018".to_string()]).unwrap(); let (sessopts, _) = build_session_options_and_crate_config(matches); assert!(sessopts.edition == Edition::Edition2018) } diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index a8800082c9a73..1a2958a0a92c9 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -1,36 +1,36 @@ use log::info; -use rustc::session::config::{Input, OutputFilenames, ErrorOutputType}; -use rustc::session::{self, config, early_error, filesearch, Session, DiagnosticOutput}; +use rustc::lint; +use rustc::session::config::{ErrorOutputType, Input, OutputFilenames}; use rustc::session::CrateDisambiguator; +use rustc::session::{self, config, early_error, filesearch, DiagnosticOutput, Session}; use rustc::ty; -use rustc::lint; use rustc_codegen_utils::codegen_backend::CodegenBackend; +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; #[cfg(parallel_compiler)] use rustc_data_structures::jobserver; -use rustc_data_structures::sync::{Lock, Lrc}; use rustc_data_structures::stable_hasher::StableHasher; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::{FxHashSet, FxHashMap}; +use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::registry::Registry; use rustc_metadata::dynamic_lib::DynamicLibrary; use rustc_resolve::{self, Resolver}; +use smallvec::SmallVec; use std::env; use std::io::{self, Write}; use std::mem; +use std::ops::DerefMut; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex, Once}; -use std::ops::DerefMut; -use smallvec::SmallVec; -use syntax::ptr::P; -use syntax::mut_visit::{*, MutVisitor, visit_clobber}; +#[cfg(not(parallel_compiler))] +use std::{panic, thread}; use syntax::ast::{AttrVec, BlockCheckMode}; -use syntax::util::lev_distance::find_best_match_for_name; +use syntax::mut_visit::{visit_clobber, MutVisitor, *}; +use syntax::ptr::P; use syntax::source_map::{FileLoader, RealFileLoader, SourceMap}; -use syntax::symbol::{Symbol, sym}; +use syntax::symbol::{sym, Symbol}; +use syntax::util::lev_distance::find_best_match_for_name; use syntax::{self, ast, attr}; use syntax_pos::edition::Edition; -#[cfg(not(parallel_compiler))] -use std::{thread, panic}; /// Adds `target_feature = "..."` cfgs for a variety of platform /// specific features (SSE, NEON etc.). @@ -44,12 +44,7 @@ pub fn add_configuration( ) { let tf = sym::target_feature; - cfg.extend( - codegen_backend - .target_features(sess) - .into_iter() - .map(|feat| (tf, Some(feat))), - ); + cfg.extend(codegen_backend.target_features(sess).into_iter().map(|feat| (tf, Some(feat)))); if sess.crt_static_feature() { cfg.insert((tf, Some(Symbol::intern("crt-static")))); @@ -66,10 +61,7 @@ pub fn create_session( descriptions: Registry, ) -> (Lrc, Lrc>, Lrc) { let loader = file_loader.unwrap_or(box RealFileLoader); - let source_map = Lrc::new(SourceMap::with_file_loader( - loader, - sopts.file_path_mapping(), - )); + let source_map = Lrc::new(SourceMap::with_file_loader(loader, sopts.file_path_mapping())); let mut sess = session::build_session_with_source_map( sopts, input_path, @@ -112,7 +104,9 @@ impl Write for Sink { fn write(&mut self, data: &[u8]) -> io::Result { Write::write(&mut *self.0.lock().unwrap(), data) } - fn flush(&mut self) -> io::Result<()> { Ok(()) } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } } #[cfg(not(parallel_compiler))] @@ -225,9 +219,12 @@ fn load_backend_from_dylib(path: &Path) -> fn() -> Box { mem::transmute::<*mut u8, _>(f) } Err(e) => { - let err = format!("couldn't load codegen backend as it \ + let err = format!( + "couldn't load codegen backend as it \ doesn't export the `__rustc_codegen_backend` \ - symbol: {:?}", e); + symbol: {:?}", + e + ); early_error(ErrorOutputType::default(), &err); } } @@ -240,12 +237,14 @@ pub fn get_codegen_backend(sess: &Session) -> Box { static mut LOAD: fn() -> Box = || unreachable!(); INIT.call_once(|| { - let codegen_name = sess.opts.debugging_opts.codegen_backend.as_ref() + let codegen_name = sess + .opts + .debugging_opts + .codegen_backend + .as_ref() .unwrap_or(&sess.target.target.options.codegen_backend); let backend = match &codegen_name[..] { - filename if filename.contains(".") => { - load_backend_from_dylib(filename.as_ref()) - } + filename if filename.contains(".") => load_backend_from_dylib(filename.as_ref()), codegen_name => get_builtin_codegen_backend(codegen_name), }; @@ -271,7 +270,8 @@ pub fn rustc_path<'a>() -> Option<&'a Path> { } fn get_rustc_path_inner(bin_path: &str) -> Option { - sysroot_candidates().iter() + sysroot_candidates() + .iter() .filter_map(|sysroot| { let candidate = sysroot.join(bin_path).join(if cfg!(target_os = "windows") { "rustc.exe" @@ -303,10 +303,12 @@ fn sysroot_candidates() -> Vec { sysroot_candidates.push(path.to_owned()); if path.ends_with(target) { - sysroot_candidates.extend(path.parent() // chop off `$target` - .and_then(|p| p.parent()) // chop off `rustlib` - .and_then(|p| p.parent()) // chop off `lib` - .map(|s| s.to_owned())); + sysroot_candidates.extend( + path.parent() // chop off `$target` + .and_then(|p| p.parent()) // chop off `rustlib` + .and_then(|p| p.parent()) // chop off `lib` + .map(|s| s.to_owned()), + ); } } } @@ -315,7 +317,7 @@ fn sysroot_candidates() -> Vec { #[cfg(unix)] fn current_dll_path() -> Option { - use std::ffi::{OsStr, CStr}; + use std::ffi::{CStr, OsStr}; use std::os::unix::prelude::*; unsafe { @@ -323,11 +325,11 @@ fn sysroot_candidates() -> Vec { let mut info = mem::zeroed(); if libc::dladdr(addr, &mut info) == 0 { info!("dladdr failed"); - return None + return None; } if info.dli_fname.is_null() { info!("dladdr returned null pointer"); - return None + return None; } let bytes = CStr::from_ptr(info.dli_fname).to_bytes(); let os = OsStr::from_bytes(bytes); @@ -341,38 +343,33 @@ fn sysroot_candidates() -> Vec { use std::os::windows::prelude::*; extern "system" { - fn GetModuleHandleExW(dwFlags: u32, - lpModuleName: usize, - phModule: *mut usize) -> i32; - fn GetModuleFileNameW(hModule: usize, - lpFilename: *mut u16, - nSize: u32) -> u32; + fn GetModuleHandleExW(dwFlags: u32, lpModuleName: usize, phModule: *mut usize) -> i32; + fn GetModuleFileNameW(hModule: usize, lpFilename: *mut u16, nSize: u32) -> u32; } const GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS: u32 = 0x00000004; unsafe { let mut module = 0; - let r = GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - current_dll_path as usize, - &mut module); + let r = GetModuleHandleExW( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + current_dll_path as usize, + &mut module, + ); if r == 0 { info!("GetModuleHandleExW failed: {}", io::Error::last_os_error()); - return None + return None; } let mut space = Vec::with_capacity(1024); - let r = GetModuleFileNameW(module, - space.as_mut_ptr(), - space.capacity() as u32); + let r = GetModuleFileNameW(module, space.as_mut_ptr(), space.capacity() as u32); if r == 0 { info!("GetModuleFileNameW failed: {}", io::Error::last_os_error()); - return None + return None; } let r = r as usize; if r >= space.capacity() { - info!("our buffer was too small? {}", - io::Error::last_os_error()); - return None + info!("our buffer was too small? {}", io::Error::last_os_error()); + return None; } space.set_len(r); let os = OsString::from_wide(&space); @@ -420,10 +417,7 @@ pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguat // Also incorporate crate type, so that we don't get symbol conflicts when // linking against a library of the same name, if this is an executable. - let is_exe = session - .crate_types - .borrow() - .contains(&config::CrateType::Executable); + let is_exe = session.crate_types.borrow().contains(&config::CrateType::Executable); hasher.write(if is_exe { b"exe" } else { b"lib" }); CrateDisambiguator::from(hasher.finish::()) @@ -443,7 +437,7 @@ pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut let lev_candidate = find_best_match_for_name( CRATE_TYPES.iter().map(|(k, _)| k), &n.as_str(), - None + None, ); if let Some(candidate) = lev_candidate { lint_buffer.buffer_lint_with_diagnostic( @@ -451,19 +445,18 @@ pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut ast::CRATE_NODE_ID, span, "invalid `crate_type` value", - lint::builtin::BuiltinLintDiagnostics:: - UnknownCrateTypes( - span, - "did you mean".to_string(), - format!("\"{}\"", candidate) - ) + lint::builtin::BuiltinLintDiagnostics::UnknownCrateTypes( + span, + "did you mean".to_string(), + format!("\"{}\"", candidate), + ), ); } else { lint_buffer.buffer_lint( lint::builtin::UNKNOWN_CRATE_TYPES, ast::CRATE_NODE_ID, span, - "invalid `crate_type` value" + "invalid `crate_type` value", ); } } @@ -515,9 +508,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec { - let unnamed_output_types = sess.opts - .output_types - .values() - .filter(|a| a.is_none()) - .count(); + let unnamed_output_types = + sess.opts.output_types.values().filter(|a| a.is_none()).count(); let ofile = if unnamed_output_types > 1 { sess.warn( "due to multiple output types requested, the explicitly specified \ @@ -626,11 +615,7 @@ pub struct ReplaceBodyWithLoop<'a, 'b> { impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> { pub fn new(resolver: &'a mut Resolver<'b>) -> ReplaceBodyWithLoop<'a, 'b> { - ReplaceBodyWithLoop { - within_static_or_const: false, - nested_blocks: None, - resolver, - } + ReplaceBodyWithLoop { within_static_or_const: false, nested_blocks: None, resolver } } fn run R>(&mut self, is_const: bool, action: F) -> R { @@ -647,11 +632,11 @@ impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> { fn involves_impl_trait(ty: &ast::Ty) -> bool { match ty.kind { ast::TyKind::ImplTrait(..) => true, - ast::TyKind::Slice(ref subty) | - ast::TyKind::Array(ref subty, _) | - ast::TyKind::Ptr(ast::MutTy { ty: ref subty, .. }) | - ast::TyKind::Rptr(_, ast::MutTy { ty: ref subty, .. }) | - ast::TyKind::Paren(ref subty) => involves_impl_trait(subty), + ast::TyKind::Slice(ref subty) + | ast::TyKind::Array(ref subty, _) + | ast::TyKind::Ptr(ast::MutTy { ty: ref subty, .. }) + | ast::TyKind::Rptr(_, ast::MutTy { ty: ref subty, .. }) + | ast::TyKind::Paren(ref subty) => involves_impl_trait(subty), ast::TyKind::Tup(ref tys) => any_involves_impl_trait(tys.iter()), ast::TyKind::Path(_, ref path) => path.segments.iter().any(|seg| { match seg.args.as_ref().map(|generic_arg| &**generic_arg) { @@ -661,18 +646,17 @@ impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> { ast::GenericArg::Type(ty) => Some(ty), _ => None, }); - any_involves_impl_trait(types.into_iter()) || - data.constraints.iter().any(|c| { - match c.kind { + any_involves_impl_trait(types.into_iter()) + || data.constraints.iter().any(|c| match c.kind { ast::AssocTyConstraintKind::Bound { .. } => true, - ast::AssocTyConstraintKind::Equality { ref ty } => - involves_impl_trait(ty), - } - }) - }, + ast::AssocTyConstraintKind::Equality { ref ty } => { + involves_impl_trait(ty) + } + }) + } Some(&ast::GenericArgs::Parenthesized(ref data)) => { - any_involves_impl_trait(data.inputs.iter()) || - ReplaceBodyWithLoop::should_ignore_fn(&data.output) + any_involves_impl_trait(data.inputs.iter()) + || ReplaceBodyWithLoop::should_ignore_fn(&data.output) } } }), @@ -691,8 +675,8 @@ impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> { } fn is_sig_const(sig: &ast::FnSig) -> bool { - sig.header.constness.node == ast::Constness::Const || - ReplaceBodyWithLoop::should_ignore_fn(&sig.decl.output) + sig.header.constness.node == ast::Constness::Const + || ReplaceBodyWithLoop::should_ignore_fn(&sig.decl.output) } } @@ -724,9 +708,11 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { } fn visit_block(&mut self, b: &mut P) { - fn stmt_to_block(rules: ast::BlockCheckMode, - s: Option, - resolver: &mut Resolver<'_>) -> ast::Block { + fn stmt_to_block( + rules: ast::BlockCheckMode, + s: Option, + resolver: &mut Resolver<'_>, + ) -> ast::Block { ast::Block { stmts: s.into_iter().collect(), rules, @@ -755,7 +741,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { kind: ast::ExprKind::Loop(P(empty_block), None), id: self.resolver.next_node_id(), span: syntax_pos::DUMMY_SP, - attrs: AttrVec::new(), + attrs: AttrVec::new(), }); let loop_stmt = ast::Stmt { @@ -780,10 +766,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { stmts.extend(new_blocks.into_iter().map(|b| block_to_stmt(b, self.resolver))); } - let mut new_block = ast::Block { - stmts, - ..b - }; + let mut new_block = ast::Block { stmts, ..b }; if let Some(old_blocks) = self.nested_blocks.as_mut() { //push our fresh block onto the cache and yield an empty block with `loop {}` diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs index 3cecb4317b19a..969ce9b06e8a8 100644 --- a/src/librustc_lexer/src/lib.rs +++ b/src/librustc_lexer/src/lib.rs @@ -17,9 +17,9 @@ mod cursor; pub mod unescape; -use crate::cursor::{Cursor, EOF_CHAR}; -use self::TokenKind::*; use self::LiteralKind::*; +use self::TokenKind::*; +use crate::cursor::{Cursor, EOF_CHAR}; /// Parsed token. /// It doesn't contain information about data that has been parsed, @@ -39,7 +39,6 @@ impl Token { #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum TokenKind { // Multi-char tokens: - /// "// comment" LineComment, /// "/* block comment */" @@ -59,7 +58,6 @@ pub enum TokenKind { Lifetime { starts_with_number: bool }, // One-char tokens: - /// ";" Semi, /// "," @@ -405,11 +403,7 @@ impl Cursor<'_> { } fn raw_ident(&mut self) -> TokenKind { - debug_assert!( - self.prev() == 'r' - && self.first() == '#' - && is_id_start(self.second()) - ); + debug_assert!(self.prev() == 'r' && self.first() == '#' && is_id_start(self.second())); // Eat "#" symbol. self.bump(); // Eat the identifier part of RawIdent. @@ -467,9 +461,7 @@ impl Cursor<'_> { // Don't be greedy if this is actually an // integer literal followed by field/method access or a range pattern // (`0..2` and `12.foo()`) - '.' if self.second() != '.' - && !is_id_start(self.second()) => - { + '.' if self.second() != '.' && !is_id_start(self.second()) => { // might have stuff after the ., and if it does, it needs to start // with a number self.bump(); @@ -710,7 +702,7 @@ impl Cursor<'_> { /// Returns amount of eaten symbols. fn eat_while(&mut self, mut predicate: F) -> usize where - F: FnMut(char) -> bool + F: FnMut(char) -> bool, { let mut eaten: usize = 0; while predicate(self.first()) && !self.is_eof() { diff --git a/src/librustc_lexer/src/unescape.rs b/src/librustc_lexer/src/unescape.rs index dee7bc2260bf0..4f5e03d008c99 100644 --- a/src/librustc_lexer/src/unescape.rs +++ b/src/librustc_lexer/src/unescape.rs @@ -1,8 +1,8 @@ //! Utilities for validating string and char literals and turning them into //! values they represent. -use std::str::Chars; use std::ops::Range; +use std::str::Chars; #[cfg(test)] mod tests; @@ -152,7 +152,6 @@ impl Mode { } } - fn scan_escape(first_char: char, chars: &mut Chars<'_>, mode: Mode) -> Result { if first_char != '\\' { // Previous character was not a slash, and we don't expect it to be @@ -246,7 +245,8 @@ fn scan_escape(first_char: char, chars: &mut Chars<'_>, mode: Mode) -> Result { - let digit = c.to_digit(16).ok_or(EscapeError::InvalidCharInUnicodeEscape)?; + let digit = + c.to_digit(16).ok_or(EscapeError::InvalidCharInUnicodeEscape)?; n_digits += 1; if n_digits > 6 { // Stop updating value since we're sure that it's is incorrect already. @@ -334,8 +334,7 @@ where let result = match curr { '\r' => Err(EscapeError::BareCarriageReturnInRawString), - c if mode.is_bytes() && !c.is_ascii() => - Err(EscapeError::NonAsciiCharInByteString), + c if mode.is_bytes() && !c.is_ascii() => Err(EscapeError::NonAsciiCharInByteString), c => Ok(c), }; let end = initial_len - chars.as_str().len(); diff --git a/src/librustc_lint/array_into_iter.rs b/src/librustc_lint/array_into_iter.rs index e73414174fb35..5a001ef18b2ed 100644 --- a/src/librustc_lint/array_into_iter.rs +++ b/src/librustc_lint/array_into_iter.rs @@ -1,17 +1,13 @@ use crate::lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass}; use rustc::{ - lint::FutureIncompatibleInfo, hir, + lint::FutureIncompatibleInfo, ty::{ self, adjustment::{Adjust, Adjustment}, }, }; -use syntax::{ - errors::Applicability, - symbol::sym, -}; - +use syntax::{errors::Applicability, symbol::sym}; declare_lint! { pub ARRAY_INTO_ITER, @@ -40,7 +36,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIntoIter { // `IntoIterator::into_iter`. let def_id = cx.tables.type_dependent_def_id(expr.hir_id).unwrap(); match cx.tcx.trait_of_item(def_id) { - Some(trait_id) if cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_id) => {}, + Some(trait_id) if cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_id) => {} _ => return, }; @@ -62,8 +58,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIntoIter { // Emit lint diagnostic. let target = match cx.tables.expr_ty_adjusted(receiver_arg).kind { - ty::Ref(_, ty::TyS { kind: ty::Array(..), ..}, _) => "[T; N]", - ty::Ref(_, ty::TyS { kind: ty::Slice(..), ..}, _) => "[T]", + ty::Ref(_, ty::TyS { kind: ty::Array(..), .. }, _) => "[T; N]", + ty::Ref(_, ty::TyS { kind: ty::Slice(..), .. }, _) => "[T]", // We know the original first argument type is an array type, // we know that the first adjustment was an autoref coercion diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 340af64adad56..332176e1b0cec 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -23,35 +23,35 @@ use std::fmt::Write; -use rustc::hir::def::{Res, DefKind}; +use hir::Node; +use lint::{EarlyContext, EarlyLintPass, LateLintPass, LintPass}; +use lint::{LateContext, LintArray, LintContext}; +use rustc::hir::def::{DefKind, Res}; use rustc::hir::def_id::DefId; -use rustc::ty::{self, Ty, TyCtxt, layout::VariantIdx}; -use rustc::{lint, util}; use rustc::lint::FutureIncompatibleInfo; -use hir::Node; +use rustc::ty::{self, layout::VariantIdx, Ty, TyCtxt}; +use rustc::{lint, util}; use util::nodemap::HirIdSet; -use lint::{LateContext, LintContext, LintArray}; -use lint::{LintPass, LateLintPass, EarlyLintPass, EarlyContext}; use rustc::util::nodemap::FxHashSet; -use rustc_feature::{AttributeGate, AttributeTemplate, AttributeType, deprecated_attributes}; use rustc_feature::Stability; +use rustc_feature::{deprecated_attributes, AttributeGate, AttributeTemplate, AttributeType}; -use syntax::tokenstream::{TokenTree, TokenStream}; use syntax::ast::{self, Expr}; -use syntax::ptr::P; use syntax::attr::{self, HasAttrs}; -use syntax::source_map::Spanned; use syntax::edition::Edition; -use syntax_pos::{BytePos, Span}; -use syntax::symbol::{Symbol, kw, sym}; use syntax::errors::{Applicability, DiagnosticBuilder}; use syntax::print::pprust::{self, expr_to_string}; +use syntax::ptr::P; +use syntax::source_map::Spanned; +use syntax::symbol::{kw, sym, Symbol}; +use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::visit::FnKind; +use syntax_pos::{BytePos, Span}; use rustc::hir::{self, GenericParamKind, PatKind}; -use crate::nonstandard_style::{MethodLateContext, method_context}; +use crate::nonstandard_style::{method_context, MethodLateContext}; use log::debug; @@ -87,7 +87,7 @@ impl EarlyLintPass for WhileTrue { condition_span, "use `loop`", "loop".to_owned(), - Applicability::MachineApplicable + Applicability::MachineApplicable, ) .emit(); } @@ -119,25 +119,23 @@ impl BoxPointers { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers { fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item<'_>) { match it.kind { - hir::ItemKind::Fn(..) | - hir::ItemKind::TyAlias(..) | - hir::ItemKind::Enum(..) | - hir::ItemKind::Struct(..) | - hir::ItemKind::Union(..) => { + hir::ItemKind::Fn(..) + | hir::ItemKind::TyAlias(..) + | hir::ItemKind::Enum(..) + | hir::ItemKind::Struct(..) + | hir::ItemKind::Union(..) => { let def_id = cx.tcx.hir().local_def_id(it.hir_id); self.check_heap_type(cx, it.span, cx.tcx.type_of(def_id)) } - _ => () + _ => (), } // If it's a struct, we also have to check the fields' types match it.kind { - hir::ItemKind::Struct(ref struct_def, _) | - hir::ItemKind::Union(ref struct_def, _) => { + hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => { for struct_field in struct_def.fields() { let def_id = cx.tcx.hir().local_def_id(struct_field.hir_id); - self.check_heap_type(cx, struct_field.span, - cx.tcx.type_of(def_id)); + self.check_heap_type(cx, struct_field.span, cx.tcx.type_of(def_id)); } } _ => (), @@ -161,9 +159,12 @@ declare_lint_pass!(NonShorthandFieldPatterns => [NON_SHORTHAND_FIELD_PATTERNS]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns { fn check_pat(&mut self, cx: &LateContext<'_, '_>, pat: &hir::Pat) { if let PatKind::Struct(ref qpath, ref field_pats, _) = pat.kind { - let variant = cx.tables.pat_ty(pat).ty_adt_def() - .expect("struct pattern type is not an ADT") - .variant_of_res(cx.tables.qpath_res(qpath, pat.hir_id)); + let variant = cx + .tables + .pat_ty(pat) + .ty_adt_def() + .expect("struct pattern type is not an ADT") + .variant_of_res(cx.tables.qpath_res(qpath, pat.hir_id)); for fieldpat in field_pats { if fieldpat.is_shorthand { continue; @@ -175,11 +176,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns { continue; } if let PatKind::Binding(binding_annot, _, ident, None) = fieldpat.pat.kind { - if cx.tcx.find_field_index(ident, &variant) == - Some(cx.tcx.field_index(fieldpat.hir_id, cx.tables)) { - let mut err = cx.struct_span_lint(NON_SHORTHAND_FIELD_PATTERNS, - fieldpat.span, - &format!("the `{}:` in this pattern is redundant", ident)); + if cx.tcx.find_field_index(ident, &variant) + == Some(cx.tcx.field_index(fieldpat.hir_id, cx.tables)) + { + let mut err = cx.struct_span_lint( + NON_SHORTHAND_FIELD_PATTERNS, + fieldpat.span, + &format!("the `{}:` in this pattern is redundant", ident), + ); let binding = match binding_annot { hir::BindingAnnotation::Unannotated => None, hir::BindingAnnotation::Mutable => Some("mut"), @@ -195,7 +199,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns { fieldpat.span, "use shorthand field pattern", ident, - Applicability::MachineApplicable + Applicability::MachineApplicable, ); err.emit(); } @@ -227,9 +231,13 @@ impl UnsafeCode { impl EarlyLintPass for UnsafeCode { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) { if attr.check_name(sym::allow_internal_unsafe) { - self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \ + self.report_unsafe( + cx, + attr.span, + "`allow_internal_unsafe` allows defining \ macros using unsafe without triggering \ - the `unsafe_code` lint at their call site"); + the `unsafe_code` lint at their call site", + ); } } @@ -256,12 +264,14 @@ impl EarlyLintPass for UnsafeCode { } } - fn check_fn(&mut self, - cx: &EarlyContext<'_>, - fk: FnKind<'_>, - _: &ast::FnDecl, - span: Span, - _: ast::NodeId) { + fn check_fn( + &mut self, + cx: &EarlyContext<'_>, + fk: FnKind<'_>, + _: &ast::FnDecl, + span: Span, + _: ast::NodeId, + ) { match fk { FnKind::ItemFn(_, ast::FnHeader { unsafety: ast::Unsafety::Unsafe, .. }, ..) => { self.report_unsafe(cx, span, "declaration of an `unsafe` function") @@ -325,22 +335,21 @@ fn has_doc(attr: &ast::Attribute) -> bool { impl MissingDoc { pub fn new() -> MissingDoc { - MissingDoc { - doc_hidden_stack: vec![false], - private_traits: FxHashSet::default(), - } + MissingDoc { doc_hidden_stack: vec![false], private_traits: FxHashSet::default() } } fn doc_hidden(&self) -> bool { *self.doc_hidden_stack.last().expect("empty doc_hidden_stack") } - fn check_missing_docs_attrs(&self, - cx: &LateContext<'_, '_>, - id: Option, - attrs: &[ast::Attribute], - sp: Span, - desc: &'static str) { + fn check_missing_docs_attrs( + &self, + cx: &LateContext<'_, '_>, + id: Option, + attrs: &[ast::Attribute], + sp: Span, + desc: &'static str, + ) { // If we're building a test harness, then warning about // documentation is probably not really relevant right now. if cx.sess().opts.test { @@ -363,23 +372,25 @@ impl MissingDoc { let has_doc = attrs.iter().any(|a| has_doc(a)); if !has_doc { - cx.span_lint(MISSING_DOCS, - cx.tcx.sess.source_map().def_span(sp), - &format!("missing documentation for {}", desc)); + cx.span_lint( + MISSING_DOCS, + cx.tcx.sess.source_map().def_span(sp), + &format!("missing documentation for {}", desc), + ); } } } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { fn enter_lint_attrs(&mut self, _: &LateContext<'_, '_>, attrs: &[ast::Attribute]) { - let doc_hidden = self.doc_hidden() || - attrs.iter().any(|attr| { - attr.check_name(sym::doc) && - match attr.meta_item_list() { - None => false, - Some(l) => attr::list_contains_name(&l, sym::hidden), - } - }); + let doc_hidden = self.doc_hidden() + || attrs.iter().any(|attr| { + attr.check_name(sym::doc) + && match attr.meta_item_list() { + None => false, + Some(l) => attr::list_contains_name(&l, sym::hidden), + } + }); self.doc_hidden_stack.push(doc_hidden); } @@ -393,9 +404,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { for macro_def in krate.exported_macros { let has_doc = macro_def.attrs.iter().any(|a| has_doc(a)); if !has_doc { - cx.span_lint(MISSING_DOCS, - cx.tcx.sess.source_map().def_span(macro_def.span), - "missing documentation for macro"); + cx.span_lint( + MISSING_DOCS, + cx.tcx.sess.source_map().def_span(macro_def.span), + "missing documentation for macro", + ); } } } @@ -456,11 +469,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { hir::TraitItemKind::Type(..) => "an associated type", }; - self.check_missing_docs_attrs(cx, - Some(trait_item.hir_id), - &trait_item.attrs, - trait_item.span, - desc); + self.check_missing_docs_attrs( + cx, + Some(trait_item.hir_id), + &trait_item.attrs, + trait_item.span, + desc, + ); } fn check_impl_item(&mut self, cx: &LateContext<'_, '_>, impl_item: &hir::ImplItem<'_>) { @@ -475,29 +490,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { hir::ImplItemKind::TyAlias(_) => "an associated type", hir::ImplItemKind::OpaqueTy(_) => "an associated `impl Trait` type", }; - self.check_missing_docs_attrs(cx, - Some(impl_item.hir_id), - &impl_item.attrs, - impl_item.span, - desc); + self.check_missing_docs_attrs( + cx, + Some(impl_item.hir_id), + &impl_item.attrs, + impl_item.span, + desc, + ); } fn check_struct_field(&mut self, cx: &LateContext<'_, '_>, sf: &hir::StructField<'_>) { if !sf.is_positional() { - self.check_missing_docs_attrs(cx, - Some(sf.hir_id), - &sf.attrs, - sf.span, - "a struct field") + self.check_missing_docs_attrs(cx, Some(sf.hir_id), &sf.attrs, sf.span, "a struct field") } } fn check_variant(&mut self, cx: &LateContext<'_, '_>, v: &hir::Variant<'_>) { - self.check_missing_docs_attrs(cx, - Some(v.id), - &v.attrs, - v.span, - "a variant"); + self.check_missing_docs_attrs(cx, Some(v.id), &v.attrs, v.span, "a variant"); } } @@ -546,10 +555,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations { return; } if param_env.can_type_implement_copy(cx.tcx, ty).is_ok() { - cx.span_lint(MISSING_COPY_IMPLEMENTATIONS, - item.span, - "type could implement `Copy`; consider adding `impl \ - Copy`") + cx.span_lint( + MISSING_COPY_IMPLEMENTATIONS, + item.span, + "type could implement `Copy`; consider adding `impl \ + Copy`", + ) } } } @@ -574,9 +585,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { } match item.kind { - hir::ItemKind::Struct(..) | - hir::ItemKind::Union(..) | - hir::ItemKind::Enum(..) => {} + hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) | hir::ItemKind::Enum(..) => {} _ => return, } @@ -600,10 +609,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { } if !self.impling_types.as_ref().unwrap().contains(&item.hir_id) { - cx.span_lint(MISSING_DEBUG_IMPLEMENTATIONS, - item.span, - "type does not implement `fmt::Debug`; consider adding `#[derive(Debug)]` \ - or a manual implementation") + cx.span_lint( + MISSING_DEBUG_IMPLEMENTATIONS, + item.span, + "type does not implement `fmt::Debug`; consider adding `#[derive(Debug)]` \ + or a manual implementation", + ) } } } @@ -631,10 +642,7 @@ impl EarlyLintPass for AnonymousParameters { match arg.pat.kind { ast::PatKind::Ident(_, ident, None) => { if ident.name == kw::Invalid { - let ty_snip = cx - .sess - .source_map() - .span_to_snippet(arg.ty.span); + let ty_snip = cx.sess.source_map().span_to_snippet(arg.ty.span); let (ty_snip, appl) = if let Ok(snip) = ty_snip { (snip, Applicability::MachineApplicable) @@ -646,20 +654,22 @@ impl EarlyLintPass for AnonymousParameters { ANONYMOUS_PARAMETERS, arg.pat.span, "anonymous parameters are deprecated and will be \ - removed in the next edition." - ).span_suggestion( + removed in the next edition.", + ) + .span_suggestion( arg.pat.span, "Try naming the parameter or explicitly \ ignoring it", format!("_: {}", ty_snip), - appl - ).emit(); + appl, + ) + .emit(); } } _ => (), } } - }, + } _ => (), } } @@ -677,9 +687,7 @@ impl_lint_pass!(DeprecatedAttr => []); impl DeprecatedAttr { pub fn new() -> DeprecatedAttr { - DeprecatedAttr { - depr_attrs: deprecated_attributes(), - } + DeprecatedAttr { depr_attrs: deprecated_attributes() } } } @@ -694,7 +702,7 @@ fn lint_deprecated_attr( attr.span, suggestion.unwrap_or("remove this attribute"), String::new(), - Applicability::MachineApplicable + Applicability::MachineApplicable, ) .emit(); } @@ -703,12 +711,15 @@ impl EarlyLintPass for DeprecatedAttr { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) { for &&(n, _, _, ref g) in &self.depr_attrs { if attr.ident().map(|ident| ident.name) == Some(n) { - if let &AttributeGate::Gated(Stability::Deprecated(link, suggestion), - ref name, - ref reason, - _) = g { - let msg = format!("use of deprecated attribute `{}`: {}. See {}", - name, reason, link); + if let &AttributeGate::Gated( + Stability::Deprecated(link, suggestion), + ref name, + ref reason, + _, + ) = g + { + let msg = + format!("use of deprecated attribute `{}`: {}. See {}", name, reason, link); lint_deprecated_attr(cx, attr, &msg, suggestion); } return; @@ -737,7 +748,7 @@ impl UnusedDocComment { node_span: Span, node_kind: &str, is_macro_expansion: bool, - attrs: &[ast::Attribute] + attrs: &[ast::Attribute], ) { let mut attrs = attrs.into_iter().peekable(); @@ -747,10 +758,7 @@ impl UnusedDocComment { while let Some(attr) = attrs.next() { if attr.is_doc_comment() { sugared_span = Some( - sugared_span.map_or_else( - || attr.span, - |span| span.with_hi(attr.span.hi()), - ), + sugared_span.map_or_else(|| attr.span, |span| span.with_hi(attr.span.hi())), ); } @@ -765,12 +773,14 @@ impl UnusedDocComment { err.span_label( node_span, - format!("rustdoc does not generate documentation for {}", node_kind) + format!("rustdoc does not generate documentation for {}", node_kind), ); if is_macro_expansion { - err.help("to document an item produced by a macro, \ - the macro must produce the documentation as part of its expansion"); + err.help( + "to document an item produced by a macro, \ + the macro must produce the documentation as part of its expansion", + ); } err.emit(); @@ -792,8 +802,7 @@ impl EarlyLintPass for UnusedDocComment { ast::StmtKind::Item(..) => ("inner items", false), ast::StmtKind::Mac(..) => ("macro expansions", true), // expressions will be reported by `check_expr`. - ast::StmtKind::Semi(..) | - ast::StmtKind::Expr(..) => return, + ast::StmtKind::Semi(..) | ast::StmtKind::Expr(..) => return, }; self.warn_if_doc(cx, stmt.span, kind, is_macro_expansion, stmt.kind.attrs()); @@ -831,8 +840,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { for param in &generics.params { match param.kind { GenericParamKind::Lifetime { .. } => {} - GenericParamKind::Type { .. } | - GenericParamKind::Const { .. } => { + GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { let mut err = cx.struct_span_lint( NO_MANGLE_GENERIC_ITEMS, it.span, @@ -844,7 +852,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { String::new(), // Use of `#[no_mangle]` suggests FFI intent; correct // fix may be to monomorphize source by hand - Applicability::MaybeIncorrect + Applicability::MaybeIncorrect, ); err.emit(); break; @@ -861,7 +869,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { let mut err = cx.struct_span_lint(NO_MANGLE_CONST_ITEMS, it.span, msg); // account for "pub const" (#45562) - let start = cx.tcx.sess.source_map().span_to_snippet(it.span) + let start = cx + .tcx + .sess + .source_map() + .span_to_snippet(it.span) .map(|snippet| snippet.find("const").unwrap_or(0)) .unwrap_or(0) as u32; // `const` is 5 chars @@ -870,7 +882,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { const_span, "try a static value", "pub static".to_owned(), - Applicability::MachineApplicable + Applicability::MachineApplicable, ); err.emit(); } @@ -896,18 +908,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes { consider instead using an UnsafeCell"; match get_transmute_from_to(cx, expr).map(|(ty1, ty2)| (&ty1.kind, &ty2.kind)) { Some((&ty::Ref(_, _, from_mt), &ty::Ref(_, _, to_mt))) => { - if to_mt == hir::Mutability::Mut && - from_mt == hir::Mutability::Not { + if to_mt == hir::Mutability::Mut && from_mt == hir::Mutability::Not { cx.span_lint(MUTABLE_TRANSMUTES, expr.span, msg); } } _ => (), } - fn get_transmute_from_to<'a, 'tcx> - (cx: &LateContext<'a, 'tcx>, - expr: &hir::Expr) - -> Option<(Ty<'tcx>, Ty<'tcx>)> { + fn get_transmute_from_to<'a, 'tcx>( + cx: &LateContext<'a, 'tcx>, + expr: &hir::Expr, + ) -> Option<(Ty<'tcx>, Ty<'tcx>)> { let def = if let hir::ExprKind::Path(ref qpath) = expr.kind { cx.tables.qpath_res(qpath, expr.hir_id) } else { @@ -926,8 +937,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes { } fn def_id_is_transmute(cx: &LateContext<'_, '_>, def_id: DefId) -> bool { - cx.tcx.fn_sig(def_id).abi() == RustIntrinsic && - cx.tcx.item_name(def_id) == sym::transmute + cx.tcx.fn_sig(def_id).abi() == RustIntrinsic + && cx.tcx.item_name(def_id) == sym::transmute } } } @@ -967,8 +978,15 @@ declare_lint_pass!( ); impl UnreachablePub { - fn perform_lint(&self, cx: &LateContext<'_, '_>, what: &str, id: hir::HirId, - vis: &hir::Visibility, span: Span, exportable: bool) { + fn perform_lint( + &self, + cx: &LateContext<'_, '_>, + what: &str, + id: hir::HirId, + vis: &hir::Visibility, + span: Span, + exportable: bool, + ) { let mut applicability = Applicability::MachineApplicable; match vis.node { hir::VisibilityKind::Public if !cx.access_levels.is_reachable(id) => { @@ -976,13 +994,17 @@ impl UnreachablePub { applicability = Applicability::MaybeIncorrect; } let def_span = cx.tcx.sess.source_map().def_span(span); - let mut err = cx.struct_span_lint(UNREACHABLE_PUB, def_span, - &format!("unreachable `pub` {}", what)); + let mut err = cx.struct_span_lint( + UNREACHABLE_PUB, + def_span, + &format!("unreachable `pub` {}", what), + ); let replacement = if cx.tcx.features().crate_visibility_modifier { "crate" } else { "pub(crate)" - }.to_owned(); + } + .to_owned(); err.span_suggestion( vis.span, @@ -994,7 +1016,7 @@ impl UnreachablePub { err.help("or consider exporting it for use by other crates"); } err.emit(); - }, + } _ => {} } } @@ -1010,8 +1032,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub { cx: &LateContext<'_, '_>, foreign_item: &hir::ForeignItem<'tcx>, ) { - self.perform_lint(cx, "item", foreign_item.hir_id, &foreign_item.vis, - foreign_item.span, true); + self.perform_lint( + cx, + "item", + foreign_item.hir_id, + &foreign_item.vis, + foreign_item.span, + true, + ); } fn check_struct_field(&mut self, cx: &LateContext<'_, '_>, field: &hir::StructField<'_>) { @@ -1042,13 +1070,11 @@ impl TypeAliasBounds { hir::QPath::TypeRelative(ref ty, _) => { // If this is a type variable, we found a `T::Assoc`. match ty.kind { - hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => { - match path.res { - Res::Def(DefKind::TyParam, _) => true, - _ => false - } - } - _ => false + hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => match path.res { + Res::Def(DefKind::TyParam, _) => true, + _ => false, + }, + _ => false, } } hir::QPath::Resolved(..) => false, @@ -1062,19 +1088,20 @@ impl TypeAliasBounds { // We use a HIR visitor to walk the type. use rustc::hir::intravisit::{self, Visitor}; struct WalkAssocTypes<'a, 'db> { - err: &'a mut DiagnosticBuilder<'db> + err: &'a mut DiagnosticBuilder<'db>, } impl<'a, 'db, 'v> Visitor<'v> for WalkAssocTypes<'a, 'db> { - fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'v> - { + fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'v> { intravisit::NestedVisitorMap::None } fn visit_qpath(&mut self, qpath: &'v hir::QPath, id: hir::HirId, span: Span) { if TypeAliasBounds::is_type_variable_assoc(qpath) { - self.err.span_help(span, + self.err.span_help( + span, "use fully disambiguated paths (i.e., `::Assoc`) to refer to \ - associated types in type aliases"); + associated types in type aliases", + ); } intravisit::walk_qpath(self, qpath, id, span) } @@ -1095,10 +1122,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds { let mut suggested_changing_assoc_types = false; // There must not be a where clause if !type_alias_generics.where_clause.predicates.is_empty() { - let spans : Vec<_> = type_alias_generics.where_clause.predicates.iter() - .map(|pred| pred.span()).collect(); - let mut err = cx.struct_span_lint(TYPE_ALIAS_BOUNDS, spans, - "where clauses are not enforced in type aliases"); + let spans: Vec<_> = type_alias_generics + .where_clause + .predicates + .iter() + .map(|pred| pred.span()) + .collect(); + let mut err = cx.struct_span_lint( + TYPE_ALIAS_BOUNDS, + spans, + "where clauses are not enforced in type aliases", + ); err.span_suggestion( type_alias_generics.where_clause.span_for_predicates_or_empty_place(), "the clause will not be checked when the type alias is used, and should be removed", @@ -1114,10 +1148,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds { // The parameters must not have bounds for param in type_alias_generics.params.iter() { let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect(); - let suggestion = spans.iter().map(|sp| { - let start = param.span.between(*sp); // Include the `:` in `T: Bound`. - (start.to(*sp), String::new()) - }).collect(); + let suggestion = spans + .iter() + .map(|sp| { + let start = param.span.between(*sp); // Include the `:` in `T: Bound`. + (start.to(*sp), String::new()) + }) + .collect(); if !spans.is_empty() { let mut err = cx.struct_span_lint( TYPE_ALIAS_BOUNDS, @@ -1157,11 +1194,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst { match it.kind { hir::ItemKind::Const(_, body_id) => { check_const(cx, body_id); - }, + } hir::ItemKind::Static(_, _, body_id) => { check_const(cx, body_id); - }, - _ => {}, + } + _ => {} } } } @@ -1179,11 +1216,7 @@ declare_lint_pass!( ); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints { - fn check_item( - &mut self, - cx: &LateContext<'a, 'tcx>, - item: &'tcx hir::Item<'tcx>, - ) { + fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item<'tcx>) { use rustc::ty::fold::TypeFoldable; use rustc::ty::Predicate::*; @@ -1210,8 +1243,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints { cx.span_lint( TRIVIAL_BOUNDS, span, - &format!("{} bound {} does not depend on any type \ - or lifetime parameters", predicate_kind_name, predicate), + &format!( + "{} bound {} does not depend on any type \ + or lifetime parameters", + predicate_kind_name, predicate + ), ); } } @@ -1261,7 +1297,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &ast::Pat) { if self.node_id.is_some() { // Don't recursively warn about patterns inside range endpoints. - return + return; } use self::ast::{PatKind, RangeEnd, RangeSyntax::DotDotDot}; @@ -1333,18 +1369,15 @@ impl_lint_pass!(UnnameableTestItems => [UNNAMEABLE_TEST_ITEMS]); impl UnnameableTestItems { pub fn new() -> Self { - Self { - boundary: hir::DUMMY_HIR_ID, - items_nameable: true - } + Self { boundary: hir::DUMMY_HIR_ID, items_nameable: true } } } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems { fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item<'_>) { if self.items_nameable { - if let hir::ItemKind::Mod(..) = it.kind {} - else { + if let hir::ItemKind::Mod(..) = it.kind { + } else { self.items_nameable = false; self.boundary = it.hir_id; } @@ -1352,11 +1385,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems { } if let Some(attr) = attr::find_by_name(&it.attrs, sym::rustc_test_marker) { - cx.struct_span_lint( - UNNAMEABLE_TEST_ITEMS, - attr.span, - "cannot test inner items", - ).emit(); + cx.struct_span_lint(UNNAMEABLE_TEST_ITEMS, attr.span, "cannot test inner items").emit(); } } @@ -1389,21 +1418,22 @@ impl KeywordIdents { for tt in tokens.into_trees() { match tt { // Only report non-raw idents. - TokenTree::Token(token) => if let Some((ident, false)) = token.ident() { - self.check_ident_token(cx, UnderMacro(true), ident); + TokenTree::Token(token) => { + if let Some((ident, false)) = token.ident() { + self.check_ident_token(cx, UnderMacro(true), ident); + } } - TokenTree::Delimited(_, _, tts) => { - self.check_tokens(cx, tts) - }, + TokenTree::Delimited(_, _, tts) => self.check_tokens(cx, tts), } } } - fn check_ident_token(&mut self, - cx: &EarlyContext<'_>, - UnderMacro(under_macro): UnderMacro, - ident: ast::Ident) - { + fn check_ident_token( + &mut self, + cx: &EarlyContext<'_>, + UnderMacro(under_macro): UnderMacro, + ident: ast::Ident, + ) { let next_edition = match cx.sess.edition() { Edition::Edition2015 => { match ident.name { @@ -1470,35 +1500,35 @@ impl ExplicitOutlivesRequirements { inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)], index: u32, ) -> Vec> { - inferred_outlives.iter().filter_map(|(pred, _)| { - match pred { + inferred_outlives + .iter() + .filter_map(|(pred, _)| match pred { ty::Predicate::RegionOutlives(outlives) => { let outlives = outlives.skip_binder(); match outlives.0 { - ty::ReEarlyBound(ebr) if ebr.index == index => { - Some(outlives.1) - } + ty::ReEarlyBound(ebr) if ebr.index == index => Some(outlives.1), _ => None, } } - _ => None - } - }).collect() + _ => None, + }) + .collect() } fn lifetimes_outliving_type<'tcx>( inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)], index: u32, ) -> Vec> { - inferred_outlives.iter().filter_map(|(pred, _)| { - match pred { + inferred_outlives + .iter() + .filter_map(|(pred, _)| match pred { ty::Predicate::TypeOutlives(outlives) => { let outlives = outlives.skip_binder(); outlives.0.is_param(index).then_some(outlives.1) } - _ => None - } - }).collect() + _ => None, + }) + .collect() } fn collect_outlived_lifetimes<'tcx>( @@ -1508,8 +1538,7 @@ impl ExplicitOutlivesRequirements { inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)], ty_generics: &'tcx ty::Generics, ) -> Vec> { - let index = ty_generics.param_def_id_to_index[ - &tcx.hir().local_def_id(param.hir_id)]; + let index = ty_generics.param_def_id_to_index[&tcx.hir().local_def_id(param.hir_id)]; match param.kind { hir::GenericParamKind::Lifetime { .. } => { @@ -1522,7 +1551,6 @@ impl ExplicitOutlivesRequirements { } } - fn collect_outlives_bound_spans<'tcx>( &self, tcx: TyCtxt<'tcx>, @@ -1538,19 +1566,12 @@ impl ExplicitOutlivesRequirements { .filter_map(|(i, bound)| { if let hir::GenericBound::Outlives(lifetime) = bound { let is_inferred = match tcx.named_region(lifetime.hir_id) { - Some(Region::Static) if infer_static => { - inferred_outlives.iter() - .any(|r| if let ty::ReStatic = r { true } else { false }) - } - Some(Region::EarlyBound(index, ..)) => inferred_outlives + Some(Region::Static) if infer_static => inferred_outlives .iter() - .any(|r| { - if let ty::ReEarlyBound(ebr) = r { - ebr.index == index - } else { - false - } - }), + .any(|r| if let ty::ReStatic = r { true } else { false }), + Some(Region::EarlyBound(index, ..)) => inferred_outlives.iter().any(|r| { + if let ty::ReEarlyBound(ebr) = r { ebr.index == index } else { false } + }), _ => false, }; is_inferred.then_some((i, bound.span())) @@ -1565,13 +1586,13 @@ impl ExplicitOutlivesRequirements { &self, lo: Span, bounds: &hir::GenericBounds, - bound_spans: Vec<(usize, Span)> + bound_spans: Vec<(usize, Span)>, ) -> Vec { if bounds.is_empty() { return Vec::new(); } if bound_spans.len() == bounds.len() { - let (_, last_bound_span) = bound_spans[bound_spans.len()-1]; + let (_, last_bound_span) = bound_spans[bound_spans.len() - 1]; // If all bounds are inferable, we want to delete the colon, so // start from just after the parameter (span passed as argument) vec![lo.to(last_bound_span)] @@ -1586,14 +1607,14 @@ impl ExplicitOutlivesRequirements { None if i == 0 => { merged.push(bound_span.to(bounds[1].span().shrink_to_lo())); last_merged_i = Some(0); - }, + } // If consecutive bounds are inferable, merge their spans - Some(h) if i == h+1 => { + Some(h) if i == h + 1 => { if let Some(tail) = merged.last_mut() { // Also eat the trailing `+` if the first // more-than-one bound is inferable let to_span = if from_start && i < bounds.len() { - bounds[i+1].span().shrink_to_lo() + bounds[i + 1].span().shrink_to_lo() } else { bound_span }; @@ -1602,13 +1623,13 @@ impl ExplicitOutlivesRequirements { } else { bug!("another bound-span visited earlier"); } - }, + } _ => { // When we find a non-inferable bound, subsequent inferable bounds // won't be consecutive from the start (and we'll eat the leading // `+` rather than the trailing one) from_start = false; - merged.push(bounds[i-1].span().shrink_to_hi().to(bound_span)); + merged.push(bounds[i - 1].span().shrink_to_hi().to(bound_span)); last_merged_i = Some(i); } } @@ -1625,8 +1646,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { let infer_static = cx.tcx.features().infer_static_outlives_requirements; let def_id = cx.tcx.hir().local_def_id(item.hir_id); if let hir::ItemKind::Struct(_, ref hir_generics) - | hir::ItemKind::Enum(_, ref hir_generics) - | hir::ItemKind::Union(_, ref hir_generics) = item.kind + | hir::ItemKind::Enum(_, ref hir_generics) + | hir::ItemKind::Union(_, ref hir_generics) = item.kind { let inferred_outlives = cx.tcx.inferred_outlives_of(def_id); if inferred_outlives.is_empty() { @@ -1640,35 +1661,30 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { for param in &hir_generics.params { let has_lifetime_bounds = param.bounds.iter().any(|bound| { - if let hir::GenericBound::Outlives(_) = bound { - true - } else { - false - } + if let hir::GenericBound::Outlives(_) = bound { true } else { false } }); if !has_lifetime_bounds { continue; } - let relevant_lifetimes = self.collect_outlived_lifetimes( - param, - cx.tcx, - inferred_outlives, - ty_generics, - ); + let relevant_lifetimes = + self.collect_outlived_lifetimes(param, cx.tcx, inferred_outlives, ty_generics); if relevant_lifetimes.is_empty() { continue; } let bound_spans = self.collect_outlives_bound_spans( - cx.tcx, ¶m.bounds, &relevant_lifetimes, infer_static, + cx.tcx, + ¶m.bounds, + &relevant_lifetimes, + infer_static, ); bound_count += bound_spans.len(); - lint_spans.extend( - self.consolidate_outlives_bound_spans( - param.span.shrink_to_hi(), ¶m.bounds, bound_spans - ) - ); + lint_spans.extend(self.consolidate_outlives_bound_spans( + param.span.shrink_to_hi(), + ¶m.bounds, + bound_spans, + )); } let mut where_lint_spans = Vec::new(); @@ -1677,8 +1693,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { for (i, where_predicate) in hir_generics.where_clause.predicates.iter().enumerate() { let (relevant_lifetimes, bounds, span) = match where_predicate { hir::WherePredicate::RegionPredicate(predicate) => { - if let Some(Region::EarlyBound(index, ..)) - = cx.tcx.named_region(predicate.lifetime.hir_id) + if let Some(Region::EarlyBound(index, ..)) = + cx.tcx.named_region(predicate.lifetime.hir_id) { ( Self::lifetimes_outliving_lifetime(inferred_outlives, index), @@ -1693,10 +1709,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { // FIXME we can also infer bounds on associated types, // and should check for them here. match predicate.bounded_ty.kind { - hir::TyKind::Path(hir::QPath::Resolved( - None, - ref path, - )) => { + hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => { if let Res::Def(DefKind::TyParam, def_id) = path.res { let index = ty_generics.param_def_id_to_index[&def_id]; ( @@ -1707,8 +1720,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { } else { continue; } - }, - _ => { continue; } + } + _ => { + continue; + } } } _ => continue, @@ -1718,7 +1733,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { } let bound_spans = self.collect_outlives_bound_spans( - cx.tcx, bounds, &relevant_lifetimes, infer_static, + cx.tcx, + bounds, + &relevant_lifetimes, + infer_static, ); bound_count += bound_spans.len(); @@ -1731,38 +1749,33 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { // further predicates, we want to eat the trailing comma. if drop_predicate && i + 1 < num_predicates { let next_predicate_span = hir_generics.where_clause.predicates[i + 1].span(); - where_lint_spans.push( - span.to(next_predicate_span.shrink_to_lo()) - ); + where_lint_spans.push(span.to(next_predicate_span.shrink_to_lo())); } else { - where_lint_spans.extend( - self.consolidate_outlives_bound_spans( - span.shrink_to_lo(), - bounds, - bound_spans - ) - ); + where_lint_spans.extend(self.consolidate_outlives_bound_spans( + span.shrink_to_lo(), + bounds, + bound_spans, + )); } } // If all predicates are inferable, drop the entire clause // (including the `where`) if num_predicates > 0 && dropped_predicate_count == num_predicates { - let where_span = hir_generics.where_clause.span() + let where_span = hir_generics + .where_clause + .span() .expect("span of (nonempty) where clause should exist"); // Extend the where clause back to the closing `>` of the // generics, except for tuple struct, which have the `where` // after the fields of the struct. - let full_where_span = if let hir::ItemKind::Struct(hir::VariantData::Tuple(..), _) - = item.kind - { - where_span - } else { - hir_generics.span.shrink_to_hi().to(where_span) - }; - lint_spans.push( - full_where_span - ); + let full_where_span = + if let hir::ItemKind::Struct(hir::VariantData::Tuple(..), _) = item.kind { + where_span + } else { + hir_generics.span.shrink_to_hi().to(where_span) + }; + lint_spans.push(full_where_span); } else { lint_spans.extend(where_lint_spans); } @@ -1771,16 +1784,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { let mut err = cx.struct_span_lint( EXPLICIT_OUTLIVES_REQUIREMENTS, lint_spans.clone(), - "outlives requirements can be inferred" + "outlives requirements can be inferred", ); err.multipart_suggestion( - if bound_count == 1 { - "remove this bound" - } else { - "remove these bounds" - }, + if bound_count == 1 { "remove this bound" } else { "remove these bounds" }, lint_spans.into_iter().map(|span| (span, "".to_owned())).collect::>(), - Applicability::MachineApplicable + Applicability::MachineApplicable, ); err.emit(); } @@ -1802,8 +1811,10 @@ declare_lint_pass!( impl EarlyLintPass for IncompleteFeatures { fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) { let features = cx.sess.features_untracked(); - features.declared_lang_features - .iter().map(|(name, span, _)| (name, span)) + features + .declared_lang_features + .iter() + .map(|(name, span, _)| (name, span)) .chain(features.declared_lib_features.iter().map(|(name, span)| (name, span))) .filter(|(name, _)| rustc_feature::INCOMPLETE_FEATURES.iter().any(|f| name == &f)) .for_each(|(name, &span)| { @@ -1813,7 +1824,7 @@ impl EarlyLintPass for IncompleteFeatures { &format!( "the feature `{}` is incomplete and may cause the compiler to crash", name, - ) + ), ) .emit(); }); @@ -1830,9 +1841,11 @@ declare_lint_pass!(InvalidValue => [INVALID_VALUE]); impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &hir::Expr) { - #[derive(Debug, Copy, Clone, PartialEq)] - enum InitKind { Zeroed, Uninit }; + enum InitKind { + Zeroed, + Uninit, + }; /// Information about why a type cannot be initialized this way. /// Contains an error message and optionally a span to point at. @@ -1843,16 +1856,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { use hir::ExprKind::*; use syntax::ast::LitKind::*; match &expr.kind { - Lit(lit) => + Lit(lit) => { if let Int(i, _) = lit.node { i == 0 } else { false - }, - Tup(tup) => - tup.iter().all(is_zero), - _ => - false + } + } + Tup(tup) => tup.iter().all(is_zero), + _ => false, } } @@ -1888,7 +1900,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { // See if the `self` parameter is one of the dangerous constructors. if let hir::ExprKind::Call(ref path_expr, _) = args[0].kind { if let hir::ExprKind::Path(ref qpath) = path_expr.kind { - let def_id = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id()?; + let def_id = + cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id()?; if cx.tcx.is_diagnostic_item(sym::maybe_uninit_zeroed, def_id) { return Some(InitKind::Zeroed); @@ -1917,13 +1930,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { Adt(..) if ty.is_box() => Some((format!("`Box` must be non-null"), None)), FnPtr(..) => Some((format!("Function pointers must be non-null"), None)), Never => Some((format!("The never type (`!`) has no valid value"), None)), - RawPtr(tm) if matches!(tm.ty.kind, Dynamic(..)) => // raw ptr to dyn Trait - Some((format!("The vtable of a wide raw pointer must be non-null"), None)), + RawPtr(tm) if matches!(tm.ty.kind, Dynamic(..)) => + // raw ptr to dyn Trait + { + Some((format!("The vtable of a wide raw pointer must be non-null"), None)) + } // Primitive types with other constraints. - Bool if init == InitKind::Uninit => - Some((format!("Booleans must be `true` or `false`"), None)), - Char if init == InitKind::Uninit => - Some((format!("Characters must be a valid unicode codepoint"), None)), + Bool if init == InitKind::Uninit => { + Some((format!("Booleans must be `true` or `false`"), None)) + } + Char if init == InitKind::Uninit => { + Some((format!("Characters must be a valid unicode codepoint"), None)) + } // Recurse and checks for some compound types. Adt(adt_def, substs) if !adt_def.is_union() => { // First check f this ADT has a layout attribute (like `NonNull` and friends). @@ -1932,14 +1950,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { // We exploit here that `layout_scalar_valid_range` will never // return `Bound::Excluded`. (And we have tests checking that we // handle the attribute correctly.) - (Bound::Included(lo), _) if lo > 0 => - return Some((format!("{} must be non-null", ty), None)), + (Bound::Included(lo), _) if lo > 0 => { + return Some((format!("{} must be non-null", ty), None)); + } (Bound::Included(_), _) | (_, Bound::Included(_)) - if init == InitKind::Uninit => + if init == InitKind::Uninit => + { return Some(( format!("{} must be initialized inside its custom valid range", ty), None, - )), + )); + } _ => {} } // Now, recurse. @@ -1950,21 +1971,25 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { // Proceed recursively, check all fields. let variant = &adt_def.variants[VariantIdx::from_u32(0)]; variant.fields.iter().find_map(|field| { - ty_find_init_error( - tcx, - field.ty(tcx, substs), - init, - ).map(|(mut msg, span)| if span.is_none() { - // Point to this field, should be helpful for figuring - // out where the source of the error is. - let span = tcx.def_span(field.did); - write!(&mut msg, " (in this {} field)", adt_def.descr()) - .unwrap(); - (msg, Some(span)) - } else { - // Just forward. - (msg, span) - }) + ty_find_init_error(tcx, field.ty(tcx, substs), init).map( + |(mut msg, span)| { + if span.is_none() { + // Point to this field, should be helpful for figuring + // out where the source of the error is. + let span = tcx.def_span(field.did); + write!( + &mut msg, + " (in this {} field)", + adt_def.descr() + ) + .unwrap(); + (msg, Some(span)) + } else { + // Just forward. + (msg, span) + } + }, + ) }) } // Multi-variant enums are tricky: if all but one variant are @@ -2000,10 +2025,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { }, ), ); - err.span_label(expr.span, - "this code causes undefined behavior when executed"); - err.span_label(expr.span, "help: use `MaybeUninit` instead, \ - and only call `assume_init` after initialization is done"); + err.span_label(expr.span, "this code causes undefined behavior when executed"); + err.span_label( + expr.span, + "help: use `MaybeUninit` instead, \ + and only call `assume_init` after initialization is done", + ); if let Some(span) = span { err.span_note(span, &msg); } else { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index b77f2cb8d6e35..e4dd2f006ab23 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -10,15 +10,13 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] - #![cfg_attr(test, feature(test))] #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(nll)] #![feature(matches_macro)] - -#![recursion_limit="256"] +#![recursion_limit = "256"] #[macro_use] extern crate rustc; @@ -26,25 +24,21 @@ extern crate rustc; extern crate rustc_session; mod array_into_iter; +pub mod builtin; +mod non_ascii_idents; mod nonstandard_style; mod redundant_semicolon; -pub mod builtin; mod types; mod unused; -mod non_ascii_idents; +use rustc::hir; +use rustc::hir::def_id::DefId; use rustc::lint; -use rustc::lint::{EarlyContext, LateContext, LateLintPass, EarlyLintPass, LintPass, LintArray}; use rustc::lint::builtin::{ - BARE_TRAIT_OBJECTS, - ELIDED_LIFETIMES_IN_PATHS, - EXPLICIT_OUTLIVES_REQUIREMENTS, - INTRA_DOC_LINK_RESOLUTION_FAILURE, - MISSING_DOC_CODE_EXAMPLES, - PRIVATE_DOC_TESTS, + BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, + INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, }; -use rustc::hir; -use rustc::hir::def_id::DefId; +use rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintPass}; use rustc::ty::query::Providers; use rustc::ty::TyCtxt; @@ -53,23 +47,20 @@ use syntax_pos::Span; use lint::LintId; -use redundant_semicolon::*; -use nonstandard_style::*; +use array_into_iter::ArrayIntoIter; use builtin::*; -use types::*; -use unused::*; use non_ascii_idents::*; +use nonstandard_style::*; +use redundant_semicolon::*; use rustc::lint::internal::*; -use array_into_iter::ArrayIntoIter; +use types::*; +use unused::*; /// Useful for other parts of the compiler. pub use builtin::SoftLints; pub fn provide(providers: &mut Providers<'_>) { - *providers = Providers { - lint_mod, - ..*providers - }; + *providers = Providers { lint_mod, ..*providers }; } fn lint_mod(tcx: TyCtxt<'_>, module_def_id: DefId) { @@ -77,30 +68,30 @@ fn lint_mod(tcx: TyCtxt<'_>, module_def_id: DefId) { } macro_rules! pre_expansion_lint_passes { - ($macro:path, $args:tt) => ( - $macro!($args, [ - KeywordIdents: KeywordIdents, - UnusedDocComment: UnusedDocComment, - ]); - ) + ($macro:path, $args:tt) => { + $macro!($args, [KeywordIdents: KeywordIdents, UnusedDocComment: UnusedDocComment,]); + }; } macro_rules! early_lint_passes { - ($macro:path, $args:tt) => ( - $macro!($args, [ - UnusedParens: UnusedParens, - UnusedImportBraces: UnusedImportBraces, - UnsafeCode: UnsafeCode, - AnonymousParameters: AnonymousParameters, - EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(), - NonCamelCaseTypes: NonCamelCaseTypes, - DeprecatedAttr: DeprecatedAttr::new(), - WhileTrue: WhileTrue, - NonAsciiIdents: NonAsciiIdents, - IncompleteFeatures: IncompleteFeatures, - RedundantSemicolon: RedundantSemicolon, - ]); - ) + ($macro:path, $args:tt) => { + $macro!( + $args, + [ + UnusedParens: UnusedParens, + UnusedImportBraces: UnusedImportBraces, + UnsafeCode: UnsafeCode, + AnonymousParameters: AnonymousParameters, + EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(), + NonCamelCaseTypes: NonCamelCaseTypes, + DeprecatedAttr: DeprecatedAttr::new(), + WhileTrue: WhileTrue, + NonAsciiIdents: NonAsciiIdents, + IncompleteFeatures: IncompleteFeatures, + RedundantSemicolon: RedundantSemicolon, + ] + ); + }; } macro_rules! declare_combined_early_pass { @@ -113,71 +104,62 @@ pre_expansion_lint_passes!(declare_combined_early_pass, [BuiltinCombinedPreExpan early_lint_passes!(declare_combined_early_pass, [BuiltinCombinedEarlyLintPass]); macro_rules! late_lint_passes { - ($macro:path, $args:tt) => ( - $macro!($args, [ - // FIXME: Look into regression when this is used as a module lint - // May Depend on constants elsewhere - UnusedBrokenConst: UnusedBrokenConst, - - // Uses attr::is_used which is untracked, can't be an incremental module pass. - UnusedAttributes: UnusedAttributes::new(), - - // Needs to run after UnusedAttributes as it marks all `feature` attributes as used. - UnstableFeatures: UnstableFeatures, - - // Tracks state across modules - UnnameableTestItems: UnnameableTestItems::new(), - - // Tracks attributes of parents - MissingDoc: MissingDoc::new(), - - // Depends on access levels - // FIXME: Turn the computation of types which implement Debug into a query - // and change this to a module lint pass - MissingDebugImplementations: MissingDebugImplementations::default(), - - ArrayIntoIter: ArrayIntoIter, - ]); - ) + ($macro:path, $args:tt) => { + $macro!( + $args, + [ + // FIXME: Look into regression when this is used as a module lint + // May Depend on constants elsewhere + UnusedBrokenConst: UnusedBrokenConst, + // Uses attr::is_used which is untracked, can't be an incremental module pass. + UnusedAttributes: UnusedAttributes::new(), + // Needs to run after UnusedAttributes as it marks all `feature` attributes as used. + UnstableFeatures: UnstableFeatures, + // Tracks state across modules + UnnameableTestItems: UnnameableTestItems::new(), + // Tracks attributes of parents + MissingDoc: MissingDoc::new(), + // Depends on access levels + // FIXME: Turn the computation of types which implement Debug into a query + // and change this to a module lint pass + MissingDebugImplementations: MissingDebugImplementations::default(), + ArrayIntoIter: ArrayIntoIter, + ] + ); + }; } macro_rules! late_lint_mod_passes { - ($macro:path, $args:tt) => ( - $macro!($args, [ - HardwiredLints: HardwiredLints, - ImproperCTypes: ImproperCTypes, - VariantSizeDifferences: VariantSizeDifferences, - BoxPointers: BoxPointers, - PathStatements: PathStatements, - - // Depends on referenced function signatures in expressions - UnusedResults: UnusedResults, - - NonUpperCaseGlobals: NonUpperCaseGlobals, - NonShorthandFieldPatterns: NonShorthandFieldPatterns, - UnusedAllocation: UnusedAllocation, - - // Depends on types used in type definitions - MissingCopyImplementations: MissingCopyImplementations, - - // Depends on referenced function signatures in expressions - MutableTransmutes: MutableTransmutes, - - TypeAliasBounds: TypeAliasBounds, - - TrivialConstraints: TrivialConstraints, - TypeLimits: TypeLimits::new(), - - NonSnakeCase: NonSnakeCase, - InvalidNoMangleItems: InvalidNoMangleItems, - - // Depends on access levels - UnreachablePub: UnreachablePub, - - ExplicitOutlivesRequirements: ExplicitOutlivesRequirements, - InvalidValue: InvalidValue, - ]); - ) + ($macro:path, $args:tt) => { + $macro!( + $args, + [ + HardwiredLints: HardwiredLints, + ImproperCTypes: ImproperCTypes, + VariantSizeDifferences: VariantSizeDifferences, + BoxPointers: BoxPointers, + PathStatements: PathStatements, + // Depends on referenced function signatures in expressions + UnusedResults: UnusedResults, + NonUpperCaseGlobals: NonUpperCaseGlobals, + NonShorthandFieldPatterns: NonShorthandFieldPatterns, + UnusedAllocation: UnusedAllocation, + // Depends on types used in type definitions + MissingCopyImplementations: MissingCopyImplementations, + // Depends on referenced function signatures in expressions + MutableTransmutes: MutableTransmutes, + TypeAliasBounds: TypeAliasBounds, + TrivialConstraints: TrivialConstraints, + TypeLimits: TypeLimits::new(), + NonSnakeCase: NonSnakeCase, + InvalidNoMangleItems: InvalidNoMangleItems, + // Depends on access levels + UnreachablePub: UnreachablePub, + ExplicitOutlivesRequirements: ExplicitOutlivesRequirements, + InvalidValue: InvalidValue, + ] + ); + }; } macro_rules! declare_combined_late_pass { @@ -213,10 +195,10 @@ fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { } macro_rules! register_pass { - ($method:ident, $ty:ident, $constructor:expr) => ( + ($method:ident, $ty:ident, $constructor:expr) => { store.register_lints(&$ty::get_lints()); store.$method(|| box $constructor); - ) + }; } macro_rules! register_passes { @@ -239,52 +221,57 @@ fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { store.register_lints(&BuiltinCombinedLateLintPass::get_lints()); } - add_lint_group!("nonstandard_style", - NON_CAMEL_CASE_TYPES, - NON_SNAKE_CASE, - NON_UPPER_CASE_GLOBALS); - - add_lint_group!("unused", - UNUSED_IMPORTS, - UNUSED_VARIABLES, - UNUSED_ASSIGNMENTS, - DEAD_CODE, - UNUSED_MUT, - UNREACHABLE_CODE, - UNREACHABLE_PATTERNS, - OVERLAPPING_PATTERNS, - UNUSED_MUST_USE, - UNUSED_UNSAFE, - PATH_STATEMENTS, - UNUSED_ATTRIBUTES, - UNUSED_MACROS, - UNUSED_ALLOCATION, - UNUSED_DOC_COMMENTS, - UNUSED_EXTERN_CRATES, - UNUSED_FEATURES, - UNUSED_LABELS, - UNUSED_PARENS); - - add_lint_group!("rust_2018_idioms", - BARE_TRAIT_OBJECTS, - UNUSED_EXTERN_CRATES, - ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, - ELIDED_LIFETIMES_IN_PATHS, - EXPLICIT_OUTLIVES_REQUIREMENTS - - // FIXME(#52665, #47816) not always applicable and not all - // macros are ready for this yet. - // UNREACHABLE_PUB, - - // FIXME macro crates are not up for this yet, too much - // breakage is seen if we try to encourage this lint. - // MACRO_USE_EXTERN_CRATE, - ); - - add_lint_group!("rustdoc", - INTRA_DOC_LINK_RESOLUTION_FAILURE, - MISSING_DOC_CODE_EXAMPLES, - PRIVATE_DOC_TESTS); + add_lint_group!( + "nonstandard_style", + NON_CAMEL_CASE_TYPES, + NON_SNAKE_CASE, + NON_UPPER_CASE_GLOBALS + ); + + add_lint_group!( + "unused", + UNUSED_IMPORTS, + UNUSED_VARIABLES, + UNUSED_ASSIGNMENTS, + DEAD_CODE, + UNUSED_MUT, + UNREACHABLE_CODE, + UNREACHABLE_PATTERNS, + OVERLAPPING_PATTERNS, + UNUSED_MUST_USE, + UNUSED_UNSAFE, + PATH_STATEMENTS, + UNUSED_ATTRIBUTES, + UNUSED_MACROS, + UNUSED_ALLOCATION, + UNUSED_DOC_COMMENTS, + UNUSED_EXTERN_CRATES, + UNUSED_FEATURES, + UNUSED_LABELS, + UNUSED_PARENS + ); + + add_lint_group!( + "rust_2018_idioms", + BARE_TRAIT_OBJECTS, + UNUSED_EXTERN_CRATES, + ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, + ELIDED_LIFETIMES_IN_PATHS, + EXPLICIT_OUTLIVES_REQUIREMENTS // FIXME(#52665, #47816) not always applicable and not all + // macros are ready for this yet. + // UNREACHABLE_PUB, + + // FIXME macro crates are not up for this yet, too much + // breakage is seen if we try to encourage this lint. + // MACRO_USE_EXTERN_CRATE + ); + + add_lint_group!( + "rustdoc", + INTRA_DOC_LINK_RESOLUTION_FAILURE, + MISSING_DOC_CODE_EXAMPLES, + PRIVATE_DOC_TESTS + ); // Register renamed and removed lints. store.register_renamed("single_use_lifetime", "single_use_lifetimes"); @@ -305,52 +292,95 @@ fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { store.register_removed("drop_with_repr_extern", "drop flags have been removed"); store.register_removed("fat_ptr_transmutes", "was accidentally removed back in 2014"); store.register_removed("deprecated_attr", "use `deprecated` instead"); - store.register_removed("transmute_from_fn_item_types", - "always cast functions before transmuting them"); - store.register_removed("hr_lifetime_in_assoc_type", - "converted into hard error, see https://github.com/rust-lang/rust/issues/33685"); - store.register_removed("inaccessible_extern_crate", - "converted into hard error, see https://github.com/rust-lang/rust/issues/36886"); - store.register_removed("super_or_self_in_global_path", - "converted into hard error, see https://github.com/rust-lang/rust/issues/36888"); - store.register_removed("overlapping_inherent_impls", - "converted into hard error, see https://github.com/rust-lang/rust/issues/36889"); - store.register_removed("illegal_floating_point_constant_pattern", - "converted into hard error, see https://github.com/rust-lang/rust/issues/36890"); - store.register_removed("illegal_struct_or_enum_constant_pattern", - "converted into hard error, see https://github.com/rust-lang/rust/issues/36891"); - store.register_removed("lifetime_underscore", - "converted into hard error, see https://github.com/rust-lang/rust/issues/36892"); - store.register_removed("extra_requirement_in_impl", - "converted into hard error, see https://github.com/rust-lang/rust/issues/37166"); - store.register_removed("legacy_imports", - "converted into hard error, see https://github.com/rust-lang/rust/issues/38260"); - store.register_removed("coerce_never", - "converted into hard error, see https://github.com/rust-lang/rust/issues/48950"); - store.register_removed("resolve_trait_on_defaulted_unit", - "converted into hard error, see https://github.com/rust-lang/rust/issues/48950"); - store.register_removed("private_no_mangle_fns", - "no longer a warning, `#[no_mangle]` functions always exported"); - store.register_removed("private_no_mangle_statics", - "no longer a warning, `#[no_mangle]` statics always exported"); - store.register_removed("bad_repr", - "replaced with a generic attribute input check"); - store.register_removed("duplicate_matcher_binding_name", - "converted into hard error, see https://github.com/rust-lang/rust/issues/57742"); - store.register_removed("incoherent_fundamental_impls", - "converted into hard error, see https://github.com/rust-lang/rust/issues/46205"); - store.register_removed("legacy_constructor_visibility", - "converted into hard error, see https://github.com/rust-lang/rust/issues/39207"); - store.register_removed("legacy_directory_ownership", - "converted into hard error, see https://github.com/rust-lang/rust/issues/37872"); - store.register_removed("safe_extern_statics", - "converted into hard error, see https://github.com/rust-lang/rust/issues/36247"); - store.register_removed("parenthesized_params_in_types_and_modules", - "converted into hard error, see https://github.com/rust-lang/rust/issues/42238"); - store.register_removed("duplicate_macro_exports", - "converted into hard error, see https://github.com/rust-lang/rust/issues/35896"); - store.register_removed("nested_impl_trait", - "converted into hard error, see https://github.com/rust-lang/rust/issues/59014"); + store.register_removed( + "transmute_from_fn_item_types", + "always cast functions before transmuting them", + ); + store.register_removed( + "hr_lifetime_in_assoc_type", + "converted into hard error, see https://github.com/rust-lang/rust/issues/33685", + ); + store.register_removed( + "inaccessible_extern_crate", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36886", + ); + store.register_removed( + "super_or_self_in_global_path", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36888", + ); + store.register_removed( + "overlapping_inherent_impls", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36889", + ); + store.register_removed( + "illegal_floating_point_constant_pattern", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36890", + ); + store.register_removed( + "illegal_struct_or_enum_constant_pattern", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36891", + ); + store.register_removed( + "lifetime_underscore", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36892", + ); + store.register_removed( + "extra_requirement_in_impl", + "converted into hard error, see https://github.com/rust-lang/rust/issues/37166", + ); + store.register_removed( + "legacy_imports", + "converted into hard error, see https://github.com/rust-lang/rust/issues/38260", + ); + store.register_removed( + "coerce_never", + "converted into hard error, see https://github.com/rust-lang/rust/issues/48950", + ); + store.register_removed( + "resolve_trait_on_defaulted_unit", + "converted into hard error, see https://github.com/rust-lang/rust/issues/48950", + ); + store.register_removed( + "private_no_mangle_fns", + "no longer a warning, `#[no_mangle]` functions always exported", + ); + store.register_removed( + "private_no_mangle_statics", + "no longer a warning, `#[no_mangle]` statics always exported", + ); + store.register_removed("bad_repr", "replaced with a generic attribute input check"); + store.register_removed( + "duplicate_matcher_binding_name", + "converted into hard error, see https://github.com/rust-lang/rust/issues/57742", + ); + store.register_removed( + "incoherent_fundamental_impls", + "converted into hard error, see https://github.com/rust-lang/rust/issues/46205", + ); + store.register_removed( + "legacy_constructor_visibility", + "converted into hard error, see https://github.com/rust-lang/rust/issues/39207", + ); + store.register_removed( + "legacy_directory_ownership", + "converted into hard error, see https://github.com/rust-lang/rust/issues/37872", + ); + store.register_removed( + "safe_extern_statics", + "converted into hard error, see https://github.com/rust-lang/rust/issues/36247", + ); + store.register_removed( + "parenthesized_params_in_types_and_modules", + "converted into hard error, see https://github.com/rust-lang/rust/issues/42238", + ); + store.register_removed( + "duplicate_macro_exports", + "converted into hard error, see https://github.com/rust-lang/rust/issues/35896", + ); + store.register_removed( + "nested_impl_trait", + "converted into hard error, see https://github.com/rust-lang/rust/issues/59014", + ); store.register_removed("plugin_as_library", "plugins have been deprecated and retired"); } diff --git a/src/librustc_lint/non_ascii_idents.rs b/src/librustc_lint/non_ascii_idents.rs index aa39211efc71e..9ec8455394295 100644 --- a/src/librustc_lint/non_ascii_idents.rs +++ b/src/librustc_lint/non_ascii_idents.rs @@ -16,7 +16,8 @@ impl EarlyLintPass for NonAsciiIdents { NON_ASCII_IDENTS, ident.span, "identifier contains non-ASCII characters", - ).emit(); + ) + .emit(); } } } diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index bd2cbee2c348c..b8b4c2b39e543 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -1,16 +1,16 @@ -use rustc::hir::{self, GenericParamKind, PatKind}; -use rustc::hir::def::{Res, DefKind}; +use lint::{EarlyContext, LateContext, LintArray, LintContext}; +use lint::{EarlyLintPass, LateLintPass, LintPass}; +use rustc::hir::def::{DefKind, Res}; use rustc::hir::intravisit::FnKind; +use rustc::hir::{self, GenericParamKind, PatKind}; use rustc::lint; use rustc::ty; use rustc_target::spec::abi::Abi; -use lint::{EarlyContext, LateContext, LintContext, LintArray}; -use lint::{EarlyLintPass, LintPass, LateLintPass}; use syntax::ast; use syntax::attr; use syntax::errors::Applicability; use syntax::symbol::sym; -use syntax_pos::{BytePos, symbol::Ident, Span}; +use syntax_pos::{symbol::Ident, BytePos, Span}; #[derive(PartialEq)] pub enum MethodLateContext { @@ -24,12 +24,10 @@ pub fn method_context(cx: &LateContext<'_, '_>, id: hir::HirId) -> MethodLateCon let item = cx.tcx.associated_item(def_id); match item.container { ty::TraitContainer(..) => MethodLateContext::TraitAutoImpl, - ty::ImplContainer(cid) => { - match cx.tcx.impl_trait_ref(cid) { - Some(_) => MethodLateContext::TraitImpl, - None => MethodLateContext::PlainImpl, - } - } + ty::ImplContainer(cid) => match cx.tcx.impl_trait_ref(cid) { + Some(_) => MethodLateContext::TraitImpl, + None => MethodLateContext::PlainImpl, + }, } } @@ -90,21 +88,18 @@ fn to_camel_case(s: &str) -> String { camel_cased_component }) - .fold( - (String::new(), None), - |(acc, prev): (String, Option), next| { - // separate two components with an underscore if their boundary cannot - // be distinguished using a uppercase/lowercase case distinction - let join = if let Some(prev) = prev { - let l = prev.chars().last().unwrap(); - let f = next.chars().next().unwrap(); - !char_has_case(l) && !char_has_case(f) - } else { - false - }; - (acc + if join { "_" } else { "" } + &next, Some(next)) - }, - ) + .fold((String::new(), None), |(acc, prev): (String, Option), next| { + // separate two components with an underscore if their boundary cannot + // be distinguished using a uppercase/lowercase case distinction + let join = if let Some(prev) = prev { + let l = prev.chars().last().unwrap(); + let f = next.chars().next().unwrap(); + !char_has_case(l) && !char_has_case(f) + } else { + false + }; + (acc + if join { "_" } else { "" } + &next, Some(next)) + }) .0 } @@ -128,7 +123,8 @@ impl NonCamelCaseTypes { impl EarlyLintPass for NonCamelCaseTypes { fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) { - let has_repr_c = it.attrs + let has_repr_c = it + .attrs .iter() .any(|attr| attr::find_repr_attrs(&cx.sess.parse_sess, attr).contains(&attr::ReprC)); @@ -137,10 +133,10 @@ impl EarlyLintPass for NonCamelCaseTypes { } match it.kind { - ast::ItemKind::TyAlias(..) | - ast::ItemKind::Enum(..) | - ast::ItemKind::Struct(..) | - ast::ItemKind::Union(..) => self.check_case(cx, "type", &it.ident), + ast::ItemKind::TyAlias(..) + | ast::ItemKind::Enum(..) + | ast::ItemKind::Struct(..) + | ast::ItemKind::Union(..) => self.check_case(cx, "type", &it.ident), ast::ItemKind::Trait(..) => self.check_case(cx, "trait", &it.ident), _ => (), } @@ -266,11 +262,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { meta.name_value_literal().and_then(|lit| { if let ast::LitKind::Str(name, ..) = lit.kind { // Discard the double quotes surrounding the literal. - let sp = cx.sess().source_map().span_to_snippet(lit.span) + let sp = cx + .sess() + .source_map() + .span_to_snippet(lit.span) .ok() .and_then(|snippet| { let left = snippet.find('"')?; - let right = snippet.rfind('"').map(|pos| snippet.len() - pos)?; + let right = + snippet.rfind('"').map(|pos| snippet.len() - pos)?; Some( lit.span @@ -309,17 +309,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { id: hir::HirId, ) { match &fk { - FnKind::Method(ident, ..) => { - match method_context(cx, id) { - MethodLateContext::PlainImpl => { - self.check_snake_case(cx, "method", ident); - } - MethodLateContext::TraitAutoImpl => { - self.check_snake_case(cx, "trait method", ident); - } - _ => (), + FnKind::Method(ident, ..) => match method_context(cx, id) { + MethodLateContext::PlainImpl => { + self.check_snake_case(cx, "method", ident); } - } + MethodLateContext::TraitAutoImpl => { + self.check_snake_case(cx, "trait method", ident); + } + _ => (), + }, FnKind::ItemFn(ident, _, header, _, attrs) => { // Skip foreign-ABI #[no_mangle] functions (Issue #31924) if header.abi != Abi::Rust && attr::contains_name(attrs, sym::no_mangle) { @@ -352,11 +350,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { } } - fn check_struct_def( - &mut self, - cx: &LateContext<'_, '_>, - s: &hir::VariantData<'_>, - ) { + fn check_struct_def(&mut self, cx: &LateContext<'_, '_>, s: &hir::VariantData<'_>) { for sf in s.fields() { self.check_snake_case(cx, "structure field", &sf.ident); } @@ -424,7 +418,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals { NonUpperCaseGlobals::check_upper_case( cx, "constant in pattern", - &path.segments[0].ident + &path.segments[0].ident, ); } } @@ -433,11 +427,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals { fn check_generic_param(&mut self, cx: &LateContext<'_, '_>, param: &hir::GenericParam) { if let GenericParamKind::Const { .. } = param.kind { - NonUpperCaseGlobals::check_upper_case( - cx, - "const parameter", - ¶m.name.ident(), - ); + NonUpperCaseGlobals::check_upper_case(cx, "const parameter", ¶m.name.ident()); } } } diff --git a/src/librustc_lint/redundant_semicolon.rs b/src/librustc_lint/redundant_semicolon.rs index 0adf1eeb410b0..8dbf96a155825 100644 --- a/src/librustc_lint/redundant_semicolon.rs +++ b/src/librustc_lint/redundant_semicolon.rs @@ -1,5 +1,5 @@ -use crate::lint::{EarlyLintPass, LintPass, EarlyContext, LintArray, LintContext}; -use syntax::ast::{Stmt, StmtKind, ExprKind}; +use crate::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; +use syntax::ast::{ExprKind, Stmt, StmtKind}; use syntax::errors::Applicability; declare_lint! { @@ -26,11 +26,7 @@ impl EarlyLintPass for RedundantSemicolon { } else { "unnecessary trailing semicolon" }; - let mut err = cx.struct_span_lint( - REDUNDANT_SEMICOLON, - stmt.span, - &msg - ); + let mut err = cx.struct_span_lint(REDUNDANT_SEMICOLON, stmt.span, &msg); let suggest_msg = if multiple { "remove these semicolons" } else { @@ -40,7 +36,7 @@ impl EarlyLintPass for RedundantSemicolon { stmt.span, &suggest_msg, String::new(), - Applicability::MaybeIncorrect + Applicability::MaybeIncorrect, ); err.emit(); } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index f1cd2037edd7a..8c9279d025d80 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -1,24 +1,24 @@ #![allow(non_snake_case)] -use rustc::hir::{ExprKind, Node}; use crate::hir::def_id::DefId; +use lint::{LateContext, LintArray, LintContext}; +use lint::{LateLintPass, LintPass}; use rustc::hir::lowering::is_range_literal; +use rustc::hir::{ExprKind, Node}; +use rustc::ty::layout::{self, IntegerExt, LayoutOf, SizeSkeleton, VariantIdx}; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; -use rustc::ty::layout::{self, IntegerExt, LayoutOf, VariantIdx, SizeSkeleton}; use rustc::{lint, util}; use rustc_index::vec::Idx; use util::nodemap::FxHashSet; -use lint::{LateContext, LintContext, LintArray}; -use lint::{LintPass, LateLintPass}; use std::cmp; -use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64}; +use std::{f32, f64, i16, i32, i64, i8, u16, u32, u64, u8}; -use syntax::{ast, attr, source_map}; +use rustc_target::spec::abi::Abi; use syntax::errors::Applicability; use syntax::symbol::sym; -use rustc_target::spec::abi::Abi; +use syntax::{ast, attr, source_map}; use syntax_pos::Span; use rustc::hir; @@ -86,7 +86,7 @@ fn lint_overflowing_range_endpoint<'a, 'tcx>( &format!("range endpoint is out of range for `{}`", ty), ); if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) { - use ast::{LitKind, LitIntType}; + use ast::{LitIntType, LitKind}; // We need to preserve the literal's suffix, // as it may determine typing information. let suffix = match lit.node { @@ -120,7 +120,7 @@ fn int_ty_range(int_ty: ast::IntTy) -> (i128, i128) { ast::IntTy::I16 => (i16::min_value() as i64 as i128, i16::max_value() as i128), ast::IntTy::I32 => (i32::min_value() as i64 as i128, i32::max_value() as i128), ast::IntTy::I64 => (i64::min_value() as i128, i64::max_value() as i128), - ast::IntTy::I128 =>(i128::min_value() as i128, i128::max_value()), + ast::IntTy::I128 => (i128::min_value() as i128, i128::max_value()), } } @@ -178,16 +178,14 @@ fn report_bin_hex_error( an `{}` and will become `{}{}`", repr_str, val, t, actually, t )); - if let Some(sugg_ty) = - get_type_suggestion(&cx.tables.node_type(expr.hir_id), val, negative) - { + if let Some(sugg_ty) = get_type_suggestion(&cx.tables.node_type(expr.hir_id), val, negative) { if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') { let (sans_suffix, _) = repr_str.split_at(pos); err.span_suggestion( expr.span, &format!("consider using `{}` instead", sugg_ty), format!("{}{}", sans_suffix, sugg_ty), - Applicability::MachineApplicable + Applicability::MachineApplicable, ); } else { err.help(&format!("consider using `{}` instead", sugg_ty)); @@ -261,14 +259,7 @@ fn lint_int_literal<'a, 'tcx>( // avoiding use of -min to prevent overflow/panic if (negative && v > max + 1) || (!negative && v > max) { if let Some(repr_str) = get_bin_hex_repr(cx, lit) { - report_bin_hex_error( - cx, - e, - attr::IntType::SignedInt(t), - repr_str, - v, - negative, - ); + report_bin_hex_error(cx, e, attr::IntType::SignedInt(t), repr_str, v, negative); return; } @@ -327,14 +318,13 @@ fn lint_uint_literal<'a, 'tcx>( return; } } - hir::ExprKind::Struct(..) - if is_range_literal(cx.sess(), par_e) => { - let t = t.name_str(); - if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) { - // The overflowing literal lint was overridden. - return; - } + hir::ExprKind::Struct(..) if is_range_literal(cx.sess(), par_e) => { + let t = t.name_str(); + if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) { + // The overflowing literal lint was overridden. + return; } + } _ => {} } } @@ -359,24 +349,20 @@ fn lint_literal<'a, 'tcx>( match cx.tables.node_type(e.hir_id).kind { ty::Int(t) => { match lit.node { - ast::LitKind::Int(v, ast::LitIntType::Signed(_)) | - ast::LitKind::Int(v, ast::LitIntType::Unsuffixed) => { + ast::LitKind::Int(v, ast::LitIntType::Signed(_)) + | ast::LitKind::Int(v, ast::LitIntType::Unsuffixed) => { lint_int_literal(cx, type_limits, e, lit, t, v) } _ => bug!(), }; } - ty::Uint(t) => { - lint_uint_literal(cx, e, lit, t) - } + ty::Uint(t) => lint_uint_literal(cx, e, lit, t), ty::Float(t) => { let is_infinite = match lit.node { - ast::LitKind::Float(v, _) => { - match t { - ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite), - ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite), - } - } + ast::LitKind::Float(v, _) => match t { + ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite), + ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite), + }, _ => bug!(), }; if is_infinite == Ok(true) { @@ -402,9 +388,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } hir::ExprKind::Binary(binop, ref l, ref r) => { if is_comparison(binop) && !check_limits(cx, binop, &l, &r) { - cx.span_lint(UNUSED_COMPARISONS, - e.span, - "comparison is useless due to type limits"); + cx.span_lint( + UNUSED_COMPARISONS, + e.span, + "comparison is useless due to type limits", + ); } } hir::ExprKind::Lit(ref lit) => lint_literal(cx, self, e, lit), @@ -423,21 +411,24 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } fn rev_binop(binop: hir::BinOp) -> hir::BinOp { - source_map::respan(binop.span, - match binop.node { - hir::BinOpKind::Lt => hir::BinOpKind::Gt, - hir::BinOpKind::Le => hir::BinOpKind::Ge, - hir::BinOpKind::Gt => hir::BinOpKind::Lt, - hir::BinOpKind::Ge => hir::BinOpKind::Le, - _ => return binop, - }) + source_map::respan( + binop.span, + match binop.node { + hir::BinOpKind::Lt => hir::BinOpKind::Gt, + hir::BinOpKind::Le => hir::BinOpKind::Ge, + hir::BinOpKind::Gt => hir::BinOpKind::Lt, + hir::BinOpKind::Ge => hir::BinOpKind::Le, + _ => return binop, + }, + ) } - fn check_limits(cx: &LateContext<'_, '_>, - binop: hir::BinOp, - l: &hir::Expr, - r: &hir::Expr) - -> bool { + fn check_limits( + cx: &LateContext<'_, '_>, + binop: hir::BinOp, + l: &hir::Expr, + r: &hir::Expr, + ) -> bool { let (lit, expr, swap) = match (&l.kind, &r.kind) { (&hir::ExprKind::Lit(_), _) => (l, r, true), (_, &hir::ExprKind::Lit(_)) => (r, l, false), @@ -450,27 +441,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { ty::Int(int_ty) => { let (min, max) = int_ty_range(int_ty); let lit_val: i128 = match lit.kind { - hir::ExprKind::Lit(ref li) => { - match li.node { - ast::LitKind::Int(v, ast::LitIntType::Signed(_)) | - ast::LitKind::Int(v, ast::LitIntType::Unsuffixed) => v as i128, - _ => return true - } + hir::ExprKind::Lit(ref li) => match li.node { + ast::LitKind::Int(v, ast::LitIntType::Signed(_)) + | ast::LitKind::Int(v, ast::LitIntType::Unsuffixed) => v as i128, + _ => return true, }, - _ => bug!() + _ => bug!(), }; is_valid(norm_binop, lit_val, min, max) } ty::Uint(uint_ty) => { - let (min, max) :(u128, u128) = uint_ty_range(uint_ty); + let (min, max): (u128, u128) = uint_ty_range(uint_ty); let lit_val: u128 = match lit.kind { - hir::ExprKind::Lit(ref li) => { - match li.node { - ast::LitKind::Int(v, _) => v, - _ => return true - } + hir::ExprKind::Lit(ref li) => match li.node { + ast::LitKind::Int(v, _) => v, + _ => return true, }, - _ => bug!() + _ => bug!(), }; is_valid(norm_binop, lit_val, min, max) } @@ -480,12 +467,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { fn is_comparison(binop: hir::BinOp) -> bool { match binop.node { - hir::BinOpKind::Eq | - hir::BinOpKind::Lt | - hir::BinOpKind::Le | - hir::BinOpKind::Ne | - hir::BinOpKind::Ge | - hir::BinOpKind::Gt => true, + hir::BinOpKind::Eq + | hir::BinOpKind::Lt + | hir::BinOpKind::Le + | hir::BinOpKind::Ne + | hir::BinOpKind::Ge + | hir::BinOpKind::Gt => true, _ => false, } } @@ -507,11 +494,7 @@ struct ImproperCTypesVisitor<'a, 'tcx> { enum FfiResult<'tcx> { FfiSafe, FfiPhantom(Ty<'tcx>), - FfiUnsafe { - ty: Ty<'tcx>, - reason: &'static str, - help: Option<&'static str>, - }, + FfiUnsafe { ty: Ty<'tcx>, reason: &'static str, help: Option<&'static str> }, } fn is_zst<'tcx>(tcx: TyCtxt<'tcx>, did: DefId, ty: Ty<'tcx>) -> bool { @@ -524,17 +507,16 @@ fn ty_is_known_nonnull<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { ty::Ref(..) => true, ty::Adt(field_def, substs) if field_def.repr.transparent() && !field_def.is_union() => { for field in field_def.all_fields() { - let field_ty = tcx.normalize_erasing_regions( - ParamEnv::reveal_all(), - field.ty(tcx, substs), - ); + let field_ty = + tcx.normalize_erasing_regions(ParamEnv::reveal_all(), field.ty(tcx, substs)); if is_zst(tcx, field.did, field_ty) { continue; } let attrs = tcx.get_attrs(field_def.did); - if attrs.iter().any(|a| a.check_name(sym::rustc_nonnull_optimization_guaranteed)) || - ty_is_known_nonnull(tcx, field_ty) { + if attrs.iter().any(|a| a.check_name(sym::rustc_nonnull_optimization_guaranteed)) + || ty_is_known_nonnull(tcx, field_ty) + { return true; } } @@ -591,7 +573,6 @@ fn is_repr_nullable_ptr<'tcx>( } impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { - /// Check if the type is array and emit an unsafe type lint. fn check_for_array_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool { if let ty::Array(..) = ty.kind { @@ -607,12 +588,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } } - /// Checks if the given type is "ffi-safe" (has a stable, well-defined /// representation which can be exported to C code). - fn check_type_for_ffi(&self, - cache: &mut FxHashSet>, - ty: Ty<'tcx>) -> FfiResult<'tcx> { + fn check_type_for_ffi(&self, cache: &mut FxHashSet>, ty: Ty<'tcx>) -> FfiResult<'tcx> { use FfiResult::*; let cx = self.cx.tcx; @@ -636,8 +614,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { return FfiUnsafe { ty, reason: "this struct has unspecified layout", - help: Some("consider adding a `#[repr(C)]` or \ - `#[repr(transparent)]` attribute to this struct"), + help: Some( + "consider adding a `#[repr(C)]` or \ + `#[repr(transparent)]` attribute to this struct", + ), }; } @@ -691,8 +671,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { return FfiUnsafe { ty, reason: "this union has unspecified layout", - help: Some("consider adding a `#[repr(C)]` or \ - `#[repr(transparent)]` attribute to this union"), + help: Some( + "consider adding a `#[repr(C)]` or \ + `#[repr(transparent)]` attribute to this union", + ), }; } @@ -743,9 +725,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { return FfiUnsafe { ty, reason: "enum has no representation hint", - help: Some("consider adding a `#[repr(C)]`, \ + help: Some( + "consider adding a `#[repr(C)]`, \ `#[repr(transparent)]`, or integer `#[repr(...)]` \ - attribute to this enum"), + attribute to this enum", + ), }; } } @@ -821,11 +805,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { help: Some("consider using a raw pointer instead"), }, - ty::Dynamic(..) => FfiUnsafe { - ty, - reason: "trait objects have no C equivalent", - help: None, - }, + ty::Dynamic(..) => { + FfiUnsafe { ty, reason: "trait objects have no C equivalent", help: None } + } ty::Str => FfiUnsafe { ty, @@ -839,8 +821,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { help: Some("consider using a struct instead"), }, - ty::RawPtr(ty::TypeAndMut { ty, .. }) | - ty::Ref(_, ty, _) => self.check_type_for_ffi(cache, ty), + ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _) => { + self.check_type_for_ffi(cache, ty) + } ty::Array(inner_ty, _) => self.check_type_for_ffi(cache, inner_ty), @@ -850,9 +833,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { return FfiUnsafe { ty, reason: "this function pointer has Rust-specific calling convention", - help: Some("consider using an `extern fn(...) -> ...` \ - function pointer instead"), - } + help: Some( + "consider using an `extern fn(...) -> ...` \ + function pointer instead", + ), + }; } _ => {} } @@ -881,18 +866,18 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ty::Foreign(..) => FfiSafe, - ty::Param(..) | - ty::Infer(..) | - ty::Bound(..) | - ty::Error | - ty::Closure(..) | - ty::Generator(..) | - ty::GeneratorWitness(..) | - ty::Placeholder(..) | - ty::UnnormalizedProjection(..) | - ty::Projection(..) | - ty::Opaque(..) | - ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty), + ty::Param(..) + | ty::Infer(..) + | ty::Bound(..) + | ty::Error + | ty::Closure(..) + | ty::Generator(..) + | ty::GeneratorWitness(..) + | ty::Placeholder(..) + | ty::UnnormalizedProjection(..) + | ty::Projection(..) + | ty::Opaque(..) + | ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty), } } @@ -942,12 +927,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { let mut visitor = ProhibitOpaqueTypes { ty: None }; ty.visit_with(&mut visitor); if let Some(ty) = visitor.ty { - self.emit_ffi_unsafe_type_lint( - ty, - sp, - "opaque types have no C equivalent", - None, - ); + self.emit_ffi_unsafe_type_lint(ty, sp, "opaque types have no C equivalent", None); true } else { false @@ -1022,7 +1002,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes { hir::ForeignItemKind::Static(ref ty, _) => { vis.check_foreign_static(it.hir_id, ty.span); } - hir::ForeignItemKind::Type => () + hir::ForeignItemKind::Type => (), } } } @@ -1055,38 +1035,47 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences { let discr_size = tag.value.size(&cx.tcx).bytes(); - debug!("enum `{}` is {} bytes large with layout:\n{:#?}", - t, layout.size.bytes(), layout); + debug!( + "enum `{}` is {} bytes large with layout:\n{:#?}", + t, + layout.size.bytes(), + layout + ); - let (largest, slargest, largest_index) = enum_definition.variants + let (largest, slargest, largest_index) = enum_definition + .variants .iter() .zip(variants) .map(|(variant, variant_layout)| { // Subtract the size of the enum discriminant. let bytes = variant_layout.size.bytes().saturating_sub(discr_size); - debug!("- variant `{}` is {} bytes large", - variant.ident, - bytes); + debug!("- variant `{}` is {} bytes large", variant.ident, bytes); bytes }) .enumerate() - .fold((0, 0, 0), |(l, s, li), (idx, size)| if size > l { - (size, l, idx) - } else if size > s { - (l, size, li) - } else { - (l, s, li) + .fold((0, 0, 0), |(l, s, li), (idx, size)| { + if size > l { + (size, l, idx) + } else if size > s { + (l, size, li) + } else { + (l, s, li) + } }); // We only warn if the largest variant is at least thrice as large as // the second-largest. if largest > slargest * 3 && slargest > 0 { - cx.span_lint(VARIANT_SIZE_DIFFERENCES, - enum_definition.variants[largest_index].span, - &format!("enum variant is more than three times \ + cx.span_lint( + VARIANT_SIZE_DIFFERENCES, + enum_definition.variants[largest_index].span, + &format!( + "enum variant is more than three times \ larger ({} bytes) than the next largest", - largest)); + largest + ), + ); } } } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 06ec3f3800915..6bdb77bb804f4 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -1,23 +1,23 @@ +use lint::{EarlyContext, LateContext, LintArray, LintContext}; +use lint::{EarlyLintPass, LateLintPass, LintPass}; use rustc::hir; -use rustc::hir::def::{Res, DefKind}; +use rustc::hir::def::{DefKind, Res}; use rustc::hir::def_id::DefId; use rustc::lint; use rustc::lint::builtin::UNUSED_ATTRIBUTES; -use rustc::ty::{self, Ty}; use rustc::ty::adjustment; +use rustc::ty::{self, Ty}; use rustc_data_structures::fx::FxHashMap; -use lint::{LateContext, EarlyContext, LintContext, LintArray}; -use lint::{LintPass, EarlyLintPass, LateLintPass}; use rustc_feature::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use syntax::ast; use syntax::attr; -use syntax::errors::{Applicability, pluralize}; +use syntax::errors::{pluralize, Applicability}; use syntax::print::pprust; -use syntax::symbol::{kw, sym}; use syntax::symbol::Symbol; +use syntax::symbol::{kw, sym}; use syntax::util::parser; -use syntax_pos::{Span, BytePos}; +use syntax_pos::{BytePos, Span}; use log::debug; @@ -57,20 +57,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { match callee.kind { hir::ExprKind::Path(ref qpath) => { match cx.tables.qpath_res(qpath, callee.hir_id) { - Res::Def(DefKind::Fn, def_id) - | Res::Def(DefKind::Method, def_id) => Some(def_id), + Res::Def(DefKind::Fn, def_id) | Res::Def(DefKind::Method, def_id) => { + Some(def_id) + } // `Res::Local` if it was a closure, for which we // do not currently support must-use linting - _ => None + _ => None, } - }, - _ => None + } + _ => None, } - }, - hir::ExprKind::MethodCall(..) => { - cx.tables.type_dependent_def_id(expr.hir_id) - }, - _ => None + } + hir::ExprKind::MethodCall(..) => cx.tables.type_dependent_def_id(expr.hir_id), + _ => None, }; if let Some(def_id) = maybe_def_id { fn_warned = check_must_use_def(cx, def_id, s.span, "return value of ", ""); @@ -84,42 +83,35 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { // Hardcoding operators here seemed more expedient than the // refactoring that would be needed to look up the `#[must_use]` // attribute which does exist on the comparison trait methods - hir::ExprKind::Binary(bin_op, ..) => { - match bin_op.node { - hir::BinOpKind::Eq | - hir::BinOpKind::Lt | - hir::BinOpKind::Le | - hir::BinOpKind::Ne | - hir::BinOpKind::Ge | - hir::BinOpKind::Gt => { - Some("comparison") - }, - hir::BinOpKind::Add | - hir::BinOpKind::Sub | - hir::BinOpKind::Div | - hir::BinOpKind::Mul | - hir::BinOpKind::Rem => { - Some("arithmetic operation") - }, - hir::BinOpKind::And | hir::BinOpKind::Or => { - Some("logical operation") - }, - hir::BinOpKind::BitXor | - hir::BinOpKind::BitAnd | - hir::BinOpKind::BitOr | - hir::BinOpKind::Shl | - hir::BinOpKind::Shr => { - Some("bitwise operation") - }, - } + hir::ExprKind::Binary(bin_op, ..) => match bin_op.node { + hir::BinOpKind::Eq + | hir::BinOpKind::Lt + | hir::BinOpKind::Le + | hir::BinOpKind::Ne + | hir::BinOpKind::Ge + | hir::BinOpKind::Gt => Some("comparison"), + hir::BinOpKind::Add + | hir::BinOpKind::Sub + | hir::BinOpKind::Div + | hir::BinOpKind::Mul + | hir::BinOpKind::Rem => Some("arithmetic operation"), + hir::BinOpKind::And | hir::BinOpKind::Or => Some("logical operation"), + hir::BinOpKind::BitXor + | hir::BinOpKind::BitAnd + | hir::BinOpKind::BitOr + | hir::BinOpKind::Shl + | hir::BinOpKind::Shr => Some("bitwise operation"), }, hir::ExprKind::Unary(..) => Some("unary operation"), - _ => None + _ => None, }; if let Some(must_use_op) = must_use_op { - cx.span_lint(UNUSED_MUST_USE, expr.span, - &format!("unused {} that must be used", must_use_op)); + cx.span_lint( + UNUSED_MUST_USE, + expr.span, + &format!("unused {} that must be used", must_use_op), + ); op_warned = true; } @@ -137,8 +129,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { descr_post: &str, plural_len: usize, ) -> bool { - if ty.is_unit() || cx.tcx.is_ty_uninhabited_from( - cx.tcx.hir().get_module_parent(expr.hir_id), ty) + if ty.is_unit() + || cx.tcx.is_ty_uninhabited_from(cx.tcx.hir().get_module_parent(expr.hir_id), ty) { return true; } @@ -151,20 +143,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { let descr_pre = &format!("{}boxed ", descr_pre); check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural_len) } - ty::Adt(def, _) => { - check_must_use_def(cx, def.did, span, descr_pre, descr_post) - } + ty::Adt(def, _) => check_must_use_def(cx, def.did, span, descr_pre, descr_post), ty::Opaque(def, _) => { let mut has_emitted = false; for (predicate, _) in cx.tcx.predicates_of(def).predicates { if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate { let trait_ref = poly_trait_predicate.skip_binder().trait_ref; let def_id = trait_ref.def_id; - let descr_pre = &format!( - "{}implementer{} of ", - descr_pre, - plural_suffix, - ); + let descr_pre = + &format!("{}implementer{} of ", descr_pre, plural_suffix,); if check_must_use_def(cx, def_id, span, descr_pre, descr_post) { has_emitted = true; break; @@ -178,11 +165,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { for predicate in binder.skip_binder().iter() { if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate { let def_id = trait_ref.def_id; - let descr_post = &format!( - " trait object{}{}", - plural_suffix, - descr_post, - ); + let descr_post = + &format!(" trait object{}{}", plural_suffix, descr_post,); if check_must_use_def(cx, def_id, span, descr_pre, descr_post) { has_emitted = true; break; @@ -202,15 +186,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() { let descr_post = &format!(" in tuple element {}", i); let span = *spans.get(i).unwrap_or(&span); - if check_must_use_ty( - cx, - ty, - expr, - span, - descr_pre, - descr_post, - plural_len - ) { + if check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, plural_len) + { has_emitted = true; } } @@ -219,16 +196,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { ty::Array(ty, len) => match len.try_eval_usize(cx.tcx, cx.param_env) { // If the array is definitely non-empty, we can do `#[must_use]` checking. Some(n) if n != 0 => { - let descr_pre = &format!( - "{}array{} of ", - descr_pre, - plural_suffix, - ); + let descr_pre = &format!("{}array{} of ", descr_pre, plural_suffix,); check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, n as usize + 1) } // Otherwise, we don't lint, to avoid false positives. _ => false, - } + }, _ => false, } } @@ -243,8 +216,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { ) -> bool { for attr in cx.tcx.get_attrs(def_id).iter() { if attr.check_name(sym::must_use) { - let msg = format!("unused {}`{}`{} that must be used", - descr_pre_path, cx.tcx.def_path_str(def_id), descr_post_path); + let msg = format!( + "unused {}`{}`{} that must be used", + descr_pre_path, + cx.tcx.def_path_str(def_id), + descr_post_path + ); let mut err = cx.struct_span_lint(UNUSED_MUST_USE, span, &msg); // check for #[must_use = "..."] if let Some(note) = attr.value_str() { @@ -284,9 +261,7 @@ pub struct UnusedAttributes { impl UnusedAttributes { pub fn new() -> Self { - UnusedAttributes { - builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP, - } + UnusedAttributes { builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP } } } @@ -337,29 +312,31 @@ declare_lint! { declare_lint_pass!(UnusedParens => [UNUSED_PARENS]); impl UnusedParens { - fn is_expr_parens_necessary(inner: &ast::Expr, followed_by_block: bool) -> bool { - followed_by_block && match inner.kind { - ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true, - _ => parser::contains_exterior_struct_lit(&inner), - } + followed_by_block + && match inner.kind { + ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true, + _ => parser::contains_exterior_struct_lit(&inner), + } } - fn check_unused_parens_expr(&self, - cx: &EarlyContext<'_>, - value: &ast::Expr, - msg: &str, - followed_by_block: bool, - left_pos: Option, - right_pos: Option) { + fn check_unused_parens_expr( + &self, + cx: &EarlyContext<'_>, + value: &ast::Expr, + msg: &str, + followed_by_block: bool, + left_pos: Option, + right_pos: Option, + ) { match value.kind { ast::ExprKind::Paren(ref inner) => { - if !Self::is_expr_parens_necessary(inner, followed_by_block) && - value.attrs.is_empty() && - !value.span.from_expansion() + if !Self::is_expr_parens_necessary(inner, followed_by_block) + && value.attrs.is_empty() + && !value.span.from_expansion() { - let expr_text = if let Ok(snippet) = cx.sess().source_map() - .span_to_snippet(value.span) { + let expr_text = + if let Ok(snippet) = cx.sess().source_map().span_to_snippet(value.span) { snippet } else { pprust::expr_to_string(value) @@ -375,10 +352,12 @@ impl UnusedParens { // FIXME(#60336): Properly handle `let true = (false && true)` // actually needing the parenthesis. self.check_unused_parens_expr( - cx, expr, + cx, + expr, "`let` head expression", followed_by_block, - None, None + None, + None, ); } _ => {} @@ -392,7 +371,7 @@ impl UnusedParens { avoid_or: bool, avoid_mut: bool, ) { - use ast::{PatKind, BindingMode, Mutability}; + use ast::{BindingMode, Mutability, PatKind}; if let PatKind::Paren(inner) = &value.kind { match inner.kind { @@ -409,8 +388,8 @@ impl UnusedParens { _ => {} } - let pattern_text = if let Ok(snippet) = cx.sess().source_map() - .span_to_snippet(value.span) { + let pattern_text = + if let Ok(snippet) = cx.sess().source_map().span_to_snippet(value.span) { snippet } else { pprust::pat_to_string(value) @@ -419,37 +398,36 @@ impl UnusedParens { } } - fn remove_outer_parens(cx: &EarlyContext<'_>, - span: Span, - pattern: &str, - msg: &str, - keep_space: (bool, bool)) { + fn remove_outer_parens( + cx: &EarlyContext<'_>, + span: Span, + pattern: &str, + msg: &str, + keep_space: (bool, bool), + ) { let span_msg = format!("unnecessary parentheses around {}", msg); let mut err = cx.struct_span_lint(UNUSED_PARENS, span, &span_msg); let mut ate_left_paren = false; let mut ate_right_paren = false; - let parens_removed = pattern - .trim_matches(|c| { - match c { - '(' => { - if ate_left_paren { - false - } else { - ate_left_paren = true; - true - } - }, - ')' => { - if ate_right_paren { - false - } else { - ate_right_paren = true; - true - } - }, - _ => false, + let parens_removed = pattern.trim_matches(|c| match c { + '(' => { + if ate_left_paren { + false + } else { + ate_left_paren = true; + true } - }); + } + ')' => { + if ate_right_paren { + false + } else { + ate_right_paren = true; + true + } + } + _ => false, + }); let replace = { let mut replace = if keep_space.0 { @@ -495,7 +473,7 @@ impl EarlyLintPass for UnusedParens { let left = e.span.lo() + syntax_pos::BytePos(5); let right = block.span.lo(); (cond, "`while` condition", true, Some(left), Some(right)) - }, + } ForLoop(ref pat, ref cond, ref block, ..) => { self.check_unused_parens_pat(cx, pat, false, false); @@ -543,7 +521,7 @@ impl EarlyLintPass for UnusedParens { } fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) { - use ast::{PatKind::*, Mutability}; + use ast::{Mutability, PatKind::*}; match &p.kind { // Do not lint on `(..)` as that will result in the other arms being useless. Paren(_) @@ -588,8 +566,8 @@ impl EarlyLintPass for UnusedParens { &ast::TyKind::TraitObject(..) => {} &ast::TyKind::ImplTrait(_, ref bounds) if bounds.len() > 1 => {} _ => { - let pattern_text = if let Ok(snippet) = cx.sess().source_map() - .span_to_snippet(ty.span) { + let pattern_text = + if let Ok(snippet) = cx.sess().source_map().span_to_snippet(ty.span) { snippet } else { pprust::ty_to_string(ty) @@ -668,10 +646,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAllocation { for adj in cx.tables.expr_adjustments(e) { if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(_, m)) = adj.kind { let msg = match m { - adjustment::AutoBorrowMutability::Not => - "unnecessary allocation, use `&` instead", - adjustment::AutoBorrowMutability::Mut { .. }=> + adjustment::AutoBorrowMutability::Not => { + "unnecessary allocation, use `&` instead" + } + adjustment::AutoBorrowMutability::Mut { .. } => { "unnecessary allocation, use `&mut` instead" + } }; cx.span_lint(UNUSED_ALLOCATION, e.span, msg); } diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index c5d5f066f4f82..dff20f8741065 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -1,6 +1,6 @@ -use std::process::Command; use std::env; -use std::path::{PathBuf, Path}; +use std::path::{Path, PathBuf}; +use std::process::Command; use build_helper::output; @@ -24,22 +24,16 @@ fn main() { build_helper::restore_library_path(); let target = env::var("TARGET").expect("TARGET was not set"); - let llvm_config = env::var_os("LLVM_CONFIG") - .map(PathBuf::from) - .unwrap_or_else(|| { - if let Some(dir) = env::var_os("CARGO_TARGET_DIR").map(PathBuf::from) { - let to_test = dir.parent() - .unwrap() - .parent() - .unwrap() - .join(&target) - .join("llvm/bin/llvm-config"); - if Command::new(&to_test).output().is_ok() { - return to_test; - } + let llvm_config = env::var_os("LLVM_CONFIG").map(PathBuf::from).unwrap_or_else(|| { + if let Some(dir) = env::var_os("CARGO_TARGET_DIR").map(PathBuf::from) { + let to_test = + dir.parent().unwrap().parent().unwrap().join(&target).join("llvm/bin/llvm-config"); + if Command::new(&to_test).output().is_ok() { + return to_test; } - PathBuf::from("llvm-config") - }); + } + PathBuf::from("llvm-config") + }); println!("cargo:rerun-if-changed={}", llvm_config.display()); println!("cargo:rerun-if-env-changed=LLVM_CONFIG"); @@ -69,34 +63,38 @@ fn main() { let host = env::var("HOST").expect("HOST was not set"); let is_crossed = target != host; - let mut optional_components = - vec!["x86", "arm", "aarch64", "amdgpu", "mips", "powerpc", - "systemz", "jsbackend", "webassembly", "msp430", "sparc", "nvptx", - "hexagon"]; + let mut optional_components = vec![ + "x86", + "arm", + "aarch64", + "amdgpu", + "mips", + "powerpc", + "systemz", + "jsbackend", + "webassembly", + "msp430", + "sparc", + "nvptx", + "hexagon", + ]; let mut version_cmd = Command::new(&llvm_config); version_cmd.arg("--version"); let version_output = output(&mut version_cmd); - let mut parts = version_output.split('.').take(2) - .filter_map(|s| s.parse::().ok()); - let (major, _minor) = - if let (Some(major), Some(minor)) = (parts.next(), parts.next()) { - (major, minor) - } else { - (6, 0) - }; + let mut parts = version_output.split('.').take(2).filter_map(|s| s.parse::().ok()); + let (major, _minor) = if let (Some(major), Some(minor)) = (parts.next(), parts.next()) { + (major, minor) + } else { + (6, 0) + }; if major > 6 { optional_components.push("riscv"); } - let required_components = &["ipo", - "bitreader", - "bitwriter", - "linker", - "asmparser", - "lto", - "instrumentation"]; + let required_components = + &["ipo", "bitreader", "bitwriter", "linker", "asmparser", "lto", "instrumentation"]; let components = output(Command::new(&llvm_config).arg("--components")); let mut components = components.split_whitespace().collect::>(); @@ -157,12 +155,12 @@ fn main() { build_helper::rerun_if_changed_anything_in_dir(Path::new("../rustllvm")); cfg.file("../rustllvm/PassWrapper.cpp") - .file("../rustllvm/RustWrapper.cpp") - .file("../rustllvm/ArchiveWrapper.cpp") - .file("../rustllvm/Linker.cpp") - .cpp(true) - .cpp_link_stdlib(None) // we handle this below - .compile("rustllvm"); + .file("../rustllvm/RustWrapper.cpp") + .file("../rustllvm/ArchiveWrapper.cpp") + .file("../rustllvm/Linker.cpp") + .cpp(true) + .cpp_link_stdlib(None) // we handle this below + .compile("rustllvm"); let (llvm_kind, llvm_link_arg) = detect_llvm_link(); @@ -204,11 +202,7 @@ fn main() { continue; } - let kind = if name.starts_with("LLVM") { - llvm_kind - } else { - "dylib" - }; + let kind = if name.starts_with("LLVM") { llvm_kind } else { "dylib" }; println!("cargo:rustc-link-lib={}={}", kind, name); } @@ -225,8 +219,7 @@ fn main() { println!("cargo:rustc-link-search=native={}", &lib[9..]); } else if is_crossed { if lib.starts_with("-L") { - println!("cargo:rustc-link-search=native={}", - lib[2..].replace(&host, &target)); + println!("cargo:rustc-link-search=native={}", lib[2..].replace(&host, &target)); } } else if lib.starts_with("-l") { println!("cargo:rustc-link-lib={}", &lib[2..]); @@ -254,11 +247,7 @@ fn main() { let llvm_use_libcxx = env::var_os("LLVM_USE_LIBCXX"); let stdcppname = if target.contains("openbsd") { - if target.contains("sparc64") { - "estdc++" - } else { - "c++" - } + if target.contains("sparc64") { "estdc++" } else { "c++" } } else if target.contains("freebsd") { "c++" } else if target.contains("darwin") { @@ -277,8 +266,7 @@ fn main() { if let Some(s) = llvm_static_stdcpp { assert!(!cxxflags.contains("stdlib=libc++")); let path = PathBuf::from(s); - println!("cargo:rustc-link-search=native={}", - path.parent().unwrap().display()); + println!("cargo:rustc-link-search=native={}", path.parent().unwrap().display()); if target.contains("windows") { println!("cargo:rustc-link-lib=static-nobundle={}", stdcppname); } else { diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 9c8943a9559a3..eca1808de3f90 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -1,14 +1,12 @@ #![feature(nll)] #![feature(static_nobundle)] - #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] // NOTE: This crate only exists to allow linking on mingw targets. +use libc::{c_char, size_t}; use std::cell::RefCell; use std::slice; -use libc::{c_char, size_t}; - #[repr(C)] pub struct RustString { @@ -17,9 +15,11 @@ pub struct RustString { /// Appending to a Rust string -- used by RawRustStringOstream. #[no_mangle] -pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: &RustString, - ptr: *const c_char, - size: size_t) { +pub unsafe extern "C" fn LLVMRustStringWriteImpl( + sr: &RustString, + ptr: *const c_char, + size: size_t, +) { let slice = slice::from_raw_parts(ptr as *const u8, size as usize); sr.bytes.borrow_mut().extend_from_slice(slice); @@ -44,85 +44,115 @@ pub fn initialize_available_targets() { init(); } } ); - init_target!(llvm_component = "x86", - LLVMInitializeX86TargetInfo, - LLVMInitializeX86Target, - LLVMInitializeX86TargetMC, - LLVMInitializeX86AsmPrinter, - LLVMInitializeX86AsmParser); - init_target!(llvm_component = "arm", - LLVMInitializeARMTargetInfo, - LLVMInitializeARMTarget, - LLVMInitializeARMTargetMC, - LLVMInitializeARMAsmPrinter, - LLVMInitializeARMAsmParser); - init_target!(llvm_component = "aarch64", - LLVMInitializeAArch64TargetInfo, - LLVMInitializeAArch64Target, - LLVMInitializeAArch64TargetMC, - LLVMInitializeAArch64AsmPrinter, - LLVMInitializeAArch64AsmParser); - init_target!(llvm_component = "amdgpu", - LLVMInitializeAMDGPUTargetInfo, - LLVMInitializeAMDGPUTarget, - LLVMInitializeAMDGPUTargetMC, - LLVMInitializeAMDGPUAsmPrinter, - LLVMInitializeAMDGPUAsmParser); - init_target!(llvm_component = "mips", - LLVMInitializeMipsTargetInfo, - LLVMInitializeMipsTarget, - LLVMInitializeMipsTargetMC, - LLVMInitializeMipsAsmPrinter, - LLVMInitializeMipsAsmParser); - init_target!(llvm_component = "powerpc", - LLVMInitializePowerPCTargetInfo, - LLVMInitializePowerPCTarget, - LLVMInitializePowerPCTargetMC, - LLVMInitializePowerPCAsmPrinter, - LLVMInitializePowerPCAsmParser); - init_target!(llvm_component = "systemz", - LLVMInitializeSystemZTargetInfo, - LLVMInitializeSystemZTarget, - LLVMInitializeSystemZTargetMC, - LLVMInitializeSystemZAsmPrinter, - LLVMInitializeSystemZAsmParser); - init_target!(llvm_component = "jsbackend", - LLVMInitializeJSBackendTargetInfo, - LLVMInitializeJSBackendTarget, - LLVMInitializeJSBackendTargetMC); - init_target!(llvm_component = "msp430", - LLVMInitializeMSP430TargetInfo, - LLVMInitializeMSP430Target, - LLVMInitializeMSP430TargetMC, - LLVMInitializeMSP430AsmPrinter); - init_target!(all(llvm_component = "msp430", llvm_has_msp430_asm_parser), - LLVMInitializeMSP430AsmParser); - init_target!(llvm_component = "riscv", - LLVMInitializeRISCVTargetInfo, - LLVMInitializeRISCVTarget, - LLVMInitializeRISCVTargetMC, - LLVMInitializeRISCVAsmPrinter, - LLVMInitializeRISCVAsmParser); - init_target!(llvm_component = "sparc", - LLVMInitializeSparcTargetInfo, - LLVMInitializeSparcTarget, - LLVMInitializeSparcTargetMC, - LLVMInitializeSparcAsmPrinter, - LLVMInitializeSparcAsmParser); - init_target!(llvm_component = "nvptx", - LLVMInitializeNVPTXTargetInfo, - LLVMInitializeNVPTXTarget, - LLVMInitializeNVPTXTargetMC, - LLVMInitializeNVPTXAsmPrinter); - init_target!(llvm_component = "hexagon", - LLVMInitializeHexagonTargetInfo, - LLVMInitializeHexagonTarget, - LLVMInitializeHexagonTargetMC, - LLVMInitializeHexagonAsmPrinter, - LLVMInitializeHexagonAsmParser); - init_target!(llvm_component = "webassembly", - LLVMInitializeWebAssemblyTargetInfo, - LLVMInitializeWebAssemblyTarget, - LLVMInitializeWebAssemblyTargetMC, - LLVMInitializeWebAssemblyAsmPrinter); + init_target!( + llvm_component = "x86", + LLVMInitializeX86TargetInfo, + LLVMInitializeX86Target, + LLVMInitializeX86TargetMC, + LLVMInitializeX86AsmPrinter, + LLVMInitializeX86AsmParser + ); + init_target!( + llvm_component = "arm", + LLVMInitializeARMTargetInfo, + LLVMInitializeARMTarget, + LLVMInitializeARMTargetMC, + LLVMInitializeARMAsmPrinter, + LLVMInitializeARMAsmParser + ); + init_target!( + llvm_component = "aarch64", + LLVMInitializeAArch64TargetInfo, + LLVMInitializeAArch64Target, + LLVMInitializeAArch64TargetMC, + LLVMInitializeAArch64AsmPrinter, + LLVMInitializeAArch64AsmParser + ); + init_target!( + llvm_component = "amdgpu", + LLVMInitializeAMDGPUTargetInfo, + LLVMInitializeAMDGPUTarget, + LLVMInitializeAMDGPUTargetMC, + LLVMInitializeAMDGPUAsmPrinter, + LLVMInitializeAMDGPUAsmParser + ); + init_target!( + llvm_component = "mips", + LLVMInitializeMipsTargetInfo, + LLVMInitializeMipsTarget, + LLVMInitializeMipsTargetMC, + LLVMInitializeMipsAsmPrinter, + LLVMInitializeMipsAsmParser + ); + init_target!( + llvm_component = "powerpc", + LLVMInitializePowerPCTargetInfo, + LLVMInitializePowerPCTarget, + LLVMInitializePowerPCTargetMC, + LLVMInitializePowerPCAsmPrinter, + LLVMInitializePowerPCAsmParser + ); + init_target!( + llvm_component = "systemz", + LLVMInitializeSystemZTargetInfo, + LLVMInitializeSystemZTarget, + LLVMInitializeSystemZTargetMC, + LLVMInitializeSystemZAsmPrinter, + LLVMInitializeSystemZAsmParser + ); + init_target!( + llvm_component = "jsbackend", + LLVMInitializeJSBackendTargetInfo, + LLVMInitializeJSBackendTarget, + LLVMInitializeJSBackendTargetMC + ); + init_target!( + llvm_component = "msp430", + LLVMInitializeMSP430TargetInfo, + LLVMInitializeMSP430Target, + LLVMInitializeMSP430TargetMC, + LLVMInitializeMSP430AsmPrinter + ); + init_target!( + all(llvm_component = "msp430", llvm_has_msp430_asm_parser), + LLVMInitializeMSP430AsmParser + ); + init_target!( + llvm_component = "riscv", + LLVMInitializeRISCVTargetInfo, + LLVMInitializeRISCVTarget, + LLVMInitializeRISCVTargetMC, + LLVMInitializeRISCVAsmPrinter, + LLVMInitializeRISCVAsmParser + ); + init_target!( + llvm_component = "sparc", + LLVMInitializeSparcTargetInfo, + LLVMInitializeSparcTarget, + LLVMInitializeSparcTargetMC, + LLVMInitializeSparcAsmPrinter, + LLVMInitializeSparcAsmParser + ); + init_target!( + llvm_component = "nvptx", + LLVMInitializeNVPTXTargetInfo, + LLVMInitializeNVPTXTarget, + LLVMInitializeNVPTXTargetMC, + LLVMInitializeNVPTXAsmPrinter + ); + init_target!( + llvm_component = "hexagon", + LLVMInitializeHexagonTargetInfo, + LLVMInitializeHexagonTarget, + LLVMInitializeHexagonTargetMC, + LLVMInitializeHexagonAsmPrinter, + LLVMInitializeHexagonAsmParser + ); + init_target!( + llvm_component = "webassembly", + LLVMInitializeWebAssemblyTargetInfo, + LLVMInitializeWebAssemblyTarget, + LLVMInitializeWebAssemblyTargetMC, + LLVMInitializeWebAssemblyAsmPrinter + ); } diff --git a/src/librustc_lsan/build.rs b/src/librustc_lsan/build.rs index 73720d8c2d64e..6201bc9356dce 100644 --- a/src/librustc_lsan/build.rs +++ b/src/librustc_lsan/build.rs @@ -1,5 +1,5 @@ -use std::env; use build_helper::sanitizer_lib_boilerplate; +use std::env; use cmake::Config; diff --git a/src/librustc_lsan/lib.rs b/src/librustc_lsan/lib.rs index 4c8c9d15d5629..bdbc154f4e861 100644 --- a/src/librustc_lsan/lib.rs +++ b/src/librustc_lsan/lib.rs @@ -3,6 +3,8 @@ #![feature(sanitizer_runtime)] #![feature(staged_api)] #![no_std] -#![unstable(feature = "sanitizer_runtime_lib", - reason = "internal implementation detail of sanitizers", - issue = "none")] +#![unstable( + feature = "sanitizer_runtime_lib", + reason = "internal implementation detail of sanitizers", + issue = "none" +)] diff --git a/src/librustc_macros/src/hash_stable.rs b/src/librustc_macros/src/hash_stable.rs index 103fcd0e8e7bd..e6f457dd663c2 100644 --- a/src/librustc_macros/src/hash_stable.rs +++ b/src/librustc_macros/src/hash_stable.rs @@ -1,7 +1,7 @@ -use synstructure; -use syn::{self, Meta, NestedMeta, parse_quote}; use proc_macro2::{self, Ident}; use quote::quote; +use syn::{self, parse_quote, Meta, NestedMeta}; +use synstructure; struct Attributes { ignore: bool, @@ -9,10 +9,7 @@ struct Attributes { } fn parse_attributes(field: &syn::Field) -> Attributes { - let mut attrs = Attributes { - ignore: false, - project: None, - }; + let mut attrs = Attributes { ignore: false, project: None }; for attr in &field.attrs { if let Ok(meta) = attr.parse_meta() { if !meta.path().is_ident("stable_hasher") { @@ -51,17 +48,17 @@ pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_ma let generic: syn::GenericParam = parse_quote!(__CTX); s.add_bounds(synstructure::AddBounds::Generics); s.add_impl_generic(generic); - s.add_where_predicate(parse_quote!{ __CTX: crate::HashStableContext }); + s.add_where_predicate(parse_quote! { __CTX: crate::HashStableContext }); let body = s.each(|bi| { let attrs = parse_attributes(bi.ast()); if attrs.ignore { - quote!{} + quote! {} } else if let Some(project) = attrs.project { - quote!{ + quote! { &#bi.#project.hash_stable(__hcx, __hasher); } } else { - quote!{ + quote! { #bi.hash_stable(__hcx, __hasher); } } @@ -75,15 +72,18 @@ pub fn hash_stable_generic_derive(mut s: synstructure::Structure<'_>) -> proc_ma syn::Data::Union(_) => panic!("cannot derive on union"), }; - s.bound_impl(quote!(::rustc_data_structures::stable_hasher::HashStable<__CTX>), quote!{ - fn hash_stable( - &self, - __hcx: &mut __CTX, - __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) { - #discriminant - match *self { #body } - } - }) + s.bound_impl( + quote!(::rustc_data_structures::stable_hasher::HashStable<__CTX>), + quote! { + fn hash_stable( + &self, + __hcx: &mut __CTX, + __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) { + #discriminant + match *self { #body } + } + }, + ) } pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { @@ -93,13 +93,13 @@ pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::To let body = s.each(|bi| { let attrs = parse_attributes(bi.ast()); if attrs.ignore { - quote!{} + quote! {} } else if let Some(project) = attrs.project { - quote!{ + quote! { &#bi.#project.hash_stable(__hcx, __hasher); } } else { - quote!{ + quote! { #bi.hash_stable(__hcx, __hasher); } } @@ -113,14 +113,20 @@ pub fn hash_stable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::To syn::Data::Union(_) => panic!("cannot derive on union"), }; - s.bound_impl(quote!(::rustc_data_structures::stable_hasher::HashStable - <::rustc::ich::StableHashingContext<'__ctx>>), quote!{ - fn hash_stable( - &self, - __hcx: &mut ::rustc::ich::StableHashingContext<'__ctx>, - __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) { - #discriminant - match *self { #body } - } - }) + s.bound_impl( + quote!( + ::rustc_data_structures::stable_hasher::HashStable< + ::rustc::ich::StableHashingContext<'__ctx>, + > + ), + quote! { + fn hash_stable( + &self, + __hcx: &mut ::rustc::ich::StableHashingContext<'__ctx>, + __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) { + #discriminant + match *self { #body } + } + }, + ) } diff --git a/src/librustc_macros/src/lib.rs b/src/librustc_macros/src/lib.rs index eee634ffebd92..3f55d81ce7d1b 100644 --- a/src/librustc_macros/src/lib.rs +++ b/src/librustc_macros/src/lib.rs @@ -1,6 +1,5 @@ #![allow(rustc::default_hash_types)] - -#![recursion_limit="128"] +#![recursion_limit = "128"] extern crate proc_macro; @@ -9,10 +8,10 @@ use synstructure::decl_derive; use proc_macro::TokenStream; mod hash_stable; -mod type_foldable; mod lift; mod query; mod symbols; +mod type_foldable; #[proc_macro] pub fn rustc_queries(input: TokenStream) -> TokenStream { diff --git a/src/librustc_macros/src/lift.rs b/src/librustc_macros/src/lift.rs index 23f30bcad2b63..1b91fc5018a23 100644 --- a/src/librustc_macros/src/lift.rs +++ b/src/librustc_macros/src/lift.rs @@ -1,7 +1,7 @@ -use synstructure; -use syn::{self, parse_quote}; use proc_macro2; use quote::quote; +use syn::{self, parse_quote}; +use synstructure; pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { s.add_bounds(synstructure::AddBounds::Generics); @@ -15,36 +15,39 @@ pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStre // Replace `'tcx` lifetime by the `'__lifted` lifetime let (_, generics, _) = ast.generics.split_for_impl(); - let mut generics : syn::AngleBracketedGenericArguments = syn::parse_quote!{ #generics }; + let mut generics: syn::AngleBracketedGenericArguments = syn::parse_quote! { #generics }; for arg in generics.args.iter_mut() { match arg { syn::GenericArgument::Lifetime(l) if *l == tcx => { *arg = parse_quote!('__lifted); - }, + } syn::GenericArgument::Type(t) => { - *arg = syn::parse_quote!{ #t::Lifted }; - }, - _ => {}, + *arg = syn::parse_quote! { #t::Lifted }; + } + _ => {} } } - quote!{ #ident #generics } + quote! { #ident #generics } }; let body = s.each_variant(|vi| { let bindings = &vi.bindings(); vi.construct(|_, index| { let bi = &bindings[index]; - quote!{ __tcx.lift(#bi)? } + quote! { __tcx.lift(#bi)? } }) }); s.add_impl_generic(newtcx); - s.bound_impl(quote!(::rustc::ty::Lift<'__lifted>), quote!{ - type Lifted = #lifted; + s.bound_impl( + quote!(::rustc::ty::Lift<'__lifted>), + quote! { + type Lifted = #lifted; - fn lift_to_tcx(&self, __tcx: ::rustc::ty::TyCtxt<'__lifted>) -> Option<#lifted> { - Some(match *self { #body }) - } - }) + fn lift_to_tcx(&self, __tcx: ::rustc::ty::TyCtxt<'__lifted>) -> Option<#lifted> { + Some(match *self { #body }) + } + }, + ) } diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index 139e1b554cf90..f680b0d64cded 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -1,15 +1,15 @@ +use itertools::Itertools; use proc_macro::TokenStream; -use proc_macro2::{TokenTree, Delimiter}; +use proc_macro2::{Delimiter, TokenTree}; +use quote::quote; +use syn; +use syn::parse::{Parse, ParseStream, Result}; +use syn::punctuated::Punctuated; +use syn::spanned::Spanned; use syn::{ - Token, Ident, Type, Attribute, ReturnType, Expr, Block, Error, - braced, parenthesized, parse_macro_input, + braced, parenthesized, parse_macro_input, Attribute, Block, Error, Expr, Ident, ReturnType, + Token, Type, }; -use syn::spanned::Spanned; -use syn::parse::{Result, Parse, ParseStream}; -use syn::punctuated::Punctuated; -use syn; -use quote::quote; -use itertools::Itertools; #[allow(non_camel_case_types)] mod kw { @@ -164,13 +164,7 @@ impl Parse for Query { braced!(content in input); let modifiers = content.parse()?; - Ok(Query { - modifiers, - name, - key, - arg, - result, - }) + Ok(Query { modifiers, name, key, arg, result }) } } @@ -198,10 +192,7 @@ impl Parse for Group { let name: Ident = input.parse()?; let content; braced!(content in input); - Ok(Group { - name, - queries: content.parse()?, - }) + Ok(Group { name, queries: content.parse()? }) } } @@ -352,14 +343,20 @@ fn add_query_description_impl( } }; - let tcx = args.as_ref().map(|t| { - let t = &(t.0).0; - quote! { #t } - }).unwrap_or(quote! { _ }); - let value = args.as_ref().map(|t| { - let t = &(t.1).0; - quote! { #t } - }).unwrap_or(quote! { _ }); + let tcx = args + .as_ref() + .map(|t| { + let t = &(t.0).0; + quote! { #t } + }) + .unwrap_or(quote! { _ }); + let value = args + .as_ref() + .map(|t| { + let t = &(t.1).0; + quote! { #t } + }) + .unwrap_or(quote! { _ }); quote! { #[inline] #[allow(unused_variables)] @@ -507,11 +504,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { }); } - add_query_description_impl( - &query, - modifiers, - &mut query_description_stream, - ); + add_query_description_impl(&query, modifiers, &mut query_description_stream); } let name = &group.name; query_stream.extend(quote! { diff --git a/src/librustc_macros/src/symbols.rs b/src/librustc_macros/src/symbols.rs index 1f6e54807d8cb..c692c7f399541 100644 --- a/src/librustc_macros/src/symbols.rs +++ b/src/librustc_macros/src/symbols.rs @@ -1,12 +1,9 @@ use proc_macro::TokenStream; -use syn::{ - Token, Ident, LitStr, - braced, parse_macro_input, -}; -use syn::parse::{Result, Parse, ParseStream}; -use syn; -use std::collections::HashSet; use quote::quote; +use std::collections::HashSet; +use syn; +use syn::parse::{Parse, ParseStream, Result}; +use syn::{braced, parse_macro_input, Ident, LitStr, Token}; #[allow(non_camel_case_types)] mod kw { @@ -26,10 +23,7 @@ impl Parse for Keyword { let value = input.parse()?; input.parse::()?; - Ok(Keyword { - name, - value, - }) + Ok(Keyword { name, value }) } } @@ -47,10 +41,7 @@ impl Parse for Symbol { }; input.parse::()?; - Ok(Symbol { - name, - value, - }) + Ok(Symbol { name, value }) } } @@ -84,10 +75,7 @@ impl Parse for Input { braced!(content in input); let symbols = content.parse()?; - Ok(Input { - keywords, - symbols, - }) + Ok(Input { keywords, symbols }) } } diff --git a/src/librustc_macros/src/type_foldable.rs b/src/librustc_macros/src/type_foldable.rs index e6057767b4773..3d58984a9009b 100644 --- a/src/librustc_macros/src/type_foldable.rs +++ b/src/librustc_macros/src/type_foldable.rs @@ -1,6 +1,6 @@ -use synstructure; -use syn; use quote::quote; +use syn; +use synstructure; pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { if let syn::Data::Union(_) = s.ast().data { @@ -12,28 +12,31 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:: let bindings = vi.bindings(); vi.construct(|_, index| { let bind = &bindings[index]; - quote!{ + quote! { ::rustc::ty::fold::TypeFoldable::fold_with(#bind, __folder) } }) }); let body_visit = s.fold(false, |acc, bind| { - quote!{ #acc || ::rustc::ty::fold::TypeFoldable::visit_with(#bind, __folder) } + quote! { #acc || ::rustc::ty::fold::TypeFoldable::visit_with(#bind, __folder) } }); - s.bound_impl(quote!(::rustc::ty::fold::TypeFoldable<'tcx>), quote!{ - fn super_fold_with<__F: ::rustc::ty::fold::TypeFolder<'tcx>>( - &self, - __folder: &mut __F - ) -> Self { - match *self { #body_fold } - } + s.bound_impl( + quote!(::rustc::ty::fold::TypeFoldable<'tcx>), + quote! { + fn super_fold_with<__F: ::rustc::ty::fold::TypeFolder<'tcx>>( + &self, + __folder: &mut __F + ) -> Self { + match *self { #body_fold } + } - fn super_visit_with<__F: ::rustc::ty::fold::TypeVisitor<'tcx>>( - &self, - __folder: &mut __F - ) -> bool { - match *self { #body_visit } - } - }) + fn super_visit_with<__F: ::rustc::ty::fold::TypeVisitor<'tcx>>( + &self, + __folder: &mut __F + ) -> bool { + match *self { #body_visit } + } + }, + ) } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 0a0f2560b994f..80d7e71e96bb6 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -1,35 +1,35 @@ //! Validates all used crates and extern libraries and loads their metadata use crate::locator::{CrateLocator, CratePaths}; -use crate::rmeta::{CrateMetadata, CrateNumMap, CrateRoot, CrateDep, MetadataBlob}; +use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob}; use rustc::hir::def_id::CrateNum; +use rustc::hir::def_id::LOCAL_CRATE; +use rustc::hir::map::Definitions; +use rustc::middle::cstore::DepKind; +use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn}; +use rustc::session::config::{self, Sanitizer}; +use rustc::session::search_paths::PathKind; +use rustc::session::{CrateDisambiguator, Session}; +use rustc::ty::TyCtxt; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; use rustc_index::vec::IndexVec; -use rustc::middle::cstore::DepKind; -use rustc::session::{Session, CrateDisambiguator}; -use rustc::session::config::{Sanitizer, self}; use rustc_target::spec::{PanicStrategy, TargetTriple}; -use rustc::session::search_paths::PathKind; -use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource, MetadataLoaderDyn}; -use rustc::hir::map::Definitions; -use rustc::hir::def_id::LOCAL_CRATE; -use rustc::ty::TyCtxt; use std::path::Path; use std::{cmp, fs}; +use log::{debug, info, log_enabled}; +use proc_macro::bridge::client::ProcMacro; use syntax::ast; use syntax::attr; use syntax::edition::Edition; use syntax::expand::allocator::{global_allocator_spans, AllocatorKind}; -use syntax::symbol::{Symbol, sym}; use syntax::span_fatal; +use syntax::symbol::{sym, Symbol}; use syntax_expand::base::SyntaxExtension; use syntax_pos::{Span, DUMMY_SP}; -use log::{debug, info, log_enabled}; -use proc_macro::bridge::client::ProcMacro; use rustc_error_codes::*; @@ -89,7 +89,7 @@ fn dump_crates(cstore: &CStore) { info!(" reqd: {:?}", data.dep_kind()); let CrateSource { dylib, rlib, rmeta } = data.source(); dylib.as_ref().map(|dl| info!(" dylib: {}", dl.0.display())); - rlib.as_ref().map(|rl| info!(" rlib: {}", rl.0.display())); + rlib.as_ref().map(|rl| info!(" rlib: {}", rl.0.display())); rmeta.as_ref().map(|rl| info!(" rmeta: {}", rl.0.display())); }); } @@ -105,7 +105,8 @@ impl CStore { } crate fn get_crate_data(&self, cnum: CrateNum) -> &CrateMetadata { - self.metas[cnum].as_ref() + self.metas[cnum] + .as_ref() .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum)) } @@ -183,7 +184,7 @@ impl<'a> CrateLoader<'a> { injected_panic_runtime: None, allocator_kind: None, has_global_allocator: false, - } + }, } } @@ -198,10 +199,15 @@ impl<'a> CrateLoader<'a> { fn existing_match(&self, name: Symbol, hash: Option, kind: PathKind) -> Option { let mut ret = None; self.cstore.iter_crate_data(|cnum, data| { - if data.name() != name { return } + if data.name() != name { + return; + } match hash { - Some(hash) if hash == data.hash() => { ret = Some(cnum); return } + Some(hash) if hash == data.hash() => { + ret = Some(cnum); + return; + } Some(..) => return, None => {} } @@ -221,13 +227,13 @@ impl<'a> CrateLoader<'a> { if let Some(mut files) = entry.files() { if files.any(|l| { let l = fs::canonicalize(l).ok(); - source.dylib.as_ref().map(|p| &p.0) == l.as_ref() || - source.rlib.as_ref().map(|p| &p.0) == l.as_ref() + source.dylib.as_ref().map(|p| &p.0) == l.as_ref() + || source.rlib.as_ref().map(|p| &p.0) == l.as_ref() }) { ret = Some(cnum); } } - return + return; } // Alright, so we've gotten this far which means that `data` has the @@ -236,9 +242,13 @@ impl<'a> CrateLoader<'a> { // have to make sure that this crate was found in the crate lookup // path (this is a top-level dependency) as we don't want to // implicitly load anything inside the dependency lookup path. - let prev_kind = source.dylib.as_ref().or(source.rlib.as_ref()) - .or(source.rmeta.as_ref()) - .expect("No sources for crate").1; + let prev_kind = source + .dylib + .as_ref() + .or(source.rlib.as_ref()) + .or(source.rmeta.as_ref()) + .expect("No sources for crate") + .1; if kind.matches(prev_kind) { ret = Some(cnum); } @@ -246,30 +256,39 @@ impl<'a> CrateLoader<'a> { return ret; } - fn verify_no_symbol_conflicts(&self, - span: Span, - root: &CrateRoot<'_>) { + fn verify_no_symbol_conflicts(&self, span: Span, root: &CrateRoot<'_>) { // Check for (potential) conflicts with the local crate - if self.local_crate_name == root.name() && - self.sess.local_crate_disambiguator() == root.disambiguator() { - span_fatal!(self.sess, span, E0519, - "the current crate is indistinguishable from one of its \ + if self.local_crate_name == root.name() + && self.sess.local_crate_disambiguator() == root.disambiguator() + { + span_fatal!( + self.sess, + span, + E0519, + "the current crate is indistinguishable from one of its \ dependencies: it has the same crate-name `{}` and was \ compiled with the same `-C metadata` arguments. This \ will result in symbol conflicts between the two.", - root.name()) + root.name() + ) } // Check for conflicts with any crate loaded so far self.cstore.iter_crate_data(|_, other| { if other.name() == root.name() && // same crate-name other.disambiguator() == root.disambiguator() && // same crate-disambiguator - other.hash() != root.hash() { // but different SVH - span_fatal!(self.sess, span, E0523, - "found two different crates with name `{}` that are \ + other.hash() != root.hash() + { + // but different SVH + span_fatal!( + self.sess, + span, + E0523, + "found two different crates with name `{}` that are \ not distinguished by differing `-C metadata`. This \ will result in symbol conflicts between the two.", - root.name()) + root.name() + ) } }); } @@ -281,7 +300,7 @@ impl<'a> CrateLoader<'a> { span: Span, lib: Library, dep_kind: DepKind, - name: Symbol + name: Symbol, ) -> CrateNum { let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate"); @@ -290,9 +309,8 @@ impl<'a> CrateLoader<'a> { let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash()); self.verify_no_symbol_conflicts(span, &crate_root); - let private_dep = self.sess.opts.externs.get(&name.as_str()) - .map(|e| e.is_private_dep) - .unwrap_or(false); + let private_dep = + self.sess.opts.externs.get(&name.as_str()).map(|e| e.is_private_dep).unwrap_or(false); info!("register crate `{}` (private_dep = {})", crate_root.name(), private_dep); @@ -314,8 +332,10 @@ impl<'a> CrateLoader<'a> { let raw_proc_macros = if crate_root.is_proc_macro_crate() { let temp_root; let (dlsym_source, dlsym_root) = match &host_lib { - Some(host_lib) => - (&host_lib.source, { temp_root = host_lib.metadata.get_root(); &temp_root }), + Some(host_lib) => (&host_lib.source, { + temp_root = host_lib.metadata.get_root(); + &temp_root + }), None => (&source, &crate_root), }; let dlsym_dylib = dlsym_source.dylib.as_ref().expect("no dylib for a proc-macro crate"); @@ -324,18 +344,21 @@ impl<'a> CrateLoader<'a> { None }; - self.cstore.set_crate_data(cnum, CrateMetadata::new( - self.sess, - metadata, - crate_root, - raw_proc_macros, + self.cstore.set_crate_data( cnum, - cnum_map, - dep_kind, - source, - private_dep, - host_hash, - )); + CrateMetadata::new( + self.sess, + metadata, + crate_root, + raw_proc_macros, + cnum, + cnum_map, + dep_kind, + source, + private_dep, + host_hash, + ), + ); cnum } @@ -360,7 +383,7 @@ impl<'a> CrateLoader<'a> { proc_macro_locator.reset(); let result = match self.load(&mut proc_macro_locator)? { LoadResult::Previous(cnum) => return Some((LoadResult::Previous(cnum), None)), - LoadResult::Loaded(library) => Some(LoadResult::Loaded(library)) + LoadResult::Loaded(library) => Some(LoadResult::Loaded(library)), }; locator.hash = locator.host_hash; // Use the locator when looking for the host proc macro crate, as that is required @@ -385,7 +408,7 @@ impl<'a> CrateLoader<'a> { LoadResult::Previous(..) => { panic!("host and target proc macros must be loaded in lock-step") } - LoadResult::Loaded(library) => library + LoadResult::Loaded(library) => library, }; (target_result.unwrap(), Some(host_result)) } else { @@ -439,10 +462,13 @@ impl<'a> CrateLoader<'a> { Some(false), // is_proc_macro ); - self.load(&mut locator).map(|r| (r, None)).or_else(|| { - dep_kind = DepKind::UnexportedMacrosOnly; - self.load_proc_macro(&mut locator, path_kind) - }).ok_or_else(move || LoadError::LocatorError(locator))? + self.load(&mut locator) + .map(|r| (r, None)) + .or_else(|| { + dep_kind = DepKind::UnexportedMacrosOnly; + self.load_proc_macro(&mut locator, path_kind) + }) + .ok_or_else(move || LoadError::LocatorError(locator))? }; match result { @@ -457,7 +483,7 @@ impl<'a> CrateLoader<'a> { (LoadResult::Loaded(library), host_library) => { Ok(self.register_crate(host_library, root, span, library, dep_kind, name)) } - _ => panic!() + _ => panic!(), } } @@ -500,14 +526,15 @@ impl<'a> CrateLoader<'a> { } // Go through the crate metadata and load any crates that it references - fn resolve_crate_deps(&mut self, - root: &CratePaths, - crate_root: &CrateRoot<'_>, - metadata: &MetadataBlob, - krate: CrateNum, - span: Span, - dep_kind: DepKind) - -> CrateNumMap { + fn resolve_crate_deps( + &mut self, + root: &CratePaths, + crate_root: &CrateRoot<'_>, + metadata: &MetadataBlob, + krate: CrateNum, + span: Span, + dep_kind: DepKind, + ) -> CrateNumMap { debug!("resolving deps of external crate"); if crate_root.is_proc_macro_crate() { return CrateNumMap::new(); @@ -516,27 +543,32 @@ impl<'a> CrateLoader<'a> { // The map from crate numbers in the crate we're resolving to local crate numbers. // We map 0 and all other holes in the map to our parent crate. The "additional" // self-dependencies should be harmless. - std::iter::once(krate).chain(crate_root.decode_crate_deps(metadata).map(|dep| { - info!("resolving dep crate {} hash: `{}` extra filename: `{}`", dep.name, dep.hash, - dep.extra_filename); - if dep.kind == DepKind::UnexportedMacrosOnly { - return krate; - } - let dep_kind = match dep_kind { - DepKind::MacrosOnly => DepKind::MacrosOnly, - _ => dep.kind, - }; - self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep))) - })).collect() + std::iter::once(krate) + .chain(crate_root.decode_crate_deps(metadata).map(|dep| { + info!( + "resolving dep crate {} hash: `{}` extra filename: `{}`", + dep.name, dep.hash, dep.extra_filename + ); + if dep.kind == DepKind::UnexportedMacrosOnly { + return krate; + } + let dep_kind = match dep_kind { + DepKind::MacrosOnly => DepKind::MacrosOnly, + _ => dep.kind, + }; + self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep))) + })) + .collect() } - fn dlsym_proc_macros(&self, - path: &Path, - disambiguator: CrateDisambiguator, - span: Span + fn dlsym_proc_macros( + &self, + path: &Path, + disambiguator: CrateDisambiguator, + span: Span, ) -> &'static [ProcMacro] { - use std::env; use crate::dynamic_lib::DynamicLibrary; + use std::env; // Make sure the path contains a / or the linker will search for it. let path = env::current_dir().unwrap().join(path); @@ -564,12 +596,11 @@ impl<'a> CrateLoader<'a> { fn inject_panic_runtime(&mut self, krate: &ast::Crate) { // If we're only compiling an rlib, then there's no need to select a // panic runtime, so we just skip this section entirely. - let any_non_rlib = self.sess.crate_types.borrow().iter().any(|ct| { - *ct != config::CrateType::Rlib - }); + let any_non_rlib = + self.sess.crate_types.borrow().iter().any(|ct| *ct != config::CrateType::Rlib); if !any_non_rlib { info!("panic runtime injection skipped, only generating rlib"); - return + return; } // If we need a panic runtime, we try to find an existing one here. At @@ -581,16 +612,16 @@ impl<'a> CrateLoader<'a> { // compilation mode also comes into play. let desired_strategy = self.sess.panic_strategy(); let mut runtime_found = false; - let mut needs_panic_runtime = attr::contains_name(&krate.attrs, - sym::needs_panic_runtime); + let mut needs_panic_runtime = attr::contains_name(&krate.attrs, sym::needs_panic_runtime); self.cstore.iter_crate_data(|cnum, data| { needs_panic_runtime = needs_panic_runtime || data.needs_panic_runtime(); if data.is_panic_runtime() { // Inject a dependency from all #![needs_panic_runtime] to this // #![panic_runtime] crate. - self.inject_dependency_if(cnum, "a panic runtime", - &|data| data.needs_panic_runtime()); + self.inject_dependency_if(cnum, "a panic runtime", &|data| { + data.needs_panic_runtime() + }); runtime_found = runtime_found || data.dep_kind() == DepKind::Explicit; } }); @@ -599,7 +630,7 @@ impl<'a> CrateLoader<'a> { // we just don't need one at all, then we're done here and there's // nothing else to do. if !needs_panic_runtime || runtime_found { - return + return; } // By this point we know that we (a) need a panic runtime and (b) no @@ -626,28 +657,29 @@ impl<'a> CrateLoader<'a> { // Sanity check the loaded crate to ensure it is indeed a panic runtime // and the panic strategy is indeed what we thought it was. if !data.is_panic_runtime() { - self.sess.err(&format!("the crate `{}` is not a panic runtime", - name)); + self.sess.err(&format!("the crate `{}` is not a panic runtime", name)); } if data.panic_strategy() != desired_strategy { - self.sess.err(&format!("the crate `{}` does not have the panic \ + self.sess.err(&format!( + "the crate `{}` does not have the panic \ strategy `{}`", - name, desired_strategy.desc())); + name, + desired_strategy.desc() + )); } self.cstore.injected_panic_runtime = Some(cnum); - self.inject_dependency_if(cnum, "a panic runtime", - &|data| data.needs_panic_runtime()); + self.inject_dependency_if(cnum, "a panic runtime", &|data| data.needs_panic_runtime()); } fn inject_sanitizer_runtime(&mut self) { if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer { // Sanitizers can only be used on some tested platforms with // executables linked to `std` - const ASAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu", - "x86_64-apple-darwin"]; - const TSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu", - "x86_64-apple-darwin"]; + const ASAN_SUPPORTED_TARGETS: &[&str] = + &["x86_64-unknown-linux-gnu", "x86_64-apple-darwin"]; + const TSAN_SUPPORTED_TARGETS: &[&str] = + &["x86_64-unknown-linux-gnu", "x86_64-apple-darwin"]; const LSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu"]; const MSAN_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu"]; @@ -658,11 +690,12 @@ impl<'a> CrateLoader<'a> { Sanitizer::Memory => MSAN_SUPPORTED_TARGETS, }; if !supported_targets.contains(&&*self.sess.opts.target_triple.triple()) { - self.sess.err(&format!("{:?}Sanitizer only works with the `{}` target", + self.sess.err(&format!( + "{:?}Sanitizer only works with the `{}` target", sanitizer, supported_targets.join("` or `") )); - return + return; } // firstyear 2017 - during testing I was unable to access an OSX machine @@ -675,20 +708,21 @@ impl<'a> CrateLoader<'a> { config::CrateType::Executable => true, // This crate will be compiled with the required // instrumentation pass - config::CrateType::Staticlib | - config::CrateType::Rlib | - config::CrateType::Dylib | - config::CrateType::Cdylib => - false, + config::CrateType::Staticlib + | config::CrateType::Rlib + | config::CrateType::Dylib + | config::CrateType::Cdylib => false, _ => { - self.sess.err(&format!("Only executables, staticlibs, \ + self.sess.err(&format!( + "Only executables, staticlibs, \ cdylibs, dylibs and rlibs can be compiled with \ - `-Z sanitizer`")); + `-Z sanitizer`" + )); false } } }) { - return + return; } } else { if !self.sess.crate_types.borrow().iter().all(|ct| { @@ -699,13 +733,15 @@ impl<'a> CrateLoader<'a> { // instrumentation pass config::CrateType::Rlib => false, _ => { - self.sess.err(&format!("Only executables and rlibs can be \ - compiled with `-Z sanitizer`")); + self.sess.err(&format!( + "Only executables and rlibs can be \ + compiled with `-Z sanitizer`" + )); false } } }) { - return + return; } } @@ -730,8 +766,7 @@ impl<'a> CrateLoader<'a> { // Sanity check the loaded crate to ensure it is indeed a sanitizer runtime if !data.is_sanitizer_runtime() { - self.sess.err(&format!("the crate `{}` is not a sanitizer runtime", - name)); + self.sess.err(&format!("the crate `{}` is not a sanitizer runtime", name)); } } else { self.sess.err("Must link std to be compiled with `-Z sanitizer`"); @@ -740,9 +775,7 @@ impl<'a> CrateLoader<'a> { } fn inject_profiler_runtime(&mut self) { - if self.sess.opts.debugging_opts.profile || - self.sess.opts.cg.profile_generate.enabled() - { + if self.sess.opts.debugging_opts.profile || self.sess.opts.cg.profile_generate.enabled() { info!("loading profiler"); let name = Symbol::intern("profiler_builtins"); @@ -751,8 +784,10 @@ impl<'a> CrateLoader<'a> { // Sanity check the loaded crate to ensure it is indeed a profiler runtime if !data.is_profiler_runtime() { - self.sess.err(&format!("the crate `profiler_builtins` is not \ - a profiler runtime")); + self.sess.err(&format!( + "the crate `profiler_builtins` is not \ + a profiler runtime" + )); } } } @@ -760,40 +795,36 @@ impl<'a> CrateLoader<'a> { fn inject_allocator_crate(&mut self, krate: &ast::Crate) { self.cstore.has_global_allocator = match &*global_allocator_spans(krate) { [span1, span2, ..] => { - self.sess.struct_span_err(*span2, "cannot define multiple global allocators") + self.sess + .struct_span_err(*span2, "cannot define multiple global allocators") .span_label(*span2, "cannot define a new global allocator") .span_label(*span1, "previous global allocator is defined here") .emit(); true } - spans => !spans.is_empty() + spans => !spans.is_empty(), }; // Check to see if we actually need an allocator. This desire comes // about through the `#![needs_allocator]` attribute and is typically // written down in liballoc. - let mut needs_allocator = attr::contains_name(&krate.attrs, - sym::needs_allocator); + let mut needs_allocator = attr::contains_name(&krate.attrs, sym::needs_allocator); self.cstore.iter_crate_data(|_, data| { needs_allocator = needs_allocator || data.needs_allocator(); }); if !needs_allocator { - return + return; } // At this point we've determined that we need an allocator. Let's see // if our compilation session actually needs an allocator based on what // we're emitting. - let all_rlib = self.sess.crate_types.borrow() - .iter() - .all(|ct| { - match *ct { - config::CrateType::Rlib => true, - _ => false, - } - }); + let all_rlib = self.sess.crate_types.borrow().iter().all(|ct| match *ct { + config::CrateType::Rlib => true, + _ => false, + }); if all_rlib { - return + return; } // Ok, we need an allocator. Not only that but we're actually going to @@ -803,26 +834,28 @@ impl<'a> CrateLoader<'a> { // First up we check for global allocators. Look at the crate graph here // and see what's a global allocator, including if we ourselves are a // global allocator. - let mut global_allocator = self.cstore.has_global_allocator - .then(|| Symbol::intern("this crate")); + let mut global_allocator = + self.cstore.has_global_allocator.then(|| Symbol::intern("this crate")); self.cstore.iter_crate_data(|_, data| { if !data.has_global_allocator() { - return + return; } match global_allocator { Some(other_crate) => { - self.sess.err(&format!("the `#[global_allocator]` in {} \ + self.sess.err(&format!( + "the `#[global_allocator]` in {} \ conflicts with global \ allocator in: {}", - other_crate, - data.name())); + other_crate, + data.name() + )); } None => global_allocator = Some(data.name()), } }); if global_allocator.is_some() { self.cstore.allocator_kind = Some(AllocatorKind::Global); - return + return; } // Ok we haven't found a global allocator but we still need an @@ -837,23 +870,27 @@ impl<'a> CrateLoader<'a> { }); if !has_default { - self.sess.err("no global memory allocator found but one is \ + self.sess.err( + "no global memory allocator found but one is \ required; link to std or \ add `#[global_allocator]` to a static item \ - that implements the GlobalAlloc trait."); + that implements the GlobalAlloc trait.", + ); } self.cstore.allocator_kind = Some(AllocatorKind::Default); } - fn inject_dependency_if(&self, - krate: CrateNum, - what: &str, - needs_dep: &dyn Fn(&CrateMetadata) -> bool) { + fn inject_dependency_if( + &self, + krate: CrateNum, + what: &str, + needs_dep: &dyn Fn(&CrateMetadata) -> bool, + ) { // don't perform this validation if the session has errors, as one of // those errors may indicate a circular dependency which could cause // this to stack overflow. if self.sess.has_errors() { - return + return; } // Before we inject any dependencies, make sure we don't inject a @@ -862,12 +899,14 @@ impl<'a> CrateLoader<'a> { for dep in self.cstore.crate_dependencies_in_reverse_postorder(krate) { let data = self.cstore.get_crate_data(dep); if needs_dep(&data) { - self.sess.err(&format!("the crate `{}` cannot depend \ + self.sess.err(&format!( + "the crate `{}` cannot depend \ on a crate that needs {}, but \ it depends on `{}`", - self.cstore.get_crate_data(krate).name(), - what, - data.name())); + self.cstore.get_crate_data(krate).name(), + what, + data.name() + )); } } @@ -877,7 +916,7 @@ impl<'a> CrateLoader<'a> { // crates on the command line correctly). self.cstore.iter_crate_data(|cnum, data| { if !needs_dep(data) { - return + return; } info!("injecting a dep from {} to {}", cnum, krate); @@ -903,12 +942,17 @@ impl<'a> CrateLoader<'a> { ) -> CrateNum { match item.kind { ast::ItemKind::ExternCrate(orig_name) => { - debug!("resolving extern crate stmt. ident: {} orig_name: {:?}", - item.ident, orig_name); + debug!( + "resolving extern crate stmt. ident: {} orig_name: {:?}", + item.ident, orig_name + ); let name = match orig_name { Some(orig_name) => { - crate::validate_crate_name(Some(self.sess), &orig_name.as_str(), - Some(item.span)); + crate::validate_crate_name( + Some(self.sess), + &orig_name.as_str(), + Some(item.span), + ); orig_name } None => item.ident.name, diff --git a/src/librustc_metadata/dependency_format.rs b/src/librustc_metadata/dependency_format.rs index d6d722c47b3a7..191231a3d608f 100644 --- a/src/librustc_metadata/dependency_format.rs +++ b/src/librustc_metadata/dependency_format.rs @@ -54,20 +54,25 @@ use crate::creader::CStore; use rustc::hir::def_id::CrateNum; -use rustc::middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic}; +use rustc::middle::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic}; use rustc::middle::cstore::{self, DepKind}; -use rustc::middle::dependency_format::{DependencyList, Dependencies, Linkage}; +use rustc::middle::dependency_format::{Dependencies, DependencyList, Linkage}; use rustc::session::config; use rustc::ty::TyCtxt; use rustc::util::nodemap::FxHashMap; use rustc_target::spec::PanicStrategy; crate fn calculate(tcx: TyCtxt<'_>) -> Dependencies { - tcx.sess.crate_types.borrow().iter().map(|&ty| { - let linkage = calculate_type(tcx, ty); - verify_ok(tcx, &linkage); - (ty, linkage) - }).collect::>() + tcx.sess + .crate_types + .borrow() + .iter() + .map(|&ty| { + let linkage = calculate_type(tcx, ty); + verify_ok(tcx, &linkage); + (ty, linkage) + }) + .collect::>() } fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { @@ -89,8 +94,9 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { // If the global prefer_dynamic switch is turned off, or the final // executable will be statically linked, prefer static crate linkage. - config::CrateType::Executable if !sess.opts.cg.prefer_dynamic || - sess.crt_static() => Linkage::Static, + config::CrateType::Executable if !sess.opts.cg.prefer_dynamic || sess.crt_static() => { + Linkage::Static + } config::CrateType::Executable => Linkage::Dynamic, // proc-macro crates are mostly cdylibs, but we also need metadata. @@ -118,16 +124,25 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { // Staticlibs, cdylibs, and static executables must have all static // dependencies. If any are not found, generate some nice pretty errors. - if ty == config::CrateType::Cdylib || ty == config::CrateType::Staticlib || - (ty == config::CrateType::Executable && sess.crt_static() && - !sess.target.target.options.crt_static_allows_dylibs) { + if ty == config::CrateType::Cdylib + || ty == config::CrateType::Staticlib + || (ty == config::CrateType::Executable + && sess.crt_static() + && !sess.target.target.options.crt_static_allows_dylibs) + { for &cnum in tcx.crates().iter() { - if tcx.dep_kind(cnum).macros_only() { continue } + if tcx.dep_kind(cnum).macros_only() { + continue; + } let src = tcx.used_crate_source(cnum); - if src.rlib.is_some() { continue } - sess.err(&format!("crate `{}` required to be available in rlib format, \ + if src.rlib.is_some() { + continue; + } + sess.err(&format!( + "crate `{}` required to be available in rlib format, \ but was not found in this form", - tcx.crate_name(cnum))); + tcx.crate_name(cnum) + )); } return Vec::new(); } @@ -139,7 +154,9 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { // dependencies, ensuring there are no conflicts. The only valid case for a // dependency to be relied upon twice is for both cases to rely on a dylib. for &cnum in tcx.crates().iter() { - if tcx.dep_kind(cnum).macros_only() { continue } + if tcx.dep_kind(cnum).macros_only() { + continue; + } let name = tcx.crate_name(cnum); let src = tcx.used_crate_source(cnum); if src.dylib.is_some() { @@ -155,13 +172,13 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { // Collect what we've got so far in the return vector. let last_crate = tcx.crates().len(); - let mut ret = (1..last_crate+1).map(|cnum| { - match formats.get(&CrateNum::new(cnum)) { + let mut ret = (1..last_crate + 1) + .map(|cnum| match formats.get(&CrateNum::new(cnum)) { Some(&RequireDynamic) => Linkage::Dynamic, Some(&RequireStatic) => Linkage::IncludedFromDylib, None => Linkage::NotLinked, - } - }).collect::>(); + }) + .collect::>(); // Run through the dependency list again, and add any missing libraries as // static libraries. @@ -170,9 +187,10 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { // (e.g., it's an allocator) then we skip it here as well. for &cnum in tcx.crates().iter() { let src = tcx.used_crate_source(cnum); - if src.dylib.is_none() && - !formats.contains_key(&cnum) && - tcx.dep_kind(cnum) == DepKind::Explicit { + if src.dylib.is_none() + && !formats.contains_key(&cnum) + && tcx.dep_kind(cnum) == DepKind::Explicit + { assert!(src.rlib.is_some() || src.rmeta.is_some()); log::info!("adding staticlib: {}", tcx.crate_name(cnum)); add_library(tcx, cnum, RequireStatic, &mut formats); @@ -186,8 +204,9 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { // // Things like allocators and panic runtimes may not have been activated // quite yet, so do so here. - activate_injected_dep(CStore::from_tcx(tcx).injected_panic_runtime(), &mut ret, - &|cnum| tcx.is_panic_runtime(cnum)); + activate_injected_dep(CStore::from_tcx(tcx).injected_panic_runtime(), &mut ret, &|cnum| { + tcx.is_panic_runtime(cnum) + }); // When dylib B links to dylib A, then when using B we must also link to A. // It could be the case, however, that the rlib for A is present (hence we @@ -199,8 +218,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { let cnum = CrateNum::new(cnum + 1); let src = tcx.used_crate_source(cnum); match *kind { - Linkage::NotLinked | - Linkage::IncludedFromDylib => {} + Linkage::NotLinked | Linkage::IncludedFromDylib => {} Linkage::Static if src.rlib.is_some() => continue, Linkage::Dynamic if src.dylib.is_some() => continue, kind => { @@ -208,9 +226,12 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList { Linkage::Static => "rlib", _ => "dylib", }; - sess.err(&format!("crate `{}` required to be available in {} format, \ + sess.err(&format!( + "crate `{}` required to be available in {} format, \ but was not found in this form", - tcx.crate_name(cnum), kind)); + tcx.crate_name(cnum), + kind + )); } } } @@ -234,39 +255,50 @@ fn add_library( // This error is probably a little obscure, but I imagine that it // can be refined over time. if link2 != link || link == RequireStatic { - tcx.sess.struct_err(&format!("cannot satisfy dependencies so `{}` only \ - shows up once", tcx.crate_name(cnum))) - .help("having upstream crates all available in one format \ - will likely make this go away") + tcx.sess + .struct_err(&format!( + "cannot satisfy dependencies so `{}` only \ + shows up once", + tcx.crate_name(cnum) + )) + .help( + "having upstream crates all available in one format \ + will likely make this go away", + ) .emit(); } } - None => { m.insert(cnum, link); } + None => { + m.insert(cnum, link); + } } } fn attempt_static(tcx: TyCtxt<'_>) -> Option { let crates = cstore::used_crates(tcx, RequireStatic); if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) { - return None + return None; } // All crates are available in an rlib format, so we're just going to link // everything in explicitly so long as it's actually required. let last_crate = tcx.crates().len(); - let mut ret = (1..last_crate+1).map(|cnum| { - if tcx.dep_kind(CrateNum::new(cnum)) == DepKind::Explicit { - Linkage::Static - } else { - Linkage::NotLinked - } - }).collect::>(); + let mut ret = (1..last_crate + 1) + .map(|cnum| { + if tcx.dep_kind(CrateNum::new(cnum)) == DepKind::Explicit { + Linkage::Static + } else { + Linkage::NotLinked + } + }) + .collect::>(); // Our allocator/panic runtime may not have been linked above if it wasn't // explicitly linked, which is the case for any injected dependency. Handle // that here and activate them. - activate_injected_dep(CStore::from_tcx(tcx).injected_panic_runtime(), &mut ret, - &|cnum| tcx.is_panic_runtime(cnum)); + activate_injected_dep(CStore::from_tcx(tcx).injected_panic_runtime(), &mut ret, &|cnum| { + tcx.is_panic_runtime(cnum) + }); Some(ret) } @@ -280,16 +312,18 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option { // a required dependency) in one of the session's field. If this field is not // set then this compilation doesn't actually need the dependency and we can // also skip this step entirely. -fn activate_injected_dep(injected: Option, - list: &mut DependencyList, - replaces_injected: &dyn Fn(CrateNum) -> bool) { +fn activate_injected_dep( + injected: Option, + list: &mut DependencyList, + replaces_injected: &dyn Fn(CrateNum) -> bool, +) { for (i, slot) in list.iter().enumerate() { let cnum = CrateNum::new(i + 1); if !replaces_injected(cnum) { - continue + continue; } if *slot != Linkage::NotLinked { - return + return; } } if let Some(injected) = injected { @@ -304,12 +338,12 @@ fn activate_injected_dep(injected: Option, fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) { let sess = &tcx.sess; if list.len() == 0 { - return + return; } let mut panic_runtime = None; for (i, linkage) in list.iter().enumerate() { if let Linkage::NotLinked = *linkage { - continue + continue; } let cnum = CrateNum::new(i + 1); @@ -317,9 +351,11 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) { if let Some((prev, _)) = panic_runtime { let prev_name = tcx.crate_name(prev); let cur_name = tcx.crate_name(cnum); - sess.err(&format!("cannot link together two \ + sess.err(&format!( + "cannot link together two \ panic runtimes: {} and {}", - prev_name, cur_name)); + prev_name, cur_name + )); } panic_runtime = Some((cnum, tcx.panic_strategy(cnum))); } @@ -334,11 +370,13 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) { // First up, validate that our selected panic runtime is indeed exactly // our same strategy. if found_strategy != desired_strategy { - sess.err(&format!("the linked panic runtime `{}` is \ + sess.err(&format!( + "the linked panic runtime `{}` is \ not compiled with this crate's \ panic strategy `{}`", - tcx.crate_name(cnum), - desired_strategy.desc())); + tcx.crate_name(cnum), + desired_strategy.desc() + )); } // Next up, verify that all other crates are compatible with this panic @@ -347,25 +385,27 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) { // panic strategy must match our own. for (i, linkage) in list.iter().enumerate() { if let Linkage::NotLinked = *linkage { - continue + continue; } if desired_strategy == PanicStrategy::Abort { - continue + continue; } let cnum = CrateNum::new(i + 1); let found_strategy = tcx.panic_strategy(cnum); let is_compiler_builtins = tcx.is_compiler_builtins(cnum); if is_compiler_builtins || desired_strategy == found_strategy { - continue + continue; } - sess.err(&format!("the crate `{}` is compiled with the \ + sess.err(&format!( + "the crate `{}` is compiled with the \ panic strategy `{}` which is \ incompatible with this crate's \ strategy of `{}`", - tcx.crate_name(cnum), - found_strategy.desc(), - desired_strategy.desc())); + tcx.crate_name(cnum), + found_strategy.desc(), + desired_strategy.desc() + )); } } } diff --git a/src/librustc_metadata/dynamic_lib.rs b/src/librustc_metadata/dynamic_lib.rs index 3871eb89f7b42..fa4983d8a815e 100644 --- a/src/librustc_metadata/dynamic_lib.rs +++ b/src/librustc_metadata/dynamic_lib.rs @@ -6,14 +6,12 @@ use std::ffi::CString; use std::path::Path; pub struct DynamicLibrary { - handle: *mut u8 + handle: *mut u8, } impl Drop for DynamicLibrary { fn drop(&mut self) { - unsafe { - dl::close(self.handle) - } + unsafe { dl::close(self.handle) } } } @@ -28,7 +26,7 @@ impl DynamicLibrary { // run. match maybe_library { Err(err) => Err(err), - Ok(handle) => Ok(DynamicLibrary { handle }) + Ok(handle) => Ok(DynamicLibrary { handle }), } } @@ -44,7 +42,7 @@ impl DynamicLibrary { // the destructor does not run. match maybe_symbol_value { Err(err) => Err(err), - Ok(symbol_value) => Ok(symbol_value as *mut T) + Ok(symbol_value) => Ok(symbol_value as *mut T), } } } @@ -54,18 +52,16 @@ mod tests; #[cfg(unix)] mod dl { - use std::ffi::{CStr, OsStr, CString}; + use std::ffi::{CStr, CString, OsStr}; use std::os::unix::prelude::*; use std::ptr; use std::str; pub(super) fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> { - check_for_errors_in(|| { - unsafe { - match filename { - Some(filename) => open_external(filename), - None => open_internal(), - } + check_for_errors_in(|| unsafe { + match filename { + Some(filename) => open_external(filename), + None => open_internal(), } }) } @@ -80,7 +76,8 @@ mod dl { } fn check_for_errors_in(f: F) -> Result - where F: FnOnce() -> T, + where + F: FnOnce() -> T, { use std::sync::{Mutex, Once}; static INIT: Once = Once::new(); @@ -112,12 +109,11 @@ mod dl { handle: *mut u8, symbol: *const libc::c_char, ) -> Result<*mut u8, String> { - check_for_errors_in(|| { - libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8 - }) + check_for_errors_in(|| libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8) } pub(super) unsafe fn close(handle: *mut u8) { - libc::dlclose(handle as *mut libc::c_void); () + libc::dlclose(handle as *mut libc::c_void); + () } } @@ -128,7 +124,7 @@ mod dl { use std::os::windows::prelude::*; use std::ptr; - use libc::{c_uint, c_void, c_char}; + use libc::{c_char, c_uint, c_void}; type DWORD = u32; type HMODULE = *mut u8; @@ -137,14 +133,10 @@ mod dl { type LPCSTR = *const i8; extern "system" { - fn SetThreadErrorMode(dwNewMode: DWORD, - lpOldMode: *mut DWORD) -> c_uint; + fn SetThreadErrorMode(dwNewMode: DWORD, lpOldMode: *mut DWORD) -> c_uint; fn LoadLibraryW(name: LPCWSTR) -> HMODULE; - fn GetModuleHandleExW(dwFlags: DWORD, - name: LPCWSTR, - handle: *mut HMODULE) -> BOOL; - fn GetProcAddress(handle: HMODULE, - name: LPCSTR) -> *mut c_void; + fn GetModuleHandleExW(dwFlags: DWORD, name: LPCWSTR, handle: *mut HMODULE) -> BOOL; + fn GetProcAddress(handle: HMODULE, name: LPCSTR) -> *mut c_void; fn FreeLibrary(handle: HMODULE) -> BOOL; } @@ -154,28 +146,22 @@ mod dl { // SEM_FAILCRITICALERRORS 0x01 let new_error_mode = 1; let mut prev_error_mode = 0; - let result = SetThreadErrorMode(new_error_mode, - &mut prev_error_mode); + let result = SetThreadErrorMode(new_error_mode, &mut prev_error_mode); if result == 0 { - return Err(io::Error::last_os_error().to_string()) + return Err(io::Error::last_os_error().to_string()); } prev_error_mode }; let result = match filename { Some(filename) => { - let filename_str: Vec<_> = - filename.encode_wide().chain(Some(0)).collect(); - let result = unsafe { - LoadLibraryW(filename_str.as_ptr()) - }; + let filename_str: Vec<_> = filename.encode_wide().chain(Some(0)).collect(); + let result = unsafe { LoadLibraryW(filename_str.as_ptr()) }; ptr_result(result) } None => { let mut handle = ptr::null_mut(); - let succeeded = unsafe { - GetModuleHandleExW(0 as DWORD, ptr::null(), &mut handle) - }; + let succeeded = unsafe { GetModuleHandleExW(0 as DWORD, ptr::null(), &mut handle) }; if succeeded == 0 { Err(io::Error::last_os_error().to_string()) } else { @@ -191,10 +177,7 @@ mod dl { result } - pub(super) unsafe fn symbol( - handle: *mut u8, - symbol: *const c_char, - ) -> Result<*mut u8, String> { + pub(super) unsafe fn symbol(handle: *mut u8, symbol: *const c_char) -> Result<*mut u8, String> { let ptr = GetProcAddress(handle as HMODULE, symbol) as *mut u8; ptr_result(ptr) } @@ -204,10 +187,6 @@ mod dl { } fn ptr_result(ptr: *mut T) -> Result<*mut T, String> { - if ptr.is_null() { - Err(io::Error::last_os_error().to_string()) - } else { - Ok(ptr) - } + if ptr.is_null() { Err(io::Error::last_os_error().to_string()) } else { Ok(ptr) } } } diff --git a/src/librustc_metadata/dynamic_lib/tests.rs b/src/librustc_metadata/dynamic_lib/tests.rs index b2302f2f1b5b7..cbf2b181e3c2a 100644 --- a/src/librustc_metadata/dynamic_lib/tests.rs +++ b/src/librustc_metadata/dynamic_lib/tests.rs @@ -4,19 +4,19 @@ use std::mem; #[test] fn test_loading_atoi() { if cfg!(windows) { - return + return; } // The C library does not need to be loaded since it is already linked in let lib = match DynamicLibrary::open(None) { Err(error) => panic!("Could not load self as module: {}", error), - Ok(lib) => lib + Ok(lib) => lib, }; - let atoi: extern fn(*const libc::c_char) -> libc::c_int = unsafe { + let atoi: extern "C" fn(*const libc::c_char) -> libc::c_int = unsafe { match lib.symbol("atoi") { Err(error) => panic!("Could not load function atoi: {}", error), - Ok(atoi) => mem::transmute::<*mut u8, _>(atoi) + Ok(atoi) => mem::transmute::<*mut u8, _>(atoi), } }; @@ -24,8 +24,7 @@ fn test_loading_atoi() { let expected_result = 0x52757374; let result = atoi(argument.as_ptr()); if result != expected_result { - panic!("atoi({:?}) != {} but equaled {} instead", argument, - expected_result, result) + panic!("atoi({:?}) != {} but equaled {} instead", argument, expected_result, result) } } @@ -34,7 +33,7 @@ fn test_errors_do_not_crash() { use std::path::Path; if !cfg!(unix) { - return + return; } // Open /dev/null as a library to get an error, and make sure @@ -42,6 +41,6 @@ fn test_errors_do_not_crash() { let path = Path::new("/dev/null"); match DynamicLibrary::open(Some(&path)) { Err(_) => {} - Ok(_) => panic!("Successfully opened the empty library.") + Ok(_) => panic!("Successfully opened the empty library."), } } diff --git a/src/librustc_metadata/foreign_modules.rs b/src/librustc_metadata/foreign_modules.rs index 2311e0422f65d..a48d7f0ba0f50 100644 --- a/src/librustc_metadata/foreign_modules.rs +++ b/src/librustc_metadata/foreign_modules.rs @@ -1,13 +1,10 @@ -use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir; +use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::middle::cstore::ForeignModule; use rustc::ty::TyCtxt; crate fn collect(tcx: TyCtxt<'_>) -> Vec { - let mut collector = Collector { - tcx, - modules: Vec::new(), - }; + let mut collector = Collector { tcx, modules: Vec::new() }; tcx.hir().krate().visit_all_item_likes(&mut collector); return collector.modules; } @@ -24,13 +21,10 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { _ => return, }; - let foreign_items = fm.items.iter() - .map(|it| self.tcx.hir().local_def_id(it.hir_id)) - .collect(); - self.modules.push(ForeignModule { - foreign_items, - def_id: self.tcx.hir().local_def_id(it.hir_id), - }); + let foreign_items = + fm.items.iter().map(|it| self.tcx.hir().local_def_id(it.hir_id)).collect(); + self.modules + .push(ForeignModule { foreign_items, def_id: self.tcx.hir().local_def_id(it.hir_id) }); } fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {} diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index aaaff7e3b0a4a..0e72433e2f547 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -1,5 +1,4 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] - #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(core_intrinsics)] @@ -14,8 +13,7 @@ #![feature(slice_patterns)] #![feature(specialization)] #![feature(stmt_expr_attributes)] - -#![recursion_limit="256"] +#![recursion_limit = "256"] extern crate libc; extern crate proc_macro; @@ -40,7 +38,7 @@ pub mod locator; pub fn validate_crate_name( sess: Option<&rustc::session::Session>, s: &str, - sp: Option + sp: Option, ) { let mut err_count = 0; { @@ -56,8 +54,12 @@ pub fn validate_crate_name( say("crate name must not be empty"); } for c in s.chars() { - if c.is_alphanumeric() { continue } - if c == '_' { continue } + if c.is_alphanumeric() { + continue; + } + if c == '_' { + continue; + } say(&format!("invalid character `{}` in crate name: `{}`", c, s)); } } diff --git a/src/librustc_metadata/link_args.rs b/src/librustc_metadata/link_args.rs index 10dfc3c72e5cf..e3f8eab294174 100644 --- a/src/librustc_metadata/link_args.rs +++ b/src/librustc_metadata/link_args.rs @@ -1,13 +1,11 @@ -use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir; +use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::TyCtxt; use rustc_target::spec::abi::Abi; use syntax::symbol::sym; crate fn collect(tcx: TyCtxt<'_>) -> Vec { - let mut collector = Collector { - args: Vec::new(), - }; + let mut collector = Collector { args: Vec::new() }; tcx.hir().krate().visit_all_item_likes(&mut collector); for attr in tcx.hir().krate().attrs.iter() { @@ -31,10 +29,8 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector { hir::ItemKind::ForeignMod(ref fm) => fm, _ => return, }; - if fm.abi == Abi::Rust || - fm.abi == Abi::RustIntrinsic || - fm.abi == Abi::PlatformIntrinsic { - return + if fm.abi == Abi::Rust || fm.abi == Abi::RustIntrinsic || fm.abi == Abi::PlatformIntrinsic { + return; } // First, add all of the custom #[link_args] attributes diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 8a1eeea02512e..48c847fc037c4 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -213,23 +213,23 @@ //! metadata::locator or metadata::creader for all the juicy details! use crate::creader::Library; -use crate::rmeta::{METADATA_HEADER, rustc_version, MetadataBlob}; +use crate::rmeta::{rustc_version, MetadataBlob, METADATA_HEADER}; -use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::MetadataRef; use rustc::middle::cstore::{CrateSource, MetadataLoader}; -use rustc::session::{config, Session, CrateDisambiguator}; -use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch}; +use rustc::session::filesearch::{FileDoesntMatch, FileMatches, FileSearch}; use rustc::session::search_paths::PathKind; +use rustc::session::{config, CrateDisambiguator, Session}; use rustc::util::nodemap::FxHashMap; +use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::svh::Svh; +use rustc_data_structures::sync::MetadataRef; use errors::DiagnosticBuilder; -use syntax::{span_err, span_fatal}; -use syntax::symbol::{Symbol, sym}; +use rustc_target::spec::{Target, TargetTriple}; use syntax::struct_span_err; +use syntax::symbol::{sym, Symbol}; +use syntax::{span_err, span_fatal}; use syntax_pos::Span; -use rustc_target::spec::{Target, TargetTriple}; use std::cmp; use std::fmt; @@ -327,10 +327,14 @@ impl<'a> CrateLocator<'a> { metadata_loader, crate_name, exact_paths: if hash.is_none() { - sess.opts.externs.get(&crate_name.as_str()).into_iter() + sess.opts + .externs + .get(&crate_name.as_str()) + .into_iter() .filter_map(|entry| entry.files()) .flatten() - .map(|location| PathBuf::from(location)).collect() + .map(|location| PathBuf::from(location)) + .collect() } else { // SVH being specified means this is a transitive dependency, // so `--extern` options do not apply. @@ -375,9 +379,10 @@ impl<'a> CrateLocator<'a> { } let mut seen_paths = FxHashSet::default(); match self.extra_filename { - Some(s) => self.find_library_crate(s, &mut seen_paths) + Some(s) => self + .find_library_crate(s, &mut seen_paths) .or_else(|| self.find_library_crate("", &mut seen_paths)), - None => self.find_library_crate("", &mut seen_paths) + None => self.find_library_crate("", &mut seen_paths), } } @@ -388,12 +393,14 @@ impl<'a> CrateLocator<'a> { }; let mut msg = "the following crate versions were found:".to_string(); let mut err = if !self.rejected_via_hash.is_empty() { - let mut err = struct_span_err!(self.sess, - self.span, - E0460, - "found possibly newer version of crate `{}`{}", - self.crate_name, - add); + let mut err = struct_span_err!( + self.sess, + self.span, + E0460, + "found possibly newer version of crate `{}`{}", + self.crate_name, + add + ); err.note("perhaps that crate needs to be recompiled?"); let mismatches = self.rejected_via_hash.iter(); for &CrateMismatch { ref path, .. } in mismatches { @@ -410,30 +417,36 @@ impl<'a> CrateLocator<'a> { err.note(&msg); err } else if !self.rejected_via_triple.is_empty() { - let mut err = struct_span_err!(self.sess, - self.span, - E0461, - "couldn't find crate `{}` \ + let mut err = struct_span_err!( + self.sess, + self.span, + E0461, + "couldn't find crate `{}` \ with expected target triple {}{}", - self.crate_name, - self.triple, - add); + self.crate_name, + self.triple, + add + ); let mismatches = self.rejected_via_triple.iter(); for &CrateMismatch { ref path, ref got } in mismatches { - msg.push_str(&format!("\ncrate `{}`, target triple {}: {}", - self.crate_name, - got, - path.display())); + msg.push_str(&format!( + "\ncrate `{}`, target triple {}: {}", + self.crate_name, + got, + path.display() + )); } err.note(&msg); err } else if !self.rejected_via_kind.is_empty() { - let mut err = struct_span_err!(self.sess, - self.span, - E0462, - "found staticlib `{}` instead of rlib or dylib{}", - self.crate_name, - add); + let mut err = struct_span_err!( + self.sess, + self.span, + E0462, + "found staticlib `{}` instead of rlib or dylib{}", + self.crate_name, + add + ); err.help("please recompile that crate using --crate-type lib"); let mismatches = self.rejected_via_kind.iter(); for &CrateMismatch { ref path, .. } in mismatches { @@ -442,34 +455,43 @@ impl<'a> CrateLocator<'a> { err.note(&msg); err } else if !self.rejected_via_version.is_empty() { - let mut err = struct_span_err!(self.sess, - self.span, - E0514, - "found crate `{}` compiled by an incompatible version \ + let mut err = struct_span_err!( + self.sess, + self.span, + E0514, + "found crate `{}` compiled by an incompatible version \ of rustc{}", - self.crate_name, - add); - err.help(&format!("please recompile that crate using this compiler ({})", - rustc_version())); + self.crate_name, + add + ); + err.help(&format!( + "please recompile that crate using this compiler ({})", + rustc_version() + )); let mismatches = self.rejected_via_version.iter(); for &CrateMismatch { ref path, ref got } in mismatches { - msg.push_str(&format!("\ncrate `{}` compiled by {}: {}", - self.crate_name, - got, - path.display())); + msg.push_str(&format!( + "\ncrate `{}` compiled by {}: {}", + self.crate_name, + got, + path.display() + )); } err.note(&msg); err } else { - let mut err = struct_span_err!(self.sess, - self.span, - E0463, - "can't find crate for `{}`{}", - self.crate_name, - add); + let mut err = struct_span_err!( + self.sess, + self.span, + E0463, + "can't find crate for `{}`{}", + self.crate_name, + add + ); if (self.crate_name == sym::std || self.crate_name == sym::core) - && self.triple != TargetTriple::from_triple(config::host_triple()) { + && self.triple != TargetTriple::from_triple(config::host_triple()) + { err.note(&format!("the `{}` target may not be installed", self.triple)); } err.span_label(self.span, "can't find crate"); @@ -480,12 +502,15 @@ impl<'a> CrateLocator<'a> { let dylibname = self.dylibname(); let mismatches = self.rejected_via_filename.iter(); for &CrateMismatch { ref path, .. } in mismatches { - err.note(&format!("extern location for {} is of an unknown type: {}", - self.crate_name, - path.display())) - .help(&format!("file name should be lib*.rlib or {}*.{}", - dylibname.0, - dylibname.1)); + err.note(&format!( + "extern location for {} is of an unknown type: {}", + self.crate_name, + path.display() + )) + .help(&format!( + "file name should be lib*.rlib or {}*.{}", + dylibname.0, dylibname.1 + )); } } @@ -494,10 +519,11 @@ impl<'a> CrateLocator<'a> { unreachable!(); } - fn find_library_crate(&mut self, - extra_prefix: &str, - seen_paths: &mut FxHashSet) - -> Option { + fn find_library_crate( + &mut self, + extra_prefix: &str, + seen_paths: &mut FxHashSet, + ) -> Option { let dypair = self.dylibname(); let staticpair = self.staticlibname(); @@ -506,10 +532,8 @@ impl<'a> CrateLocator<'a> { let rlib_prefix = format!("lib{}{}", self.crate_name, extra_prefix); let staticlib_prefix = format!("{}{}{}", staticpair.0, self.crate_name, extra_prefix); - let mut candidates: FxHashMap< - _, - (FxHashMap<_, _>, FxHashMap<_, _>, FxHashMap<_, _>), - > = Default::default(); + let mut candidates: FxHashMap<_, (FxHashMap<_, _>, FxHashMap<_, _>, FxHashMap<_, _>)> = + Default::default(); let mut staticlibs = vec![]; // First, find all possible candidate rlibs and dylibs purely based on @@ -530,23 +554,21 @@ impl<'a> CrateLocator<'a> { None => return FileDoesntMatch, Some(file) => file, }; - let (hash, found_kind) = - if file.starts_with(&rlib_prefix) && file.ends_with(".rlib") { - (&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib) - } else if file.starts_with(&rlib_prefix) && file.ends_with(".rmeta") { - (&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta) - } else if file.starts_with(&dylib_prefix) && - file.ends_with(&dypair.1) { - (&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib) - } else { - if file.starts_with(&staticlib_prefix) && file.ends_with(&staticpair.1) { - staticlibs.push(CrateMismatch { - path: path.to_path_buf(), - got: "static".to_string(), - }); - } - return FileDoesntMatch; - }; + let (hash, found_kind) = if file.starts_with(&rlib_prefix) && file.ends_with(".rlib") { + (&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], CrateFlavor::Rlib) + } else if file.starts_with(&rlib_prefix) && file.ends_with(".rmeta") { + (&file[(rlib_prefix.len())..(file.len() - ".rmeta".len())], CrateFlavor::Rmeta) + } else if file.starts_with(&dylib_prefix) && file.ends_with(&dypair.1) { + (&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], CrateFlavor::Dylib) + } else { + if file.starts_with(&staticlib_prefix) && file.ends_with(&staticpair.1) { + staticlibs.push(CrateMismatch { + path: path.to_path_buf(), + got: "static".to_string(), + }); + } + return FileDoesntMatch; + }; info!("lib candidate: {}", path.display()); @@ -556,13 +578,19 @@ impl<'a> CrateLocator<'a> { fs::canonicalize(path) .map(|p| { if seen_paths.contains(&p) { - return FileDoesntMatch + return FileDoesntMatch; }; seen_paths.insert(p.clone()); match found_kind { - CrateFlavor::Rlib => { rlibs.insert(p, kind); } - CrateFlavor::Rmeta => { rmetas.insert(p, kind); } - CrateFlavor::Dylib => { dylibs.insert(p, kind); } + CrateFlavor::Rlib => { + rlibs.insert(p, kind); + } + CrateFlavor::Rmeta => { + rmetas.insert(p, kind); + } + CrateFlavor::Dylib => { + dylibs.insert(p, kind); + } } FileMatches }) @@ -592,27 +620,32 @@ impl<'a> CrateLocator<'a> { 0 => None, 1 => Some(libraries.into_iter().next().unwrap().1), _ => { - let mut err = struct_span_err!(self.sess, - self.span, - E0464, - "multiple matching crates for `{}`", - self.crate_name); - let candidates = libraries.iter().filter_map(|(_, lib)| { - let crate_name = &lib.metadata.get_root().name().as_str(); - match &(&lib.source.dylib, &lib.source.rlib) { - &(&Some((ref pd, _)), &Some((ref pr, _))) => { - Some(format!("\ncrate `{}`: {}\n{:>padding$}", - crate_name, - pd.display(), - pr.display(), - padding=8 + crate_name.len())) - } - &(&Some((ref p, _)), &None) | &(&None, &Some((ref p, _))) => { - Some(format!("\ncrate `{}`: {}", crate_name, p.display())) + let mut err = struct_span_err!( + self.sess, + self.span, + E0464, + "multiple matching crates for `{}`", + self.crate_name + ); + let candidates = libraries + .iter() + .filter_map(|(_, lib)| { + let crate_name = &lib.metadata.get_root().name().as_str(); + match &(&lib.source.dylib, &lib.source.rlib) { + &(&Some((ref pd, _)), &Some((ref pr, _))) => Some(format!( + "\ncrate `{}`: {}\n{:>padding$}", + crate_name, + pd.display(), + pr.display(), + padding = 8 + crate_name.len() + )), + &(&Some((ref p, _)), &None) | &(&None, &Some((ref p, _))) => { + Some(format!("\ncrate `{}`: {}", crate_name, p.display())) + } + &(&None, &None) => None, } - &(&None, &None) => None, - } - }).collect::(); + }) + .collect::(); err.note(&format!("candidates:{}", candidates)); err.emit(); None @@ -643,11 +676,12 @@ impl<'a> CrateLocator<'a> { // read the metadata from it if `*slot` is `None`. If the metadata couldn't // be read, it is assumed that the file isn't a valid rust library (no // errors are emitted). - fn extract_one(&mut self, - m: FxHashMap, - flavor: CrateFlavor, - slot: &mut Option<(Svh, MetadataBlob)>) - -> Option<(PathBuf, PathKind)> { + fn extract_one( + &mut self, + m: FxHashMap, + flavor: CrateFlavor, + slot: &mut Option<(Svh, MetadataBlob)>, + ) -> Option<(PathBuf, PathKind)> { let mut ret: Option<(PathBuf, PathKind)> = None; let mut error = 0; @@ -683,18 +717,18 @@ impl<'a> CrateLocator<'a> { }; // If we see multiple hashes, emit an error about duplicate candidates. if slot.as_ref().map_or(false, |s| s.0 != hash) { - let mut e = struct_span_err!(self.sess, - self.span, - E0465, - "multiple {} candidates for `{}` found", - flavor, - self.crate_name); - e.span_note(self.span, - &format!(r"candidate #1: {}", - ret.as_ref() - .unwrap() - .0 - .display())); + let mut e = struct_span_err!( + self.sess, + self.span, + E0465, + "multiple {} candidates for `{}` found", + flavor, + self.crate_name + ); + e.span_note( + self.span, + &format!(r"candidate #1: {}", ret.as_ref().unwrap().0.display()), + ); if let Some(ref mut e) = err { e.emit(); } @@ -704,10 +738,9 @@ impl<'a> CrateLocator<'a> { } if error > 0 { error += 1; - err.as_mut().unwrap().span_note(self.span, - &format!(r"candidate #{}: {}", - error, - lib.display())); + err.as_mut() + .unwrap() + .span_note(self.span, &format!(r"candidate #{}: {}", error, lib.display())); continue; } @@ -732,10 +765,9 @@ impl<'a> CrateLocator<'a> { // as well. if let Some((ref prev, _)) = ret { let sysroot = &self.sess.sysroot; - let sysroot = sysroot.canonicalize() - .unwrap_or_else(|_| sysroot.to_path_buf()); + let sysroot = sysroot.canonicalize().unwrap_or_else(|_| sysroot.to_path_buf()); if prev.starts_with(&sysroot) { - continue + continue; } } *slot = Some((hash, metadata)); @@ -754,13 +786,9 @@ impl<'a> CrateLocator<'a> { let rustc_version = rustc_version(); let found_version = metadata.get_rustc_version(); if found_version != rustc_version { - info!("Rejecting via version: expected {} got {}", - rustc_version, - found_version); - self.rejected_via_version.push(CrateMismatch { - path: libpath.to_path_buf(), - got: found_version, - }); + info!("Rejecting via version: expected {} got {}", rustc_version, found_version); + self.rejected_via_version + .push(CrateMismatch { path: libpath.to_path_buf(), got: found_version }); return None; } @@ -768,8 +796,10 @@ impl<'a> CrateLocator<'a> { if let Some(expected_is_proc_macro) = self.is_proc_macro { let is_proc_macro = root.is_proc_macro_crate(); if is_proc_macro != expected_is_proc_macro { - info!("Rejecting via proc macro: expected {} got {}", - expected_is_proc_macro, is_proc_macro); + info!( + "Rejecting via proc macro: expected {} got {}", + expected_is_proc_macro, is_proc_macro + ); return None; } } @@ -782,9 +812,7 @@ impl<'a> CrateLocator<'a> { } if root.triple() != &self.triple { - info!("Rejecting via crate triple: expected {} got {}", - self.triple, - root.triple()); + info!("Rejecting via crate triple: expected {} got {}", self.triple, root.triple()); self.rejected_via_triple.push(CrateMismatch { path: libpath.to_path_buf(), got: root.triple().to_string(), @@ -796,10 +824,8 @@ impl<'a> CrateLocator<'a> { if let Some(expected_hash) = self.hash { if hash != expected_hash { info!("Rejecting via hash: expected {} got {}", expected_hash, hash); - self.rejected_via_hash.push(CrateMismatch { - path: libpath.to_path_buf(), - got: hash.to_string(), - }); + self.rejected_via_hash + .push(CrateMismatch { path: libpath.to_path_buf(), got: hash.to_string() }); return None; } } @@ -807,7 +833,6 @@ impl<'a> CrateLocator<'a> { Some(hash) } - // Returns the corresponding (prefix, suffix) that files need to have for // dynamic libraries fn dylibname(&self) -> (String, String) { @@ -832,26 +857,30 @@ impl<'a> CrateLocator<'a> { let mut rmetas = FxHashMap::default(); let mut dylibs = FxHashMap::default(); { - let crate_name = self.crate_name; - let rejected_via_filename = &mut self.rejected_via_filename; - let locs = self.exact_paths.iter().filter(|loc| { + let crate_name = self.crate_name; + let rejected_via_filename = &mut self.rejected_via_filename; + let locs = self.exact_paths.iter().filter(|loc| { if !loc.exists() { - sess.err(&format!("extern location for {} does not exist: {}", - crate_name, - loc.display())); + sess.err(&format!( + "extern location for {} does not exist: {}", + crate_name, + loc.display() + )); return false; } let file = match loc.file_name().and_then(|s| s.to_str()) { Some(file) => file, None => { - sess.err(&format!("extern location for {} is not a file: {}", - crate_name, - loc.display())); + sess.err(&format!( + "extern location for {} is not a file: {}", + crate_name, + loc.display() + )); return false; } }; - if file.starts_with("lib") && - (file.ends_with(".rlib") || file.ends_with(".rmeta")) { + if file.starts_with("lib") && (file.ends_with(".rlib") || file.ends_with(".rmeta")) + { return true; } else { let (ref prefix, ref suffix) = dylibname; @@ -860,10 +889,8 @@ impl<'a> CrateLocator<'a> { } } - rejected_via_filename.push(CrateMismatch { - path: (*loc).clone(), - got: String::new(), - }); + rejected_via_filename + .push(CrateMismatch { path: (*loc).clone(), got: String::new() }); false }); @@ -887,16 +914,15 @@ impl<'a> CrateLocator<'a> { } // Just a small wrapper to time how long reading metadata takes. -fn get_metadata_section(target: &Target, - flavor: CrateFlavor, - filename: &Path, - loader: &dyn MetadataLoader) - -> Result { +fn get_metadata_section( + target: &Target, + flavor: CrateFlavor, + filename: &Path, + loader: &dyn MetadataLoader, +) -> Result { let start = Instant::now(); let ret = get_metadata_section_imp(target, flavor, filename, loader); - info!("reading {:?} => {:?}", - filename.file_name().unwrap(), - start.elapsed()); + info!("reading {:?} => {:?}", filename.file_name().unwrap(), start.elapsed()); return ret; } @@ -913,11 +939,12 @@ impl Deref for StableDerefMmap { unsafe impl stable_deref_trait::StableDeref for StableDerefMmap {} -fn get_metadata_section_imp(target: &Target, - flavor: CrateFlavor, - filename: &Path, - loader: &dyn MetadataLoader) - -> Result { +fn get_metadata_section_imp( + target: &Target, + flavor: CrateFlavor, + filename: &Path, + loader: &dyn MetadataLoader, +) -> Result { if !filename.exists() { return Err(format!("no such file: '{}'", filename.display())); } @@ -930,8 +957,10 @@ fn get_metadata_section_imp(target: &Target, debug!("checking {} bytes of metadata-version stamp", header_len); let header = &buf[..cmp::min(header_len, buf.len())]; if header != METADATA_HEADER { - return Err(format!("incompatible metadata version found: '{}'", - filename.display())); + return Err(format!( + "incompatible metadata version found: '{}'", + filename.display() + )); } // Header is okay -> inflate the actual metadata @@ -939,9 +968,7 @@ fn get_metadata_section_imp(target: &Target, debug!("inflating {} bytes of compressed metadata", compressed_bytes.len()); let mut inflated = Vec::new(); match DeflateDecoder::new(compressed_bytes).read_to_end(&mut inflated) { - Ok(_) => { - rustc_erase_owner!(OwningRef::new(inflated).map_owner_box()) - } + Ok(_) => rustc_erase_owner!(OwningRef::new(inflated).map_owner_box()), Err(_) => { return Err(format!("failed to decompress metadata: {}", filename.display())); } @@ -949,11 +976,11 @@ fn get_metadata_section_imp(target: &Target, } CrateFlavor::Rmeta => { // mmap the file, because only a small fraction of it is read. - let file = std::fs::File::open(filename).map_err(|_| - format!("failed to open rmeta metadata: '{}'", filename.display()))?; + let file = std::fs::File::open(filename) + .map_err(|_| format!("failed to open rmeta metadata: '{}'", filename.display()))?; let mmap = unsafe { memmap::Mmap::map(&file) }; - let mmap = mmap.map_err(|_| - format!("failed to mmap rmeta metadata: '{}'", filename.display()))?; + let mmap = mmap + .map_err(|_| format!("failed to mmap rmeta metadata: '{}'", filename.display()))?; rustc_erase_owner!(OwningRef::new(StableDerefMmap(mmap)).map_owner_box()) } @@ -994,7 +1021,7 @@ pub fn find_plugin_registrar( let library = locator.maybe_load_library_crate().or_else(|| { if !is_cross { - return None + return None; } // Try loading from target crates. This will abort later if we // try to load a plugin registrar function, @@ -1013,23 +1040,27 @@ pub fn find_plugin_registrar( if target_only { // Need to abort before syntax expansion. - let message = format!("plugin `{}` is not available for triple `{}` \ + let message = format!( + "plugin `{}` is not available for triple `{}` \ (only found {})", - name, - config::host_triple(), - sess.opts.target_triple); + name, + config::host_triple(), + sess.opts.target_triple + ); span_fatal!(sess, span, E0456, "{}", &message); } match library.source.dylib { - Some(dylib) => { - Some((dylib.0, library.metadata.get_root().disambiguator())) - } + Some(dylib) => Some((dylib.0, library.metadata.get_root().disambiguator())), None => { - span_err!(sess, span, E0457, - "plugin `{}` only found in rlib format, but must be available \ + span_err!( + sess, + span, + E0457, + "plugin `{}` only found in rlib format, but must be available \ in dylib format", - name); + name + ); // No need to abort because the loading code will just ignore this // empty dylib. None @@ -1038,11 +1069,12 @@ pub fn find_plugin_registrar( } /// A diagnostic function for dumping crate metadata to an output stream. -pub fn list_file_metadata(target: &Target, - path: &Path, - metadata_loader: &dyn MetadataLoader, - out: &mut dyn io::Write) - -> io::Result<()> { +pub fn list_file_metadata( + target: &Target, + path: &Path, + metadata_loader: &dyn MetadataLoader, + out: &mut dyn io::Write, +) -> io::Result<()> { let filename = path.file_name().unwrap().to_str().unwrap(); let flavor = if filename.ends_with(".rlib") { CrateFlavor::Rlib diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index 6ab2027177424..d836d985345fa 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -1,23 +1,20 @@ -use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir; +use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::middle::cstore::{self, NativeLibrary}; use rustc::session::Session; use rustc::ty::TyCtxt; use rustc::util::nodemap::FxHashSet; use rustc_target::spec::abi::Abi; use syntax::attr; -use syntax::source_map::Span; use syntax::feature_gate::feature_err; +use syntax::source_map::Span; use syntax::symbol::{kw, sym, Symbol}; use syntax::{span_err, struct_span_err}; use rustc_error_codes::*; crate fn collect(tcx: TyCtxt<'_>) -> Vec { - let mut collector = Collector { - tcx, - libs: Vec::new(), - }; + let mut collector = Collector { tcx, libs: Vec::new() }; tcx.hir().krate().visit_all_item_likes(&mut collector); collector.process_command_line(); return collector.libs; @@ -42,10 +39,8 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { _ => return, }; - if fm.abi == Abi::Rust || - fm.abi == Abi::RustIntrinsic || - fm.abi == Abi::PlatformIntrinsic { - return + if fm.abi == Abi::Rust || fm.abi == Abi::RustIntrinsic || fm.abi == Abi::PlatformIntrinsic { + return; } // Process all of the #[link(..)]-style arguments @@ -77,10 +72,16 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { "framework" => cstore::NativeFramework, "raw-dylib" => cstore::NativeRawDylib, k => { - struct_span_err!(self.tcx.sess, item.span(), E0458, - "unknown kind: `{}`", k) - .span_label(item.span(), "unknown kind") - .span_label(m.span, "").emit(); + struct_span_err!( + self.tcx.sess, + item.span(), + E0458, + "unknown kind: `{}`", + k + ) + .span_label(item.span(), "unknown kind") + .span_label(m.span, "") + .emit(); cstore::NativeUnknown } }; @@ -92,10 +93,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { None => continue, // skip like historical compilers }; if cfg.is_empty() { - self.tcx.sess.span_err( - item.span(), - "`cfg()` must have an argument", - ); + self.tcx.sess.span_err(item.span(), "`cfg()` must have an argument"); } else if let cfg @ Some(..) = cfg[0].meta_item() { lib.cfg = cfg.cloned(); } else { @@ -119,11 +117,15 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { // #[link(wasm_import_module = "...")] without the `name`. let requires_name = kind_specified || lib.wasm_import_module.is_none(); if lib.name.is_none() && requires_name { - struct_span_err!(self.tcx.sess, m.span, E0459, - "`#[link(...)]` specified without \ - `name = \"foo\"`") - .span_label(m.span, "missing `name` argument") - .emit(); + struct_span_err!( + self.tcx.sess, + m.span, + E0459, + "`#[link(...)]` specified without \ + `name = \"foo\"`" + ) + .span_label(m.span, "missing `name` argument") + .emit(); } self.register_native_lib(Some(m.span), lib); } @@ -138,16 +140,20 @@ impl Collector<'tcx> { if lib.name.as_ref().map(|&s| s == kw::Invalid).unwrap_or(false) { match span { Some(span) => { - struct_span_err!(self.tcx.sess, span, E0454, - "`#[link(name = \"\")]` given with empty name") - .span_label(span, "empty name given") - .emit(); + struct_span_err!( + self.tcx.sess, + span, + E0454, + "`#[link(name = \"\")]` given with empty name" + ) + .span_label(span, "empty name given") + .emit(); } None => { self.tcx.sess.err("empty library name given via `-l`"); } } - return + return; } let is_osx = self.tcx.sess.target.target.options.is_like_osx; if lib.kind == cstore::NativeFramework && !is_osx { @@ -161,24 +167,21 @@ impl Collector<'tcx> { feature_err(&self.tcx.sess.parse_sess, sym::link_cfg, span.unwrap(), "is unstable") .emit(); } - if lib.kind == cstore::NativeStaticNobundle && - !self.tcx.features().static_nobundle - { + if lib.kind == cstore::NativeStaticNobundle && !self.tcx.features().static_nobundle { feature_err( &self.tcx.sess.parse_sess, sym::static_nobundle, span.unwrap_or_else(|| syntax_pos::DUMMY_SP), - "kind=\"static-nobundle\" is unstable" + "kind=\"static-nobundle\" is unstable", ) .emit(); } - if lib.kind == cstore::NativeRawDylib && - !self.tcx.features().raw_dylib { + if lib.kind == cstore::NativeRawDylib && !self.tcx.features().raw_dylib { feature_err( &self.tcx.sess.parse_sess, sym::raw_dylib, span.unwrap_or_else(|| syntax_pos::DUMMY_SP), - "kind=\"raw-dylib\" is unstable" + "kind=\"raw-dylib\" is unstable", ) .emit(); } @@ -191,21 +194,29 @@ impl Collector<'tcx> { let mut renames = FxHashSet::default(); for &(ref name, ref new_name, _) in &self.tcx.sess.opts.libs { if let &Some(ref new_name) = new_name { - let any_duplicate = self.libs + let any_duplicate = self + .libs .iter() .filter_map(|lib| lib.name.as_ref()) .any(|n| n.as_str() == *name); if new_name.is_empty() { - self.tcx.sess.err( - &format!("an empty renaming target was specified for library `{}`",name)); + self.tcx.sess.err(&format!( + "an empty renaming target was specified for library `{}`", + name + )); } else if !any_duplicate { - self.tcx.sess.err(&format!("renaming of the library `{}` was specified, \ + self.tcx.sess.err(&format!( + "renaming of the library `{}` was specified, \ however this crate contains no `#[link(...)]` \ - attributes referencing this library.", name)); + attributes referencing this library.", + name + )); } else if !renames.insert(name) { - self.tcx.sess.err(&format!("multiple renamings were \ + self.tcx.sess.err(&format!( + "multiple renamings were \ specified for library `{}` .", - name)); + name + )); } } } @@ -221,20 +232,23 @@ impl Collector<'tcx> { // If we've already added any native libraries with the same // name, they will be pulled out into `existing`, so that we // can move them to the end of the list below. - let mut existing = self.libs.drain_filter(|lib| { - if let Some(lib_name) = lib.name { - if lib_name.as_str() == *name { - if let Some(k) = kind { - lib.kind = k; + let mut existing = self + .libs + .drain_filter(|lib| { + if let Some(lib_name) = lib.name { + if lib_name.as_str() == *name { + if let Some(k) = kind { + lib.kind = k; + } + if let &Some(ref new_name) = new_name { + lib.name = Some(Symbol::intern(new_name)); + } + return true; } - if let &Some(ref new_name) = new_name { - lib.name = Some(Symbol::intern(new_name)); - } - return true; } - } - false - }).collect::>(); + false + }) + .collect::>(); if existing.is_empty() { // Add if not found let new_name = new_name.as_ref().map(|s| &**s); // &Option -> Option<&str> diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index eb2fb39fb2f25..d0f86f96e0759 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -1,46 +1,46 @@ // Decoding metadata from a single crate's metadata -use crate::rmeta::*; use crate::rmeta::table::{FixedSizeEncoding, Table}; +use crate::rmeta::*; -use rustc_index::vec::{Idx, IndexVec}; -use rustc_data_structures::sync::{Lrc, Lock, LockGuard, Once, AtomicCell}; -use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash}; -use rustc::hir::map::definitions::DefPathTable; +use rustc::dep_graph::{self, DepNodeIndex}; use rustc::hir; +use rustc::hir::def::{self, CtorKind, CtorOf, DefKind, Res}; +use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc::hir::map::definitions::DefPathTable; +use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc::middle::cstore::{CrateSource, ExternCrate}; -use rustc::middle::cstore::{LinkagePreference, NativeLibrary, ForeignModule}; +use rustc::middle::cstore::{ForeignModule, LinkagePreference, NativeLibrary}; use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; -use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind}; -use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::svh::Svh; -use rustc::dep_graph::{self, DepNodeIndex}; use rustc::middle::lang_items; -use rustc::mir::{self, BodyAndCache, interpret, Promoted}; use rustc::mir::interpret::{AllocDecodingSession, AllocDecodingState}; +use rustc::mir::{self, interpret, BodyAndCache, Promoted}; use rustc::session::Session; -use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::codec::TyDecoder; -use rustc::util::common::record_time; +use rustc::ty::{self, Ty, TyCtxt}; use rustc::util::captures::Captures; +use rustc::util::common::record_time; +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::svh::Svh; +use rustc_data_structures::sync::{AtomicCell, Lock, LockGuard, Lrc, Once}; +use rustc_index::vec::{Idx, IndexVec}; use std::io; use std::mem; use std::num::NonZeroUsize; use std::u32; -use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque}; -use syntax::attr; -use syntax::ast::{self, Ident}; -use syntax::source_map::{self, respan, Spanned}; -use syntax_expand::base::{SyntaxExtensionKind, SyntaxExtension}; -use syntax_expand::proc_macro::{AttrProcMacro, ProcMacroDerive, BangProcMacro}; -use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, hygiene::MacroKind}; -use syntax_pos::symbol::{Symbol, sym}; use log::debug; use proc_macro::bridge::client::ProcMacro; +use rustc_serialize::{opaque, Decodable, Decoder, SpecializedDecoder}; +use syntax::ast::{self, Ident}; +use syntax::attr; +use syntax::source_map::{self, respan, Spanned}; +use syntax_expand::base::{SyntaxExtension, SyntaxExtensionKind}; +use syntax_expand::proc_macro::{AttrProcMacro, BangProcMacro, ProcMacroDerive}; +use syntax_pos::symbol::{sym, Symbol}; +use syntax_pos::{self, hygiene::MacroKind, BytePos, Pos, Span, DUMMY_SP}; pub use cstore_impl::{provide, provide_extern}; @@ -59,7 +59,6 @@ crate struct CrateMetadata { blob: MetadataBlob, // --- Some data pre-decoded from the metadata blob, usually for performance --- - /// Properties of the whole crate. /// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this /// lifetime is only used behind `Lazy`, and therefore acts like an @@ -89,7 +88,6 @@ crate struct CrateMetadata { dep_node_index: AtomicCell, // --- Other significant crate properties --- - /// ID of this crate, from the current compilation session's point of view. cnum: CrateNum, /// Maps crate IDs as they are were seen from this crate's compilation sessions into @@ -108,7 +106,6 @@ crate struct CrateMetadata { host_hash: Option, // --- Data used only for improving diagnostics --- - /// Information about the `extern crate` item or path that caused this crate to be loaded. /// If this is `None`, then the crate was injected (e.g., by the allocator). extern_crate: Lock>, @@ -143,9 +140,15 @@ pub(super) struct DecodeContext<'a, 'tcx> { /// Abstract over the various ways one can create metadata decoders. pub(super) trait Metadata<'a, 'tcx>: Copy { fn raw_bytes(self) -> &'a [u8]; - fn cdata(self) -> Option<&'a CrateMetadata> { None } - fn sess(self) -> Option<&'tcx Session> { None } - fn tcx(self) -> Option> { None } + fn cdata(self) -> Option<&'a CrateMetadata> { + None + } + fn sess(self) -> Option<&'tcx Session> { + None + } + fn tcx(self) -> Option> { + None + } fn decoder(self, pos: usize) -> DecodeContext<'a, 'tcx> { let tcx = self.tcx(); @@ -156,9 +159,9 @@ pub(super) trait Metadata<'a, 'tcx>: Copy { tcx, last_source_file_index: 0, lazy_state: LazyState::NoNode, - alloc_decoding_session: self.cdata().map(|cdata| { - cdata.alloc_decoding_state.new_decoding_session() - }), + alloc_decoding_session: self + .cdata() + .map(|cdata| cdata.alloc_decoding_state.new_decoding_session()), } } } @@ -169,7 +172,6 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob { } } - impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a MetadataBlob, &'tcx Session) { fn raw_bytes(self) -> &'a [u8] { let (blob, _) = self; @@ -182,7 +184,6 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a MetadataBlob, &'tcx Session) { } } - impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a CrateMetadata { fn raw_bytes(self) -> &'a [u8] { self.blob.raw_bytes() @@ -280,18 +281,17 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> { self.opaque.position() } - fn cached_ty_for_shorthand(&mut self, - shorthand: usize, - or_insert_with: F) - -> Result, Self::Error> - where F: FnOnce(&mut Self) -> Result, Self::Error> + fn cached_ty_for_shorthand( + &mut self, + shorthand: usize, + or_insert_with: F, + ) -> Result, Self::Error> + where + F: FnOnce(&mut Self) -> Result, Self::Error>, { let tcx = self.tcx(); - let key = ty::CReaderCacheKey { - cnum: self.cdata().cnum, - pos: shorthand, - }; + let key = ty::CReaderCacheKey { cnum: self.cdata().cnum, pos: shorthand }; if let Some(&ty) = tcx.rcache.borrow().get(&key) { return Ok(ty); @@ -303,7 +303,8 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> { } fn with_position(&mut self, pos: usize, f: F) -> R - where F: FnOnce(&mut Self) -> R + where + F: FnOnce(&mut Self) -> R, { let new_opaque = opaque::Decoder::new(self.opaque.data, pos); let old_opaque = mem::replace(&mut self.opaque, new_opaque); @@ -315,11 +316,7 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> { } fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum { - if cnum == LOCAL_CRATE { - self.cdata().cnum - } else { - self.cdata().cnum_map[cnum] - } + if cnum == LOCAL_CRATE { self.cdata().cnum } else { self.cdata().cnum_map[cnum] } } } @@ -332,16 +329,13 @@ impl<'a, 'tcx, T> SpecializedDecoder> for DecodeContext<'a, 'tcx> { impl<'a, 'tcx, T> SpecializedDecoder> for DecodeContext<'a, 'tcx> { fn specialized_decode(&mut self) -> Result, Self::Error> { let len = self.read_usize()?; - if len == 0 { - Ok(Lazy::empty()) - } else { - self.read_lazy_with_meta(len) - } + if len == 0 { Ok(Lazy::empty()) } else { self.read_lazy_with_meta(len) } } } impl<'a, 'tcx, I: Idx, T> SpecializedDecoder>> for DecodeContext<'a, 'tcx> - where Option: FixedSizeEncoding, +where + Option: FixedSizeEncoding, { fn specialized_decode(&mut self) -> Result>, Self::Error> { let len = self.read_usize()?; @@ -355,10 +349,7 @@ impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { let krate = CrateNum::decode(self)?; let index = DefIndex::decode(self)?; - Ok(DefId { - krate, - index, - }) + Ok(DefId { krate, index }) } } @@ -391,7 +382,7 @@ impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { let tag = u8::decode(self)?; if tag == TAG_INVALID_SPAN { - return Ok(DUMMY_SP) + return Ok(DUMMY_SP); } debug_assert_eq!(tag, TAG_VALID_SPAN); @@ -412,8 +403,8 @@ impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { // originate from the same source_file. let last_source_file = &imported_source_files[self.last_source_file_index]; - if lo >= last_source_file.original_start_pos && - lo <= last_source_file.original_end_pos { + if lo >= last_source_file.original_start_pos && lo <= last_source_file.original_end_pos + { last_source_file } else { let mut a = 0; @@ -434,17 +425,15 @@ impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { }; // Make sure our binary search above is correct. - debug_assert!(lo >= source_file.original_start_pos && - lo <= source_file.original_end_pos); + debug_assert!(lo >= source_file.original_start_pos && lo <= source_file.original_end_pos); // Make sure we correctly filtered out invalid spans during encoding - debug_assert!(hi >= source_file.original_start_pos && - hi <= source_file.original_end_pos); + debug_assert!(hi >= source_file.original_start_pos && hi <= source_file.original_end_pos); - let lo = (lo + source_file.translated_source_file.start_pos) - - source_file.original_start_pos; - let hi = (hi + source_file.translated_source_file.start_pos) - - source_file.original_start_pos; + let lo = + (lo + source_file.translated_source_file.start_pos) - source_file.original_start_pos; + let hi = + (hi + source_file.translated_source_file.start_pos) - source_file.original_start_pos; Ok(Span::with_root_ctxt(lo, hi)) } @@ -465,14 +454,15 @@ impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { } impl<'a, 'tcx, T: Decodable> SpecializedDecoder> -for DecodeContext<'a, 'tcx> { + for DecodeContext<'a, 'tcx> +{ #[inline] fn specialized_decode(&mut self) -> Result, Self::Error> { Ok(mir::ClearCrossCrate::Clear) } } -implement_ty_decoder!( DecodeContext<'a, 'tcx> ); +implement_ty_decoder!(DecodeContext<'a, 'tcx>); impl MetadataBlob { crate fn new(metadata_ref: MetadataRef) -> MetadataBlob { @@ -484,29 +474,24 @@ impl MetadataBlob { } crate fn get_rustc_version(&self) -> String { - Lazy::::from_position( - NonZeroUsize::new(METADATA_HEADER.len() + 4).unwrap(), - ).decode(self) + Lazy::::from_position(NonZeroUsize::new(METADATA_HEADER.len() + 4).unwrap()) + .decode(self) } crate fn get_root(&self) -> CrateRoot<'tcx> { let slice = self.raw_bytes(); let offset = METADATA_HEADER.len(); - let pos = (((slice[offset + 0] as u32) << 24) | ((slice[offset + 1] as u32) << 16) | - ((slice[offset + 2] as u32) << 8) | - ((slice[offset + 3] as u32) << 0)) as usize; - Lazy::>::from_position( - NonZeroUsize::new(pos).unwrap(), - ).decode(self) + let pos = (((slice[offset + 0] as u32) << 24) + | ((slice[offset + 1] as u32) << 16) + | ((slice[offset + 2] as u32) << 8) + | ((slice[offset + 3] as u32) << 0)) as usize; + Lazy::>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self) } - crate fn list_crate_metadata(&self, - out: &mut dyn io::Write) -> io::Result<()> { + crate fn list_crate_metadata(&self, out: &mut dyn io::Write) -> io::Result<()> { write!(out, "=External Dependencies=\n")?; let root = self.get_root(); - for (i, dep) in root.crate_deps - .decode(self) - .enumerate() { + for (i, dep) in root.crate_deps.decode(self).enumerate() { write!(out, "{} {}{}\n", i + 1, dep.name, dep.extra_filename)?; } write!(out, "\n")?; @@ -519,14 +504,13 @@ impl<'tcx> EntryKind<'tcx> { Some(match *self { EntryKind::Const(..) => DefKind::Const, EntryKind::AssocConst(..) => DefKind::AssocConst, - EntryKind::ImmStatic | - EntryKind::MutStatic | - EntryKind::ForeignImmStatic | - EntryKind::ForeignMutStatic => DefKind::Static, + EntryKind::ImmStatic + | EntryKind::MutStatic + | EntryKind::ForeignImmStatic + | EntryKind::ForeignMutStatic => DefKind::Static, EntryKind::Struct(_, _) => DefKind::Struct, EntryKind::Union(_, _) => DefKind::Union, - EntryKind::Fn(_) | - EntryKind::ForeignFn(_) => DefKind::Fn, + EntryKind::Fn(_) | EntryKind::ForeignFn(_) => DefKind::Fn, EntryKind::Method(_) => DefKind::Method, EntryKind::Type => DefKind::TyAlias, EntryKind::TypeParam => DefKind::TyParam, @@ -542,12 +526,12 @@ impl<'tcx> EntryKind<'tcx> { EntryKind::MacroDef(_) => DefKind::Macro(MacroKind::Bang), EntryKind::ForeignType => DefKind::ForeignTy, - EntryKind::ForeignMod | - EntryKind::GlobalAsm | - EntryKind::Impl(_) | - EntryKind::Field | - EntryKind::Generator(_) | - EntryKind::Closure => return None, + EntryKind::ForeignMod + | EntryKind::GlobalAsm + | EntryKind::Impl(_) + | EntryKind::Field + | EntryKind::Generator(_) + | EntryKind::Closure => return None, }) } } @@ -597,8 +581,11 @@ impl<'a, 'tcx> CrateMetadata { let def_path_table = record_time(&sess.perf_stats.decode_def_path_tables_time, || { root.def_path_table.decode((&blob, sess)) }); - let trait_impls = root.impls.decode((&blob, sess)) - .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls)).collect(); + let trait_impls = root + .impls + .decode((&blob, sess)) + .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls)) + .collect(); let alloc_decoding_state = AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect()); let dependencies = Lock::new(cnum_map.iter().cloned().collect()); @@ -643,10 +630,7 @@ impl<'a, 'tcx> CrateMetadata { } fn local_def_id(&self, index: DefIndex) -> DefId { - DefId { - krate: self.cnum, - index, - } + DefId { krate: self.cnum, index } } fn raw_proc_macro(&self, id: DefIndex) -> &ProcMacro { @@ -676,9 +660,7 @@ impl<'a, 'tcx> CrateMetadata { if !self.is_proc_macro(index) { self.kind(index).def_kind() } else { - Some(DefKind::Macro( - macro_kind(self.raw_proc_macro(index)) - )) + Some(DefKind::Macro(macro_kind(self.raw_proc_macro(index)))) } } @@ -697,12 +679,12 @@ impl<'a, 'tcx> CrateMetadata { helper_attrs, ) } - ProcMacro::Attr { name, client } => ( - name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new() - ), - ProcMacro::Bang { name, client } => ( - name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new() - ) + ProcMacro::Attr { name, client } => { + (name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new()) + } + ProcMacro::Bang { name, client } => { + (name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new()) + } }; SyntaxExtension::new( @@ -720,21 +702,23 @@ impl<'a, 'tcx> CrateMetadata { match self.kind(item_id) { EntryKind::Trait(data) => { let data = data.decode((self, sess)); - ty::TraitDef::new(self.local_def_id(item_id), - data.unsafety, - data.paren_sugar, - data.has_auto_impl, - data.is_marker, - self.def_path_table.def_path_hash(item_id)) - }, - EntryKind::TraitAlias => { - ty::TraitDef::new(self.local_def_id(item_id), - hir::Unsafety::Normal, - false, - false, - false, - self.def_path_table.def_path_hash(item_id)) - }, + ty::TraitDef::new( + self.local_def_id(item_id), + data.unsafety, + data.paren_sugar, + data.has_auto_impl, + data.is_marker, + self.def_path_table.def_path_hash(item_id), + ) + } + EntryKind::TraitAlias => ty::TraitDef::new( + self.local_def_id(item_id), + hir::Unsafety::Normal, + false, + false, + false, + self.def_path_table.def_path_hash(item_id), + ), _ => bug!("def-index does not refer to trait or trait alias"), } } @@ -747,9 +731,9 @@ impl<'a, 'tcx> CrateMetadata { parent_did: DefId, ) -> ty::VariantDef { let data = match kind { - EntryKind::Variant(data) | - EntryKind::Struct(data, _) | - EntryKind::Union(data, _) => data.decode(self), + EntryKind::Variant(data) | EntryKind::Struct(data, _) | EntryKind::Union(data, _) => { + data.decode(self) + } _ => bug!(), }; @@ -760,11 +744,8 @@ impl<'a, 'tcx> CrateMetadata { _ => bug!(), }; - let variant_did = if adt_kind == ty::AdtKind::Enum { - Some(self.local_def_id(index)) - } else { - None - }; + let variant_did = + if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None }; let ctor_did = data.ctor.map(|index| self.local_def_id(index)); ty::VariantDef::new( @@ -773,12 +754,18 @@ impl<'a, 'tcx> CrateMetadata { variant_did, ctor_did, data.discr, - self.root.per_def.children.get(self, index).unwrap_or(Lazy::empty()) - .decode(self).map(|index| ty::FieldDef { + self.root + .per_def + .children + .get(self, index) + .unwrap_or(Lazy::empty()) + .decode(self) + .map(|index| ty::FieldDef { did: self.local_def_id(index), ident: Ident::with_dummy_span(self.item_name(index)), vis: self.get_visibility(index), - }).collect(), + }) + .collect(), data.ctor_kind, adt_kind, parent_did, @@ -798,11 +785,13 @@ impl<'a, 'tcx> CrateMetadata { }; let variants = if let ty::AdtKind::Enum = adt_kind { - self.root.per_def.children.get(self, item_id).unwrap_or(Lazy::empty()) + self.root + .per_def + .children + .get(self, item_id) + .unwrap_or(Lazy::empty()) .decode(self) - .map(|index| { - self.get_variant(tcx, &self.kind(index), index, did) - }) + .map(|index| self.get_variant(tcx, &self.kind(index), index, did)) .collect() } else { std::iter::once(self.get_variant(tcx, &kind, item_id, did)).collect() @@ -824,9 +813,12 @@ impl<'a, 'tcx> CrateMetadata { item_id: DefIndex, tcx: TyCtxt<'tcx>, ) -> &'tcx [(ty::Predicate<'tcx>, Span)] { - self.root.per_def.inferred_outlives.get(self, item_id).map(|predicates| { - predicates.decode((self, tcx)) - }).unwrap_or_default() + self.root + .per_def + .inferred_outlives + .get(self, item_id) + .map(|predicates| predicates.decode((self, tcx))) + .unwrap_or_default() } fn get_super_predicates( @@ -857,7 +849,10 @@ impl<'a, 'tcx> CrateMetadata { } fn get_deprecation(&self, id: DefIndex) -> Option { - self.root.per_def.deprecation.get(self, id) + self.root + .per_def + .deprecation + .get(self, id) .filter(|_| !self.is_proc_macro(id)) .map(|depr| depr.decode(self)) } @@ -888,10 +883,7 @@ impl<'a, 'tcx> CrateMetadata { self.get_impl_data(id).defaultness } - fn get_coerce_unsized_info( - &self, - id: DefIndex, - ) -> Option { + fn get_coerce_unsized_info(&self, id: DefIndex) -> Option { self.get_impl_data(id).coerce_unsized_info } @@ -903,9 +895,7 @@ impl<'a, 'tcx> CrateMetadata { fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(ast::Name, Option)] { // FIXME: For a proc macro crate, not sure whether we should return the "host" // features or an empty Vec. Both don't cause ICEs. - tcx.arena.alloc_from_iter(self.root - .lib_features - .decode(self)) + tcx.arena.alloc_from_iter(self.root.lib_features.decode(self)) } /// Iterates over the language items in the given crate. @@ -914,18 +904,17 @@ impl<'a, 'tcx> CrateMetadata { // Proc macro crates do not export any lang-items to the target. &[] } else { - tcx.arena.alloc_from_iter(self.root - .lang_items - .decode(self) - .map(|(def_index, index)| (self.local_def_id(def_index), index))) + tcx.arena.alloc_from_iter( + self.root + .lang_items + .decode(self) + .map(|(def_index, index)| (self.local_def_id(def_index), index)), + ) } } /// Iterates over the diagnostic items in the given crate. - fn get_diagnostic_items( - &self, - tcx: TyCtxt<'tcx>, - ) -> &'tcx FxHashMap { + fn get_diagnostic_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx FxHashMap { tcx.arena.alloc(if self.root.is_proc_macro_crate() { // Proc macro crates do not export any diagnostic-items to the target. Default::default() @@ -940,7 +929,8 @@ impl<'a, 'tcx> CrateMetadata { /// Iterates over each child of the given item. fn each_child_of_item(&self, id: DefIndex, mut callback: F, sess: &Session) - where F: FnMut(def::Export) + where + F: FnMut(def::Export), { if let Some(proc_macros_ids) = self.root.proc_macro_data.map(|d| d.decode(self)) { /* If we are loading as a proc macro, we want to return the view of this crate @@ -962,7 +952,7 @@ impl<'a, 'tcx> CrateMetadata { }); } } - return + return; } // Find the item. @@ -976,7 +966,7 @@ impl<'a, 'tcx> CrateMetadata { let children = self.root.per_def.children.get(self, id).unwrap_or(Lazy::empty()); for child_index in children.decode((self, sess)) { if macros_only { - continue + continue; } // Get the item. @@ -991,16 +981,24 @@ impl<'a, 'tcx> CrateMetadata { match child_kind { // FIXME(eddyb) Don't encode these in children. EntryKind::ForeignMod => { - let child_children = - self.root.per_def.children.get(self, child_index) - .unwrap_or(Lazy::empty()); + let child_children = self + .root + .per_def + .children + .get(self, child_index) + .unwrap_or(Lazy::empty()); for child_index in child_children.decode((self, sess)) { if let Some(kind) = self.def_kind(child_index) { callback(def::Export { res: Res::Def(kind, self.local_def_id(child_index)), ident: Ident::with_dummy_span(self.item_name(child_index)), vis: self.get_visibility(child_index), - span: self.root.per_def.span.get(self, child_index).unwrap() + span: self + .root + .per_def + .span + .get(self, child_index) + .unwrap() .decode((self, sess)), }); } @@ -1015,7 +1013,8 @@ impl<'a, 'tcx> CrateMetadata { let def_key = self.def_key(child_index); let span = self.get_span(child_index, sess); if let (Some(kind), Some(name)) = - (self.def_kind(child_index), def_key.disambiguated_data.data.get_opt_name()) { + (self.def_kind(child_index), def_key.disambiguated_data.data.get_opt_name()) + { let ident = Ident::with_dummy_span(name); let vis = self.get_visibility(child_index); let def_id = self.local_def_id(child_index); @@ -1027,10 +1026,8 @@ impl<'a, 'tcx> CrateMetadata { DefKind::Struct => { if let Some(ctor_def_id) = self.get_ctor_def_id(child_index) { let ctor_kind = self.get_ctor_kind(child_index); - let ctor_res = Res::Def( - DefKind::Ctor(CtorOf::Struct, ctor_kind), - ctor_def_id, - ); + let ctor_res = + Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id); let vis = self.get_visibility(ctor_def_id.index); callback(def::Export { res: ctor_res, vis, ident, span }); } @@ -1042,10 +1039,8 @@ impl<'a, 'tcx> CrateMetadata { // error will be reported on any use of such resolution anyway. let ctor_def_id = self.get_ctor_def_id(child_index).unwrap_or(def_id); let ctor_kind = self.get_ctor_kind(child_index); - let ctor_res = Res::Def( - DefKind::Ctor(CtorOf::Variant, ctor_kind), - ctor_def_id, - ); + let ctor_res = + Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id); let mut vis = self.get_visibility(ctor_def_id.index); if ctor_def_id == def_id && vis == ty::Visibility::Public { // For non-exhaustive variants lower the constructor visibility to @@ -1079,12 +1074,15 @@ impl<'a, 'tcx> CrateMetadata { } fn is_item_mir_available(&self, id: DefIndex) -> bool { - !self.is_proc_macro(id) && - self.root.per_def.mir.get(self, id).is_some() + !self.is_proc_macro(id) && self.root.per_def.mir.get(self, id).is_some() } fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> BodyAndCache<'tcx> { - let mut cache = self.root.per_def.mir.get(self, id) + let mut cache = self + .root + .per_def + .mir + .get(self, id) .filter(|_| !self.is_proc_macro(id)) .unwrap_or_else(|| { bug!("get_optimized_mir: missing MIR for `{:?}`", self.local_def_id(id)) @@ -1099,7 +1097,11 @@ impl<'a, 'tcx> CrateMetadata { tcx: TyCtxt<'tcx>, id: DefIndex, ) -> IndexVec> { - let mut cache = self.root.per_def.promoted_mir.get(self, id) + let mut cache = self + .root + .per_def + .promoted_mir + .get(self, id) .filter(|_| !self.is_proc_macro(id)) .unwrap_or_else(|| { bug!("get_promoted_mir: missing MIR for `{:?}`", self.local_def_id(id)) @@ -1113,11 +1115,9 @@ impl<'a, 'tcx> CrateMetadata { fn mir_const_qualif(&self, id: DefIndex) -> mir::ConstQualifs { match self.kind(id) { - EntryKind::Const(qualif, _) | - EntryKind::AssocConst(AssocContainer::ImplDefault, qualif, _) | - EntryKind::AssocConst(AssocContainer::ImplFinal, qualif, _) => { - qualif - } + EntryKind::Const(qualif, _) + | EntryKind::AssocConst(AssocContainer::ImplDefault, qualif, _) + | EntryKind::AssocConst(AssocContainer::ImplFinal, qualif, _) => qualif, _ => bug!(), } } @@ -1128,20 +1128,14 @@ impl<'a, 'tcx> CrateMetadata { let name = def_key.disambiguated_data.data.get_opt_name().unwrap(); let (kind, container, has_self) = match self.kind(id) { - EntryKind::AssocConst(container, _, _) => { - (ty::AssocKind::Const, container, false) - } + EntryKind::AssocConst(container, _, _) => (ty::AssocKind::Const, container, false), EntryKind::Method(data) => { let data = data.decode(self); (ty::AssocKind::Method, data.container, data.has_self) } - EntryKind::AssocType(container) => { - (ty::AssocKind::Type, container, false) - } - EntryKind::AssocOpaqueTy(container) => { - (ty::AssocKind::OpaqueTy, container, false) - } - _ => bug!("cannot get associated-item of `{:?}`", def_key) + EntryKind::AssocType(container) => (ty::AssocKind::Type, container, false), + EntryKind::AssocOpaqueTy(container) => (ty::AssocKind::OpaqueTy, container, false), + _ => bug!("cannot get associated-item of `{:?}`", def_key), }; ty::AssocItem { @@ -1151,20 +1145,19 @@ impl<'a, 'tcx> CrateMetadata { defaultness: container.defaultness(), def_id: self.local_def_id(id), container: container.with_def_id(parent), - method_has_self_argument: has_self + method_has_self_argument: has_self, } } fn get_item_variances(&self, id: DefIndex) -> Vec { - self.root.per_def.variances.get(self, id).unwrap_or(Lazy::empty()) - .decode(self).collect() + self.root.per_def.variances.get(self, id).unwrap_or(Lazy::empty()).decode(self).collect() } fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind { match self.kind(node_id) { - EntryKind::Struct(data, _) | - EntryKind::Union(data, _) | - EntryKind::Variant(data) => data.decode(self).ctor_kind, + EntryKind::Struct(data, _) | EntryKind::Union(data, _) | EntryKind::Variant(data) => { + data.decode(self).ctor_kind + } _ => CtorKind::Fictive, } } @@ -1192,17 +1185,23 @@ impl<'a, 'tcx> CrateMetadata { node_id }; - Lrc::from(self.root.per_def.attributes.get(self, item_id).unwrap_or(Lazy::empty()) - .decode((self, sess)) - .collect::>()) + Lrc::from( + self.root + .per_def + .attributes + .get(self, item_id) + .unwrap_or(Lazy::empty()) + .decode((self, sess)) + .collect::>(), + ) } - fn get_struct_field_names( - &self, - id: DefIndex, - sess: &Session, - ) -> Vec> { - self.root.per_def.children.get(self, id).unwrap_or(Lazy::empty()) + fn get_struct_field_names(&self, id: DefIndex, sess: &Session) -> Vec> { + self.root + .per_def + .children + .get(self, id) + .unwrap_or(Lazy::empty()) .decode(self) .map(|index| respan(self.get_span(index, sess), self.item_name(index))) .collect() @@ -1213,10 +1212,7 @@ impl<'a, 'tcx> CrateMetadata { fn reverse_translate_def_id(&self, did: DefId) -> Option { for (local, &global) in self.cnum_map.iter_enumerated() { if global == did.krate { - return Some(DefId { - krate: local, - index: did.index, - }); + return Some(DefId { krate: local, index: did.index }); } } @@ -1229,9 +1225,13 @@ impl<'a, 'tcx> CrateMetadata { id: DefIndex, ) -> &'tcx [DefId] { tcx.arena.alloc_from_iter( - self.root.per_def.inherent_impls.get(self, id).unwrap_or(Lazy::empty()) + self.root + .per_def + .inherent_impls + .get(self, id) + .unwrap_or(Lazy::empty()) .decode(self) - .map(|index| self.local_def_id(index)) + .map(|index| self.local_def_id(index)), ) } @@ -1242,7 +1242,7 @@ impl<'a, 'tcx> CrateMetadata { ) -> &'tcx [DefId] { if self.root.is_proc_macro_crate() { // proc-macro crates export no trait impls. - return &[] + return &[]; } // Do a reverse lookup beforehand to avoid touching the crate_num @@ -1260,9 +1260,11 @@ impl<'a, 'tcx> CrateMetadata { &[] } } else { - tcx.arena.alloc_from_iter(self.trait_impls.values().flat_map(|impls| { - impls.decode(self).map(|idx| self.local_def_id(idx)) - })) + tcx.arena.alloc_from_iter( + self.trait_impls + .values() + .flat_map(|impls| impls.decode(self).map(|idx| self.local_def_id(idx))), + ) } } @@ -1273,16 +1275,12 @@ impl<'a, 'tcx> CrateMetadata { // Not an associated item _ => return None, } - def_key.parent.and_then(|parent_index| { - match self.kind(parent_index) { - EntryKind::Trait(_) | - EntryKind::TraitAlias => Some(self.local_def_id(parent_index)), - _ => None, - } + def_key.parent.and_then(|parent_index| match self.kind(parent_index) { + EntryKind::Trait(_) | EntryKind::TraitAlias => Some(self.local_def_id(parent_index)), + _ => None, }) } - fn get_native_libraries(&self, sess: &Session) -> Vec { if self.root.is_proc_macro_crate() { // Proc macro crates do not have any *target* native libraries. @@ -1305,14 +1303,12 @@ impl<'a, 'tcx> CrateMetadata { &self, tcx: TyCtxt<'tcx>, ) -> &'tcx [(CrateNum, LinkagePreference)] { - tcx.arena.alloc_from_iter(self.root - .dylib_dependency_formats - .decode(self) - .enumerate() - .flat_map(|(i, link)| { + tcx.arena.alloc_from_iter( + self.root.dylib_dependency_formats.decode(self).enumerate().flat_map(|(i, link)| { let cnum = CrateNum::new(i + 1); link.map(|link| (self.cnum_map[cnum], link)) - })) + }), + ) } fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] { @@ -1320,16 +1316,13 @@ impl<'a, 'tcx> CrateMetadata { // Proc macro crates do not depend on any target weak lang-items. &[] } else { - tcx.arena.alloc_from_iter(self.root - .lang_items_missing - .decode(self)) + tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self)) } } fn get_fn_param_names(&self, id: DefIndex) -> Vec { let param_names = match self.kind(id) { - EntryKind::Fn(data) | - EntryKind::ForeignFn(data) => data.decode(self).param_names, + EntryKind::Fn(data) | EntryKind::ForeignFn(data) => data.decode(self).param_names, EntryKind::Method(data) => data.decode(self).fn_data.param_names, _ => Lazy::empty(), }; @@ -1351,8 +1344,7 @@ impl<'a, 'tcx> CrateMetadata { fn get_rendered_const(&self, id: DefIndex) -> String { match self.kind(id) { - EntryKind::Const(_, data) | - EntryKind::AssocConst(_, _, data) => data.decode(self).0, + EntryKind::Const(_, data) | EntryKind::AssocConst(_, _, data) => data.decode(self).0, _ => bug!(), } } @@ -1381,7 +1373,7 @@ impl<'a, 'tcx> CrateMetadata { } fn asyncness(&self, id: DefIndex) -> hir::IsAsync { - match self.kind(id) { + match self.kind(id) { EntryKind::Fn(data) => data.decode(self).asyncness, EntryKind::Method(data) => data.decode(self).fn_data.asyncness, EntryKind::ForeignFn(data) => data.decode(self).asyncness, @@ -1391,19 +1383,17 @@ impl<'a, 'tcx> CrateMetadata { fn is_foreign_item(&self, id: DefIndex) -> bool { match self.kind(id) { - EntryKind::ForeignImmStatic | - EntryKind::ForeignMutStatic | - EntryKind::ForeignFn(_) => true, + EntryKind::ForeignImmStatic | EntryKind::ForeignMutStatic | EntryKind::ForeignFn(_) => { + true + } _ => false, } } fn static_mutability(&self, id: DefIndex) -> Option { match self.kind(id) { - EntryKind::ImmStatic | - EntryKind::ForeignImmStatic => Some(hir::Mutability::Not), - EntryKind::MutStatic | - EntryKind::ForeignMutStatic => Some(hir::Mutability::Mut), + EntryKind::ImmStatic | EntryKind::ForeignImmStatic => Some(hir::Mutability::Not), + EntryKind::MutStatic | EntryKind::ForeignMutStatic => Some(hir::Mutability::Mut), _ => None, } } @@ -1465,63 +1455,74 @@ impl<'a, 'tcx> CrateMetadata { self.source_map_import_info.init_locking(|| { let external_source_map = self.root.source_map.decode(self); - external_source_map.map(|source_file_to_import| { - // We can't reuse an existing SourceFile, so allocate a new one - // containing the information we need. - let syntax_pos::SourceFile { name, - name_was_remapped, - src_hash, - start_pos, - end_pos, - mut lines, - mut multibyte_chars, - mut non_narrow_chars, - mut normalized_pos, - name_hash, - .. } = source_file_to_import; - - let source_length = (end_pos - start_pos).to_usize(); - - // Translate line-start positions and multibyte character - // position into frame of reference local to file. - // `SourceMap::new_imported_source_file()` will then translate those - // coordinates to their new global frame of reference when the - // offset of the SourceFile is known. - for pos in &mut lines { - *pos = *pos - start_pos; - } - for mbc in &mut multibyte_chars { - mbc.pos = mbc.pos - start_pos; - } - for swc in &mut non_narrow_chars { - *swc = *swc - start_pos; - } - for np in &mut normalized_pos { - np.pos = np.pos - start_pos; - } + external_source_map + .map(|source_file_to_import| { + // We can't reuse an existing SourceFile, so allocate a new one + // containing the information we need. + let syntax_pos::SourceFile { + name, + name_was_remapped, + src_hash, + start_pos, + end_pos, + mut lines, + mut multibyte_chars, + mut non_narrow_chars, + mut normalized_pos, + name_hash, + .. + } = source_file_to_import; + + let source_length = (end_pos - start_pos).to_usize(); + + // Translate line-start positions and multibyte character + // position into frame of reference local to file. + // `SourceMap::new_imported_source_file()` will then translate those + // coordinates to their new global frame of reference when the + // offset of the SourceFile is known. + for pos in &mut lines { + *pos = *pos - start_pos; + } + for mbc in &mut multibyte_chars { + mbc.pos = mbc.pos - start_pos; + } + for swc in &mut non_narrow_chars { + *swc = *swc - start_pos; + } + for np in &mut normalized_pos { + np.pos = np.pos - start_pos; + } - let local_version = local_source_map.new_imported_source_file(name, - name_was_remapped, - self.cnum.as_u32(), - src_hash, - name_hash, - source_length, - lines, - multibyte_chars, - non_narrow_chars, - normalized_pos); - debug!("CrateMetaData::imported_source_files alloc \ + let local_version = local_source_map.new_imported_source_file( + name, + name_was_remapped, + self.cnum.as_u32(), + src_hash, + name_hash, + source_length, + lines, + multibyte_chars, + non_narrow_chars, + normalized_pos, + ); + debug!( + "CrateMetaData::imported_source_files alloc \ source_file {:?} original (start_pos {:?} end_pos {:?}) \ translated (start_pos {:?} end_pos {:?})", - local_version.name, start_pos, end_pos, - local_version.start_pos, local_version.end_pos); + local_version.name, + start_pos, + end_pos, + local_version.start_pos, + local_version.end_pos + ); - ImportedSourceFile { - original_start_pos: start_pos, - original_end_pos: end_pos, - translated_source_file: local_version, - } - }).collect() + ImportedSourceFile { + original_start_pos: start_pos, + original_end_pos: end_pos, + translated_source_file: local_version, + } + }) + .collect() }) } @@ -1633,6 +1634,6 @@ fn macro_kind(raw: &ProcMacro) -> MacroKind { match raw { ProcMacro::CustomDerive { .. } => MacroKind::Derive, ProcMacro::Attr { .. } => MacroKind::Attr, - ProcMacro::Bang { .. } => MacroKind::Bang + ProcMacro::Bang { .. } => MacroKind::Bang, } } diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs index 4a6b25930c869..23ef896017d59 100644 --- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs +++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs @@ -1,40 +1,40 @@ use crate::creader::{CStore, LoadedMacro}; +use crate::foreign_modules; use crate::link_args; use crate::native_libs; -use crate::foreign_modules; use crate::rmeta::{self, encoder}; -use rustc::ty::query::QueryConfig; +use rustc::hir; +use rustc::hir::def; +use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc::hir::map::definitions::DefPathTable; +use rustc::hir::map::{DefKey, DefPath, DefPathHash}; use rustc::middle::cstore::{CrateSource, CrateStore, DepKind, EncodedMetadata, NativeLibraryKind}; use rustc::middle::exported_symbols::ExportedSymbol; use rustc::middle::stability::DeprecationEntry; -use rustc::hir::def; -use rustc::hir; use rustc::session::{CrateDisambiguator, Session}; -use rustc::ty::{self, TyCtxt}; use rustc::ty::query::Providers; -use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX}; -use rustc::hir::map::{DefKey, DefPath, DefPathHash}; -use rustc::hir::map::definitions::DefPathTable; +use rustc::ty::query::QueryConfig; +use rustc::ty::{self, TyCtxt}; use rustc::util::nodemap::DefIdMap; use rustc_data_structures::svh::Svh; -use rustc_parse::source_file_to_stream; use rustc_parse::parser::emit_unclosed_delims; +use rustc_parse::source_file_to_stream; +use rustc_data_structures::sync::Lrc; use smallvec::SmallVec; use std::any::Any; -use rustc_data_structures::sync::Lrc; use std::sync::Arc; use syntax::ast; use syntax::attr; +use syntax::expand::allocator::AllocatorKind; +use syntax::ptr::P; use syntax::source_map; use syntax::source_map::Spanned; use syntax::symbol::Symbol; -use syntax::expand::allocator::AllocatorKind; -use syntax::ptr::P; use syntax::tokenstream::DelimSpan; -use syntax_pos::{Span, FileName}; +use syntax_pos::{FileName, Span}; macro_rules! provide { (<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident, @@ -78,15 +78,21 @@ trait IntoArgs { } impl IntoArgs for DefId { - fn into_args(self) -> (DefId, DefId) { (self, self) } + fn into_args(self) -> (DefId, DefId) { + (self, self) + } } impl IntoArgs for CrateNum { - fn into_args(self) -> (DefId, DefId) { (self.as_def_id(), self.as_def_id()) } + fn into_args(self) -> (DefId, DefId) { + (self.as_def_id(), self.as_def_id()) + } } impl IntoArgs for (CrateNum, DefId) { - fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) } + fn into_args(self) -> (DefId, DefId) { + (self.0.as_def_id(), self.1) + } } provide! { <'tcx> tcx, def_id, other, cdata, @@ -250,19 +256,16 @@ pub fn provide(providers: &mut Providers<'_>) { // therefore no actual inputs, they're just reading tables calculated in // resolve! Does this work? Unsure! That's what the issue is about *providers = Providers { - is_dllimport_foreign_item: |tcx, id| { - match tcx.native_library_kind(id) { - Some(NativeLibraryKind::NativeUnknown) | - Some(NativeLibraryKind::NativeRawDylib) => true, - _ => false, + is_dllimport_foreign_item: |tcx, id| match tcx.native_library_kind(id) { + Some(NativeLibraryKind::NativeUnknown) | Some(NativeLibraryKind::NativeRawDylib) => { + true } + _ => false, }, - is_statically_included_foreign_item: |tcx, id| { - match tcx.native_library_kind(id) { - Some(NativeLibraryKind::NativeStatic) | - Some(NativeLibraryKind::NativeStaticNobundle) => true, - _ => false, - } + is_statically_included_foreign_item: |tcx, id| match tcx.native_library_kind(id) { + Some(NativeLibraryKind::NativeStatic) + | Some(NativeLibraryKind::NativeStaticNobundle) => true, + _ => false, }, native_library_kind: |tcx, id| { tcx.native_libraries(id.krate) @@ -300,8 +303,8 @@ pub fn provide(providers: &mut Providers<'_>) { // sufficiently visible parent (considering modules that re-export the // external item to be parents). visible_parent_map: |tcx, cnum| { - use std::collections::vec_deque::VecDeque; use std::collections::hash_map::Entry; + use std::collections::vec_deque::VecDeque; assert_eq!(cnum, LOCAL_CRATE); let mut visible_parent_map: DefIdMap = Default::default(); @@ -331,13 +334,10 @@ pub fn provide(providers: &mut Providers<'_>) { for &cnum in crates.iter() { // Ignore crates without a corresponding local `extern crate` item. if tcx.missing_extern_crate_item(cnum) { - continue + continue; } - bfs_queue.push_back(DefId { - krate: cnum, - index: CRATE_DEF_INDEX - }); + bfs_queue.push_back(DefId { krate: cnum, index: CRATE_DEF_INDEX }); } // (restrict scope of mutable-borrow of `visible_parent_map`) @@ -410,11 +410,14 @@ impl CStore { pub fn item_children_untracked( &self, def_id: DefId, - sess: &Session + sess: &Session, ) -> Vec> { let mut result = vec![]; - self.get_crate_data(def_id.krate) - .each_child_of_item(def_id.index, |child| result.push(child), sess); + self.get_crate_data(def_id.krate).each_child_of_item( + def_id.index, + |child| result.push(child), + sess, + ); result } @@ -442,24 +445,32 @@ impl CStore { attr::mark_used(attr); } - let name = data.def_key(id.index).disambiguated_data.data - .get_opt_name().expect("no name in load_macro"); - sess.imported_macro_spans.borrow_mut() + let name = data + .def_key(id.index) + .disambiguated_data + .data + .get_opt_name() + .expect("no name in load_macro"); + sess.imported_macro_spans + .borrow_mut() .insert(local_span, (name.to_string(), data.get_span(id.index, sess))); - LoadedMacro::MacroDef(ast::Item { - // FIXME: cross-crate hygiene - ident: ast::Ident::with_dummy_span(name), - id: ast::DUMMY_NODE_ID, - span: local_span, - attrs: attrs.iter().cloned().collect(), - kind: ast::ItemKind::MacroDef(ast::MacroDef { - body: P(ast::MacArgs::Delimited(dspan, ast::MacDelimiter::Brace, body)), - legacy: def.legacy, - }), - vis: source_map::respan(local_span.shrink_to_lo(), ast::VisibilityKind::Inherited), - tokens: None, - }, data.root.edition) + LoadedMacro::MacroDef( + ast::Item { + // FIXME: cross-crate hygiene + ident: ast::Ident::with_dummy_span(name), + id: ast::DUMMY_NODE_ID, + span: local_span, + attrs: attrs.iter().cloned().collect(), + kind: ast::ItemKind::MacroDef(ast::MacroDef { + body: P(ast::MacArgs::Delimited(dspan, ast::MacDelimiter::Brace, body)), + legacy: def.legacy, + }), + vis: source_map::respan(local_span.shrink_to_lo(), ast::VisibilityKind::Inherited), + tokens: None, + }, + data.root.edition, + ) } pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem { @@ -480,8 +491,7 @@ impl CrateStore for CStore { self.get_crate_data(def.krate).get_generics(def.index, sess) } - fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol - { + fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol { self.get_crate_data(cnum).root.name } @@ -489,13 +499,11 @@ impl CrateStore for CStore { self.get_crate_data(cnum).private_dep } - fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator - { + fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator { self.get_crate_data(cnum).root.disambiguator } - fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh - { + fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh { self.get_crate_data(cnum).root.hash } @@ -518,8 +526,7 @@ impl CrateStore for CStore { &self.get_crate_data(cnum).def_path_table } - fn crates_untracked(&self) -> Vec - { + fn crates_untracked(&self) -> Vec { let mut result = vec![]; self.iter_crate_data(|cnum, _| result.push(cnum)); result @@ -529,8 +536,7 @@ impl CrateStore for CStore { encoder::encode_metadata(tcx) } - fn metadata_encoding_version(&self) -> &[u8] - { + fn metadata_encoding_version(&self) -> &[u8] { rmeta::METADATA_HEADER } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index cfe5ea65fca5b..1e93d144f15df 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -1,31 +1,30 @@ -use crate::rmeta::*; use crate::rmeta::table::FixedSizeEncoding; +use crate::rmeta::*; -use rustc::middle::cstore::{LinkagePreference, NativeLibrary, - EncodedMetadata, ForeignModule}; use rustc::hir::def::CtorKind; -use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId, LOCAL_CRATE}; -use rustc::hir::{GenericParamKind, AnonConst}; +use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::hir::map::definitions::DefPathTable; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_index::vec::Idx; +use rustc::hir::{AnonConst, GenericParamKind}; +use rustc::middle::cstore::{EncodedMetadata, ForeignModule, LinkagePreference, NativeLibrary}; use rustc::middle::dependency_format::Linkage; -use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel, - metadata_symbol_name}; +use rustc::middle::exported_symbols::{metadata_symbol_name, ExportedSymbol, SymbolExportLevel}; use rustc::middle::lang_items; use rustc::mir::{self, interpret}; use rustc::traits::specialization_graph; -use rustc::ty::{self, Ty, TyCtxt, SymbolName}; use rustc::ty::codec::{self as ty_codec, TyEncoder}; use rustc::ty::layout::VariantIdx; +use rustc::ty::{self, SymbolName, Ty, TyCtxt}; +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_index::vec::Idx; use rustc::session::config::{self, CrateType}; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::Lrc; -use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque}; +use rustc_serialize::{opaque, Encodable, Encoder, SpecializedEncoder}; +use log::{debug, trace}; use std::hash::Hash; use std::num::NonZeroUsize; use std::path::Path; @@ -36,12 +35,11 @@ use syntax::expand::is_proc_macro_attr; use syntax::source_map::Spanned; use syntax::symbol::{kw, sym, Ident, Symbol}; use syntax_pos::{self, FileName, SourceFile, Span}; -use log::{debug, trace}; -use rustc::hir::{self, PatKind}; -use rustc::hir::itemlikevisit::ItemLikeVisitor; -use rustc::hir::intravisit::{Visitor, NestedVisitorMap}; use rustc::hir::intravisit; +use rustc::hir::intravisit::{NestedVisitorMap, Visitor}; +use rustc::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir::{self, PatKind}; struct EncodeContext<'tcx> { opaque: opaque::Encoder, @@ -115,7 +113,8 @@ impl<'tcx, T> SpecializedEncoder> for EncodeContext<'tcx> { } impl<'tcx, I: Idx, T> SpecializedEncoder>> for EncodeContext<'tcx> - where Option: FixedSizeEncoding, +where + Option: FixedSizeEncoding, { fn specialized_encode(&mut self, lazy: &Lazy>) -> Result<(), Self::Error> { self.emit_usize(lazy.meta)?; @@ -133,10 +132,7 @@ impl<'tcx> SpecializedEncoder for EncodeContext<'tcx> { impl<'tcx> SpecializedEncoder for EncodeContext<'tcx> { #[inline] fn specialized_encode(&mut self, def_id: &DefId) -> Result<(), Self::Error> { - let DefId { - krate, - index, - } = *def_id; + let DefId { krate, index } = *def_id; krate.encode(self)?; index.encode(self) @@ -153,7 +149,7 @@ impl<'tcx> SpecializedEncoder for EncodeContext<'tcx> { impl<'tcx> SpecializedEncoder for EncodeContext<'tcx> { fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> { if span.is_dummy() { - return TAG_INVALID_SPAN.encode(self) + return TAG_INVALID_SPAN.encode(self); } let span = span.data(); @@ -170,14 +166,14 @@ impl<'tcx> SpecializedEncoder for EncodeContext<'tcx> { if !self.source_file_cache.contains(span.hi) { // Unfortunately, macro expansion still sometimes generates Spans // that malformed in this way. - return TAG_INVALID_SPAN.encode(self) + return TAG_INVALID_SPAN.encode(self); } // HACK(eddyb) there's no way to indicate which crate a Span is coming // from right now, so decoding would fail to find the SourceFile if // it's not local to the crate the Span is found in. if self.source_file_cache.is_imported() { - return TAG_INVALID_SPAN.encode(self) + return TAG_INVALID_SPAN.encode(self); } TAG_VALID_SPAN.encode(self)?; @@ -222,7 +218,7 @@ impl<'tcx> SpecializedEncoder for EncodeContext<'tcx> { self.interpret_allocs_inverse.push(*alloc_id); e.insert(idx); idx - }, + } }; index.encode(self) @@ -230,9 +226,10 @@ impl<'tcx> SpecializedEncoder for EncodeContext<'tcx> { } impl<'tcx> SpecializedEncoder<&'tcx [(ty::Predicate<'tcx>, Span)]> for EncodeContext<'tcx> { - fn specialized_encode(&mut self, - predicates: &&'tcx [(ty::Predicate<'tcx>, Span)]) - -> Result<(), Self::Error> { + fn specialized_encode( + &mut self, + predicates: &&'tcx [(ty::Predicate<'tcx>, Span)], + ) -> Result<(), Self::Error> { ty_codec::encode_spanned_predicates(self, predicates, |ecx| &mut ecx.predicate_shorthands) } } @@ -244,9 +241,7 @@ impl<'tcx> SpecializedEncoder for EncodeContext<'tcx> { } impl<'tcx, T: Encodable> SpecializedEncoder> for EncodeContext<'tcx> { - fn specialized_encode(&mut self, - _: &mir::ClearCrossCrate) - -> Result<(), Self::Error> { + fn specialized_encode(&mut self, _: &mir::ClearCrossCrate) -> Result<(), Self::Error> { Ok(()) } } @@ -275,8 +270,9 @@ impl EncodeContentsForLazy for T { } impl EncodeContentsForLazy<[T]> for I - where I: IntoIterator, - I::Item: EncodeContentsForLazy, +where + I: IntoIterator, + I::Item: EncodeContentsForLazy, { fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'tcx>) -> usize { self.into_iter().map(|value| value.encode_contents_for_lazy(ecx)).count() @@ -292,7 +288,7 @@ macro_rules! record { let lazy = $self.lazy(value); $self.$tables.$table.set($def_id.index, lazy); } - }} + }}; } impl<'tcx> EncodeContext<'tcx> { @@ -321,10 +317,7 @@ impl<'tcx> EncodeContext<'tcx> { self.emit_usize(distance) } - fn lazy( - &mut self, - value: impl EncodeContentsForLazy, - ) -> Lazy { + fn lazy(&mut self, value: impl EncodeContentsForLazy) -> Lazy { let pos = NonZeroUsize::new(self.position()).unwrap(); assert_eq!(self.lazy_state, LazyState::NoNode); @@ -358,7 +351,8 @@ impl<'tcx> EncodeContext<'tcx> { let (working_dir, _cwd_remapped) = self.tcx.sess.working_dir.clone(); - let adapted = all_source_files.iter() + let adapted = all_source_files + .iter() .filter(|source_file| { // No need to re-export imported source_files, as any downstream // crate will import them from their original source. @@ -370,7 +364,7 @@ impl<'tcx> EncodeContext<'tcx> { // This path of this SourceFile has been modified by // path-remapping, so we use it verbatim (and avoid // cloning the whole map in the process). - _ if source_file.name_was_remapped => source_file.clone(), + _ if source_file.name_was_remapped => source_file.clone(), // Otherwise expand all paths to absolute paths because // any relative paths are potentially relative to a @@ -384,7 +378,7 @@ impl<'tcx> EncodeContext<'tcx> { hasher.finish::() }; Lrc::new(adapted) - }, + } // expanded code, not from a file _ => source_file.clone(), @@ -472,18 +466,13 @@ impl<'tcx> EncodeContext<'tcx> { let id = self.interpret_allocs_inverse[idx]; let pos = self.position() as u32; interpret_alloc_index.push(pos); - interpret::specialized_encode_alloc_id( - self, - tcx, - id, - ).unwrap(); + interpret::specialized_encode_alloc_id(self, tcx, id).unwrap(); } n = new_n; } self.lazy(interpret_alloc_index) }; - i = self.position(); let per_def = self.per_def.encode(&mut self.opaque); let per_def_bytes = self.position() - i; @@ -493,7 +482,6 @@ impl<'tcx> EncodeContext<'tcx> { let proc_macro_data = self.encode_proc_macros(); let proc_macro_data_bytes = self.position() - i; - let attrs = tcx.hir().krate_attrs(); let has_default_lib_allocator = attr::contains_name(&attrs, sym::default_lib_allocator); @@ -588,11 +576,7 @@ impl EncodeContext<'tcx> { record!(self.per_def.ty[def_id] <- self.tcx.type_of(def_id)); } - fn encode_enum_variant_info( - &mut self, - enum_did: DefId, - index: VariantIdx, - ) { + fn encode_enum_variant_info(&mut self, enum_did: DefId, index: VariantIdx) { let tcx = self.tcx; let def = tcx.adt_def(enum_did); let variant = &def.variants[index]; @@ -635,11 +619,7 @@ impl EncodeContext<'tcx> { self.encode_promoted_mir(def_id); } - fn encode_enum_variant_ctor( - &mut self, - enum_did: DefId, - index: VariantIdx, - ) { + fn encode_enum_variant_ctor(&mut self, enum_did: DefId, index: VariantIdx) { let tcx = self.tcx; let def = tcx.adt_def(enum_did); let variant = &def.variants[index]; @@ -708,12 +688,7 @@ impl EncodeContext<'tcx> { self.encode_deprecation(def_id); } - fn encode_field( - &mut self, - adt_def_id: DefId, - variant_index: VariantIdx, - field_index: usize, - ) { + fn encode_field(&mut self, adt_def_id: DefId, variant_index: VariantIdx, field_index: usize) { let tcx = self.tcx; let variant = &tcx.adt_def(adt_def_id).variants[variant_index]; let field = &variant.fields[field_index]; @@ -759,8 +734,8 @@ impl EncodeContext<'tcx> { // If the structure is marked as non_exhaustive then lower the visibility // to within the crate. - if adt_def.non_enum_variant().is_field_list_non_exhaustive() && - ctor_vis == ty::Visibility::Public + if adt_def.non_enum_variant().is_field_list_non_exhaustive() + && ctor_vis == ty::Visibility::Public { ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)); } @@ -815,12 +790,9 @@ impl EncodeContext<'tcx> { let trait_item = tcx.associated_item(def_id); let container = match trait_item.defaultness { - hir::Defaultness::Default { has_value: true } => - AssocContainer::TraitWithDefault, - hir::Defaultness::Default { has_value: false } => - AssocContainer::TraitRequired, - hir::Defaultness::Final => - span_bug!(ast_item.span, "traits cannot have final items"), + hir::Defaultness::Default { has_value: true } => AssocContainer::TraitWithDefault, + hir::Defaultness::Default { has_value: false } => AssocContainer::TraitRequired, + hir::Defaultness::Final => span_bug!(ast_item.span, "traits cannot have final items"), }; record!(self.per_def.kind[def_id] <- match trait_item.kind { @@ -869,8 +841,7 @@ impl EncodeContext<'tcx> { self.encode_const_stability(def_id); self.encode_deprecation(def_id); match trait_item.kind { - ty::AssocKind::Const | - ty::AssocKind::Method => { + ty::AssocKind::Const | ty::AssocKind::Method => { self.encode_item_type(def_id); } ty::AssocKind::Type => { @@ -907,8 +878,9 @@ impl EncodeContext<'tcx> { let container = match impl_item.defaultness { hir::Defaultness::Default { has_value: true } => AssocContainer::ImplDefault, hir::Defaultness::Final => AssocContainer::ImplFinal, - hir::Defaultness::Default { has_value: false } => - span_bug!(ast_item.span, "impl items always have values (currently)"), + hir::Defaultness::Default { has_value: false } => { + span_bug!(ast_item.span, "impl items always have values (currently)") + } }; record!(self.per_def.kind[def_id] <- match impl_item.kind { @@ -961,15 +933,14 @@ impl EncodeContext<'tcx> { hir::ImplItemKind::Const(..) => true, hir::ImplItemKind::Method(ref sig, _) => { let generics = self.tcx.generics_of(def_id); - let needs_inline = (generics.requires_monomorphization(self.tcx) || - tcx.codegen_fn_attrs(def_id).requests_inline()) && - !self.metadata_output_only(); + let needs_inline = (generics.requires_monomorphization(self.tcx) + || tcx.codegen_fn_attrs(def_id).requests_inline()) + && !self.metadata_output_only(); let is_const_fn = sig.header.constness == hir::Constness::Const; let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir; needs_inline || is_const_fn || always_encode_mir - }, - hir::ImplItemKind::OpaqueTy(..) | - hir::ImplItemKind::TyAlias(..) => false, + } + hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(..) => false, }; if mir { self.encode_optimized_mir(def_id); @@ -977,15 +948,12 @@ impl EncodeContext<'tcx> { } } - fn encode_fn_param_names_for_body(&mut self, body_id: hir::BodyId) - -> Lazy<[ast::Name]> { + fn encode_fn_param_names_for_body(&mut self, body_id: hir::BodyId) -> Lazy<[ast::Name]> { self.tcx.dep_graph.with_ignore(|| { let body = self.tcx.hir().body(body_id); - self.lazy(body.params.iter().map(|arg| { - match arg.pat.kind { - PatKind::Binding(_, _, ident, _) => ident.name, - _ => kw::Invalid, - } + self.lazy(body.params.iter().map(|arg| match arg.pat.kind { + PatKind::Binding(_, _, ident, _) => ident.name, + _ => kw::Invalid, })) }) } @@ -1175,15 +1143,15 @@ impl EncodeContext<'tcx> { v.def_id.index }) ), - hir::ItemKind::Struct(..) | - hir::ItemKind::Union(..) => record!(self.per_def.children[def_id] <- - self.tcx.adt_def(def_id).non_enum_variant().fields.iter().map(|f| { - assert!(f.did.is_local()); - f.did.index - }) - ), - hir::ItemKind::Impl(..) | - hir::ItemKind::Trait(..) => { + hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => { + record!(self.per_def.children[def_id] <- + self.tcx.adt_def(def_id).non_enum_variant().fields.iter().map(|f| { + assert!(f.did.is_local()); + f.did.index + }) + ) + } + hir::ItemKind::Impl(..) | hir::ItemKind::Trait(..) => { let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); record!(self.per_def.children[def_id] <- associated_item_def_ids.iter().map(|&def_id| { @@ -1198,15 +1166,15 @@ impl EncodeContext<'tcx> { self.encode_const_stability(def_id); self.encode_deprecation(def_id); match item.kind { - hir::ItemKind::Static(..) | - hir::ItemKind::Const(..) | - hir::ItemKind::Fn(..) | - hir::ItemKind::TyAlias(..) | - hir::ItemKind::OpaqueTy(..) | - hir::ItemKind::Enum(..) | - hir::ItemKind::Struct(..) | - hir::ItemKind::Union(..) | - hir::ItemKind::Impl(..) => self.encode_item_type(def_id), + hir::ItemKind::Static(..) + | hir::ItemKind::Const(..) + | hir::ItemKind::Fn(..) + | hir::ItemKind::TyAlias(..) + | hir::ItemKind::OpaqueTy(..) + | hir::ItemKind::Enum(..) + | hir::ItemKind::Struct(..) + | hir::ItemKind::Union(..) + | hir::ItemKind::Impl(..) => self.encode_item_type(def_id), _ => {} } if let hir::ItemKind::Fn(..) = item.kind { @@ -1219,24 +1187,24 @@ impl EncodeContext<'tcx> { } self.encode_inherent_implementations(def_id); match item.kind { - hir::ItemKind::Enum(..) | - hir::ItemKind::Struct(..) | - hir::ItemKind::Union(..) | - hir::ItemKind::Fn(..) => self.encode_variances_of(def_id), + hir::ItemKind::Enum(..) + | hir::ItemKind::Struct(..) + | hir::ItemKind::Union(..) + | hir::ItemKind::Fn(..) => self.encode_variances_of(def_id), _ => {} } match item.kind { - hir::ItemKind::Static(..) | - hir::ItemKind::Const(..) | - hir::ItemKind::Fn(..) | - hir::ItemKind::TyAlias(..) | - hir::ItemKind::Enum(..) | - hir::ItemKind::Struct(..) | - hir::ItemKind::Union(..) | - hir::ItemKind::Impl(..) | - hir::ItemKind::OpaqueTy(..) | - hir::ItemKind::Trait(..) | - hir::ItemKind::TraitAlias(..) => { + hir::ItemKind::Static(..) + | hir::ItemKind::Const(..) + | hir::ItemKind::Fn(..) + | hir::ItemKind::TyAlias(..) + | hir::ItemKind::Enum(..) + | hir::ItemKind::Struct(..) + | hir::ItemKind::Union(..) + | hir::ItemKind::Impl(..) + | hir::ItemKind::OpaqueTy(..) + | hir::ItemKind::Trait(..) + | hir::ItemKind::TraitAlias(..) => { self.encode_generics(def_id); self.encode_explicit_predicates(def_id); self.encode_inferred_outlives(def_id); @@ -1244,8 +1212,7 @@ impl EncodeContext<'tcx> { _ => {} } match item.kind { - hir::ItemKind::Trait(..) | - hir::ItemKind::TraitAlias(..) => { + hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) => { self.encode_super_predicates(def_id); } _ => {} @@ -1255,10 +1222,9 @@ impl EncodeContext<'tcx> { hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => true, hir::ItemKind::Fn(ref sig, ..) => { let generics = tcx.generics_of(def_id); - let needs_inline = - (generics.requires_monomorphization(tcx) || - tcx.codegen_fn_attrs(def_id).requests_inline()) && - !self.metadata_output_only(); + let needs_inline = (generics.requires_monomorphization(tcx) + || tcx.codegen_fn_attrs(def_id).requests_inline()) + && !self.metadata_output_only(); let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir; needs_inline || sig.header.constness == hir::Constness::Const || always_encode_mir } @@ -1446,18 +1412,13 @@ impl EncodeContext<'tcx> { fn encode_impls(&mut self) -> Lazy<[TraitImpls]> { debug!("EncodeContext::encode_impls()"); let tcx = self.tcx; - let mut visitor = ImplVisitor { - tcx, - impls: FxHashMap::default(), - }; + let mut visitor = ImplVisitor { tcx, impls: FxHashMap::default() }; tcx.hir().krate().visit_all_item_likes(&mut visitor); let mut all_impls: Vec<_> = visitor.impls.into_iter().collect(); // Bring everything into deterministic order for hashing - all_impls.sort_by_cached_key(|&(trait_def_id, _)| { - tcx.def_path_hash(trait_def_id) - }); + all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id)); let all_impls: Vec<_> = all_impls .into_iter() @@ -1483,24 +1444,23 @@ impl EncodeContext<'tcx> { // middle::reachable module but filters out items that either don't have a // symbol associated with them (they weren't translated) or if they're an FFI // definition (as that's not defined in this crate). - fn encode_exported_symbols(&mut self, - exported_symbols: &[(ExportedSymbol<'tcx>, SymbolExportLevel)]) - -> Lazy<[(ExportedSymbol<'tcx>, SymbolExportLevel)]> { + fn encode_exported_symbols( + &mut self, + exported_symbols: &[(ExportedSymbol<'tcx>, SymbolExportLevel)], + ) -> Lazy<[(ExportedSymbol<'tcx>, SymbolExportLevel)]> { // The metadata symbol name is special. It should not show up in // downstream crates. let metadata_symbol_name = SymbolName::new(&metadata_symbol_name(self.tcx)); - self.lazy(exported_symbols - .iter() - .filter(|&&(ref exported_symbol, _)| { - match *exported_symbol { - ExportedSymbol::NoDefId(symbol_name) => { - symbol_name != metadata_symbol_name - }, + self.lazy( + exported_symbols + .iter() + .filter(|&&(ref exported_symbol, _)| match *exported_symbol { + ExportedSymbol::NoDefId(symbol_name) => symbol_name != metadata_symbol_name, _ => true, - } - }) - .cloned()) + }) + .cloned(), + ) } fn encode_dylib_dependency_formats(&mut self) -> Lazy<[Option]> { @@ -1509,24 +1469,17 @@ impl EncodeContext<'tcx> { if *ty != config::CrateType::Dylib { continue; } - return self.lazy(arr.iter().map(|slot| { - match *slot { - Linkage::NotLinked | - Linkage::IncludedFromDylib => None, + return self.lazy(arr.iter().map(|slot| match *slot { + Linkage::NotLinked | Linkage::IncludedFromDylib => None, - Linkage::Dynamic => Some(LinkagePreference::RequireDynamic), - Linkage::Static => Some(LinkagePreference::RequireStatic), - } + Linkage::Dynamic => Some(LinkagePreference::RequireDynamic), + Linkage::Static => Some(LinkagePreference::RequireStatic), })); } Lazy::empty() } - fn encode_info_for_foreign_item( - &mut self, - def_id: DefId, - nitem: &hir::ForeignItem<'_>, - ) { + fn encode_info_for_foreign_item(&mut self, def_id: DefId, nitem: &hir::ForeignItem<'_>) { let tcx = self.tcx; debug!("EncodeContext::encode_info_for_foreign_item({:?})", def_id); @@ -1584,8 +1537,7 @@ impl Visitor<'tcx> for EncodeContext<'tcx> { intravisit::walk_item(self, item); let def_id = self.tcx.hir().local_def_id(item.hir_id); match item.kind { - hir::ItemKind::ExternCrate(_) | - hir::ItemKind::Use(..) => {} // ignore these + hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {} // ignore these _ => self.encode_info_for_item(def_id, item), } self.encode_addl_info_for_item(item); @@ -1652,17 +1604,17 @@ impl EncodeContext<'tcx> { fn encode_addl_info_for_item(&mut self, item: &hir::Item<'_>) { let def_id = self.tcx.hir().local_def_id(item.hir_id); match item.kind { - hir::ItemKind::Static(..) | - hir::ItemKind::Const(..) | - hir::ItemKind::Fn(..) | - hir::ItemKind::Mod(..) | - hir::ItemKind::ForeignMod(..) | - hir::ItemKind::GlobalAsm(..) | - hir::ItemKind::ExternCrate(..) | - hir::ItemKind::Use(..) | - hir::ItemKind::TyAlias(..) | - hir::ItemKind::OpaqueTy(..) | - hir::ItemKind::TraitAlias(..) => { + hir::ItemKind::Static(..) + | hir::ItemKind::Const(..) + | hir::ItemKind::Fn(..) + | hir::ItemKind::Mod(..) + | hir::ItemKind::ForeignMod(..) + | hir::ItemKind::GlobalAsm(..) + | hir::ItemKind::ExternCrate(..) + | hir::ItemKind::Use(..) + | hir::ItemKind::TyAlias(..) + | hir::ItemKind::OpaqueTy(..) + | hir::ItemKind::TraitAlias(..) => { // no sub-item recording needed in these cases } hir::ItemKind::Enum(..) => { @@ -1717,10 +1669,7 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> { if let hir::ItemKind::Impl(..) = item.kind { let impl_id = self.tcx.hir().local_def_id(item.hir_id); if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) { - self.impls - .entry(trait_ref.def_id) - .or_default() - .push(impl_id.index); + self.impls.entry(trait_ref.def_id).or_default().push(impl_id.index); } } } diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index e13edc2d621c5..8859695cc9474 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -3,22 +3,22 @@ use table::{Table, TableBuilder}; use rustc::hir; use rustc::hir::def::{self, CtorKind}; -use rustc::hir::def_id::{DefIndex, DefId}; +use rustc::hir::def_id::{DefId, DefIndex}; +use rustc::middle::cstore::{DepKind, ForeignModule, LinkagePreference, NativeLibrary}; use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; -use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary, ForeignModule}; use rustc::middle::lang_items; use rustc::mir; -use rustc::session::CrateDisambiguator; use rustc::session::config::SymbolManglingVersion; -use rustc::ty::{self, Ty, ReprOptions}; -use rustc_target::spec::{PanicStrategy, TargetTriple}; -use rustc_index::vec::IndexVec; +use rustc::session::CrateDisambiguator; +use rustc::ty::{self, ReprOptions, Ty}; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::MetadataRef; +use rustc_index::vec::IndexVec; use rustc_serialize::opaque::Encoder; -use syntax::{ast, attr}; +use rustc_target::spec::{PanicStrategy, TargetTriple}; use syntax::edition::Edition; use syntax::symbol::Symbol; +use syntax::{ast, attr}; use syntax_pos::{self, Span}; use std::marker::PhantomData; @@ -32,8 +32,7 @@ mod encoder; mod table; crate fn rustc_version() -> String { - format!("rustc {}", - option_env!("CFG_VERSION").unwrap_or("unknown version")) + format!("rustc {}", option_env!("CFG_VERSION").unwrap_or("unknown version")) } /// Metadata encoding version. @@ -46,8 +45,7 @@ const METADATA_VERSION: u8 = 5; /// This header is followed by the position of the `CrateRoot`, /// which is encoded as a 32-bit big-endian unsigned integer, /// and further followed by the rustc version string. -crate const METADATA_HEADER: &[u8; 8] = - &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION]; +crate const METADATA_HEADER: &[u8; 8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION]; /// Additional metadata for a `Lazy` where `T` may not be `Sized`, /// e.g. for `Lazy<[T]>`, this is the length (count of `T` values). @@ -106,8 +104,9 @@ impl LazyMeta for [T] { // FIXME(#59875) the `Meta` parameter only exists to dodge // invariance wrt `T` (coming from the `meta: T::Meta` field). struct Lazy::Meta> - where T: ?Sized + LazyMeta, - Meta: 'static + Copy, +where + T: ?Sized + LazyMeta, + Meta: 'static + Copy, { position: NonZeroUsize, meta: Meta, @@ -115,12 +114,8 @@ struct Lazy::Meta> } impl Lazy { - fn from_position_and_meta(position: NonZeroUsize, meta: T::Meta) -> Lazy { - Lazy { - position, - meta, - _marker: PhantomData, - } + fn from_position_and_meta(position: NonZeroUsize, meta: T::Meta) -> Lazy { + Lazy { position, meta, _marker: PhantomData } } } @@ -365,7 +360,6 @@ struct ImplData { coerce_unsized_info: Option, } - /// Describes whether the container of an associated item /// is a trait or an impl and whether, in a trait, it has /// a default, or an in impl, whether it's marked "default". @@ -380,24 +374,21 @@ enum AssocContainer { impl AssocContainer { fn with_def_id(&self, def_id: DefId) -> ty::AssocItemContainer { match *self { - AssocContainer::TraitRequired | - AssocContainer::TraitWithDefault => ty::TraitContainer(def_id), + AssocContainer::TraitRequired | AssocContainer::TraitWithDefault => { + ty::TraitContainer(def_id) + } - AssocContainer::ImplDefault | - AssocContainer::ImplFinal => ty::ImplContainer(def_id), + AssocContainer::ImplDefault | AssocContainer::ImplFinal => ty::ImplContainer(def_id), } } fn defaultness(&self) -> hir::Defaultness { match *self { - AssocContainer::TraitRequired => hir::Defaultness::Default { - has_value: false, - }, - - AssocContainer::TraitWithDefault | - AssocContainer::ImplDefault => hir::Defaultness::Default { - has_value: true, - }, + AssocContainer::TraitRequired => hir::Defaultness::Default { has_value: false }, + + AssocContainer::TraitWithDefault | AssocContainer::ImplDefault => { + hir::Defaultness::Default { has_value: true } + } AssocContainer::ImplFinal => hir::Defaultness::Final, } diff --git a/src/librustc_metadata/rmeta/table.rs b/src/librustc_metadata/rmeta/table.rs index 10122fbba1fd4..752caff754eeb 100644 --- a/src/librustc_metadata/rmeta/table.rs +++ b/src/librustc_metadata/rmeta/table.rs @@ -1,11 +1,11 @@ use crate::rmeta::*; +use log::debug; use rustc_index::vec::Idx; -use rustc_serialize::{Encodable, opaque::Encoder}; +use rustc_serialize::{opaque::Encoder, Encodable}; use std::convert::TryInto; use std::marker::PhantomData; use std::num::NonZeroUsize; -use log::debug; /// Helper trait, for encoding to, and decoding from, a fixed number of bytes. /// Used mainly for Lazy positions and lengths. @@ -107,8 +107,7 @@ impl FixedSizeEncoding for Option> { } fn write_to_bytes(self, b: &mut [u8]) { - self.map(|lazy| Lazy::::from_position(lazy.position)) - .write_to_bytes(b); + self.map(|lazy| Lazy::::from_position(lazy.position)).write_to_bytes(b); let len = self.map_or(0, |lazy| lazy.meta); let len: u32 = len.try_into().unwrap(); @@ -123,7 +122,10 @@ impl FixedSizeEncoding for Option> { /// A total of `(max_idx + 1) * as FixedSizeEncoding>::BYTE_LEN` bytes /// are used for a table, where `max_idx` is the largest index passed to /// `TableBuilder::set`. -pub(super) struct Table where Option: FixedSizeEncoding { +pub(super) struct Table +where + Option: FixedSizeEncoding, +{ _marker: PhantomData<(fn(&I), T)>, // NOTE(eddyb) this makes `Table` not implement `Sized`, but no // value of `Table` is ever created (it's always behind `Lazy`). @@ -131,7 +133,10 @@ pub(super) struct Table where Option: FixedSizeEncoding { } /// Helper for constructing a table's serialization (also see `Table`). -pub(super) struct TableBuilder where Option: FixedSizeEncoding { +pub(super) struct TableBuilder +where + Option: FixedSizeEncoding, +{ // FIXME(eddyb) use `IndexVec>::BYTE_LEN]>` instead of // `Vec`, once that starts working (i.e. lazy normalization). // Then again, that has the downside of not allowing `TableBuilder::encode` to @@ -140,16 +145,19 @@ pub(super) struct TableBuilder where Option: FixedSizeEncoding { _marker: PhantomData<(fn(&I), T)>, } -impl Default for TableBuilder where Option: FixedSizeEncoding { +impl Default for TableBuilder +where + Option: FixedSizeEncoding, +{ fn default() -> Self { - TableBuilder { - bytes: vec![], - _marker: PhantomData, - } + TableBuilder { bytes: vec![], _marker: PhantomData } } } -impl TableBuilder where Option: FixedSizeEncoding { +impl TableBuilder +where + Option: FixedSizeEncoding, +{ pub(super) fn set(&mut self, i: I, value: T) { // FIXME(eddyb) investigate more compact encodings for sparse tables. // On the PR @michaelwoerister mentioned: @@ -168,14 +176,14 @@ impl TableBuilder where Option: FixedSizeEncoding { pub(super) fn encode(&self, buf: &mut Encoder) -> Lazy> { let pos = buf.position(); buf.emit_raw_bytes(&self.bytes); - Lazy::from_position_and_meta( - NonZeroUsize::new(pos as usize).unwrap(), - self.bytes.len(), - ) + Lazy::from_position_and_meta(NonZeroUsize::new(pos as usize).unwrap(), self.bytes.len()) } } -impl LazyMeta for Table where Option: FixedSizeEncoding { +impl LazyMeta for Table +where + Option: FixedSizeEncoding, +{ type Meta = usize; fn min_size(len: usize) -> usize { @@ -183,14 +191,13 @@ impl LazyMeta for Table where Option: FixedSizeEncoding { } } -impl Lazy> where Option: FixedSizeEncoding { +impl Lazy> +where + Option: FixedSizeEncoding, +{ /// Given the metadata, extract out the value at a particular index (if any). #[inline(never)] - pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>( - &self, - metadata: M, - i: I, - ) -> Option { + pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(&self, metadata: M, i: I) -> Option { debug!("Table::lookup: index={:?} len={:?}", i, self.meta); let start = self.position.get(); diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index 2980483bfa4c7..1423ff2ed417d 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -1,15 +1,15 @@ -use crate::borrow_check::place_ext::PlaceExt; use crate::borrow_check::nll::ToRegionVid; use crate::borrow_check::path_utils::allow_two_phase_borrow; +use crate::borrow_check::place_ext::PlaceExt; use crate::dataflow::indexes::BorrowIndex; use crate::dataflow::move_paths::MoveData; use rustc::mir::traversal; -use rustc::mir::visit::{PlaceContext, Visitor, NonUseContext, MutatingUseContext}; -use rustc::mir::{self, Location, Body, Local, ReadOnlyBodyAndCache}; +use rustc::mir::visit::{MutatingUseContext, NonUseContext, PlaceContext, Visitor}; +use rustc::mir::{self, Body, Local, Location, ReadOnlyBodyAndCache}; use rustc::ty::{RegionVid, TyCtxt}; use rustc::util::nodemap::{FxHashMap, FxHashSet}; -use rustc_index::vec::IndexVec; use rustc_index::bit_set::BitSet; +use rustc_index::vec::IndexVec; use std::fmt; use std::ops::Index; @@ -84,14 +84,14 @@ impl<'tcx> fmt::Display for BorrowData<'tcx> { crate enum LocalsStateAtExit { AllAreInvalidated, - SomeAreInvalidated { has_storage_dead_or_moved: BitSet } + SomeAreInvalidated { has_storage_dead_or_moved: BitSet }, } impl LocalsStateAtExit { fn build( locals_are_invalidated_at_exit: bool, body: ReadOnlyBodyAndCache<'_, 'tcx>, - move_data: &MoveData<'tcx> + move_data: &MoveData<'tcx>, ) -> Self { struct HasStorageDead(BitSet); @@ -106,17 +106,15 @@ impl LocalsStateAtExit { if locals_are_invalidated_at_exit { LocalsStateAtExit::AllAreInvalidated } else { - let mut has_storage_dead - = HasStorageDead(BitSet::new_empty(body.local_decls.len())); + let mut has_storage_dead = HasStorageDead(BitSet::new_empty(body.local_decls.len())); has_storage_dead.visit_body(body); let mut has_storage_dead_or_moved = has_storage_dead.0; for move_out in &move_data.moves { if let Some(index) = move_data.base_local(move_out.path) { has_storage_dead_or_moved.insert(index); - } } - LocalsStateAtExit::SomeAreInvalidated{ has_storage_dead_or_moved } + LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } } } } @@ -136,8 +134,11 @@ impl<'tcx> BorrowSet<'tcx> { activation_map: Default::default(), local_map: Default::default(), pending_activations: Default::default(), - locals_state_at_exit: - LocalsStateAtExit::build(locals_are_invalidated_at_exit, body, move_data), + locals_state_at_exit: LocalsStateAtExit::build( + locals_are_invalidated_at_exit, + body, + move_data, + ), }; for (block, block_data) in traversal::preorder(&body) { @@ -154,10 +155,7 @@ impl<'tcx> BorrowSet<'tcx> { } crate fn activations_at_location(&self, location: Location) -> &[BorrowIndex] { - self.activation_map - .get(&location) - .map(|activations| &activations[..]) - .unwrap_or(&[]) + self.activation_map.get(&location).map(|activations| &activations[..]).unwrap_or(&[]) } } @@ -218,12 +216,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> { self.super_assign(assigned_place, rvalue, location) } - fn visit_local( - &mut self, - temp: &Local, - context: PlaceContext, - location: Location, - ) { + fn visit_local(&mut self, temp: &Local, context: PlaceContext, location: Location) { if !context.is_use() { return; } @@ -237,14 +230,14 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> { // Watch out: the use of TMP in the borrow itself // doesn't count as an activation. =) - if borrow_data.reserve_location == location && - context == PlaceContext::MutatingUse(MutatingUseContext::Store) + if borrow_data.reserve_location == location + && context == PlaceContext::MutatingUse(MutatingUseContext::Store) { return; } - if let TwoPhaseActivation::ActivatedAt(other_location) = - borrow_data.activation_location { + if let TwoPhaseActivation::ActivatedAt(other_location) = borrow_data.activation_location + { span_bug!( self.body.source_info(location).span, "found two uses for 2-phase borrow temporary {:?}: \ @@ -264,10 +257,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> { TwoPhaseActivation::NotActivated, "never found an activation for this borrow!", ); - self.activation_map - .entry(location) - .or_default() - .push(borrow_index); + self.activation_map.entry(location).or_default().push(borrow_index); borrow_data.activation_location = TwoPhaseActivation::ActivatedAt(location); } @@ -290,7 +280,6 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> { } impl<'a, 'tcx> GatherBorrows<'a, 'tcx> { - /// If this is a two-phase borrow, then we will record it /// as "pending" until we find the activating use. fn insert_as_pending_if_two_phase( @@ -339,10 +328,14 @@ impl<'a, 'tcx> GatherBorrows<'a, 'tcx> { // assignment. let old_value = self.pending_activations.insert(temp, borrow_index); if let Some(old_index) = old_value { - span_bug!(self.body.source_info(start_location).span, - "found already pending activation for temp: {:?} \ + span_bug!( + self.body.source_info(start_location).span, + "found already pending activation for temp: {:?} \ at borrow_index: {:?} with associated data {:?}", - temp, old_index, self.idx_vec[old_index]); + temp, + old_index, + self.idx_vec[old_index] + ); } } } diff --git a/src/librustc_mir/borrow_check/constraint_generation.rs b/src/librustc_mir/borrow_check/constraint_generation.rs index 28a631a711a87..97de201faba01 100644 --- a/src/librustc_mir/borrow_check/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/constraint_generation.rs @@ -6,16 +6,12 @@ use rustc::mir::{ Rvalue, SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UserTypeProjection, }; use rustc::ty::fold::TypeFoldable; -use rustc::ty::{self, RegionVid, Ty}; use rustc::ty::subst::SubstsRef; +use rustc::ty::{self, RegionVid, Ty}; use crate::borrow_check::{ - borrow_set::BorrowSet, - location::LocationTable, - nll::ToRegionVid, - facts::AllFacts, - region_infer::values::LivenessValues, - places_conflict, + borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, nll::ToRegionVid, + places_conflict, region_infer::values::LivenessValues, }; pub(super) fn generate_constraints<'cx, 'tcx>( @@ -80,11 +76,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { | TyContext::YieldTy(SourceInfo { span, .. }) | TyContext::UserTy(span) | TyContext::LocalDecl { source_info: SourceInfo { span, .. }, .. } => { - span_bug!( - span, - "should not be visiting outside of the CFG: {:?}", - ty_context - ); + span_bug!(span, "should not be visiting outside of the CFG: {:?}", ty_context); } TyContext::Location(location) => { self.add_regular_live_constraint(ty, location); @@ -94,11 +86,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { self.super_ty(ty); } - fn visit_statement( - &mut self, - statement: &Statement<'tcx>, - location: Location, - ) { + fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { if let Some(all_facts) = self.all_facts { let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation"); all_facts.cfg_edge.push(( @@ -108,8 +96,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { all_facts.cfg_edge.push(( self.location_table.mid_index(location), - self.location_table - .start_index(location.successor_within_block()), + self.location_table.start_index(location.successor_within_block()), )); // If there are borrows on this now dead local, we need to record them as `killed`. @@ -127,12 +114,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { self.super_statement(statement, location); } - fn visit_assign( - &mut self, - place: &Place<'tcx>, - rvalue: &Rvalue<'tcx>, - location: Location, - ) { + fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { // When we see `X = ...`, then kill borrows of // `(*X).foo` and so forth. self.record_killed_borrows_for_place(place, location); @@ -140,11 +122,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { self.super_assign(place, rvalue, location); } - fn visit_terminator( - &mut self, - terminator: &Terminator<'tcx>, - location: Location, - ) { + fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { if let Some(all_facts) = self.all_facts { let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation"); all_facts.cfg_edge.push(( @@ -157,8 +135,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> { for successor_block in successor_blocks { all_facts.cfg_edge.push(( self.location_table.mid_index(location), - self.location_table - .start_index(successor_block.start_location()), + self.location_table.start_index(successor_block.start_location()), )); } } @@ -193,17 +170,12 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { where T: TypeFoldable<'tcx>, { - debug!( - "add_regular_live_constraint(live_ty={:?}, location={:?})", - live_ty, location - ); + debug!("add_regular_live_constraint(live_ty={:?}, location={:?})", live_ty, location); - self.infcx - .tcx - .for_each_free_region(&live_ty, |live_region| { - let vid = live_region.to_region_vid(); - self.liveness_constraints.add_element(vid, location); - }); + self.infcx.tcx.for_each_free_region(&live_ty, |live_region| { + let vid = live_region.to_region_vid(); + self.liveness_constraints.add_element(vid, location); + }); } /// When recording facts for Polonius, records the borrows on the specified place @@ -219,11 +191,8 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { // of the borrows are killed: the ones whose `borrowed_place` // conflicts with the `place`. match place.as_ref() { - PlaceRef { - base: &PlaceBase::Local(local), - projection: &[], - } | - PlaceRef { + PlaceRef { base: &PlaceBase::Local(local), projection: &[] } + | PlaceRef { base: &PlaceBase::Local(local), projection: &[ProjectionElem::Deref], } => { @@ -241,17 +210,11 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> { ); } - PlaceRef { - base: &PlaceBase::Static(_), - .. - } => { + PlaceRef { base: &PlaceBase::Static(_), .. } => { // Ignore kills of static or static mut variables. } - PlaceRef { - base: &PlaceBase::Local(local), - projection: &[.., _], - } => { + PlaceRef { base: &PlaceBase::Local(local), projection: &[.., _] } => { // Kill conflicting borrows of the innermost local. debug!( "Recording `killed` facts for borrows of \ diff --git a/src/librustc_mir/borrow_check/constraints/graph.rs b/src/librustc_mir/borrow_check/constraints/graph.rs index 3e7aa67ef6c7d..1eef76e591da6 100644 --- a/src/librustc_mir/borrow_check/constraints/graph.rs +++ b/src/librustc_mir/borrow_check/constraints/graph.rs @@ -5,9 +5,9 @@ use rustc_index::vec::IndexVec; use syntax_pos::DUMMY_SP; use crate::borrow_check::{ - type_check::Locations, constraints::OutlivesConstraintIndex, - constraints::{OutlivesConstraintSet, OutlivesConstraint}, + constraints::{OutlivesConstraint, OutlivesConstraintSet}, + type_check::Locations, }; /// The construct graph organizes the constraints by their end-points. @@ -78,11 +78,7 @@ impl ConstraintGraph { /// R2` is treated as an edge `R1 -> R2`. We use this graph to /// construct SCCs for region inference but also for error /// reporting. - crate fn new( - direction: D, - set: &OutlivesConstraintSet, - num_region_vars: usize, - ) -> Self { + crate fn new(direction: D, set: &OutlivesConstraintSet, num_region_vars: usize) -> Self { let mut first_constraints = IndexVec::from_elem_n(None, num_region_vars); let mut next_constraints = IndexVec::from_elem(None, &set.outlives); @@ -94,11 +90,7 @@ impl ConstraintGraph { *head = Some(idx); } - Self { - _direction: direction, - first_constraints, - next_constraints, - } + Self { _direction: direction, first_constraints, next_constraints } } /// Given the constraint set from which this graph was built @@ -132,13 +124,7 @@ impl ConstraintGraph { } else { //otherwise, just setup the iterator as normal let first = self.first_constraints[region_sup]; - Edges { - graph: self, - constraints, - pointer: first, - next_static_idx: None, - static_region, - } + Edges { graph: self, constraints, pointer: first, next_static_idx: None, static_region } } } } @@ -160,12 +146,11 @@ impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> { Some(self.constraints[p]) } else if let Some(next_static_idx) = self.next_static_idx { - self.next_static_idx = - if next_static_idx == (self.graph.first_constraints.len() - 1) { - None - } else { - Some(next_static_idx + 1) - }; + self.next_static_idx = if next_static_idx == (self.graph.first_constraints.len() - 1) { + None + } else { + Some(next_static_idx + 1) + }; Some(OutlivesConstraint { sup: self.static_region, @@ -198,11 +183,7 @@ impl<'s, D: ConstraintGraphDirecton> RegionGraph<'s, D> { constraint_graph: &'s ConstraintGraph, static_region: RegionVid, ) -> Self { - Self { - set, - constraint_graph, - static_region, - } + Self { set, constraint_graph, static_region } } /// Given a region `R`, iterate over all regions `R1` such that @@ -237,10 +218,7 @@ impl<'s, D: ConstraintGraphDirecton> graph::WithNumNodes for RegionGraph<'s, D> } impl<'s, D: ConstraintGraphDirecton> graph::WithSuccessors for RegionGraph<'s, D> { - fn successors( - &self, - node: Self::Node, - ) -> >::Iter { + fn successors(&self, node: Self::Node) -> >::Iter { self.outgoing_regions(node) } } diff --git a/src/librustc_mir/borrow_check/constraints/mod.rs b/src/librustc_mir/borrow_check/constraints/mod.rs index 96982b604c0be..48defecd28cb0 100644 --- a/src/librustc_mir/borrow_check/constraints/mod.rs +++ b/src/librustc_mir/borrow_check/constraints/mod.rs @@ -93,11 +93,7 @@ pub struct OutlivesConstraint { impl fmt::Debug for OutlivesConstraint { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - formatter, - "({:?}: {:?}) due to {:?}", - self.sup, self.sub, self.locations - ) + write!(formatter, "({:?}: {:?}) due to {:?}", self.sup, self.sub, self.locations) } } diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 1cd43d4fdd411..79221329ead48 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -6,28 +6,25 @@ use rustc::mir::{ FakeReadCause, Local, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceBase, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm, }; -use rustc::ty::{self, Ty}; use rustc::traits::error_reporting::suggest_constraining_type_param; +use rustc::ty::{self, Ty}; use rustc_data_structures::fx::FxHashSet; -use rustc_index::vec::Idx; use rustc_errors::{Applicability, DiagnosticBuilder}; -use syntax_pos::Span; +use rustc_index::vec::Idx; use syntax::source_map::DesugaringKind; +use syntax_pos::Span; use crate::dataflow::drop_flag_effects; -use crate::dataflow::indexes::{MovePathIndex, MoveOutIndex}; +use crate::dataflow::indexes::{MoveOutIndex, MovePathIndex}; use crate::util::borrowck_errors; use crate::borrow_check::{ - prefixes::IsPrefixOf, - WriteKind, - borrow_set::BorrowData, - MirBorrowckCtxt, InitializationRequiringAction, PrefixSet + borrow_set::BorrowData, prefixes::IsPrefixOf, InitializationRequiringAction, MirBorrowckCtxt, + PrefixSet, WriteKind, }; use super::{ - IncludingDowncast, UseSpans, RegionName, RegionNameSource, - explain_borrow::BorrowExplanation, + explain_borrow::BorrowExplanation, IncludingDowncast, RegionName, RegionNameSource, UseSpans, }; #[derive(Debug)] @@ -38,7 +35,7 @@ struct MoveSite { /// `true` if we traversed a back edge while walking from the point /// of error to the move site. - traversed_back_edge: bool + traversed_back_edge: bool, } /// Which case a StorageDeadOrDrop is for. @@ -63,19 +60,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { location, desired_action, moved_place, used_place, span, mpi ); - let use_spans = self.move_spans(moved_place, location) - .or_else(|| self.borrow_spans(span, location)); + let use_spans = + self.move_spans(moved_place, location).or_else(|| self.borrow_spans(span, location)); let span = use_spans.args_or_use(); let move_site_vec = self.get_moved_indexes(location, mpi); - debug!( - "report_use_of_moved_or_uninitialized: move_site_vec={:?}", - move_site_vec - ); - let move_out_indices: Vec<_> = move_site_vec - .iter() - .map(|move_site| move_site.moi) - .collect(); + debug!("report_use_of_moved_or_uninitialized: move_site_vec={:?}", move_site_vec); + let move_out_indices: Vec<_> = + move_site_vec.iter().map(|move_site| move_site.moi).collect(); if move_out_indices.is_empty() { let root_place = PlaceRef { projection: &[], ..used_place }; @@ -88,15 +80,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return; } - let item_msg = match self.describe_place_with_options(used_place, - IncludingDowncast(true)) { - Some(name) => format!("`{}`", name), - None => "value".to_owned(), - }; + let item_msg = + match self.describe_place_with_options(used_place, IncludingDowncast(true)) { + Some(name) => format!("`{}`", name), + None => "value".to_owned(), + }; let mut err = self.cannot_act_on_uninitialized_variable( span, desired_action.as_noun(), - &self.describe_place_with_options(moved_place, IncludingDowncast(true)) + &self + .describe_place_with_options(moved_place, IncludingDowncast(true)) .unwrap_or_else(|| "_".to_owned()), ); err.span_label(span, format!("use of possibly-uninitialized {}", item_msg)); @@ -109,9 +102,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.buffer(&mut self.errors_buffer); } else { if let Some((reported_place, _)) = self.move_error_reported.get(&move_out_indices) { - if self.prefixes(*reported_place, PrefixSet::All) - .any(|p| p == used_place) - { + if self.prefixes(*reported_place, PrefixSet::All).any(|p| p == used_place) { debug!( "report_use_of_moved_or_uninitialized place: error suppressed \ mois={:?}", @@ -130,18 +121,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.describe_place_with_options(moved_place, IncludingDowncast(true)), ); - self.add_moved_or_invoked_closure_note( - location, - used_place, - &mut err, - ); + self.add_moved_or_invoked_closure_note(location, used_place, &mut err); let mut is_loop_move = false; let is_partial_move = move_site_vec.iter().any(|move_site| { let move_out = self.move_data.moves[(*move_site).moi]; let moved_place = &self.move_data.move_paths[move_out.path].place; - used_place != moved_place.as_ref() - && used_place.is_prefix_of(moved_place.as_ref()) + used_place != moved_place.as_ref() && used_place.is_prefix_of(moved_place.as_ref()) }); for move_site in &move_site_vec { let move_out = self.move_data.moves[(*move_site).moi]; @@ -150,11 +136,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let move_spans = self.move_spans(moved_place.as_ref(), move_out.source); let move_span = move_spans.args_or_use(); - let move_msg = if move_spans.for_closure() { - " into closure" - } else { - "" - }; + let move_msg = if move_spans.for_closure() { " into closure" } else { "" }; if span == move_span { err.span_label( @@ -165,10 +147,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else if move_site.traversed_back_edge { err.span_label( move_span, - format!( - "value moved{} here, in previous iteration of loop", - move_msg - ), + format!("value moved{} here, in previous iteration of loop", move_msg), ); } else { err.span_label(move_span, format!("value moved{} here", move_msg)); @@ -206,12 +185,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } - let ty = Place::ty_from( - used_place.base, - used_place.projection, - *self.body, - self.infcx.tcx - ).ty; + let ty = + Place::ty_from(used_place.base, used_place.projection, *self.body, self.infcx.tcx) + .ty; let needs_note = match ty.kind { ty::Closure(id, _) => { let tables = self.infcx.tcx.typeck_tables_of(id); @@ -238,7 +214,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let generics = tcx.generics_of(self.mir_def_id); let param = generics.type_param(¶m_ty, tcx); if let Some(generics) = - tcx.hir().get_generics(tcx.closure_base_def_id(self.mir_def_id)) { + tcx.hir().get_generics(tcx.closure_base_def_id(self.mir_def_id)) + { suggest_constraining_type_param( generics, &mut err, @@ -255,16 +232,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else { None }; - self.note_type_does_not_implement_copy( - &mut err, - ¬e_msg, - ty, - span, - ); + self.note_type_does_not_implement_copy(&mut err, ¬e_msg, ty, span); } - if let Some((_, mut old_err)) = self.move_error_reported - .insert(move_out_indices, (used_place, err)) + if let Some((_, mut old_err)) = + self.move_error_reported.insert(move_out_indices, (used_place, err)) { // Cancel the old error so it doesn't ICE. old_err.cancel(); @@ -306,26 +278,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow_spans.var_span_label( &mut err, - format!("borrow occurs due to use{}", borrow_spans.describe()) + format!("borrow occurs due to use{}", borrow_spans.describe()), ); - move_spans.var_span_label( - &mut err, - format!("move occurs due to use{}", move_spans.describe()) - ); + move_spans + .var_span_label(&mut err, format!("move occurs due to use{}", move_spans.describe())); - self.explain_why_borrow_contains_point( - location, - borrow, - None, - ).add_explanation_to_diagnostic( - self.infcx.tcx, - &self.body, - &self.local_names, - &mut err, - "", - Some(borrow_span), - ); + self.explain_why_borrow_contains_point(location, borrow, None) + .add_explanation_to_diagnostic( + self.infcx.tcx, + &self.body, + &self.local_names, + &mut err, + "", + Some(borrow_span), + ); err.buffer(&mut self.errors_buffer); } @@ -347,14 +314,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { span, &self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()), borrow_span, - &self.describe_place(borrow.borrowed_place.as_ref()) - .unwrap_or_else(|| "_".to_owned()), + &self.describe_place(borrow.borrowed_place.as_ref()).unwrap_or_else(|| "_".to_owned()), ); borrow_spans.var_span_label(&mut err, { let place = &borrow.borrowed_place; - let desc_place = - self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()); + let desc_place = self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()); format!("borrow occurs due to use of `{}`{}", desc_place, borrow_spans.describe()) }); @@ -394,18 +359,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.describe_place_for_conflicting_borrow(place, &issued_borrow.borrowed_place); let explanation = self.explain_why_borrow_contains_point(location, issued_borrow, None); - let second_borrow_desc = if explanation.is_explained() { - "second " - } else { - "" - }; + let second_borrow_desc = if explanation.is_explained() { "second " } else { "" }; // FIXME: supply non-"" `opt_via` when appropriate let first_borrow_desc; - let mut err = match ( - gen_borrow_kind, - issued_borrow.kind, - ) { + let mut err = match (gen_borrow_kind, issued_borrow.kind) { (BorrowKind::Shared, BorrowKind::Mut { .. }) => { first_borrow_desc = "mutable "; self.cannot_reborrow_already_borrowed( @@ -449,19 +407,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { (BorrowKind::Unique, BorrowKind::Unique) => { first_borrow_desc = "first "; - self.cannot_uniquely_borrow_by_two_closures( - span, - &desc_place, - issued_span, - None, - ) + self.cannot_uniquely_borrow_by_two_closures(span, &desc_place, issued_span, None) } (BorrowKind::Mut { .. }, BorrowKind::Shallow) | (BorrowKind::Unique, BorrowKind::Shallow) => { - if let Some(immutable_section_description) = self.classify_immutable_section( - &issued_borrow.assigned_place, - ) { + if let Some(immutable_section_description) = + self.classify_immutable_section(&issued_borrow.assigned_place) + { let mut err = self.cannot_mutate_in_immutable_section( span, issued_span, @@ -507,7 +460,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "", None, ) - }, + } (BorrowKind::Shared, BorrowKind::Unique) => { first_borrow_desc = "first "; @@ -554,8 +507,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } else { let borrow_place = &issued_borrow.borrowed_place; - let borrow_place_desc = self.describe_place(borrow_place.as_ref()) - .unwrap_or_else(|| "_".to_owned()); + let borrow_place_desc = + self.describe_place(borrow_place.as_ref()).unwrap_or_else(|| "_".to_owned()); issued_spans.var_span_label( &mut err, format!( @@ -625,12 +578,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Define a small closure that we can use to check if the type of a place // is a union. let union_ty = |place_base, place_projection| { - let ty = Place::ty_from( - place_base, - place_projection, - *self.body, - self.infcx.tcx - ).ty; + let ty = Place::ty_from(place_base, place_projection, *self.body, self.infcx.tcx).ty; ty.ty_adt_def().filter(|adt| adt.is_union()).map(|_| ty) }; let describe_place = |place| self.describe_place(place).unwrap_or_else(|| "_".to_owned()); @@ -649,10 +597,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // field access to a union. If we find that, then we will keep the place of the // union being accessed and the field that was being accessed so we can check the // second borrowed place for the same union and a access to a different field. - let Place { - base, - projection, - } = first_borrowed_place; + let Place { base, projection } = first_borrowed_place; let mut cursor = projection.as_ref(); while let [proj_base @ .., elem] = cursor { @@ -660,12 +605,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { match elem { ProjectionElem::Field(field, _) if union_ty(base, proj_base).is_some() => { - return Some((PlaceRef { - base: base, - projection: proj_base, - }, field)); - }, - _ => {}, + return Some((PlaceRef { base: base, projection: proj_base }, field)); + } + _ => {} } } None @@ -673,10 +615,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .and_then(|(target_base, target_field)| { // With the place of a union and a field access into it, we traverse the second // borrowed place and look for a access to a different field of the same union. - let Place { - base, - projection, - } = second_borrowed_place; + let Place { base, projection } = second_borrowed_place; let mut cursor = projection.as_ref(); while let [proj_base @ .., elem] = cursor { @@ -686,12 +625,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let Some(union_ty) = union_ty(base, proj_base) { if field != target_field && base == target_base.base - && proj_base == target_base.projection { + && proj_base == target_base.projection + { // FIXME when we avoid clone reuse describe_place closure - let describe_base_place = self.describe_place(PlaceRef { - base: base, - projection: proj_base, - }).unwrap_or_else(|| "_".to_owned()); + let describe_base_place = self + .describe_place(PlaceRef { base: base, projection: proj_base }) + .unwrap_or_else(|| "_".to_owned()); return Some(( describe_base_place, @@ -740,9 +679,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); let drop_span = place_span.1; - let root_place = self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All) - .last() - .unwrap(); + let root_place = + self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap(); let borrow_spans = self.retrieve_borrow_spans(borrow); let borrow_span = borrow_spans.var_or_use(); @@ -755,12 +693,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let root_place_projection = self.infcx.tcx.intern_place_elems(root_place.projection); - if self.access_place_error_reported - .contains(&(Place { - base: root_place.base.clone(), - projection: root_place_projection, - }, borrow_span)) - { + if self.access_place_error_reported.contains(&( + Place { base: root_place.base.clone(), projection: root_place_projection }, + borrow_span, + )) { debug!( "suppressing access_place error when borrow doesn't live long enough for {:?}", borrow_span @@ -768,18 +704,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return; } - self.access_place_error_reported - .insert((Place { - base: root_place.base.clone(), - projection: root_place_projection, - }, borrow_span)); + self.access_place_error_reported.insert(( + Place { base: root_place.base.clone(), projection: root_place_projection }, + borrow_span, + )); if let PlaceBase::Local(local) = borrow.borrowed_place.base { if self.body.local_decls[local].is_ref_to_thread_local() { - let err = self.report_thread_local_value_does_not_live_long_enough( - drop_span, - borrow_span, - ); + let err = self + .report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span); err.buffer(&mut self.errors_buffer); return; } @@ -807,8 +740,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { debug!( "report_borrowed_value_does_not_live_long_enough(place_desc: {:?}, explanation: {:?})", - place_desc, - explanation + place_desc, explanation ); let err = match (place_desc, explanation) { // If the outlives constraint comes from inside the closure, @@ -856,7 +788,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { span, .. }, - ) if borrow_spans.for_generator() => self.report_escaping_closure_capture( borrow_spans, borrow_span, @@ -870,10 +801,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { BorrowExplanation::MustBeValidFor { category: ConstraintCategory::Assignment, from_closure: false, - region_name: RegionName { - source: RegionNameSource::AnonRegionFromUpvar(upvar_span, ref upvar_name), - .. - }, + region_name: + RegionName { + source: + RegionNameSource::AnonRegionFromUpvar(upvar_span, ref upvar_name), + .. + }, span, .. }, @@ -922,7 +855,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ref opt_place_desc, from_closure: false, .. - } = explanation { + } = explanation + { if let Some(diag) = self.try_report_cannot_return_reference_to_local( borrow, borrow_span, @@ -934,10 +868,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - let mut err = self.path_does_not_live_long_enough( - borrow_span, - &format!("`{}`", name), - ); + let mut err = self.path_does_not_live_long_enough(borrow_span, &format!("`{}`", name)); if let Some(annotation) = self.annotate_argument_and_return_for_borrow(borrow) { let region_name = annotation.emit(self, &mut err); @@ -985,24 +916,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } else { err.span_label(borrow_span, "borrowed value does not live long enough"); - err.span_label( - drop_span, - format!("`{}` dropped here while still borrowed", name), - ); + err.span_label(drop_span, format!("`{}` dropped here while still borrowed", name)); - let within = if borrow_spans.for_generator() { - " by generator" - } else { - "" - }; + let within = if borrow_spans.for_generator() { " by generator" } else { "" }; - borrow_spans.args_span_label( - &mut err, - format!("value captured here{}", within), - ); + borrow_spans.args_span_label(&mut err, format!("value captured here{}", within)); explanation.add_explanation_to_diagnostic( - self.infcx.tcx, &self.body, &self.local_names, &mut err, "", None); + self.infcx.tcx, + &self.body, + &self.local_names, + &mut err, + "", + None, + ); } err @@ -1111,12 +1038,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { location, borrow, drop_span, proper_span ); - if let BorrowExplanation::MustBeValidFor { - category, - span, - from_closure: false, - .. - } = explanation { + if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } = + explanation + { if let Some(diag) = self.try_report_cannot_return_reference_to_local( borrow, proper_span, @@ -1129,14 +1053,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } let mut err = self.temporary_value_borrowed_for_too_long(proper_span); - err.span_label( - proper_span, - "creates a temporary which is freed while still in use", - ); - err.span_label( - drop_span, - "temporary value is freed at the end of this statement", - ); + err.span_label(proper_span, "creates a temporary which is freed while still in use"); + err.span_label(drop_span, "temporary value is freed at the end of this statement"); match explanation { BorrowExplanation::UsedLater(..) @@ -1156,16 +1074,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { None, ); - let within = if borrow_spans.for_generator() { - " by generator" - } else { - "" - }; + let within = if borrow_spans.for_generator() { " by generator" } else { "" }; - borrow_spans.args_span_label( - &mut err, - format!("value captured here{}", within), - ); + borrow_spans.args_span_label(&mut err, format!("value captured here{}", within)); err } @@ -1185,27 +1096,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }; // FIXME use a better heuristic than Spans - let reference_desc - = if return_span == self.body.source_info(borrow.reserve_location).span { - "reference to" - } else { - "value referencing" - }; + let reference_desc = if return_span == self.body.source_info(borrow.reserve_location).span { + "reference to" + } else { + "value referencing" + }; let (place_desc, note) = if let Some(place_desc) = opt_place_desc { let local_kind = if let Some(local) = borrow.borrowed_place.as_local() { match self.body.local_kind(local) { - LocalKind::ReturnPointer - | LocalKind::Temp => bug!("temporary or return pointer with a name"), + LocalKind::ReturnPointer | LocalKind::Temp => { + bug!("temporary or return pointer with a name") + } LocalKind::Var => "local variable ", - LocalKind::Arg - if !self.upvars.is_empty() - && local == Local::new(1) => { + LocalKind::Arg if !self.upvars.is_empty() && local == Local::new(1) => { "variable captured by `move` " } - LocalKind::Arg => { - "function parameter " - } + LocalKind::Arg => "function parameter ", } } else { "local data " @@ -1215,31 +1122,25 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { format!("`{}` is borrowed here", place_desc), ) } else { - let root_place = self.prefixes(borrow.borrowed_place.as_ref(), - PrefixSet::All) - .last() - .unwrap(); - let local = if let PlaceRef { - base: PlaceBase::Local(local), - projection: [], - } = root_place { - local - } else { - bug!("try_report_cannot_return_reference_to_local: not a local") - }; + let root_place = + self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap(); + let local = + if let PlaceRef { base: PlaceBase::Local(local), projection: [] } = root_place { + local + } else { + bug!("try_report_cannot_return_reference_to_local: not a local") + }; match self.body.local_kind(*local) { - LocalKind::ReturnPointer | LocalKind::Temp => ( - "temporary value".to_string(), - "temporary value created here".to_string(), - ), + LocalKind::ReturnPointer | LocalKind::Temp => { + ("temporary value".to_string(), "temporary value created here".to_string()) + } LocalKind::Arg => ( "function parameter".to_string(), "function parameter borrowed here".to_string(), ), - LocalKind::Var => ( - "local binding".to_string(), - "local binding introduced here".to_string(), - ), + LocalKind::Var => { + ("local binding".to_string(), "local binding introduced here".to_string()) + } } }; @@ -1268,11 +1169,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) -> DiagnosticBuilder<'cx> { let tcx = self.infcx.tcx; let args_span = use_span.args_or_use(); - let mut err = self.cannot_capture_in_long_lived_closure( - args_span, - captured_var, - var_span, - ); + let mut err = self.cannot_capture_in_long_lived_closure(args_span, captured_var, var_span); let suggestion = match tcx.sess.source_map().span_to_snippet(args_span) { Ok(mut string) => { @@ -1284,8 +1181,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { string.insert_str(0, "move "); }; string - }, - Err(_) => "move || ".to_string() + } + Err(_) => "move || ".to_string(), }; let kind = match use_span.generator_kind() { Some(generator_kind) => match generator_kind { @@ -1295,7 +1192,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { _ => bug!("async block/closure expected, but async funtion found."), }, GeneratorKind::Gen => "generator", - } + }, None => "closure", }; err.span_suggestion( @@ -1303,8 +1200,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &format!( "to force the {} to take ownership of {} (and any \ other referenced variables), use the `move` keyword", - kind, - captured_var + kind, captured_var ), suggestion, Applicability::MachineApplicable, @@ -1317,8 +1213,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fr_name.highlight_region_name(&mut err); format!("function requires argument type to outlive `{}`", fr_name) } - _ => bug!("report_escaping_closure_capture called with unexpected constraint \ - category: `{:?}`", category), + _ => bug!( + "report_escaping_closure_capture called with unexpected constraint \ + category: `{:?}`", + category + ), }; err.span_note(constraint_span, &msg); err @@ -1346,27 +1245,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "function" }; - let mut err = borrowck_errors::borrowed_data_escapes_closure( - tcx, - escape_span, - escapes_from, - ); + let mut err = + borrowck_errors::borrowed_data_escapes_closure(tcx, escape_span, escapes_from); err.span_label( upvar_span, - format!( - "`{}` is declared here, outside of the {} body", - upvar_name, escapes_from - ), + format!("`{}` is declared here, outside of the {} body", upvar_name, escapes_from), ); - err.span_label( - borrow_span, - format!( - "borrow is only valid in the {} body", - escapes_from - ), - ); + err.span_label(borrow_span, format!("borrow is only valid in the {} body", escapes_from)); if let Some(name) = name { err.span_label( @@ -1404,10 +1291,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } // check for moves - let stmt_kind = self.body[location.block] - .statements - .get(location.statement_index) - .map(|s| &s.kind); + let stmt_kind = + self.body[location.block].statements.get(location.statement_index).map(|s| &s.kind); if let Some(StatementKind::StorageDead(..)) = stmt_kind { // this analysis only tries to find moves explicitly // written by the user, so we ignore the move-outs @@ -1429,10 +1314,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { debug!("report_use_of_moved_or_uninitialized: moi={:?}", moi); if mpis.contains(&self.move_data.moves[*moi].path) { debug!("report_use_of_moved_or_uninitialized: found"); - result.push(MoveSite { - moi: *moi, - traversed_back_edge: is_back_edge, - }); + result.push(MoveSite { moi: *moi, traversed_back_edge: is_back_edge }); // Strictly speaking, we could continue our DFS here. There may be // other moves that can reach the point of error. But it is kind of @@ -1516,21 +1398,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()), ); - loan_spans.var_span_label( + loan_spans + .var_span_label(&mut err, format!("borrow occurs due to use{}", loan_spans.describe())); + + self.explain_why_borrow_contains_point(location, loan, None).add_explanation_to_diagnostic( + self.infcx.tcx, + &self.body, + &self.local_names, &mut err, - format!("borrow occurs due to use{}", loan_spans.describe()), + "", + None, ); - self.explain_why_borrow_contains_point(location, loan, None) - .add_explanation_to_diagnostic( - self.infcx.tcx, - &self.body, - &self.local_names, - &mut err, - "", - None, - ); - err.buffer(&mut self.errors_buffer); } @@ -1560,25 +1439,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // PATTERN;) then make the error refer to that local, rather than the // place being assigned later. let (place_description, assigned_span) = match local_decl { - Some(LocalDecl { - local_info: LocalInfo::User(ClearCrossCrate::Clear), - .. - }) - | Some(LocalDecl { - local_info: LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm { - opt_match_place: None, - .. - }))), - .. - }) + Some(LocalDecl { local_info: LocalInfo::User(ClearCrossCrate::Clear), .. }) | Some(LocalDecl { - local_info: LocalInfo::StaticRef { .. }, - .. - }) - | Some(LocalDecl { - local_info: LocalInfo::Other, + local_info: + LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm { + opt_match_place: None, + .. + }))), .. }) + | Some(LocalDecl { local_info: LocalInfo::StaticRef { .. }, .. }) + | Some(LocalDecl { local_info: LocalInfo::Other, .. }) | None => (self.describe_place(place.as_ref()), assigned_span), Some(decl) => (self.describe_place(err_place.as_ref()), decl.source_info.span), }; @@ -1621,9 +1492,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn classify_drop_access_kind(&self, place: PlaceRef<'cx, 'tcx>) -> StorageDeadOrDrop<'tcx> { let tcx = self.infcx.tcx; match place.projection { - [] => { - StorageDeadOrDrop::LocalStorageDead - } + [] => StorageDeadOrDrop::LocalStorageDead, [proj_base @ .., elem] => { // FIXME(spastorino) make this iterate let base_access = self.classify_drop_access_kind(PlaceRef { @@ -1635,12 +1504,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { StorageDeadOrDrop::LocalStorageDead | StorageDeadOrDrop::BoxedStorageDead => { assert!( - Place::ty_from( - &place.base, - proj_base, - *self.body, - tcx - ).ty.is_box(), + Place::ty_from(&place.base, proj_base, *self.body, tcx).ty.is_box(), "Drop of value behind a reference or raw pointer" ); StorageDeadOrDrop::BoxedStorageDead @@ -1648,12 +1512,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { StorageDeadOrDrop::Destructor(_) => base_access, }, ProjectionElem::Field(..) | ProjectionElem::Downcast(..) => { - let base_ty = Place::ty_from( - &place.base, - proj_base, - *self.body, - tcx - ).ty; + let base_ty = Place::ty_from(&place.base, proj_base, *self.body, tcx).ty; match base_ty.kind { ty::Adt(def, _) if def.has_dtor(tcx) => { // Report the outermost adt with a destructor @@ -1687,10 +1546,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'_, 'tcx> { fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) { match statement { - Statement { - kind: StatementKind::FakeRead(cause, box ref place), - .. - } if *place == *self.place => { + Statement { kind: StatementKind::FakeRead(cause, box ref place), .. } + if *place == *self.place => + { self.cause = Some(*cause); } _ => (), @@ -1720,10 +1578,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else { let ty = self.infcx.tcx.type_of(self.mir_def_id); match ty.kind { - ty::FnDef(_, _) | ty::FnPtr(_) => self.annotate_fn_sig( - self.mir_def_id, - self.infcx.tcx.fn_sig(self.mir_def_id), - ), + ty::FnDef(_, _) | ty::FnPtr(_) => self + .annotate_fn_sig(self.mir_def_id, self.infcx.tcx.fn_sig(self.mir_def_id)), _ => None, } } @@ -1736,17 +1592,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // place. If it was, we can add annotations about the function's return type and arguments // and it'll make sense. let location = borrow.reserve_location; - debug!( - "annotate_argument_and_return_for_borrow: location={:?}", - location - ); - if let Some(&Statement { kind: StatementKind::Assign(box(ref reservation, _)), ..}) - = &self.body[location.block].statements.get(location.statement_index) + debug!("annotate_argument_and_return_for_borrow: location={:?}", location); + if let Some(&Statement { kind: StatementKind::Assign(box (ref reservation, _)), .. }) = + &self.body[location.block].statements.get(location.statement_index) { - debug!( - "annotate_argument_and_return_for_borrow: reservation={:?}", - reservation - ); + debug!("annotate_argument_and_return_for_borrow: reservation={:?}", reservation); // Check that the initial assignment of the reserve location is into a temporary. let mut target = match reservation.as_local() { Some(local) if self.body.local_kind(local) == LocalKind::Temp => local, @@ -1756,13 +1606,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Next, look through the rest of the block, checking if we are assigning the // `target` (that is, the place that contains our borrow) to anything. let mut annotated_closure = None; - for stmt in &self.body[location.block].statements[location.statement_index + 1..] - { + for stmt in &self.body[location.block].statements[location.statement_index + 1..] { debug!( "annotate_argument_and_return_for_borrow: target={:?} stmt={:?}", target, stmt ); - if let StatementKind::Assign(box(place, rvalue)) = &stmt.kind { + if let StatementKind::Assign(box (place, rvalue)) = &stmt.kind { if let Some(assigned_to) = place.as_local() { debug!( "annotate_argument_and_return_for_borrow: assigned_to={:?} \ @@ -1887,11 +1736,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "annotate_argument_and_return_for_borrow: target={:?} terminator={:?}", target, terminator ); - if let TerminatorKind::Call { - destination: Some((place, _)), - args, - .. - } = &terminator.kind + if let TerminatorKind::Call { destination: Some((place, _)), args, .. } = + &terminator.kind { if let Some(assigned_to) = place.as_local() { debug!( @@ -2089,10 +1935,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { diag: &mut DiagnosticBuilder<'_>, ) -> String { match self { - AnnotatedBorrowFnSignature::Closure { - argument_ty, - argument_span, - } => { + AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => { diag.span_label( *argument_span, format!("has type `{}`", cx.get_name_for_ty(argument_ty, 0)), @@ -2130,21 +1973,14 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { cx.get_region_name_for_ty(return_ty, 0) } - AnnotatedBorrowFnSignature::NamedFunction { - arguments, - return_ty, - return_span, - } => { + AnnotatedBorrowFnSignature::NamedFunction { arguments, return_ty, return_span } => { // Region of return type and arguments checked to be the same earlier. let region_name = cx.get_region_name_for_ty(return_ty, 0); for (_, argument_span) in arguments { diag.span_label(*argument_span, format!("has lifetime `{}`", region_name)); } - diag.span_label( - *return_span, - format!("also has lifetime `{}`", region_name,), - ); + diag.span_label(*return_span, format!("also has lifetime `{}`", region_name,)); diag.help(&format!( "use data from the highlighted arguments which match the `{}` lifetime of \ diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs index a463d2cb2990b..04f025fcbead9 100644 --- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs +++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs @@ -3,25 +3,23 @@ use std::collections::VecDeque; use rustc::mir::{ - CastKind, ConstraintCategory, FakeReadCause, Local, Location, Body, Operand, Place, Rvalue, + Body, CastKind, ConstraintCategory, FakeReadCause, Local, Location, Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind, }; +use rustc::ty::adjustment::PointerCast; use rustc::ty::{self, TyCtxt}; -use rustc::ty::adjustment::{PointerCast}; -use rustc_index::vec::IndexVec; use rustc_data_structures::fx::FxHashSet; use rustc_errors::DiagnosticBuilder; -use syntax_pos::Span; +use rustc_index::vec::IndexVec; use syntax_pos::symbol::Symbol; +use syntax_pos::Span; use crate::borrow_check::{ - borrow_set::BorrowData, - region_infer::Cause, - nll::ConstraintDescription, - MirBorrowckCtxt, WriteKind, + borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt, + WriteKind, }; -use super::{UseSpans, find_use, RegionName}; +use super::{find_use, RegionName, UseSpans}; #[derive(Debug)] pub(in crate::borrow_check) enum BorrowExplanation { @@ -106,10 +104,9 @@ impl BorrowExplanation { let (dtor_desc, type_desc) = match local_decl.ty.kind { // If type is an ADT that implements Drop, then // simplify output by reporting just the ADT name. - ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => ( - "`Drop` code", - format!("type `{}`", tcx.def_path_str(adt.did)), - ), + ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => { + ("`Drop` code", format!("type `{}`", tcx.def_path_str(adt.did))) + } // Otherwise, just report the whole type (and use // the intentionally fuzzy phrase "destructor") @@ -245,16 +242,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tcx = self.infcx.tcx; let borrow_region_vid = borrow.region; - debug!( - "explain_why_borrow_contains_point: borrow_region_vid={:?}", - borrow_region_vid - ); + debug!("explain_why_borrow_contains_point: borrow_region_vid={:?}", borrow_region_vid); let region_sub = regioncx.find_sub_region_live_at(borrow_region_vid, location); - debug!( - "explain_why_borrow_contains_point: region_sub={:?}", - region_sub - ); + debug!("explain_why_borrow_contains_point: region_sub={:?}", region_sub); match find_use::find(body, regioncx, tcx, region_sub, location) { Some(Cause::LiveVar(local, location)) => { @@ -281,8 +272,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if self.local_names[local].is_some() { if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place { if let Some(borrowed_local) = place.as_local() { - if self.local_names[borrowed_local].is_some() - && local != borrowed_local + if self.local_names[borrowed_local].is_some() && local != borrowed_local { should_note_order = true; } @@ -310,8 +300,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { region, ); if let Some(region_name) = region_name { - let opt_place_desc = - self.describe_place(borrow.borrowed_place.as_ref()); + let opt_place_desc = self.describe_place(borrow.borrowed_place.as_ref()); BorrowExplanation::MustBeValidFor { category, from_closure, @@ -320,13 +309,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { opt_place_desc, } } else { - debug!("explain_why_borrow_contains_point: \ - Could not generate a region name"); + debug!( + "explain_why_borrow_contains_point: \ + Could not generate a region name" + ); BorrowExplanation::Unexplained } } else { - debug!("explain_why_borrow_contains_point: \ - Could not generate an error region vid"); + debug!( + "explain_why_borrow_contains_point: \ + Could not generate an error region vid" + ); BorrowExplanation::Unexplained } } @@ -341,9 +334,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { use_location: Location, ) -> bool { let back_edge = self.reach_through_backedge(borrow_location, use_location); - back_edge.map_or(false, |back_edge| { - self.can_reach_head_of_loop(use_location, back_edge) - }) + back_edge.map_or(false, |back_edge| self.can_reach_head_of_loop(use_location, back_edge)) } /// Returns the outmost back edge if `from` location can reach `to` location passing through @@ -381,10 +372,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { block .terminator() .successors() - .map(|bb| Location { - statement_index: 0, - block: *bb, - }) + .map(|bb| Location { statement_index: 0, block: *bb }) .filter(|s| visited_locations.insert(*s)) .map(|s| { if self.is_back_edge(location, s) { @@ -443,10 +431,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } else { for bb in block.terminator().successors() { - let successor = Location { - statement_index: 0, - block: *bb, - }; + let successor = Location { statement_index: 0, block: *bb }; if !visited_locations.contains(&successor) && self.find_loop_head_dfs(successor, loop_head, visited_locations) @@ -490,17 +475,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else if self.was_captured_by_trait_object(borrow) { LaterUseKind::TraitCapture } else if location.statement_index == block.statements.len() { - if let TerminatorKind::Call { - ref func, - from_hir_call: true, - .. - } = block.terminator().kind + if let TerminatorKind::Call { ref func, from_hir_call: true, .. } = + block.terminator().kind { // Just point to the function, to reduce the chance of overlapping spans. let function_span = match func { Operand::Constant(c) => c.span, - Operand::Copy(place) | - Operand::Move(place) => { + Operand::Copy(place) | Operand::Move(place) => { if let Some(l) = place.as_local() { let local_decl = &self.body.local_decls[l]; if self.local_names[l].is_none() { @@ -534,19 +515,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let location = borrow.reserve_location; let block = &self.body[location.block]; let stmt = block.statements.get(location.statement_index); - debug!( - "was_captured_by_trait_object: location={:?} stmt={:?}", - location, stmt - ); + debug!("was_captured_by_trait_object: location={:?} stmt={:?}", location, stmt); // We make a `queue` vector that has the locations we want to visit. As of writing, this // will only ever have one item at any given time, but by using a vector, we can pop from // it which simplifies the termination logic. let mut queue = vec![location]; let mut target = if let Some(&Statement { - kind: StatementKind::Assign(box(ref place, _)), + kind: StatementKind::Assign(box (ref place, _)), .. - }) = stmt { + }) = stmt + { if let Some(local) = place.as_local() { local } else { @@ -556,10 +535,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return false; }; - debug!( - "was_captured_by_trait: target={:?} queue={:?}", - target, queue - ); + debug!("was_captured_by_trait: target={:?} queue={:?}", target, queue); while let Some(current_location) = queue.pop() { debug!("was_captured_by_trait: target={:?}", target); let block = &self.body[current_location.block]; @@ -570,7 +546,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { debug!("was_captured_by_trait_object: stmt={:?}", stmt); // The only kind of statement that we care about is assignments... - if let StatementKind::Assign(box(place, rvalue)) = &stmt.kind { + if let StatementKind::Assign(box (place, rvalue)) = &stmt.kind { let into = match place.local_or_deref_local() { Some(into) => into, None => { @@ -584,8 +560,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // If we see a use, we should check whether it is our data, and if so // update the place that we're looking for to that new place. Rvalue::Use(operand) => match operand { - Operand::Copy(place) - | Operand::Move(place) => { + Operand::Copy(place) | Operand::Move(place) => { if let Some(from) = place.as_local() { if from == target { target = into; @@ -596,31 +571,32 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }, // If we see a unsized cast, then if it is our data we should check // whether it is being cast to a trait object. - Rvalue::Cast( - CastKind::Pointer(PointerCast::Unsize), operand, ty - ) => match operand { - Operand::Copy(place) - | Operand::Move(place) => { - if let Some(from) = place.as_local() { - if from == target { - debug!("was_captured_by_trait_object: ty={:?}", ty); - // Check the type for a trait object. - return match ty.kind { - // `&dyn Trait` - ty::Ref(_, ty, _) if ty.is_trait() => true, - // `Box` - _ if ty.is_box() && ty.boxed_ty().is_trait() => true, - // `dyn Trait` - _ if ty.is_trait() => true, - // Anything else. - _ => false, - }; + Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), operand, ty) => { + match operand { + Operand::Copy(place) | Operand::Move(place) => { + if let Some(from) = place.as_local() { + if from == target { + debug!("was_captured_by_trait_object: ty={:?}", ty); + // Check the type for a trait object. + return match ty.kind { + // `&dyn Trait` + ty::Ref(_, ty, _) if ty.is_trait() => true, + // `Box` + _ if ty.is_box() && ty.boxed_ty().is_trait() => { + true + } + // `dyn Trait` + _ if ty.is_trait() => true, + // Anything else. + _ => false, + }; + } } + return false; } - return false; + _ => return false, } - _ => return false, - }, + } _ => {} } } @@ -632,11 +608,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let terminator = block.terminator(); debug!("was_captured_by_trait_object: terminator={:?}", terminator); - if let TerminatorKind::Call { - destination: Some((place, block)), - args, - .. - } = &terminator.kind { + if let TerminatorKind::Call { destination: Some((place, block)), args, .. } = + &terminator.kind + { if let Some(dest) = place.as_local() { debug!( "was_captured_by_trait_object: target={:?} dest={:?} args={:?}", diff --git a/src/librustc_mir/borrow_check/diagnostics/find_use.rs b/src/librustc_mir/borrow_check/diagnostics/find_use.rs index c557e528768c5..ca4141d5fa51c 100644 --- a/src/librustc_mir/borrow_check/diagnostics/find_use.rs +++ b/src/librustc_mir/borrow_check/diagnostics/find_use.rs @@ -1,10 +1,13 @@ use std::collections::VecDeque; use std::rc::Rc; -use crate::borrow_check::{nll::ToRegionVid, region_infer::{Cause, RegionInferenceContext}}; +use crate::borrow_check::{ + nll::ToRegionVid, + region_infer::{Cause, RegionInferenceContext}, +}; use crate::util::liveness::{self, DefUse}; use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor}; -use rustc::mir::{Local, Location, Body}; +use rustc::mir::{Body, Local, Location}; use rustc::ty::{RegionVid, TyCtxt}; use rustc_data_structures::fx::FxHashSet; @@ -15,13 +18,7 @@ crate fn find<'tcx>( region_vid: RegionVid, start_point: Location, ) -> Option { - let mut uf = UseFinder { - body, - regioncx, - tcx, - region_vid, - start_point, - }; + let mut uf = UseFinder { body, regioncx, tcx, region_vid, start_point }; uf.find() } @@ -71,10 +68,7 @@ impl<'cx, 'tcx> UseFinder<'cx, 'tcx> { .terminator() .successors() .filter(|&bb| Some(&Some(*bb)) != block_data.terminator().unwind()) - .map(|&bb| Location { - statement_index: 0, - block: bb, - }), + .map(|&bb| Location { statement_index: 0, block: bb }), ); } } diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index 1a76265fbdcf0..0fa79051b783a 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -5,13 +5,13 @@ use rustc::hir::def::Namespace; use rustc::hir::def_id::DefId; use rustc::hir::GeneratorKind; use rustc::mir::{ - AggregateKind, Constant, Field, Local, LocalInfo, LocalKind, Location, Operand, - Place, PlaceBase, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, - Static, StaticKind, Terminator, TerminatorKind, + AggregateKind, Constant, Field, Local, LocalInfo, LocalKind, Location, Operand, Place, + PlaceBase, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Static, StaticKind, + Terminator, TerminatorKind, }; -use rustc::ty::{self, DefIdTree, Ty, TyCtxt}; use rustc::ty::layout::VariantIdx; use rustc::ty::print::Print; +use rustc::ty::{self, DefIdTree, Ty, TyCtxt}; use rustc_errors::DiagnosticBuilder; use syntax_pos::Span; @@ -20,20 +20,20 @@ use super::MirBorrowckCtxt; use crate::dataflow::move_paths::{InitLocation, LookupResult}; mod find_use; -mod var_name; -mod region_name; mod outlives_suggestion; +mod region_name; +mod var_name; mod conflict_errors; +mod explain_borrow; mod move_errors; mod mutability_errors; mod region_errors; -mod explain_borrow; crate use mutability_errors::AccessKind; -crate use region_name::{RegionName, RegionNameSource, RegionErrorNamingCtx}; -crate use region_errors::{ErrorReportingCtx, ErrorConstraintInfo}; crate use outlives_suggestion::OutlivesSuggestionBuilder; +crate use region_errors::{ErrorConstraintInfo, ErrorReportingCtx}; +crate use region_name::{RegionErrorNamingCtx, RegionName, RegionNameSource}; pub(super) struct IncludingDowncast(pub(super) bool); @@ -59,13 +59,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let mut target = place.local_or_deref_local(); for stmt in &self.body[location.block].statements[location.statement_index..] { debug!("add_moved_or_invoked_closure_note: stmt={:?} target={:?}", stmt, target); - if let StatementKind::Assign(box(into, Rvalue::Use(from))) = &stmt.kind { + if let StatementKind::Assign(box (into, Rvalue::Use(from))) = &stmt.kind { debug!("add_fnonce_closure_note: into={:?} from={:?}", into, from); match from { - Operand::Copy(ref place) | - Operand::Move(ref place) if target == place.local_or_deref_local() => - target = into.local_or_deref_local(), - _ => {}, + Operand::Copy(ref place) | Operand::Move(ref place) + if target == place.local_or_deref_local() => + { + target = into.local_or_deref_local() + } + _ => {} } } } @@ -74,22 +76,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let terminator = self.body[location.block].terminator(); debug!("add_moved_or_invoked_closure_note: terminator={:?}", terminator); if let TerminatorKind::Call { - func: Operand::Constant(box Constant { - literal: ty::Const { - ty: &ty::TyS { kind: ty::FnDef(id, _), .. }, + func: + Operand::Constant(box Constant { + literal: ty::Const { ty: &ty::TyS { kind: ty::FnDef(id, _), .. }, .. }, .. - }, - .. - }), + }), args, .. - } = &terminator.kind { + } = &terminator.kind + { debug!("add_moved_or_invoked_closure_note: id={:?}", id); if self.infcx.tcx.parent(id) == self.infcx.tcx.lang_items().fn_once_trait() { let closure = match args.first() { - Some(Operand::Copy(ref place)) | - Some(Operand::Move(ref place)) if target == place.local_or_deref_local() => - place.local_or_deref_local().unwrap(), + Some(Operand::Copy(ref place)) | Some(Operand::Move(ref place)) + if target == place.local_or_deref_local() => + { + place.local_or_deref_local().unwrap() + } _ => return, }; @@ -97,9 +100,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let ty::Closure(did, _) = self.body.local_decls[closure].ty.kind { let hir_id = self.infcx.tcx.hir().as_local_hir_id(did).unwrap(); - if let Some((span, name)) = self.infcx.tcx.typeck_tables_of(did) - .closure_kind_origins() - .get(hir_id) + if let Some((span, name)) = + self.infcx.tcx.typeck_tables_of(did).closure_kind_origins().get(hir_id) { diag.span_note( *span, @@ -120,16 +122,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let ty::Closure(did, _) = self.body.local_decls[target].ty.kind { let hir_id = self.infcx.tcx.hir().as_local_hir_id(did).unwrap(); - if let Some((span, name)) = self.infcx.tcx.typeck_tables_of(did) - .closure_kind_origins() - .get(hir_id) + if let Some((span, name)) = + self.infcx.tcx.typeck_tables_of(did).closure_kind_origins().get(hir_id) { diag.span_note( *span, &format!( "closure cannot be moved more than once as it is not `Copy` due to \ moving the variable `{}` out of its environment", - name + name ), ); } @@ -168,66 +169,45 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { including_downcast: &IncludingDowncast, ) -> Result<(), ()> { match place { - PlaceRef { - base: PlaceBase::Local(local), - projection: [], - } => { + PlaceRef { base: PlaceBase::Local(local), projection: [] } => { self.append_local_to_string(*local, buf)?; } PlaceRef { - base: - PlaceBase::Static(box Static { - kind: StaticKind::Promoted(..), - .. - }), + base: PlaceBase::Static(box Static { kind: StaticKind::Promoted(..), .. }), projection: [], } => { buf.push_str("promoted"); } PlaceRef { - base: - PlaceBase::Static(box Static { - kind: StaticKind::Static, - def_id, - .. - }), + base: PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }), projection: [], } => { buf.push_str(&self.infcx.tcx.item_name(*def_id).to_string()); } - PlaceRef { - base: &PlaceBase::Local(local), - projection: [ProjectionElem::Deref] - } if self.body.local_decls[local].is_ref_for_guard() => { + PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] } + if self.body.local_decls[local].is_ref_for_guard() => + { self.append_place_to_string( - PlaceRef { - base: &PlaceBase::Local(local), - projection: &[], - }, + PlaceRef { base: &PlaceBase::Local(local), projection: &[] }, buf, autoderef, &including_downcast, )?; - }, - PlaceRef { - base: &PlaceBase::Local(local), - projection: [ProjectionElem::Deref] - } if self.body.local_decls[local].is_ref_to_static() => { + } + PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] } + if self.body.local_decls[local].is_ref_to_static() => + { let local_info = &self.body.local_decls[local].local_info; if let LocalInfo::StaticRef { def_id, .. } = *local_info { buf.push_str(&self.infcx.tcx.item_name(def_id).as_str()); } else { unreachable!(); } - }, - PlaceRef { - base, - projection: [proj_base @ .., elem], - } => { + } + PlaceRef { base, projection: [proj_base @ .., elem] } => { match elem { ProjectionElem::Deref => { - let upvar_field_projection = - self.is_upvar_field_projection(place); + let upvar_field_projection = self.is_upvar_field_projection(place); if let Some(field) = upvar_field_projection { let var_index = field.index(); let name = self.upvars[var_index].name.to_string(); @@ -240,10 +220,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if autoderef { // FIXME turn this recursion into iteration self.append_place_to_string( - PlaceRef { - base, - projection: proj_base, - }, + PlaceRef { base, projection: proj_base }, buf, autoderef, &including_downcast, @@ -253,10 +230,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { _ => { buf.push_str(&"*"); self.append_place_to_string( - PlaceRef { - base, - projection: proj_base, - }, + PlaceRef { base, projection: proj_base }, buf, autoderef, &including_downcast, @@ -268,10 +242,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } ProjectionElem::Downcast(..) => { self.append_place_to_string( - PlaceRef { - base, - projection: proj_base, - }, + PlaceRef { base, projection: proj_base }, buf, autoderef, &including_downcast, @@ -283,22 +254,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ProjectionElem::Field(field, _ty) => { autoderef = true; - let upvar_field_projection = - self.is_upvar_field_projection(place); + let upvar_field_projection = self.is_upvar_field_projection(place); if let Some(field) = upvar_field_projection { let var_index = field.index(); let name = self.upvars[var_index].name.to_string(); buf.push_str(&name); } else { - let field_name = self.describe_field(PlaceRef { - base, - projection: proj_base, - }, *field); + let field_name = self + .describe_field(PlaceRef { base, projection: proj_base }, *field); self.append_place_to_string( - PlaceRef { - base, - projection: proj_base, - }, + PlaceRef { base, projection: proj_base }, buf, autoderef, &including_downcast, @@ -310,10 +275,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { autoderef = true; self.append_place_to_string( - PlaceRef { - base, - projection: proj_base, - }, + PlaceRef { base, projection: proj_base }, buf, autoderef, &including_downcast, @@ -330,10 +292,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // then use another while the borrow is held, don't output indices details // to avoid confusing the end-user self.append_place_to_string( - PlaceRef { - base, - projection: proj_base, - }, + PlaceRef { base, projection: proj_base }, buf, autoderef, &including_downcast, @@ -364,34 +323,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn describe_field(&self, place: PlaceRef<'cx, 'tcx>, field: Field) -> String { // FIXME Place2 Make this work iteratively match place { - PlaceRef { - base: PlaceBase::Local(local), - projection: [], - } => { + PlaceRef { base: PlaceBase::Local(local), projection: [] } => { let local = &self.body.local_decls[*local]; self.describe_field_from_ty(&local.ty, field, None) } - PlaceRef { - base: PlaceBase::Static(static_), - projection: [], - } => - self.describe_field_from_ty(&static_.ty, field, None), - PlaceRef { - base, - projection: [proj_base @ .., elem], - } => match elem { + PlaceRef { base: PlaceBase::Static(static_), projection: [] } => { + self.describe_field_from_ty(&static_.ty, field, None) + } + PlaceRef { base, projection: [proj_base @ .., elem] } => match elem { ProjectionElem::Deref => { - self.describe_field(PlaceRef { - base, - projection: proj_base, - }, field) + self.describe_field(PlaceRef { base, projection: proj_base }, field) } ProjectionElem::Downcast(_, variant_index) => { - let base_ty = Place::ty_from( - place.base, - place.projection, - *self.body, - self.infcx.tcx).ty; + let base_ty = + Place::ty_from(place.base, place.projection, *self.body, self.infcx.tcx).ty; self.describe_field_from_ty(&base_ty, field, Some(*variant_index)) } ProjectionElem::Field(_, field_type) => { @@ -400,10 +345,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => { - self.describe_field(PlaceRef { - base, - projection: proj_base, - }, field) + self.describe_field(PlaceRef { base, projection: proj_base }, field) } }, } @@ -414,7 +356,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &self, ty: Ty<'_>, field: Field, - variant_index: Option + variant_index: Option, ) -> String { if ty.is_box() { // If the type is a box, the field is described from the boxed type @@ -428,32 +370,28 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else { def.non_enum_variant() }; - variant.fields[field.index()] - .ident - .to_string() - }, + variant.fields[field.index()].ident.to_string() + } ty::Tuple(_) => field.index().to_string(), ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => { self.describe_field_from_ty(&ty, field, variant_index) } - ty::Array(ty, _) | ty::Slice(ty) => - self.describe_field_from_ty(&ty, field, variant_index), + ty::Array(ty, _) | ty::Slice(ty) => { + self.describe_field_from_ty(&ty, field, variant_index) + } ty::Closure(def_id, _) | ty::Generator(def_id, _, _) => { // `tcx.upvars(def_id)` returns an `Option`, which is `None` in case // the closure comes from another crate. But in that case we wouldn't // be borrowck'ing it, so we can just unwrap: - let (&var_id, _) = self.infcx.tcx.upvars(def_id).unwrap() - .get_index(field.index()).unwrap(); + let (&var_id, _) = + self.infcx.tcx.upvars(def_id).unwrap().get_index(field.index()).unwrap(); self.infcx.tcx.hir().name(var_id).to_string() } _ => { // Might need a revision when the fields in trait RFC is implemented // (https://github.com/rust-lang/rfcs/pull/1546) - bug!( - "End-user description not implemented for field access on `{:?}`", - ty - ); + bug!("End-user description not implemented for field access on `{:?}`", ty); } } } @@ -469,8 +407,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) { let message = format!( "move occurs because {} has type `{}`, which does not implement the `Copy` trait", - place_desc, - ty, + place_desc, ty, ); if let Some(span) = span { err.span_label(span, message); @@ -506,23 +443,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let is_terminator = bbd.statements.len() == loc.statement_index; debug!( "borrowed_content_source: loc={:?} is_terminator={:?}", - loc, - is_terminator, + loc, is_terminator, ); if !is_terminator { continue; } else if let Some(Terminator { - kind: TerminatorKind::Call { - ref func, - from_hir_call: false, - .. - }, + kind: TerminatorKind::Call { ref func, from_hir_call: false, .. }, .. - }) = bbd.terminator { - if let Some(source) = BorrowedContentSource::from_call( - func.ty(*self.body, tcx), - tcx - ) { + }) = bbd.terminator + { + if let Some(source) = + BorrowedContentSource::from_call(func.ty(*self.body, tcx), tcx) + { return source; } } @@ -534,12 +466,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // If we didn't find an overloaded deref or index, then assume it's a // built in deref and check the type of the base. - let base_ty = Place::ty_from( - deref_base.base, - deref_base.projection, - *self.body, - tcx - ).ty; + let base_ty = Place::ty_from(deref_base.base, deref_base.projection, *self.body, tcx).ty; if base_ty.is_unsafe_ptr() { BorrowedContentSource::DerefRawPointer } else if base_ty.is_mutable_ptr() { @@ -620,10 +547,7 @@ pub(super) enum UseSpans { impl UseSpans { pub(super) fn args_or_use(self) -> Span { match self { - UseSpans::ClosureUse { - args_span: span, .. - } - | UseSpans::OtherUse(span) => span, + UseSpans::ClosureUse { args_span: span, .. } | UseSpans::OtherUse(span) => span, } } @@ -681,11 +605,13 @@ impl UseSpans { /// Describe the span associated with a use of a place. pub(super) fn describe(&self) -> String { match *self { - UseSpans::ClosureUse { generator_kind, .. } => if generator_kind.is_some() { - " in generator".to_string() - } else { - " in closure".to_string() - }, + UseSpans::ClosureUse { generator_kind, .. } => { + if generator_kind.is_some() { + " in generator".to_string() + } else { + " in closure".to_string() + } + } _ => "".to_string(), } } @@ -714,12 +640,10 @@ impl BorrowedContentSource<'tcx> { match *self { BorrowedContentSource::DerefRawPointer => format!("a raw pointer"), BorrowedContentSource::DerefSharedRef => format!("a shared reference"), - BorrowedContentSource::DerefMutableRef => { - format!("a mutable reference") - } + BorrowedContentSource::DerefMutableRef => format!("a mutable reference"), BorrowedContentSource::OverloadedDeref(ty) => { if ty.is_rc() { - format!("an `Rc`") + format!("an `Rc`") } else if ty.is_arc() { format!("an `Arc`") } else { @@ -738,7 +662,7 @@ impl BorrowedContentSource<'tcx> { // Overloaded deref and index operators should be evaluated into a // temporary. So we don't need a description here. BorrowedContentSource::OverloadedDeref(_) - | BorrowedContentSource::OverloadedIndex(_) => None + | BorrowedContentSource::OverloadedIndex(_) => None, } } @@ -747,11 +671,11 @@ impl BorrowedContentSource<'tcx> { BorrowedContentSource::DerefRawPointer => format!("a `*const` pointer"), BorrowedContentSource::DerefSharedRef => format!("a `&` reference"), BorrowedContentSource::DerefMutableRef => { - bug!("describe_for_immutable_place: DerefMutableRef isn't immutable") - }, + bug!("describe_for_immutable_place: DerefMutableRef isn't immutable") + } BorrowedContentSource::OverloadedDeref(ty) => { if ty.is_rc() { - format!("an `Rc`") + format!("an `Rc`") } else if ty.is_arc() { format!("an `Arc`") } else { @@ -800,26 +724,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }; debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt); - if let StatementKind::Assign( - box(_, Rvalue::Aggregate(ref kind, ref places)) - ) = stmt.kind { + if let StatementKind::Assign(box (_, Rvalue::Aggregate(ref kind, ref places))) = stmt.kind { let def_id = match kind { box AggregateKind::Closure(def_id, _) | box AggregateKind::Generator(def_id, _, _) => def_id, _ => return OtherUse(stmt.source_info.span), }; - debug!( - "move_spans: def_id={:?} places={:?}", - def_id, places - ); - if let Some((args_span, generator_kind, var_span)) - = self.closure_span(*def_id, moved_place, places) { - return ClosureUse { - generator_kind, - args_span, - var_span, - }; + debug!("move_spans: def_id={:?} places={:?}", def_id, places); + if let Some((args_span, generator_kind, var_span)) = + self.closure_span(*def_id, moved_place, places) + { + return ClosureUse { generator_kind, args_span, var_span }; } } @@ -834,14 +750,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { use self::UseSpans::*; debug!("borrow_spans: use_span={:?} location={:?}", use_span, location); - let target = match self.body[location.block] - .statements - .get(location.statement_index) - { - Some(&Statement { - kind: StatementKind::Assign(box(ref place, _)), - .. - }) => { + let target = match self.body[location.block].statements.get(location.statement_index) { + Some(&Statement { kind: StatementKind::Assign(box (ref place, _)), .. }) => { if let Some(local) = place.as_local() { local } else { @@ -857,9 +767,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } for stmt in &self.body[location.block].statements[location.statement_index + 1..] { - if let StatementKind::Assign( - box(_, Rvalue::Aggregate(ref kind, ref places)) - ) = stmt.kind { + if let StatementKind::Assign(box (_, Rvalue::Aggregate(ref kind, ref places))) = + stmt.kind + { let (def_id, is_generator) = match kind { box AggregateKind::Closure(def_id, _) => (def_id, false), box AggregateKind::Generator(def_id, _, _) => (def_id, true), @@ -870,14 +780,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { "borrow_spans: def_id={:?} is_generator={:?} places={:?}", def_id, is_generator, places ); - if let Some((args_span, generator_kind, var_span)) = self.closure_span( - *def_id, Place::from(target).as_ref(), places - ) { - return ClosureUse { - generator_kind, - args_span, - var_span, - }; + if let Some((args_span, generator_kind, var_span)) = + self.closure_span(*def_id, Place::from(target).as_ref(), places) + { + return ClosureUse { generator_kind, args_span, var_span }; } else { return OtherUse(use_span); } @@ -905,22 +811,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let hir_id = self.infcx.tcx.hir().as_local_hir_id(def_id)?; let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind; debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr); - if let hir::ExprKind::Closure( - .., body_id, args_span, _ - ) = expr { + if let hir::ExprKind::Closure(.., body_id, args_span, _) = expr { for (upvar, place) in self.infcx.tcx.upvars(def_id)?.values().zip(places) { match place { - Operand::Copy(place) | - Operand::Move(place) if target_place == place.as_ref() => { + Operand::Copy(place) | Operand::Move(place) + if target_place == place.as_ref() => + { debug!("closure_span: found captured local {:?}", place); let body = self.infcx.tcx.hir().body(*body_id); let generator_kind = body.generator_kind(); return Some((*args_span, generator_kind, upvar.span)); - }, + } _ => {} } } - } None } diff --git a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs index cc634101f0adf..5f06623f9dbd7 100644 --- a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs @@ -1,14 +1,13 @@ use rustc::mir::*; use rustc::ty; -use rustc_errors::{DiagnosticBuilder,Applicability}; +use rustc_errors::{Applicability, DiagnosticBuilder}; use syntax_pos::Span; -use crate::borrow_check::MirBorrowckCtxt; -use crate::borrow_check::prefixes::PrefixSet; use crate::borrow_check::diagnostics::UseSpans; +use crate::borrow_check::prefixes::PrefixSet; +use crate::borrow_check::MirBorrowckCtxt; use crate::dataflow::move_paths::{ - IllegalMoveOrigin, IllegalMoveOriginKind, - LookupResult, MoveError, MovePathIndex, + IllegalMoveOrigin, IllegalMoveOriginKind, LookupResult, MoveError, MovePathIndex, }; // Often when desugaring a pattern match we may have many individual moves in @@ -62,7 +61,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fn group_move_errors( &self, - errors: Vec<(Place<'tcx>, MoveError<'tcx>)> + errors: Vec<(Place<'tcx>, MoveError<'tcx>)>, ) -> Vec> { let mut grouped_errors = Vec::new(); for (original_path, error) in errors { @@ -81,16 +80,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { MoveError::UnionMove { .. } => { unimplemented!("don't know how to report union move errors yet.") } - MoveError::IllegalMove { - cannot_move_out_of: IllegalMoveOrigin { location, kind }, - } => { + MoveError::IllegalMove { cannot_move_out_of: IllegalMoveOrigin { location, kind } } => { // Note: that the only time we assign a place isn't a temporary // to a user variable is when initializing it. // If that ever stops being the case, then the ever initialized // flow could be used. - if let Some(StatementKind::Assign( - box(place, Rvalue::Use(Operand::Move(move_from))) - )) = self.body.basic_blocks()[location.block] + if let Some(StatementKind::Assign(box ( + place, + Rvalue::Use(Operand::Move(move_from)), + ))) = self.body.basic_blocks()[location.block] .statements .get(location.statement_index) .map(|stmt| &stmt.kind) @@ -111,7 +109,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { opt_ty_info: _, pat_span: _, }, - ))) = local_decl.local_info { + ))) = local_decl.local_info + { let stmt_source_info = self.body.source_info(location); self.append_binding_error( grouped_errors, @@ -149,10 +148,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { match_span: Span, statement_span: Span, ) { - debug!( - "append_binding_error(match_place={:?}, match_span={:?})", - match_place, match_span - ); + debug!("append_binding_error(match_place={:?}, match_span={:?})", match_place, match_span); let from_simple_let = match_place.is_none(); let match_place = match_place.as_ref().unwrap_or(move_from); @@ -223,49 +219,46 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fn report(&mut self, error: GroupedMoveError<'tcx>) { let (mut err, err_span) = { - let (span, use_spans, original_path, kind,): - ( + let (span, use_spans, original_path, kind): ( Span, Option, &Place<'tcx>, &IllegalMoveOriginKind<'_>, - ) = - match error { - GroupedMoveError::MovesFromPlace { span, ref original_path, ref kind, .. } | - GroupedMoveError::MovesFromValue { span, ref original_path, ref kind, .. } => { - (span, None, original_path, kind) - } - GroupedMoveError::OtherIllegalMove { - use_spans, - ref original_path, - ref kind - } => { - (use_spans.args_or_use(), Some(use_spans), original_path, kind) - }, - }; - debug!("report: original_path={:?} span={:?}, kind={:?} \ - original_path.is_upvar_field_projection={:?}", original_path, span, kind, - self.is_upvar_field_projection(original_path.as_ref())); + ) = match error { + GroupedMoveError::MovesFromPlace { span, ref original_path, ref kind, .. } + | GroupedMoveError::MovesFromValue { span, ref original_path, ref kind, .. } => { + (span, None, original_path, kind) + } + GroupedMoveError::OtherIllegalMove { use_spans, ref original_path, ref kind } => { + (use_spans.args_or_use(), Some(use_spans), original_path, kind) + } + }; + debug!( + "report: original_path={:?} span={:?}, kind={:?} \ + original_path.is_upvar_field_projection={:?}", + original_path, + span, + kind, + self.is_upvar_field_projection(original_path.as_ref()) + ); ( match kind { IllegalMoveOriginKind::Static => { unreachable!(); } - IllegalMoveOriginKind::BorrowedContent { target_place } => { - self.report_cannot_move_from_borrowed_content( + IllegalMoveOriginKind::BorrowedContent { target_place } => self + .report_cannot_move_from_borrowed_content( original_path, target_place, span, use_spans, - ) - } + ), IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => { self.cannot_move_out_of_interior_of_drop(span, ty) } - IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => - self.cannot_move_out_of_interior_noncopy( - span, ty, Some(*is_index), - ), + IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => { + self.cannot_move_out_of_interior_noncopy(span, ty, Some(*is_index)) + } }, span, ) @@ -278,15 +271,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fn report_cannot_move_from_static( &mut self, place: &Place<'tcx>, - span: Span + span: Span, ) -> DiagnosticBuilder<'a> { let description = if place.projection.len() == 1 { format!("static item `{}`", self.describe_place(place.as_ref()).unwrap()) } else { - let base_static = PlaceRef { - base: &place.base, - projection: &[ProjectionElem::Deref], - }; + let base_static = PlaceRef { base: &place.base, projection: &[ProjectionElem::Deref] }; format!( "`{:?}` as `{:?}` is a static item", @@ -309,23 +299,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // borrow to provide feedback about why this // was a move rather than a copy. let ty = deref_target_place.ty(*self.body, self.infcx.tcx).ty; - let upvar_field = self.prefixes(move_place.as_ref(), PrefixSet::All) + let upvar_field = self + .prefixes(move_place.as_ref(), PrefixSet::All) .find_map(|p| self.is_upvar_field_projection(p)); let deref_base = match deref_target_place.projection.as_ref() { &[ref proj_base @ .., ProjectionElem::Deref] => { - PlaceRef { - base: &deref_target_place.base, - projection: &proj_base, - } + PlaceRef { base: &deref_target_place.base, projection: &proj_base } } _ => bug!("deref_target_place is not a deref projection"), }; - if let PlaceRef { - base: PlaceBase::Local(local), - projection: [], - } = deref_base { + if let PlaceRef { base: PlaceBase::Local(local), projection: [] } = deref_base { let decl = &self.body.local_decls[*local]; if decl.is_ref_for_guard() { let mut err = self.cannot_move_out_of( @@ -334,7 +319,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); err.note( "variables bound in patterns cannot be moved from \ - until after the end of the pattern guard"); + until after the end of the pattern guard", + ); return err; } else if decl.is_ref_to_static() { return self.report_cannot_move_from_static(move_place, span); @@ -343,21 +329,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { debug!("report: ty={:?}", ty); let mut err = match ty.kind { - ty::Array(..) | ty::Slice(..) => - self.cannot_move_out_of_interior_noncopy(span, ty, None), + ty::Array(..) | ty::Slice(..) => { + self.cannot_move_out_of_interior_noncopy(span, ty, None) + } ty::Closure(def_id, closure_substs) - if def_id == self.mir_def_id && upvar_field.is_some() - => { - let closure_kind_ty = closure_substs - .as_closure().kind_ty(def_id, self.infcx.tcx); + if def_id == self.mir_def_id && upvar_field.is_some() => + { + let closure_kind_ty = closure_substs.as_closure().kind_ty(def_id, self.infcx.tcx); let closure_kind = closure_kind_ty.to_opt_closure_kind(); let capture_description = match closure_kind { - Some(ty::ClosureKind::Fn) => { - "captured variable in an `Fn` closure" - } - Some(ty::ClosureKind::FnMut) => { - "captured variable in an `FnMut` closure" - } + Some(ty::ClosureKind::Fn) => "captured variable in an `Fn` closure", + Some(ty::ClosureKind::FnMut) => "captured variable in an `FnMut` closure", Some(ty::ClosureKind::FnOnce) => { bug!("closure kind does not match first argument type") } @@ -377,12 +359,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { { format!("`{}`, a {}", place_name, capture_description) } else { - format!( - "`{}`, as `{}` is a {}", - place_name, - upvar_name, - capture_description, - ) + format!("`{}`, as `{}` is a {}", place_name, upvar_name, capture_description,) }; debug!( @@ -398,40 +375,27 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } _ => { let source = self.borrowed_content_source(deref_base); - match ( - self.describe_place(move_place.as_ref()), - source.describe_for_named_place(), - ) { - (Some(place_desc), Some(source_desc)) => { - self.cannot_move_out_of( - span, - &format!("`{}` which is behind a {}", place_desc, source_desc), - ) - } - (_, _) => { - self.cannot_move_out_of( - span, - &source.describe_for_unnamed_place(), - ) - } + match (self.describe_place(move_place.as_ref()), source.describe_for_named_place()) + { + (Some(place_desc), Some(source_desc)) => self.cannot_move_out_of( + span, + &format!("`{}` which is behind a {}", place_desc, source_desc), + ), + (_, _) => self.cannot_move_out_of(span, &source.describe_for_unnamed_place()), } - }, + } }; - let move_ty = format!( - "{:?}", - move_place.ty(*self.body, self.infcx.tcx).ty, - ); + let move_ty = format!("{:?}", move_place.ty(*self.body, self.infcx.tcx).ty,); if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { let is_option = move_ty.starts_with("std::option::Option"); let is_result = move_ty.starts_with("std::result::Result"); if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) { err.span_suggestion( span, - &format!("consider borrowing the `{}`'s content", if is_option { - "Option" - } else { - "Result" - }), + &format!( + "consider borrowing the `{}`'s content", + if is_option { "Option" } else { "Result" } + ), format!("{}.as_ref()", snippet), Applicability::MaybeIncorrect, ); @@ -447,11 +411,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { span: Span, ) { match error { - GroupedMoveError::MovesFromPlace { - mut binds_to, - move_from, - .. - } => { + GroupedMoveError::MovesFromPlace { mut binds_to, move_from, .. } => { if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { err.span_suggestion( span, @@ -468,12 +428,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { None => format!("value"), }; - self.note_type_does_not_implement_copy( - err, - &place_desc, - place_ty, - Some(span) - ); + self.note_type_does_not_implement_copy(err, &place_desc, place_ty, Some(span)); } else { binds_to.sort(); binds_to.dedup(); @@ -495,36 +450,24 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { Some(desc) => format!("`{}`", desc), None => format!("value"), }; - self.note_type_does_not_implement_copy( - err, - &place_desc, - place_ty, - Some(span), - ); + self.note_type_does_not_implement_copy(err, &place_desc, place_ty, Some(span)); use_spans.args_span_label(err, format!("move out of {} occurs here", place_desc)); - use_spans.var_span_label( - err, - format!("move occurs due to use{}", use_spans.describe()), - ); - }, + use_spans + .var_span_label(err, format!("move occurs due to use{}", use_spans.describe())); + } } } - fn add_move_error_suggestions( - &self, - err: &mut DiagnosticBuilder<'a>, - binds_to: &[Local], - ) { + fn add_move_error_suggestions(&self, err: &mut DiagnosticBuilder<'a>, binds_to: &[Local]) { let mut suggestions: Vec<(Span, &str, String)> = Vec::new(); for local in binds_to { let bind_to = &self.body.local_decls[*local]; - if let LocalInfo::User( - ClearCrossCrate::Set(BindingForm::Var(VarBindingForm { - pat_span, - .. - })) - ) = bind_to.local_info { + if let LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm { + pat_span, + .. + }))) = bind_to.local_info + { if let Ok(pat_snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(pat_span) { if pat_snippet.starts_with('&') { @@ -540,11 +483,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { suggestion = pat_snippet; to_remove = "&"; } - suggestions.push(( - pat_span, - to_remove, - suggestion.to_owned(), - )); + suggestions.push((pat_span, to_remove, suggestion.to_owned())); } } } @@ -561,11 +500,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } - fn add_move_error_details( - &self, - err: &mut DiagnosticBuilder<'a>, - binds_to: &[Local], - ) { + fn add_move_error_details(&self, err: &mut DiagnosticBuilder<'a>, binds_to: &[Local]) { for (j, local) in binds_to.into_iter().enumerate() { let bind_to = &self.body.local_decls[*local]; let binding_span = bind_to.source_info.span; @@ -581,13 +516,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err, &format!("`{}`", self.local_names[*local].unwrap()), bind_to.ty, - Some(binding_span) + Some(binding_span), ); } } if binds_to.len() > 1 { - err.note("move occurs because these variables have types that \ + err.note( + "move occurs because these variables have types that \ don't implement the `Copy` trait", ); } diff --git a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs index b61c37b061396..40fe75d0666fb 100644 --- a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs +++ b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs @@ -4,8 +4,8 @@ use std::collections::BTreeMap; use log::debug; -use rustc::{hir::def_id::DefId, infer::InferCtxt, ty::RegionVid}; use rustc::mir::{Body, Local}; +use rustc::{hir::def_id::DefId, infer::InferCtxt, ty::RegionVid}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Diagnostic, DiagnosticBuilder}; use rustc_index::vec::IndexVec; @@ -16,7 +16,7 @@ use smallvec::SmallVec; use crate::borrow_check::region_infer::RegionInferenceContext; use super::{ - RegionName, RegionNameSource, ErrorConstraintInfo, ErrorReportingCtx, RegionErrorNamingCtx, + ErrorConstraintInfo, ErrorReportingCtx, RegionErrorNamingCtx, RegionName, RegionNameSource, }; /// The different things we could suggest. @@ -51,10 +51,7 @@ pub struct OutlivesSuggestionBuilder<'a> { impl OutlivesSuggestionBuilder<'a> { /// Create a new builder for the given MIR node representing a fn definition. - crate fn new( - mir_def_id: DefId, - local_names: &'a IndexVec>, - ) -> Self { + crate fn new(mir_def_id: DefId, local_names: &'a IndexVec>) -> Self { OutlivesSuggestionBuilder { mir_def_id, local_names, @@ -160,11 +157,7 @@ impl OutlivesSuggestionBuilder<'a> { // 3) Suggest unifying 'a with 'b if we have both 'a: 'b and 'b: 'a if outlived.iter().any(|(_, outlived_name)| { - if let RegionNameSource::Static = outlived_name.source { - true - } else { - false - } + if let RegionNameSource::Static = outlived_name.source { true } else { false } }) { suggested.push(SuggestedConstraint::Static(fr_name)); } else { diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index b78cd6bccf8ca..bf8e51befa25e 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -2,33 +2,27 @@ use rustc::hir::def_id::DefId; use rustc::infer::{ - error_reporting::nice_region_error::NiceRegionError, - InferCtxt, NLLRegionVariableOrigin, -}; -use rustc::mir::{ - ConstraintCategory, Local, Location, Body, + error_reporting::nice_region_error::NiceRegionError, InferCtxt, NLLRegionVariableOrigin, }; +use rustc::mir::{Body, ConstraintCategory, Local, Location}; use rustc::ty::{self, RegionVid}; -use rustc_index::vec::IndexVec; use rustc_errors::DiagnosticBuilder; +use rustc_index::vec::IndexVec; use std::collections::VecDeque; use syntax::errors::Applicability; use syntax::symbol::kw; -use syntax_pos::Span; use syntax_pos::symbol::Symbol; +use syntax_pos::Span; use crate::util::borrowck_errors; use crate::borrow_check::{ - constraints::OutlivesConstraint, - region_infer::RegionInferenceContext, - type_check::Locations, - universal_regions::DefiningTy, - nll::ConstraintDescription, + constraints::OutlivesConstraint, nll::ConstraintDescription, + region_infer::RegionInferenceContext, type_check::Locations, universal_regions::DefiningTy, Upvar, }; -use super::{OutlivesSuggestionBuilder, RegionName, RegionNameSource, RegionErrorNamingCtx}; +use super::{OutlivesSuggestionBuilder, RegionErrorNamingCtx, RegionName, RegionNameSource}; impl ConstraintDescription for ConstraintCategory { fn description(&self) -> &'static str { @@ -135,13 +129,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { from_region_origin: NLLRegionVariableOrigin, target_test: impl Fn(RegionVid) -> bool, ) -> (ConstraintCategory, bool, Span) { - debug!("best_blame_constraint(from_region={:?}, from_region_origin={:?})", - from_region, from_region_origin); + debug!( + "best_blame_constraint(from_region={:?}, from_region_origin={:?})", + from_region, from_region_origin + ); // Find all paths let (path, target_region) = - self.find_constraint_paths_between_regions(from_region, target_test) - .unwrap(); + self.find_constraint_paths_between_regions(from_region, target_test).unwrap(); debug!( "best_blame_constraint: path={:#?}", path.iter() @@ -155,7 +150,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { ); // Classify each of the constraints along the path. - let mut categorized_path: Vec<(ConstraintCategory, bool, Span)> = path.iter() + let mut categorized_path: Vec<(ConstraintCategory, bool, Span)> = path + .iter() .map(|constraint| { if constraint.category == ConstraintCategory::ClosureBounds { self.retrieve_closure_constraint_info(body, &constraint) @@ -164,10 +160,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } }) .collect(); - debug!( - "best_blame_constraint: categorized_path={:#?}", - categorized_path - ); + debug!("best_blame_constraint: categorized_path={:#?}", categorized_path); // To find the best span to cite, we first try to look for the // final constraint that is interesting and where the `sup` is @@ -228,13 +221,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { // and here we prefer to blame the source (the y = x statement). let blame_source = match from_region_origin { NLLRegionVariableOrigin::FreeRegion - | NLLRegionVariableOrigin::Existential { from_forall: false } => { - true - } + | NLLRegionVariableOrigin::Existential { from_forall: false } => true, NLLRegionVariableOrigin::Placeholder(_) - | NLLRegionVariableOrigin::Existential { from_forall: true } => { - false - } + | NLLRegionVariableOrigin::Existential { from_forall: true } => false, }; let find_region = |i: &usize| { @@ -244,29 +233,33 @@ impl<'tcx> RegionInferenceContext<'tcx> { if blame_source { match categorized_path[*i].0 { - ConstraintCategory::OpaqueType | ConstraintCategory::Boring | - ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal => false, - ConstraintCategory::TypeAnnotation | ConstraintCategory::Return | - ConstraintCategory::Yield => true, + ConstraintCategory::OpaqueType + | ConstraintCategory::Boring + | ConstraintCategory::BoringNoLocation + | ConstraintCategory::Internal => false, + ConstraintCategory::TypeAnnotation + | ConstraintCategory::Return + | ConstraintCategory::Yield => true, _ => constraint_sup_scc != target_scc, } } else { match categorized_path[*i].0 { - ConstraintCategory::OpaqueType | ConstraintCategory::Boring | - ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal => false, - _ => true + ConstraintCategory::OpaqueType + | ConstraintCategory::Boring + | ConstraintCategory::BoringNoLocation + | ConstraintCategory::Internal => false, + _ => true, } } }; - let best_choice = if blame_source { - range.rev().find(find_region) - } else { - range.find(find_region) - }; + let best_choice = + if blame_source { range.rev().find(find_region) } else { range.find(find_region) }; - debug!("best_blame_constraint: best_choice={:?} blame_source={}", - best_choice, blame_source); + debug!( + "best_blame_constraint: best_choice={:?} blame_source={}", + best_choice, blame_source + ); if let Some(i) = best_choice { if let Some(next) = categorized_path.get(i + 1) { @@ -352,11 +345,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { // A constraint like `'r: 'x` can come from our constraint // graph. let fr_static = self.universal_regions.fr_static; - let outgoing_edges_from_graph = self.constraint_graph - .outgoing_edges(r, &self.constraints, fr_static); + let outgoing_edges_from_graph = + self.constraint_graph.outgoing_edges(r, &self.constraints, fr_static); // Always inline this closure because it can be hot. - let mut handle_constraint = #[inline(always)] |constraint: OutlivesConstraint| { + let mut handle_constraint = #[inline(always)] + |constraint: OutlivesConstraint| { debug_assert_eq!(constraint.sup, r); let sub_region = constraint.sub; if let Trace::NotVisited = context[sub_region] { @@ -435,17 +429,16 @@ impl<'tcx> RegionInferenceContext<'tcx> { fr_is_local, outlived_fr_is_local, category ); - let errctx = ErrorReportingCtx { - region_infcx: self, - infcx, - mir_def_id, - body, - local_names, - upvars, - }; + let errctx = + ErrorReportingCtx { region_infcx: self, infcx, mir_def_id, body, local_names, upvars }; let errci = ErrorConstraintInfo { - fr, outlived_fr, fr_is_local, outlived_fr_is_local, category, span + fr, + outlived_fr, + fr_is_local, + outlived_fr_is_local, + category, + span, }; match (category, fr_is_local, outlived_fr_is_local) { @@ -486,10 +479,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// that `fr1: 'static` because it is the only way to `fr1: r` to /// be satisfied. (See `add_incompatible_universe`.) fn provides_universal_region(&self, r: RegionVid, fr1: RegionVid, fr2: RegionVid) -> bool { - debug!( - "provides_universal_region(r={:?}, fr1={:?}, fr2={:?})", - r, fr1, fr2 - ); + debug!("provides_universal_region(r={:?}, fr1={:?}, fr2={:?})", r, fr1, fr2); let result = { r == fr2 || { fr2 == self.universal_regions.fr_static && self.cannot_name_placeholder(fr1, r) @@ -521,9 +511,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { errci: &ErrorConstraintInfo, renctx: &mut RegionErrorNamingCtx, ) -> DiagnosticBuilder<'_> { - let ErrorConstraintInfo { - outlived_fr, span, .. - } = errci; + let ErrorConstraintInfo { outlived_fr, span, .. } = errci; let mut diag = errctx .infcx @@ -584,13 +572,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { errci: &ErrorConstraintInfo, renctx: &mut RegionErrorNamingCtx, ) -> DiagnosticBuilder<'_> { - let ErrorReportingCtx { - infcx, body, upvars, local_names, .. - } = errctx; + let ErrorReportingCtx { infcx, body, upvars, local_names, .. } = errctx; - let ErrorConstraintInfo { - span, category, .. - } = errci; + let ErrorConstraintInfo { span, category, .. } = errci; let fr_name_and_span = self.get_var_name_and_span_for_region(infcx.tcx, body, local_names, upvars, errci.fr); @@ -617,20 +601,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { { return self.report_general_error( errctx, - &ErrorConstraintInfo { - fr_is_local: true, - outlived_fr_is_local: false, - .. *errci - }, + &ErrorConstraintInfo { fr_is_local: true, outlived_fr_is_local: false, ..*errci }, renctx, ); } - let mut diag = borrowck_errors::borrowed_data_escapes_closure( - infcx.tcx, - *span, - escapes_from, - ); + let mut diag = + borrowck_errors::borrowed_data_escapes_closure(infcx.tcx, *span, escapes_from); if let Some((Some(outlived_fr_name), outlived_fr_span)) = outlived_fr_name_and_span { diag.span_label( @@ -651,10 +628,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { ), ); - diag.span_label( - *span, - format!("`{}` escapes the {} body here", fr_name, escapes_from), - ); + diag.span_label(*span, format!("`{}` escapes the {} body here", fr_name, escapes_from)); } diag @@ -681,23 +655,20 @@ impl<'tcx> RegionInferenceContext<'tcx> { errci: &ErrorConstraintInfo, renctx: &mut RegionErrorNamingCtx, ) -> DiagnosticBuilder<'_> { - let ErrorReportingCtx { - infcx, mir_def_id, .. - } = errctx; + let ErrorReportingCtx { infcx, mir_def_id, .. } = errctx; let ErrorConstraintInfo { - fr, fr_is_local, outlived_fr, outlived_fr_is_local, span, category, .. + fr, + fr_is_local, + outlived_fr, + outlived_fr_is_local, + span, + category, + .. } = errci; - let mut diag = infcx.tcx.sess.struct_span_err( - *span, - "lifetime may not live long enough" - ); + let mut diag = infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough"); - let mir_def_name = if infcx.tcx.is_closure(*mir_def_id) { - "closure" - } else { - "function" - }; + let mir_def_name = if infcx.tcx.is_closure(*mir_def_id) { "closure" } else { "function" }; let fr_name = self.give_region_a_name(errctx, renctx, *fr).unwrap(); fr_name.highlight_region_name(&mut diag); @@ -754,10 +725,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { if let (Some(f), Some(ty::RegionKind::ReStatic)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { - if let Some((ty::TyS { - kind: ty::Opaque(did, substs), - .. - }, _)) = infcx + if let Some((ty::TyS { kind: ty::Opaque(did, substs), .. }, _)) = infcx .tcx .is_suitable_region(f) .map(|r| r.def_id) @@ -795,10 +763,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // If there is a static predicate, then the only sensible suggestion is to replace // fr with `'static`. if has_static_predicate { - diag.help(&format!( - "consider replacing `{}` with `{}`", - fr_name, static_str, - )); + diag.help(&format!("consider replacing `{}` with `{}`", fr_name, static_str,)); } else { // Otherwise, we should suggest adding a constraint on the return type. let span = infcx.tcx.def_span(*did); @@ -839,14 +804,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { body, borrow_region, NLLRegionVariableOrigin::FreeRegion, - |r| self.provides_universal_region(r, borrow_region, outlived_region) + |r| self.provides_universal_region(r, borrow_region, outlived_region), ); let mut renctx = RegionErrorNamingCtx::new(); - let errctx = ErrorReportingCtx { - infcx, body, local_names, upvars, mir_def_id, - region_infcx: self, - }; + let errctx = + ErrorReportingCtx { infcx, body, local_names, upvars, mir_def_id, region_infcx: self }; let outlived_fr_name = self.give_region_a_name(&errctx, &mut renctx, outlived_region); (category, from_closure, span, outlived_fr_name) @@ -854,11 +817,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Finds some region R such that `fr1: R` and `R` is live at // `elem`. - crate fn find_sub_region_live_at( - &self, - fr1: RegionVid, - elem: Location, - ) -> RegionVid { + crate fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid { debug!("find_sub_region_live_at(fr1={:?}, elem={:?})", fr1, elem); self.find_constraint_paths_between_regions(fr1, |r| { // First look for some `r` such that `fr1: r` and `r` is live at `elem` @@ -868,29 +827,30 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.liveness_constraints.region_value_str(r), ); self.liveness_constraints.contains(r, elem) - }).or_else(|| { - // If we fail to find that, we may find some `r` such that - // `fr1: r` and `r` is a placeholder from some universe - // `fr1` cannot name. This would force `fr1` to be - // `'static`. - self.find_constraint_paths_between_regions(fr1, |r| { - self.cannot_name_placeholder(fr1, r) - }) + }) + .or_else(|| { + // If we fail to find that, we may find some `r` such that + // `fr1: r` and `r` is a placeholder from some universe + // `fr1` cannot name. This would force `fr1` to be + // `'static`. + self.find_constraint_paths_between_regions(fr1, |r| { + self.cannot_name_placeholder(fr1, r) }) - .or_else(|| { - // If we fail to find THAT, it may be that `fr1` is a - // placeholder that cannot "fit" into its SCC. In that - // case, there should be some `r` where `fr1: r`, both - // `fr1` and `r` are in the same SCC, and `fr1` is a - // placeholder that `r` cannot name. We can blame that - // edge. - self.find_constraint_paths_between_regions(fr1, |r| { - self.constraint_sccs.scc(fr1) == self.constraint_sccs.scc(r) - && self.cannot_name_placeholder(r, fr1) - }) + }) + .or_else(|| { + // If we fail to find THAT, it may be that `fr1` is a + // placeholder that cannot "fit" into its SCC. In that + // case, there should be some `r` where `fr1: r`, both + // `fr1` and `r` are in the same SCC, and `fr1` is a + // placeholder that `r` cannot name. We can blame that + // edge. + self.find_constraint_paths_between_regions(fr1, |r| { + self.constraint_sccs.scc(fr1) == self.constraint_sccs.scc(r) + && self.cannot_name_placeholder(r, fr1) }) - .map(|(_path, r)| r) - .unwrap() + }) + .map(|(_path, r)| r) + .unwrap() } // Finds a good span to blame for the fact that `fr1` outlives `fr2`. @@ -901,12 +861,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { fr1_origin: NLLRegionVariableOrigin, fr2: RegionVid, ) -> (ConstraintCategory, Span) { - let (category, _, span) = self.best_blame_constraint( - body, - fr1, - fr1_origin, - |r| self.provides_universal_region(r, fr1, fr2), - ); + let (category, _, span) = self.best_blame_constraint(body, fr1, fr1_origin, |r| { + self.provides_universal_region(r, fr1, fr2) + }); (category, span) } @@ -922,9 +879,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { let opt_span_category = self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub)); - opt_span_category - .map(|&(category, span)| (category, true, span)) - .unwrap_or((constraint.category, false, body.source_info(loc).span)) + opt_span_category.map(|&(category, span)| (category, true, span)).unwrap_or(( + constraint.category, + false, + body.source_info(loc).span, + )) } /// Returns `true` if a closure is inferred to be an `FnMut` closure. diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index 720c77beaf8b5..e551e2eb59fed 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -1,25 +1,22 @@ use std::fmt::{self, Display}; use rustc::hir; -use rustc::hir::def::{Res, DefKind}; +use rustc::hir::def::{DefKind, Res}; use rustc::hir::def_id::DefId; use rustc::infer::InferCtxt; -use rustc::mir::{Local, Body}; -use rustc::ty::subst::{SubstsRef, GenericArgKind}; -use rustc::ty::{self, RegionVid, Ty, TyCtxt}; +use rustc::mir::{Body, Local}; use rustc::ty::print::RegionHighlightMode; -use rustc_index::vec::IndexVec; +use rustc::ty::subst::{GenericArgKind, SubstsRef}; +use rustc::ty::{self, RegionVid, Ty, TyCtxt}; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::DiagnosticBuilder; +use rustc_index::vec::IndexVec; use syntax::symbol::kw; -use rustc_data_structures::fx::FxHashMap; -use syntax_pos::{Span, symbol::Symbol, DUMMY_SP}; +use syntax_pos::{symbol::Symbol, Span, DUMMY_SP}; use crate::borrow_check::{ - diagnostics::region_errors::ErrorReportingCtx, - region_infer::RegionInferenceContext, - universal_regions::DefiningTy, - nll::ToRegionVid, - Upvar, + diagnostics::region_errors::ErrorReportingCtx, nll::ToRegionVid, + region_infer::RegionInferenceContext, universal_regions::DefiningTy, Upvar, }; /// A name for a particular region used in emitting diagnostics. This name could be a generated @@ -76,10 +73,7 @@ crate struct RegionErrorNamingCtx { impl RegionErrorNamingCtx { crate fn new() -> Self { - Self { - counter: 1, - renctx: FxHashMap::default(), - } + Self { counter: 1, renctx: FxHashMap::default() } } /// Get the name of `region` if it has previously been named. @@ -108,17 +102,17 @@ impl RegionErrorNamingCtx { impl RegionName { crate fn was_named(&self) -> bool { match self.source { - RegionNameSource::NamedEarlyBoundRegion(..) | - RegionNameSource::NamedFreeRegion(..) | - RegionNameSource::Static => true, - RegionNameSource::SynthesizedFreeEnvRegion(..) | - RegionNameSource::CannotMatchHirTy(..) | - RegionNameSource::MatchedHirTy(..) | - RegionNameSource::MatchedAdtAndSegment(..) | - RegionNameSource::AnonRegionFromUpvar(..) | - RegionNameSource::AnonRegionFromOutput(..) | - RegionNameSource::AnonRegionFromYieldTy(..) | - RegionNameSource::AnonRegionFromAsyncFn(..) => false, + RegionNameSource::NamedEarlyBoundRegion(..) + | RegionNameSource::NamedFreeRegion(..) + | RegionNameSource::Static => true, + RegionNameSource::SynthesizedFreeEnvRegion(..) + | RegionNameSource::CannotMatchHirTy(..) + | RegionNameSource::MatchedHirTy(..) + | RegionNameSource::MatchedAdtAndSegment(..) + | RegionNameSource::AnonRegionFromUpvar(..) + | RegionNameSource::AnonRegionFromOutput(..) + | RegionNameSource::AnonRegionFromYieldTy(..) + | RegionNameSource::AnonRegionFromAsyncFn(..) => false, } } @@ -138,8 +132,8 @@ impl RegionName { RegionNameSource::CannotMatchHirTy(span, type_name) => { diag.span_label(*span, format!("has type `{}`", type_name)); } - RegionNameSource::MatchedHirTy(span) | - RegionNameSource::AnonRegionFromAsyncFn(span) => { + RegionNameSource::MatchedHirTy(span) + | RegionNameSource::AnonRegionFromAsyncFn(span) => { diag.span_label( *span, format!("let's call the lifetime of this reference `{}`", self), @@ -151,25 +145,16 @@ impl RegionName { RegionNameSource::AnonRegionFromUpvar(span, upvar_name) => { diag.span_label( *span, - format!( - "lifetime `{}` appears in the type of `{}`", - self, upvar_name - ), + format!("lifetime `{}` appears in the type of `{}`", self, upvar_name), ); } RegionNameSource::AnonRegionFromOutput(span, mir_description, type_name) => { - diag.span_label( - *span, - format!("return type{} is {}", mir_description, type_name), - ); - }, + diag.span_label(*span, format!("return type{} is {}", mir_description, type_name)); + } RegionNameSource::AnonRegionFromYieldTy(span, type_name) => { - diag.span_label( - *span, - format!("yield type is {}", type_name), - ); + diag.span_label(*span, format!("yield type is {}", type_name)); } - RegionNameSource::Static => {}, + RegionNameSource::Static => {} } } } @@ -212,9 +197,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { renctx: &mut RegionErrorNamingCtx, fr: RegionVid, ) -> Option { - let ErrorReportingCtx { - infcx, body, mir_def_id, local_names, upvars, .. - } = errctx; + let ErrorReportingCtx { infcx, body, mir_def_id, local_names, upvars, .. } = errctx; debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter); @@ -228,22 +211,33 @@ impl<'tcx> RegionInferenceContext<'tcx> { .give_name_from_error_region(infcx.tcx, *mir_def_id, fr, renctx) .or_else(|| { self.give_name_if_anonymous_region_appears_in_arguments( - infcx, body, local_names, *mir_def_id, fr, renctx, + infcx, + body, + local_names, + *mir_def_id, + fr, + renctx, ) }) .or_else(|| { - self.give_name_if_anonymous_region_appears_in_upvars( - infcx.tcx, upvars, fr, renctx - ) + self.give_name_if_anonymous_region_appears_in_upvars(infcx.tcx, upvars, fr, renctx) }) .or_else(|| { self.give_name_if_anonymous_region_appears_in_output( - infcx, body, *mir_def_id, fr, renctx, + infcx, + body, + *mir_def_id, + fr, + renctx, ) }) .or_else(|| { self.give_name_if_anonymous_region_appears_in_yield_ty( - infcx, body, *mir_def_id, fr, renctx, + infcx, + body, + *mir_def_id, + fr, + renctx, ) }); @@ -282,24 +276,23 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - ty::ReStatic => Some(RegionName { - name: kw::StaticLifetime, - source: RegionNameSource::Static - }), + ty::ReStatic => { + Some(RegionName { name: kw::StaticLifetime, source: RegionNameSource::Static }) + } ty::ReFree(free_region) => match free_region.bound_region { ty::BoundRegion::BrNamed(region_def_id, name) => { // Get the span to point to, even if we don't use the name. let span = tcx.hir().span_if_local(region_def_id).unwrap_or(DUMMY_SP); - debug!("bound region named: {:?}, is_named: {:?}", - name, free_region.bound_region.is_named()); + debug!( + "bound region named: {:?}, is_named: {:?}", + name, + free_region.bound_region.is_named() + ); if free_region.bound_region.is_named() { // A named region that is actually named. - Some(RegionName { - name, - source: RegionNameSource::NamedFreeRegion(span), - }) + Some(RegionName { name, source: RegionNameSource::NamedFreeRegion(span) }) } else { // If we spuriously thought that the region is named, we should let the // system generate a true name for error messages. Currently this can @@ -557,15 +550,17 @@ impl<'tcx> RegionInferenceContext<'tcx> { // FIXME: We should be able to do something similar to // match_adt_and_segment in this case. Res::Def(DefKind::TyAlias, _) => (), - _ => if let Some(last_segment) = path.segments.last() { - if let Some(name) = self.match_adt_and_segment( - substs, - needle_fr, - last_segment, - renctx, - search_stack, - ) { - return Some(name); + _ => { + if let Some(last_segment) = path.segments.last() { + if let Some(name) = self.match_adt_and_segment( + substs, + needle_fr, + last_segment, + renctx, + search_stack, + ) { + return Some(name); + } } } } @@ -626,8 +621,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { }) } - hir::LifetimeName::ImplicitObjectLifetimeDefault - | hir::LifetimeName::Implicit => { + hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Implicit => { // In this case, the user left off the lifetime; so // they wrote something like: // @@ -733,10 +727,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let tcx = infcx.tcx; let return_ty = self.universal_regions.unnormalized_output_ty; - debug!( - "give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", - return_ty - ); + debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) { return None; } @@ -756,11 +747,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { hir::FunctionRetTy::DefaultReturn(_) => tcx.sess.source_map().end_point(*span), hir::FunctionRetTy::Return(_) => return_ty.output.span(), }, - if gen_move.is_some() { - " of generator" - } else { - " of closure" - }, + if gen_move.is_some() { " of generator" } else { " of closure" }, ), hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Method(method_sig, _), @@ -793,10 +780,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Note: generators from `async fn` yield `()`, so we don't have to // worry about them here. let yield_ty = self.universal_regions.yield_ty?; - debug!( - "give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", - yield_ty, - ); + debug!("give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", yield_ty,); let tcx = infcx.tcx; @@ -812,19 +796,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { let yield_span = match tcx.hir().get(mir_hir_id) { hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(_, _, _, span, _), - .. - }) => ( - tcx.sess.source_map().end_point(*span) - ), + kind: hir::ExprKind::Closure(_, _, _, span, _), .. + }) => (tcx.sess.source_map().end_point(*span)), _ => body.span, }; debug!( "give_name_if_anonymous_region_appears_in_yield_ty: \ type_name = {:?}, yield_span = {:?}", - yield_span, - type_name, + yield_span, type_name, ); Some(RegionName { diff --git a/src/librustc_mir/borrow_check/diagnostics/var_name.rs b/src/librustc_mir/borrow_check/diagnostics/var_name.rs index 839e09be7af82..76ad7bf886be5 100644 --- a/src/librustc_mir/borrow_check/diagnostics/var_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/var_name.rs @@ -1,6 +1,6 @@ -use crate::borrow_check::{nll::ToRegionVid, region_infer::RegionInferenceContext}; use crate::borrow_check::Upvar; -use rustc::mir::{Local, Body}; +use crate::borrow_check::{nll::ToRegionVid, region_infer::RegionInferenceContext}; +use rustc::mir::{Body, Local}; use rustc::ty::{RegionVid, TyCtxt}; use rustc_index::vec::{Idx, IndexVec}; use syntax::source_map::Span; @@ -21,8 +21,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!("get_var_name_and_span_for_region: attempting upvar"); self.get_upvar_index_for_region(tcx, fr) .map(|index| { - let (name, span) = - self.get_upvar_name_and_span_for_region(tcx, upvars, index); + let (name, span) = self.get_upvar_name_and_span_for_region(tcx, upvars, index); (Some(name), span) }) .or_else(|| { @@ -35,11 +34,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Search the upvars (if any) to find one that references fr. Return its index. crate fn get_upvar_index_for_region(&self, tcx: TyCtxt<'tcx>, fr: RegionVid) -> Option { - let upvar_index = self - .universal_regions - .defining_ty - .upvar_tys(tcx) - .position(|upvar_ty| { + let upvar_index = + self.universal_regions.defining_ty.upvar_tys(tcx).position(|upvar_ty| { debug!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty); tcx.any_free_region_meets(&upvar_ty, |r| { let r = r.to_region_vid(); @@ -48,11 +44,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { }) })?; - let upvar_ty = self - .universal_regions - .defining_ty - .upvar_tys(tcx) - .nth(upvar_index); + let upvar_ty = self.universal_regions.defining_ty.upvar_tys(tcx).nth(upvar_index); debug!( "get_upvar_index_for_region: found {:?} in upvar {} which has type {:?}", @@ -75,8 +67,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { let upvar_name = tcx.hir().name(upvar_hir_id); let upvar_span = tcx.hir().span(upvar_hir_id); - debug!("get_upvar_name_and_span_for_region: upvar_name={:?} upvar_span={:?}", - upvar_name, upvar_span); + debug!( + "get_upvar_name_and_span_for_region: upvar_name={:?} upvar_span={:?}", + upvar_name, upvar_span + ); (upvar_name, upvar_span) } @@ -92,18 +86,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { fr: RegionVid, ) -> Option { let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs(); - let argument_index = self - .universal_regions - .unnormalized_input_tys - .iter() - .skip(implicit_inputs) - .position(|arg_ty| { - debug!( - "get_argument_index_for_region: arg_ty = {:?}", - arg_ty - ); - tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr) - })?; + let argument_index = + self.universal_regions.unnormalized_input_tys.iter().skip(implicit_inputs).position( + |arg_ty| { + debug!("get_argument_index_for_region: arg_ty = {:?}", arg_ty); + tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr) + }, + )?; debug!( "get_argument_index_for_region: found {:?} in argument {} which has type {:?}", @@ -127,8 +116,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { let argument_name = local_names[argument_local]; let argument_span = body.local_decls[argument_local].source_info.span; - debug!("get_argument_name_and_span_for_region: argument_name={:?} argument_span={:?}", - argument_name, argument_span); + debug!( + "get_argument_name_and_span_for_region: argument_name={:?} argument_span={:?}", + argument_name, argument_span + ); (argument_name, argument_span) } diff --git a/src/librustc_mir/borrow_check/invalidation.rs b/src/librustc_mir/borrow_check/invalidation.rs index d5b9aaf9511a1..f9ffa2138ba40 100644 --- a/src/librustc_mir/borrow_check/invalidation.rs +++ b/src/librustc_mir/borrow_check/invalidation.rs @@ -1,20 +1,17 @@ -use rustc::ty::{self, TyCtxt}; use rustc::mir::visit::Visitor; -use rustc::mir::{BasicBlock, Location, Body, Place, ReadOnlyBodyAndCache, Rvalue}; -use rustc::mir::{Statement, StatementKind}; use rustc::mir::TerminatorKind; -use rustc::mir::{Operand, BorrowKind, Mutability}; +use rustc::mir::{BasicBlock, Body, Location, Place, ReadOnlyBodyAndCache, Rvalue}; +use rustc::mir::{BorrowKind, Mutability, Operand}; +use rustc::mir::{Statement, StatementKind}; +use rustc::ty::{self, TyCtxt}; use rustc_data_structures::graph::dominators::Dominators; use crate::dataflow::indexes::BorrowIndex; use crate::borrow_check::{ - borrow_set::BorrowSet, - location::LocationTable, - facts::AllFacts, - path_utils::*, - JustWrite, WriteAndRead, AccessDepth, Deep, Shallow, ReadOrWrite, Activation, Read, - Reservation, Write, LocalMutationIsAllowed, MutateMode, ArtificialField, ReadKind, WriteKind, + borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, path_utils::*, AccessDepth, + Activation, ArtificialField, Deep, JustWrite, LocalMutationIsAllowed, MutateMode, Read, + ReadKind, ReadOrWrite, Reservation, Shallow, Write, WriteAndRead, WriteKind, }; pub(super) fn generate_invalidates<'tcx>( @@ -59,40 +56,20 @@ struct InvalidationGenerator<'cx, 'tcx> { /// Visits the whole MIR and generates `invalidates()` facts. /// Most of the code implementing this was stolen from `borrow_check/mod.rs`. impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { - fn visit_statement( - &mut self, - statement: &Statement<'tcx>, - location: Location, - ) { + fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { self.check_activations(location); match statement.kind { - StatementKind::Assign(box(ref lhs, ref rhs)) => { - self.consume_rvalue( - location, - rhs, - ); + StatementKind::Assign(box (ref lhs, ref rhs)) => { + self.consume_rvalue(location, rhs); - self.mutate_place( - location, - lhs, - Shallow(None), - JustWrite - ); + self.mutate_place(location, lhs, Shallow(None), JustWrite); } StatementKind::FakeRead(_, _) => { // Only relavent for initialized/liveness/safety checks. } - StatementKind::SetDiscriminant { - ref place, - variant_index: _, - } => { - self.mutate_place( - location, - place, - Shallow(None), - JustWrite, - ); + StatementKind::SetDiscriminant { ref place, variant_index: _ } => { + self.mutate_place(location, place, Shallow(None), JustWrite); } StatementKind::InlineAsm(ref asm) => { for (o, output) in asm.asm.outputs.iter().zip(asm.outputs.iter()) { @@ -118,10 +95,10 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { self.consume_operand(location, input); } } - StatementKind::Nop | - StatementKind::AscribeUserType(..) | - StatementKind::Retag { .. } | - StatementKind::StorageLive(..) => { + StatementKind::Nop + | StatementKind::AscribeUserType(..) + | StatementKind::Retag { .. } + | StatementKind::StorageLive(..) => { // `Nop`, `AscribeUserType`, `Retag`, and `StorageLive` are irrelevant // to borrow check. } @@ -138,27 +115,14 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { self.super_statement(statement, location); } - fn visit_terminator_kind( - &mut self, - kind: &TerminatorKind<'tcx>, - location: Location - ) { + fn visit_terminator_kind(&mut self, kind: &TerminatorKind<'tcx>, location: Location) { self.check_activations(location); match kind { - TerminatorKind::SwitchInt { - ref discr, - switch_ty: _, - values: _, - targets: _, - } => { + TerminatorKind::SwitchInt { ref discr, switch_ty: _, values: _, targets: _ } => { self.consume_operand(location, discr); } - TerminatorKind::Drop { - location: ref drop_place, - target: _, - unwind: _, - } => { + TerminatorKind::Drop { location: ref drop_place, target: _, unwind: _ } => { self.access_place( location, drop_place, @@ -172,16 +136,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { target: _, unwind: _, } => { - self.mutate_place( - location, - drop_place, - Deep, - JustWrite, - ); - self.consume_operand( - location, - new_value, - ); + self.mutate_place(location, drop_place, Deep, JustWrite); + self.consume_operand(location, new_value); } TerminatorKind::Call { ref func, @@ -195,21 +151,10 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { self.consume_operand(location, arg); } if let Some((ref dest, _ /*bb*/)) = *destination { - self.mutate_place( - location, - dest, - Deep, - JustWrite, - ); + self.mutate_place(location, dest, Deep, JustWrite); } } - TerminatorKind::Assert { - ref cond, - expected: _, - ref msg, - target: _, - cleanup: _, - } => { + TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => { self.consume_operand(location, cond); use rustc::mir::interpret::PanicInfo; if let PanicInfo::BoundsCheck { ref len, ref index } = *msg { @@ -217,11 +162,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { self.consume_operand(location, index); } } - TerminatorKind::Yield { - ref value, - resume, - drop: _, - } => { + TerminatorKind::Yield { ref value, resume, drop: _ } => { self.consume_operand(location, value); // Invalidate all borrows of local places @@ -246,14 +187,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { TerminatorKind::Goto { target: _ } | TerminatorKind::Abort | TerminatorKind::Unreachable - | TerminatorKind::FalseEdges { - real_target: _, - imaginary_target: _, - } - | TerminatorKind::FalseUnwind { - real_target: _, - unwind: _, - } => { + | TerminatorKind::FalseEdges { real_target: _, imaginary_target: _ } + | TerminatorKind::FalseUnwind { real_target: _, unwind: _ } => { // no data used, thus irrelevant to borrowck } } @@ -280,11 +215,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { } /// Simulates consumption of an operand. - fn consume_operand( - &mut self, - location: Location, - operand: &Operand<'tcx>, - ) { + fn consume_operand(&mut self, location: Location, operand: &Operand<'tcx>) { match *operand { Operand::Copy(ref place) => { self.access_place( @@ -307,17 +238,13 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { } // Simulates consumption of an rvalue - fn consume_rvalue( - &mut self, - location: Location, - rvalue: &Rvalue<'tcx>, - ) { + fn consume_rvalue(&mut self, location: Location, rvalue: &Rvalue<'tcx>) { match *rvalue { Rvalue::Ref(_ /*rgn*/, bk, ref place) => { let access_kind = match bk { BorrowKind::Shallow => { (Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk))) - }, + } BorrowKind::Shared => (Deep, Read(ReadKind::Borrow(bk))), BorrowKind::Unique | BorrowKind::Mut { .. } => { let wk = WriteKind::MutableBorrow(bk); @@ -329,28 +256,21 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { } }; - self.access_place( - location, - place, - access_kind, - LocalMutationIsAllowed::No, - ); + self.access_place(location, place, access_kind, LocalMutationIsAllowed::No); } Rvalue::AddressOf(mutability, ref place) => { let access_kind = match mutability { - Mutability::Mut => (Deep, Write(WriteKind::MutableBorrow(BorrowKind::Mut { - allow_two_phase_borrow: false, - }))), + Mutability::Mut => ( + Deep, + Write(WriteKind::MutableBorrow(BorrowKind::Mut { + allow_two_phase_borrow: false, + })), + ), Mutability::Not => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))), }; - self.access_place( - location, - place, - access_kind, - LocalMutationIsAllowed::No, - ); + self.access_place(location, place, access_kind, LocalMutationIsAllowed::No); } Rvalue::Use(ref operand) @@ -380,8 +300,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { self.consume_operand(location, operand2); } - Rvalue::NullaryOp(_op, _ty) => { - } + Rvalue::NullaryOp(_op, _ty) => {} Rvalue::Aggregate(_, ref operands) => { for operand in operands { @@ -414,10 +333,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { debug!( "invalidation::check_access_for_conflict(location={:?}, place={:?}, sd={:?}, \ rw={:?})", - location, - place, - sd, - rw, + location, place, sd, rw, ); let tcx = self.tcx; let body = self.body; @@ -466,9 +382,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { this.generate_invalidates(borrow_index, location); } - (Reservation(_), _) - | (Activation(_, _), _) - | (Write(_), _) => { + (Reservation(_), _) | (Activation(_, _), _) | (Write(_), _) => { // unique or mutable borrows are invalidated by writes. // Reservations count as writes since we need to check // that activating the borrow will be OK @@ -481,17 +395,13 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { ); } - /// Generates a new `invalidates(L, B)` fact. fn generate_invalidates(&mut self, b: BorrowIndex, l: Location) { let lidx = self.location_table.start_index(l); self.all_facts.invalidates.push((lidx, b)); } - fn check_activations( - &mut self, - location: Location, - ) { + fn check_activations(&mut self, location: Location) { // Two-phase borrow support: For each activation that is newly // generated at this statement, check if it interferes with // another borrow. @@ -507,10 +417,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { self.access_place( location, &borrow.borrowed_place, - ( - Deep, - Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index), - ), + (Deep, Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index)), LocalMutationIsAllowed::No, ); diff --git a/src/librustc_mir/borrow_check/location.rs b/src/librustc_mir/borrow_check/location.rs index 9e94317b87e54..7bc746b181d81 100644 --- a/src/librustc_mir/borrow_check/location.rs +++ b/src/librustc_mir/borrow_check/location.rs @@ -1,4 +1,4 @@ -use rustc::mir::{BasicBlock, Location, Body}; +use rustc::mir::{BasicBlock, Body, Location}; use rustc_index::vec::{Idx, IndexVec}; /// Maps between a MIR Location, which identifies a particular @@ -32,7 +32,8 @@ crate enum RichLocation { impl LocationTable { crate fn new(body: &Body<'_>) -> Self { let mut num_points = 0; - let statements_before_block = body.basic_blocks() + let statements_before_block = body + .basic_blocks() .iter() .map(|block_data| { let v = num_points; @@ -41,16 +42,10 @@ impl LocationTable { }) .collect(); - debug!( - "LocationTable(statements_before_block={:#?})", - statements_before_block - ); + debug!("LocationTable(statements_before_block={:#?})", statements_before_block); debug!("LocationTable: num_points={:#?}", num_points); - Self { - num_points, - statements_before_block, - } + Self { num_points, statements_before_block } } crate fn all_points(&self) -> impl Iterator { @@ -58,19 +53,13 @@ impl LocationTable { } crate fn start_index(&self, location: Location) -> LocationIndex { - let Location { - block, - statement_index, - } = location; + let Location { block, statement_index } = location; let start_index = self.statements_before_block[block]; LocationIndex::new(start_index + statement_index * 2) } crate fn mid_index(&self, location: Location) -> LocationIndex { - let Location { - block, - statement_index, - } = location; + let Location { block, statement_index } = location; let start_index = self.statements_before_block[block]; LocationIndex::new(start_index + statement_index * 2 + 1) } @@ -94,7 +83,8 @@ impl LocationTable { // the last point where the "first index" (0, 10, or 20) // was less than the statement index (22). In our case, this will // be (BB2, 20). - let (block, &first_index) = self.statements_before_block + let (block, &first_index) = self + .statements_before_block .iter_enumerated() .filter(|(_, first_index)| **first_index <= point_index) .last() diff --git a/src/librustc_mir/borrow_check/member_constraints.rs b/src/librustc_mir/borrow_check/member_constraints.rs index 75213d30982f9..9d310fedaf1e9 100644 --- a/src/librustc_mir/borrow_check/member_constraints.rs +++ b/src/librustc_mir/borrow_check/member_constraints.rs @@ -141,11 +141,7 @@ where first_constraints2.insert(r2, start1); } - MemberConstraintSet { - first_constraints: first_constraints2, - constraints, - choice_regions, - } + MemberConstraintSet { first_constraints: first_constraints2, constraints, choice_regions } } } @@ -153,9 +149,7 @@ impl MemberConstraintSet<'tcx, R> where R: Copy + Hash + Eq, { - crate fn all_indices( - &self, - ) -> impl Iterator { + crate fn all_indices(&self) -> impl Iterator { self.constraints.indices() } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index cd1e72e9d1701..4a6379e3bc155 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1,25 +1,25 @@ //! This query borrow-checks the MIR to (further) ensure it is not broken. -use rustc::hir::{self, HirId}; -use rustc::hir::Node; use rustc::hir::def_id::DefId; +use rustc::hir::Node; +use rustc::hir::{self, HirId}; use rustc::infer::InferCtxt; +use rustc::lint::builtin::MUTABLE_BORROW_RESERVATION_CONFLICT; use rustc::lint::builtin::UNUSED_MUT; -use rustc::lint::builtin::{MUTABLE_BORROW_RESERVATION_CONFLICT}; -use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc::mir::{ - ClearCrossCrate, Local, Location, Body, BodyAndCache, Mutability, Operand, Place, PlaceBase, - PlaceElem, PlaceRef, ReadOnlyBodyAndCache, Static, StaticKind, read_only + read_only, Body, BodyAndCache, ClearCrossCrate, Local, Location, Mutability, Operand, Place, + PlaceBase, PlaceElem, PlaceRef, ReadOnlyBodyAndCache, Static, StaticKind, }; +use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; use rustc::mir::{Terminator, TerminatorKind}; use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt}; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; -use rustc_index::bit_set::BitSet; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; use smallvec::SmallVec; @@ -34,45 +34,45 @@ use crate::dataflow::indexes::{BorrowIndex, InitIndex, MoveOutIndex, MovePathInd use crate::dataflow::move_paths::{HasMoveData, InitLocation, LookupResult, MoveData, MoveError}; use crate::dataflow::Borrows; use crate::dataflow::DataflowResultsConsumer; +use crate::dataflow::EverInitializedPlaces; use crate::dataflow::FlowAtLocation; use crate::dataflow::MoveDataParamEnv; use crate::dataflow::{do_dataflow, DebugFormatted}; -use crate::dataflow::EverInitializedPlaces; use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; +use self::diagnostics::AccessKind; use self::flows::Flows; use self::location::LocationTable; use self::prefixes::PrefixSet; use self::MutateMode::{JustWrite, WriteAndRead}; -use self::diagnostics::AccessKind; use self::path_utils::*; +mod borrow_set; +mod constraint_generation; +mod constraints; mod diagnostics; +mod facts; mod flows; +mod invalidation; mod location; +mod member_constraints; +mod nll; mod path_utils; +mod place_ext; +mod places_conflict; mod prefixes; -mod used_muts; -mod constraint_generation; -mod facts; -mod invalidation; +mod region_infer; mod renumber; -mod member_constraints; -mod constraints; -mod universal_regions; mod type_check; -mod region_infer; -mod borrow_set; -mod place_ext; -mod places_conflict; -mod nll; +mod universal_regions; +mod used_muts; -crate use region_infer::RegionInferenceContext; -crate use borrow_set::{BorrowSet, BorrowData}; -crate use places_conflict::{places_conflict, PlaceConflictBias}; -crate use place_ext::PlaceExt; +crate use borrow_set::{BorrowData, BorrowSet}; crate use nll::ToRegionVid; +crate use place_ext::PlaceExt; +crate use places_conflict::{places_conflict, PlaceConflictBias}; +crate use region_infer::RegionInferenceContext; // FIXME(eddyb) perhaps move this somewhere more centrally. #[derive(Debug)] @@ -88,10 +88,7 @@ crate struct Upvar { } pub fn provide(providers: &mut Providers<'_>) { - *providers = Providers { - mir_borrowck, - ..*providers - }; + *providers = Providers { mir_borrowck, ..*providers }; } fn mir_borrowck(tcx: TyCtxt<'_>, def_id: DefId) -> BorrowCheckResult<'_> { @@ -119,19 +116,20 @@ fn do_mir_borrowck<'a, 'tcx>( let tcx = infcx.tcx; let attributes = tcx.get_attrs(def_id); let param_env = tcx.param_env(def_id); - let id = tcx - .hir() - .as_local_hir_id(def_id) - .expect("do_mir_borrowck: non-local DefId"); + let id = tcx.hir().as_local_hir_id(def_id).expect("do_mir_borrowck: non-local DefId"); let mut local_names = IndexVec::from_elem(None, &input_body.local_decls); for var_debug_info in &input_body.var_debug_info { if let Some(local) = var_debug_info.place.as_local() { if let Some(prev_name) = local_names[local] { if var_debug_info.name != prev_name { - span_bug!(var_debug_info.source_info.span, + span_bug!( + var_debug_info.source_info.span, "local {:?} has many names (`{}` vs `{}`)", - local, prev_name, var_debug_info.name); + local, + prev_name, + var_debug_info.name + ); } } local_names[local] = Some(var_debug_info.name); @@ -158,8 +156,7 @@ fn do_mir_borrowck<'a, 'tcx>( by_ref, mutability: Mutability::Not, }; - let bm = *tables.pat_binding_modes().get(var_hir_id) - .expect("missing binding mode"); + let bm = *tables.pat_binding_modes().get(var_hir_id).expect("missing binding mode"); if bm == ty::BindByValue(hir::Mutability::Mut) { upvar.mutability = Mutability::Mut; } @@ -177,10 +174,7 @@ fn do_mir_borrowck<'a, 'tcx>( let free_regions = nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body, &mut promoted); let body = read_only!(body); // no further changes - let promoted: IndexVec<_, _> = promoted - .iter_mut() - .map(|body| read_only!(body)) - .collect(); + let promoted: IndexVec<_, _> = promoted.iter_mut().map(|body| read_only!(body)).collect(); let location_table = &LocationTable::new(&body); @@ -191,10 +185,7 @@ fn do_mir_borrowck<'a, 'tcx>( Err((move_data, move_errors)) => (move_data, Some(move_errors)), }; - let mdpe = MoveDataParamEnv { - move_data, - param_env, - }; + let mdpe = MoveDataParamEnv { move_data, param_env }; let dead_unwinds = BitSet::new_empty(body.basic_blocks().len()); let mut flow_inits = FlowAtLocation::new(do_dataflow( @@ -208,8 +199,8 @@ fn do_mir_borrowck<'a, 'tcx>( )); let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(id).is_fn_or_closure(); - let borrow_set = Rc::new(BorrowSet::build( - tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data)); + let borrow_set = + Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data)); // If we are in non-lexical mode, compute the non-lexical lifetimes. let (regioncx, polonius_output, opt_closure_req) = nll::compute_regions( @@ -297,12 +288,7 @@ fn do_mir_borrowck<'a, 'tcx>( local_names, }; - let mut state = Flows::new( - flow_borrows, - flow_uninits, - flow_ever_inits, - polonius_output, - ); + let mut state = Flows::new(flow_borrows, flow_uninits, flow_ever_inits, polonius_output); if let Some(errors) = move_errors { mbcx.report_move_errors(errors); @@ -323,7 +309,11 @@ fn do_mir_borrowck<'a, 'tcx>( // Span and message don't matter; we overwrite them below anyway let mut diag = mbcx.infcx.tcx.struct_span_lint_hir( - MUTABLE_BORROW_RESERVATION_CONFLICT, lint_root, DUMMY_SP, ""); + MUTABLE_BORROW_RESERVATION_CONFLICT, + lint_root, + DUMMY_SP, + "", + ); diag.message = initial_diag.styled_message().clone(); diag.span = initial_diag.span.clone(); @@ -337,22 +327,22 @@ fn do_mir_borrowck<'a, 'tcx>( // Note that this set is expected to be small - only upvars from closures // would have a chance of erroneously adding non-user-defined mutable vars // to the set. - let temporary_used_locals: FxHashSet = mbcx.used_mut.iter() + let temporary_used_locals: FxHashSet = mbcx + .used_mut + .iter() .filter(|&local| !mbcx.body.local_decls[*local].is_user_variable()) .cloned() .collect(); // For the remaining unused locals that are marked as mutable, we avoid linting any that // were never initialized. These locals may have been removed as unreachable code; or will be // linted as unused variables. - let unused_mut_locals = mbcx.body.mut_vars_iter() - .filter(|local| !mbcx.used_mut.contains(local)) - .collect(); + let unused_mut_locals = + mbcx.body.mut_vars_iter().filter(|local| !mbcx.used_mut.contains(local)).collect(); mbcx.gather_used_muts(temporary_used_locals, unused_mut_locals); debug!("mbcx.used_mut: {:?}", mbcx.used_mut); let used_mut = mbcx.used_mut; - for local in mbcx.body.mut_vars_and_args_iter().filter(|local| !used_mut.contains(local)) - { + for local in mbcx.body.mut_vars_and_args_iter().filter(|local| !used_mut.contains(local)) { let local_decl = &mbcx.body.local_decls[local]; let lint_root = match &mbcx.body.source_scopes[local_decl.source_info.scope].local_data { ClearCrossCrate::Set(data) => data.lint_root, @@ -361,9 +351,11 @@ fn do_mir_borrowck<'a, 'tcx>( // Skip over locals that begin with an underscore or have no name match mbcx.local_names[local] { - Some(name) => if name.as_str().starts_with("_") { - continue; - }, + Some(name) => { + if name.as_str().starts_with("_") { + continue; + } + } None => continue, } @@ -448,10 +440,8 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> { /// Migration warnings to be reported for #56254. We delay reporting these /// so that we can suppress the warning if there's a corresponding error /// for the activation of the borrow. - reservation_warnings: FxHashMap< - BorrowIndex, - (Place<'tcx>, Span, Location, BorrowKind, BorrowData<'tcx>) - >, + reservation_warnings: + FxHashMap, Span, Location, BorrowKind, BorrowData<'tcx>)>, /// This field keeps track of move errors that are to be reported for given move indicies. /// /// There are situations where many errors can be reported for a single move out (see #53807) @@ -518,29 +508,16 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx stmt: &'cx Statement<'tcx>, flow_state: &Self::FlowState, ) { - debug!( - "MirBorrowckCtxt::process_statement({:?}, {:?}): {}", - location, stmt, flow_state - ); + debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {}", location, stmt, flow_state); let span = stmt.source_info.span; self.check_activations(location, span, flow_state); match stmt.kind { - StatementKind::Assign(box(ref lhs, ref rhs)) => { - self.consume_rvalue( - location, - (rhs, span), - flow_state, - ); + StatementKind::Assign(box (ref lhs, ref rhs)) => { + self.consume_rvalue(location, (rhs, span), flow_state); - self.mutate_place( - location, - (lhs, span), - Shallow(None), - JustWrite, - flow_state, - ); + self.mutate_place(location, (lhs, span), Shallow(None), JustWrite, flow_state); } StatementKind::FakeRead(_, box ref place) => { // Read for match doesn't access any memory and is used to @@ -560,17 +537,8 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx flow_state, ); } - StatementKind::SetDiscriminant { - ref place, - variant_index: _, - } => { - self.mutate_place( - location, - (place, span), - Shallow(None), - JustWrite, - flow_state, - ); + StatementKind::SetDiscriminant { ref place, variant_index: _ } => { + self.mutate_place(location, (place, span), Shallow(None), JustWrite, flow_state); } StatementKind::InlineAsm(ref asm) => { for (o, output) in asm.asm.outputs.iter().zip(asm.outputs.iter()) { @@ -630,28 +598,16 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx flow_state: &Self::FlowState, ) { let loc = location; - debug!( - "MirBorrowckCtxt::process_terminator({:?}, {:?}): {}", - location, term, flow_state - ); + debug!("MirBorrowckCtxt::process_terminator({:?}, {:?}): {}", location, term, flow_state); let span = term.source_info.span; self.check_activations(location, span, flow_state); match term.kind { - TerminatorKind::SwitchInt { - ref discr, - switch_ty: _, - values: _, - targets: _, - } => { + TerminatorKind::SwitchInt { ref discr, switch_ty: _, values: _, targets: _ } => { self.consume_operand(loc, (discr, span), flow_state); } - TerminatorKind::Drop { - location: ref drop_place, - target: _, - unwind: _, - } => { + TerminatorKind::Drop { location: ref drop_place, target: _, unwind: _ } => { let tcx = self.infcx.tcx; // Compute the type with accurate region information. @@ -665,9 +621,11 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx // that is useful later. tcx.lift(&drop_place_ty).unwrap(); - debug!("visit_terminator_drop \ + debug!( + "visit_terminator_drop \ loc: {:?} term: {:?} drop_place: {:?} drop_place_ty: {:?} span: {:?}", - loc, term, drop_place, drop_place_ty, span); + loc, term, drop_place, drop_place_ty, span + ); self.access_place( loc, @@ -683,18 +641,8 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx target: _, unwind: _, } => { - self.mutate_place( - loc, - (drop_place, span), - Deep, - JustWrite, - flow_state, - ); - self.consume_operand( - loc, - (new_value, span), - flow_state, - ); + self.mutate_place(loc, (drop_place, span), Deep, JustWrite, flow_state); + self.consume_operand(loc, (new_value, span), flow_state); } TerminatorKind::Call { ref func, @@ -705,29 +653,13 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx } => { self.consume_operand(loc, (func, span), flow_state); for arg in args { - self.consume_operand( - loc, - (arg, span), - flow_state, - ); + self.consume_operand(loc, (arg, span), flow_state); } if let Some((ref dest, _ /*bb*/)) = *destination { - self.mutate_place( - loc, - (dest, span), - Deep, - JustWrite, - flow_state, - ); + self.mutate_place(loc, (dest, span), Deep, JustWrite, flow_state); } } - TerminatorKind::Assert { - ref cond, - expected: _, - ref msg, - target: _, - cleanup: _, - } => { + TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => { self.consume_operand(loc, (cond, span), flow_state); use rustc::mir::interpret::PanicInfo; if let PanicInfo::BoundsCheck { ref len, ref index } = *msg { @@ -736,11 +668,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx } } - TerminatorKind::Yield { - ref value, - resume: _, - drop: _, - } => { + TerminatorKind::Yield { ref value, resume: _, drop: _ } => { self.consume_operand(loc, (value, span), flow_state); if self.movable_generator { @@ -771,14 +699,8 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx TerminatorKind::Goto { target: _ } | TerminatorKind::Abort | TerminatorKind::Unreachable - | TerminatorKind::FalseEdges { - real_target: _, - imaginary_target: _, - } - | TerminatorKind::FalseUnwind { - real_target: _, - unwind: _, - } => { + | TerminatorKind::FalseEdges { real_target: _, imaginary_target: _ } + | TerminatorKind::FalseUnwind { real_target: _, unwind: _ } => { // no data used, thus irrelevant to borrowck } } @@ -791,8 +713,8 @@ enum MutateMode { WriteAndRead, } -use self::ReadOrWrite::{Activation, Read, Reservation, Write}; use self::AccessDepth::{Deep, Shallow}; +use self::ReadOrWrite::{Activation, Read, Reservation, Write}; #[derive(Copy, Clone, PartialEq, Eq, Debug)] enum ArtificialField { @@ -944,10 +866,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Check is_empty() first because it's the common case, and doing that // way we avoid the clone() call. - if !self.access_place_error_reported.is_empty() && - self - .access_place_error_reported - .contains(&(place_span.0.clone(), place_span.1)) + if !self.access_place_error_reported.is_empty() + && self.access_place_error_reported.contains(&(place_span.0.clone(), place_span.1)) { debug!( "access_place: suppressing error place_span=`{:?}` kind=`{:?}`", @@ -956,14 +876,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return; } - let mutability_error = - self.check_access_permissions( - place_span, - rw, - is_local_mutation_allowed, - flow_state, - location, - ); + let mutability_error = self.check_access_permissions( + place_span, + rw, + is_local_mutation_allowed, + flow_state, + location, + ); let conflict_error = self.check_access_for_conflict(location, place_span, sd, rw, flow_state); @@ -974,13 +893,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } if conflict_error || mutability_error { - debug!( - "access_place: logging error place_span=`{:?}` kind=`{:?}`", - place_span, kind - ); + debug!("access_place: logging error place_span=`{:?}` kind=`{:?}`", place_span, kind); - self.access_place_error_reported - .insert((place_span.0.clone(), place_span.1)); + self.access_place_error_reported.insert((place_span.0.clone(), place_span.1)); } } @@ -1053,7 +968,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { error_reported = true; match kind { - ReadKind::Copy => { + ReadKind::Copy => { this.report_use_while_mutably_borrowed(location, place_span, borrow) .buffer(&mut this.errors_buffer); } @@ -1066,15 +981,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } (Reservation(WriteKind::MutableBorrow(bk)), BorrowKind::Shallow) - | (Reservation(WriteKind::MutableBorrow(bk)), BorrowKind::Shared) if { - tcx.migrate_borrowck() && this.borrow_set.location_map.contains_key(&location) - } => { + | (Reservation(WriteKind::MutableBorrow(bk)), BorrowKind::Shared) + if { + tcx.migrate_borrowck() + && this.borrow_set.location_map.contains_key(&location) + } => + { let bi = this.borrow_set.location_map[&location]; debug!( "recording invalid reservation of place: {:?} with \ borrow index {:?} as warning", - place_span.0, - bi, + place_span.0, bi, ); // rust-lang/rust#56254 - This was previously permitted on // the 2018 edition so we emit it as a warning. We buffer @@ -1089,9 +1006,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Control::Continue } - (Reservation(kind), _) - | (Activation(kind, _), _) - | (Write(kind), _) => { + (Reservation(kind), _) | (Activation(kind, _), _) | (Write(kind), _) => { match rw { Reservation(..) => { debug!( @@ -1117,13 +1032,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { this.report_conflicting_borrow(location, place_span, bk, borrow) .buffer(&mut this.errors_buffer); } - WriteKind::StorageDeadOrDrop => { - this.report_borrowed_value_does_not_live_long_enough( + WriteKind::StorageDeadOrDrop => this + .report_borrowed_value_does_not_live_long_enough( location, borrow, place_span, - Some(kind)) - } + Some(kind), + ), WriteKind::Mutate => { this.report_illegal_mutation_of_borrowed(location, place_span, borrow) } @@ -1169,10 +1084,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let Mutability::Not = self.body.local_decls[local].mutability { // check for reassignments to immutable local variables self.check_if_reassignment_to_immutable_state( - location, - local, - place_span, - flow_state, + location, local, place_span, flow_state, ); return; } @@ -1199,7 +1111,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let access_kind = match bk { BorrowKind::Shallow => { (Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk))) - }, + } BorrowKind::Shared => (Deep, Read(ReadKind::Borrow(bk))), BorrowKind::Unique | BorrowKind::Mut { .. } => { let wk = WriteKind::MutableBorrow(bk); @@ -1233,12 +1145,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } - Rvalue::AddressOf(mutability, ref place) => { let access_kind = match mutability { - Mutability::Mut => (Deep, Write(WriteKind::MutableBorrow(BorrowKind::Mut { - allow_two_phase_borrow: false, - }))), + Mutability::Mut => ( + Deep, + Write(WriteKind::MutableBorrow(BorrowKind::Mut { + allow_two_phase_borrow: false, + })), + ), Mutability::Not => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))), }; @@ -1305,11 +1219,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // moved into the closure and subsequently used by the closure, // in order to populate our used_mut set. match **aggregate_kind { - AggregateKind::Closure(def_id, _) - | AggregateKind::Generator(def_id, _, _) => { - let BorrowCheckResult { - used_mut_upvars, .. - } = self.infcx.tcx.mir_borrowck(def_id); + AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) => { + let BorrowCheckResult { used_mut_upvars, .. } = + self.infcx.tcx.mir_borrowck(def_id); debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars); for field in used_mut_upvars { self.propagate_closure_used_mut_upvar(&operands[field.index()]); @@ -1467,9 +1379,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // FIXME: allow thread-locals to borrow other thread locals? let (might_be_alive, will_be_dropped) = match root_place.base { - PlaceBase::Static(_) => { - (true, false) - } + PlaceBase::Static(_) => (true, false), PlaceBase::Local(local) => { if self.body.local_decls[*local].is_ref_to_thread_local() { // Thread-locals might be dropped after the function exits @@ -1484,10 +1394,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }; if !will_be_dropped { - debug!( - "place_is_invalidated_at_exit({:?}) - won't be dropped", - place - ); + debug!("place_is_invalidated_at_exit({:?}) - won't be dropped", place); return; } @@ -1523,9 +1430,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if borrow_of_local_data(&borrow.borrowed_place) { let err = self.cannot_borrow_across_generator_yield( - self.retrieve_borrow_spans(borrow).var_or_use(), - yield_span, - ); + self.retrieve_borrow_spans(borrow).var_or_use(), + yield_span, + ); err.buffer(&mut self.errors_buffer); } @@ -1548,10 +1455,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.access_place( location, (&borrow.borrowed_place, span), - ( - Deep, - Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index), - ), + (Deep, Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index)), LocalMutationIsAllowed::No, flow_state, ); @@ -1577,9 +1481,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // And, if so, report an error. let init = &self.move_data.inits[init_index]; let span = init.span(&self.body); - self.report_illegal_reassignment( - location, place_span, span, place_span.0 - ); + self.report_illegal_reassignment(location, place_span, span, place_span.0); } } @@ -1716,16 +1618,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.check_if_full_path_is_moved(location, desired_action, place_span, flow_state); - if let [ - base_proj @ .., - ProjectionElem::Subslice { from, to, from_end: false }, - ] = place_span.0.projection { - let place_ty = Place::ty_from( - place_span.0.base, - base_proj, - self.body(), - self.infcx.tcx, - ); + if let [base_proj @ .., ProjectionElem::Subslice { from, to, from_end: false }] = + place_span.0.projection + { + let place_ty = + Place::ty_from(place_span.0.base, base_proj, self.body(), self.infcx.tcx); if let ty::Array(..) = place_ty.ty.kind { let array_place = PlaceRef { base: place_span.0.base, projection: base_proj }; self.check_if_subslice_element_is_moved( @@ -1778,8 +1675,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { place: PlaceRef<'_, 'tcx>, ) -> Result<(PlaceRef<'cx, 'tcx>, MovePathIndex), NoMovePathFound> { match self.move_data.rev_lookup.find(place) { - LookupResult::Parent(Some(mpi)) - | LookupResult::Exact(mpi) => Ok((self.move_data.move_paths[mpi].place.as_ref(), mpi)), + LookupResult::Parent(Some(mpi)) | LookupResult::Exact(mpi) => { + Ok((self.move_data.move_paths[mpi].place.as_ref(), mpi)) + } LookupResult::Parent(None) => Err(NoMovePathFound::ReachedStatic), } } @@ -1928,12 +1826,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let mut shortest_uninit_seen = None; for prefix in this.prefixes(base, PrefixSet::Shallow) { let mpi = match this.move_path_for_place(prefix) { - Some(mpi) => mpi, None => continue, + Some(mpi) => mpi, + None => continue, }; if maybe_uninits.contains(mpi) { - debug!("check_parent_of_field updating shortest_uninit_seen from {:?} to {:?}", - shortest_uninit_seen, Some((prefix, mpi))); + debug!( + "check_parent_of_field updating shortest_uninit_seen from {:?} to {:?}", + shortest_uninit_seen, + Some((prefix, mpi)) + ); shortest_uninit_seen = Some((prefix, mpi)); } else { debug!("check_parent_of_field {:?} is definitely initialized", (prefix, mpi)); @@ -1952,9 +1854,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { { if def.is_union() { if this.move_data.path_map[mpi].iter().any(|moi| { - this.move_data.moves[*moi].source.is_predecessor_of( - location, this.body, - ) + this.move_data.moves[*moi].source.is_predecessor_of(location, this.body) }) { return; } @@ -2034,18 +1934,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { | Write(WriteKind::MutableBorrow(BorrowKind::Shallow)) => { if let (Err(_), true) = ( self.is_mutable(place.as_ref(), is_local_mutation_allowed), - self.errors_buffer.is_empty() + self.errors_buffer.is_empty(), ) { // rust-lang/rust#46908: In pure NLL mode this code path should be // unreachable, but we use `delay_span_bug` because we can hit this when // dereferencing a non-Copy raw pointer *and* have `-Ztreat-err-as-bug` // enabled. We don't want to ICE for that case, as other errors will have // been emitted (#52262). - self.infcx.tcx.sess.delay_span_bug(span, &format!( - "Accessing `{:?}` with the kind `{:?}` shouldn't be possible", - place, - kind, - )); + self.infcx.tcx.sess.delay_span_bug( + span, + &format!( + "Accessing `{:?}` with the kind `{:?}` shouldn't be possible", + place, kind, + ), + ); } return false; } @@ -2075,13 +1977,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // at this point, we have set up the error reporting state. if previously_initialized { - self.report_mutability_error( - place, - span, - the_place_err, - error_access, - location, - ); + self.report_mutability_error(place, span, the_place_err, error_access, location); true } else { false @@ -2114,8 +2010,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // If the local may have been initialized, and it is now currently being // mutated, then it is justified to be annotated with the `mut` // keyword, since the mutation may be a possible reassignment. - if is_local_mutation_allowed != LocalMutationIsAllowed::Yes && - self.is_local_ever_initialized(*local, flow_state).is_some() + if is_local_mutation_allowed != LocalMutationIsAllowed::Yes + && self.is_local_ever_initialized(*local, flow_state).is_some() { self.used_mut.insert(*local); } @@ -2153,10 +2049,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { is_local_mutation_allowed: LocalMutationIsAllowed, ) -> Result, PlaceRef<'d, 'tcx>> { match place { - PlaceRef { - base: PlaceBase::Local(local), - projection: [], - } => { + PlaceRef { base: PlaceBase::Local(local), projection: [] } => { let local = &self.body.local_decls[*local]; match local.mutability { Mutability::Not => match is_local_mutation_allowed { @@ -2182,23 +2075,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // The rules for promotion are made by `qualify_consts`, there wouldn't even be a // `Place::Promoted` if the promotion weren't 100% legal. So we just forward this PlaceRef { - base: PlaceBase::Static(box Static { - kind: StaticKind::Promoted(..), - .. - }), + base: PlaceBase::Static(box Static { kind: StaticKind::Promoted(..), .. }), projection: [], - } => - Ok(RootPlace { - place_base: place.base, - place_projection: place.projection, - is_local_mutation_allowed, - }), + } => Ok(RootPlace { + place_base: place.base, + place_projection: place.projection, + is_local_mutation_allowed, + }), PlaceRef { - base: PlaceBase::Static(box Static { - kind: StaticKind::Static, - def_id, - .. - }), + base: PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }), projection: [], } => { if !self.infcx.tcx.is_mutable_static(*def_id) { @@ -2211,10 +2096,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }) } } - PlaceRef { - base: _, - projection: [proj_base @ .., elem], - } => { + PlaceRef { base: _, projection: [proj_base @ .., elem] } => { match elem { ProjectionElem::Deref => { let base_ty = @@ -2230,18 +2112,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // unique path to the `&mut` hir::Mutability::Mut => { let mode = match self.is_upvar_field_projection(place) { - Some(field) - if self.upvars[field.index()].by_ref => - { + Some(field) if self.upvars[field.index()].by_ref => { is_local_mutation_allowed } _ => LocalMutationIsAllowed::Yes, }; - self.is_mutable(PlaceRef { - base: place.base, - projection: proj_base, - }, mode) + self.is_mutable( + PlaceRef { base: place.base, projection: proj_base }, + mode, + ) } } } @@ -2251,22 +2131,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { hir::Mutability::Not => Err(place), // `*mut` raw pointers are always mutable, regardless of // context. The users have to check by themselves. - hir::Mutability::Mut => { - Ok(RootPlace { - place_base: place.base, - place_projection: place.projection, - is_local_mutation_allowed, - }) - } + hir::Mutability::Mut => Ok(RootPlace { + place_base: place.base, + place_projection: place.projection, + is_local_mutation_allowed, + }), } } // `Box` owns its content, so mutable if its location is mutable - _ if base_ty.is_box() => { - self.is_mutable(PlaceRef { - base: place.base, - projection: proj_base, - }, is_local_mutation_allowed) - } + _ if base_ty.is_box() => self.is_mutable( + PlaceRef { base: place.base, projection: proj_base }, + is_local_mutation_allowed, + ), // Deref should only be for reference, pointers or boxes _ => bug!("Deref of unexpected type: {:?}", base_ty), } @@ -2319,10 +2195,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // }); // } // ``` - let _ = self.is_mutable(PlaceRef { - base: place.base, - projection: proj_base, - }, is_local_mutation_allowed)?; + let _ = self.is_mutable( + PlaceRef { base: place.base, projection: proj_base }, + is_local_mutation_allowed, + )?; Ok(RootPlace { place_base: place.base, place_projection: place.projection, @@ -2331,10 +2207,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } } else { - self.is_mutable(PlaceRef { - base: place.base, - projection: proj_base, - }, is_local_mutation_allowed) + self.is_mutable( + PlaceRef { base: place.base, projection: proj_base }, + is_local_mutation_allowed, + ) } } } @@ -2360,8 +2236,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tcx = self.infcx.tcx; let base_ty = Place::ty_from(place_ref.base, base, self.body(), tcx).ty; - if (base_ty.is_closure() || base_ty.is_generator()) && - (!by_ref || self.upvars[field.index()].by_ref) { + if (base_ty.is_closure() || base_ty.is_generator()) + && (!by_ref || self.upvars[field.index()].by_ref) + { Some(*field) } else { None diff --git a/src/librustc_mir/borrow_check/nll.rs b/src/librustc_mir/borrow_check/nll.rs index 6d28a8caa92bd..ba387cfbbe80d 100644 --- a/src/librustc_mir/borrow_check/nll.rs +++ b/src/librustc_mir/borrow_check/nll.rs @@ -2,39 +2,43 @@ use rustc::hir::def_id::DefId; use rustc::infer::InferCtxt; -use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, - Local, Location, Body, BodyAndCache, LocalKind, BasicBlock, - Promoted, ReadOnlyBodyAndCache}; +use rustc::mir::{ + BasicBlock, Body, BodyAndCache, ClosureOutlivesSubject, ClosureRegionRequirements, Local, + LocalKind, Location, Promoted, ReadOnlyBodyAndCache, +}; use rustc::ty::{self, RegionKind, RegionVid}; -use rustc_index::vec::IndexVec; use rustc_errors::Diagnostic; -use syntax_pos::symbol::Symbol; -use std::fmt::Debug; +use rustc_index::vec::IndexVec; use std::env; +use std::fmt::Debug; use std::io; use std::path::PathBuf; use std::rc::Rc; use std::str::FromStr; use syntax::symbol::sym; +use syntax_pos::symbol::Symbol; use self::mir_util::PassWhere; use polonius_engine::{Algorithm, Output}; -use crate::util as mir_util; -use crate::util::pretty; -use crate::dataflow::move_paths::{InitLocation, MoveData, InitKind}; +use crate::dataflow::move_paths::{InitKind, InitLocation, MoveData}; use crate::dataflow::FlowAtLocation; use crate::dataflow::MaybeInitializedPlaces; use crate::transform::MirSource; +use crate::util as mir_util; +use crate::util::pretty; use crate::borrow_check::{ borrow_set::BorrowSet, - location::LocationTable, + constraint_generation, facts::{AllFacts, AllFactsExt, RustcFacts}, - region_infer::{RegionInferenceContext, values::RegionValueElements}, + invalidation, + location::LocationTable, + region_infer::{values::RegionValueElements, RegionInferenceContext}, + renumber, + type_check::{self, MirTypeckRegionConstraints, MirTypeckResults}, universal_regions::UniversalRegions, - type_check::{self, MirTypeckResults, MirTypeckRegionConstraints}, - Upvar, renumber, constraint_generation, invalidation, + Upvar, }; crate type PoloniusOutput = Output; @@ -64,35 +68,26 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>( universal_regions } - // This function populates an AllFacts instance with base facts related to // MovePaths and needed for the move analysis. fn populate_polonius_move_facts( all_facts: &mut AllFacts, move_data: &MoveData<'_>, location_table: &LocationTable, - body: &Body<'_>) { + body: &Body<'_>, +) { all_facts .path_belongs_to_var - .extend( - move_data - .rev_lookup - .iter_locals_enumerated() - .map(|(v, &m)| (m, v))); + .extend(move_data.rev_lookup.iter_locals_enumerated().map(|(v, &m)| (m, v))); for (child, move_path) in move_data.move_paths.iter_enumerated() { all_facts .child - .extend( - move_path - .parents(&move_data.move_paths) - .iter() - .map(|&parent| (child, parent))); + .extend(move_path.parents(&move_data.move_paths).iter().map(|&parent| (child, parent))); } // initialized_at for init in move_data.inits.iter() { - match init.location { InitLocation::Statement(location) => { let block_data = &body[location.block]; @@ -109,38 +104,31 @@ fn populate_polonius_move_facts( // The initialization happened in (or rather, when arriving at) // the successors, but not in the unwind block. - let first_statement = Location { block: successor, statement_index: 0}; + let first_statement = Location { block: successor, statement_index: 0 }; all_facts .initialized_at .push((init.path, location_table.start_index(first_statement))); } - } else { // In all other cases, the initialization just happens at the // midpoint, like any other effect. all_facts.initialized_at.push((init.path, location_table.mid_index(location))); } - }, + } // Arguments are initialized on function entry InitLocation::Argument(local) => { assert!(body.local_kind(local) == LocalKind::Arg); - let fn_entry = Location {block: BasicBlock::from_u32(0u32), statement_index: 0 }; + let fn_entry = Location { block: BasicBlock::from_u32(0u32), statement_index: 0 }; all_facts.initialized_at.push((init.path, location_table.start_index(fn_entry))); - } } } - // moved_out_at // deinitialisation is assumed to always happen! all_facts .moved_out_at - .extend( - move_data - .moves - .iter() - .map(|mo| (mo.path, location_table.mid_index(mo.source)))); + .extend(move_data.moves.iter().map(|mo| (mo.path, location_table.mid_index(mo.source)))); } /// Computes the (non-lexical) regions from the input MIR. @@ -169,14 +157,10 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( let universal_regions = Rc::new(universal_regions); - let elements - = &Rc::new(RegionValueElements::new(&body)); + let elements = &Rc::new(RegionValueElements::new(&body)); // Run the MIR type-checker. - let MirTypeckResults { - constraints, - universal_region_relations, - } = type_check::type_check( + let MirTypeckResults { constraints, universal_region_relations } = type_check::type_check( infcx, param_env, body, @@ -193,9 +177,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( if let Some(all_facts) = &mut all_facts { let _prof_timer = infcx.tcx.prof.generic_activity("polonius_fact_generation"); - all_facts - .universal_region - .extend(universal_regions.universal_regions()); + all_facts.universal_region.extend(universal_regions.universal_regions()); populate_polonius_move_facts(all_facts, move_data, location_table, &body); // Emit universal regions facts, and their relations, for Polonius. @@ -290,16 +272,12 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( } if infcx.tcx.sess.opts.debugging_opts.polonius { - let algorithm = env::var("POLONIUS_ALGORITHM") - .unwrap_or_else(|_| String::from("Naive")); + let algorithm = + env::var("POLONIUS_ALGORITHM").unwrap_or_else(|_| String::from("Naive")); let algorithm = Algorithm::from_str(&algorithm).unwrap(); debug!("compute_regions: using polonius algorithm {:?}", algorithm); let _prof_timer = infcx.tcx.prof.generic_activity("polonius_analysis"); - Some(Rc::new(Output::compute( - &all_facts, - algorithm, - false, - ))) + Some(Rc::new(Output::compute(&all_facts, algorithm, false))) } else { None } @@ -328,13 +306,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( // We also have a `#[rustc_nll]` annotation that causes us to dump // information - dump_annotation( - infcx, - &body, - def_id, - ®ioncx, - &closure_region_requirements, - errors_buffer); + dump_annotation(infcx, &body, def_id, ®ioncx, &closure_region_requirements, errors_buffer); (regioncx, polonius_output, closure_region_requirements) } @@ -350,40 +322,30 @@ fn dump_mir_results<'a, 'tcx>( return; } - mir_util::dump_mir( - infcx.tcx, - None, - "nll", - &0, - source, - body, - |pass_where, out| { - match pass_where { - // Before the CFG, dump out the values for each region variable. - PassWhere::BeforeCFG => { - regioncx.dump_mir(out)?; + mir_util::dump_mir(infcx.tcx, None, "nll", &0, source, body, |pass_where, out| { + match pass_where { + // Before the CFG, dump out the values for each region variable. + PassWhere::BeforeCFG => { + regioncx.dump_mir(out)?; + writeln!(out, "|")?; + + if let Some(closure_region_requirements) = closure_region_requirements { + writeln!(out, "| Free Region Constraints")?; + for_each_region_constraint(closure_region_requirements, &mut |msg| { + writeln!(out, "| {}", msg) + })?; writeln!(out, "|")?; - - if let Some(closure_region_requirements) = closure_region_requirements { - writeln!(out, "| Free Region Constraints")?; - for_each_region_constraint(closure_region_requirements, &mut |msg| { - writeln!(out, "| {}", msg) - })?; - writeln!(out, "|")?; - } } + } - PassWhere::BeforeLocation(_) => { - } + PassWhere::BeforeLocation(_) => {} - PassWhere::AfterTerminator(_) => { - } + PassWhere::AfterTerminator(_) => {} - PassWhere::BeforeBlock(_) | PassWhere::AfterLocation(_) | PassWhere::AfterCFG => {} - } - Ok(()) - }, - ); + PassWhere::BeforeBlock(_) | PassWhere::AfterLocation(_) | PassWhere::AfterCFG => {} + } + Ok(()) + }); // Also dump the inference graph constraints as a graphviz file. let _: io::Result<()> = try { @@ -422,10 +384,7 @@ fn dump_annotation<'a, 'tcx>( // better. if let Some(closure_region_requirements) = closure_region_requirements { - let mut err = tcx - .sess - .diagnostic() - .span_note_diag(body.span, "External requirements"); + let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "External requirements"); regioncx.annotate(tcx, &mut err); @@ -439,14 +398,12 @@ fn dump_annotation<'a, 'tcx>( for_each_region_constraint(closure_region_requirements, &mut |msg| { err.note(msg); Ok(()) - }).unwrap(); + }) + .unwrap(); err.buffer(errors_buffer); } else { - let mut err = tcx - .sess - .diagnostic() - .span_note_diag(body.span, "No external requirements"); + let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "No external requirements"); regioncx.annotate(tcx, &mut err); err.buffer(errors_buffer); @@ -462,10 +419,7 @@ fn for_each_region_constraint( ClosureOutlivesSubject::Region(subject) => subject, ClosureOutlivesSubject::Ty(ty) => ty, }; - with_msg(&format!( - "where {:?}: {:?}", - subject, req.outlived_free_region, - ))?; + with_msg(&format!("where {:?}: {:?}", subject, req.outlived_free_region,))?; } Ok(()) } @@ -481,11 +435,7 @@ pub trait ToRegionVid { impl<'tcx> ToRegionVid for &'tcx RegionKind { fn to_region_vid(self) -> RegionVid { - if let ty::ReVar(vid) = self { - *vid - } else { - bug!("region is not an ReVar: {:?}", self) - } + if let ty::ReVar(vid) = self { *vid } else { bug!("region is not an ReVar: {:?}", self) } } } diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs index bac08090817d9..ea541bd93bc94 100644 --- a/src/librustc_mir/borrow_check/path_utils.rs +++ b/src/librustc_mir/borrow_check/path_utils.rs @@ -1,9 +1,9 @@ -use crate::borrow_check::borrow_set::{BorrowSet, BorrowData, TwoPhaseActivation}; +use crate::borrow_check::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation}; use crate::borrow_check::places_conflict; use crate::borrow_check::AccessDepth; use crate::dataflow::indexes::BorrowIndex; -use rustc::mir::{BasicBlock, Location, Body, Place, PlaceBase}; use rustc::mir::BorrowKind; +use rustc::mir::{BasicBlock, Body, Location, Place, PlaceBase}; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::graph::dominators::Dominators; @@ -71,7 +71,7 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>( pub(super) fn is_active<'tcx>( dominators: &Dominators, borrow_data: &BorrowData<'tcx>, - location: Location + location: Location, ) -> bool { debug!("is_active(borrow_data={:?}, location={:?})", borrow_data, location); diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs index e11db4ad5bb60..fd590467e4610 100644 --- a/src/librustc_mir/borrow_check/place_ext.rs +++ b/src/librustc_mir/borrow_check/place_ext.rs @@ -1,8 +1,8 @@ +use crate::borrow_check::borrow_set::LocalsStateAtExit; use rustc::hir; use rustc::mir::ProjectionElem; -use rustc::mir::{Body, Place, PlaceBase, Mutability}; +use rustc::mir::{Body, Mutability, Place, PlaceBase}; use rustc::ty::{self, TyCtxt}; -use crate::borrow_check::borrow_set::LocalsStateAtExit; /// Extension methods for the `Place` type. crate trait PlaceExt<'tcx> { @@ -34,21 +34,19 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> { // // In particular, the variable cannot be mutated -- the "access checks" will fail -- // so we don't have to worry about mutation while borrowed. - PlaceBase::Local(local) => { - match locals_state_at_exit { - LocalsStateAtExit::AllAreInvalidated => local, - LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => { - let ignore = !has_storage_dead_or_moved.contains(local) && - body.local_decls[local].mutability == Mutability::Not; - debug!("ignore_borrow: local {:?} => {:?}", local, ignore); - if ignore { - return true; - } else { - local - } + PlaceBase::Local(local) => match locals_state_at_exit { + LocalsStateAtExit::AllAreInvalidated => local, + LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => { + let ignore = !has_storage_dead_or_moved.contains(local) + && body.local_decls[local].mutability == Mutability::Not; + debug!("ignore_borrow: local {:?} => {:?}", local, ignore); + if ignore { + return true; + } else { + local } } - } + }, PlaceBase::Static(_) => return true, }; diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index 0cc7af330caad..f0d51c96d903c 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -1,6 +1,6 @@ use crate::borrow_check::ArtificialField; use crate::borrow_check::Overlap; -use crate::borrow_check::{Deep, Shallow, AccessDepth}; +use crate::borrow_check::{AccessDepth, Deep, Shallow}; use rustc::hir; use rustc::mir::{ Body, BorrowKind, Place, PlaceBase, PlaceElem, PlaceRef, ProjectionElem, StaticKind, @@ -340,7 +340,7 @@ fn place_base_conflict<'tcx>( debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC"); Overlap::EqualOrDisjoint } - }, + } (StaticKind::Promoted(promoted_1, _), StaticKind::Promoted(promoted_2, _)) => { if promoted_1 == promoted_2 { if let ty::Array(_, len) = s1.ty.kind { @@ -358,15 +358,15 @@ fn place_base_conflict<'tcx>( debug!("place_element_conflict: DISJOINT-PROMOTED"); Overlap::Disjoint } - }, + } (_, _) => { debug!("place_element_conflict: DISJOINT-STATIC-PROMOTED"); Overlap::Disjoint } } } - (PlaceBase::Local(_), PlaceBase::Static(_)) | - (PlaceBase::Static(_), PlaceBase::Local(_)) => { + (PlaceBase::Local(_), PlaceBase::Static(_)) + | (PlaceBase::Static(_), PlaceBase::Local(_)) => { debug!("place_element_conflict: DISJOINT-STATIC-LOCAL-PROMOTED"); Overlap::Disjoint } @@ -466,11 +466,14 @@ fn place_projection_conflict<'tcx>( } } } - (ProjectionElem::ConstantIndex { offset: o1, min_length: _, from_end: false }, - ProjectionElem::ConstantIndex { offset: o2, min_length: _, from_end: false }) - | (ProjectionElem::ConstantIndex { offset: o1, min_length: _, from_end: true }, - ProjectionElem::ConstantIndex { - offset: o2, min_length: _, from_end: true }) => { + ( + ProjectionElem::ConstantIndex { offset: o1, min_length: _, from_end: false }, + ProjectionElem::ConstantIndex { offset: o2, min_length: _, from_end: false }, + ) + | ( + ProjectionElem::ConstantIndex { offset: o1, min_length: _, from_end: true }, + ProjectionElem::ConstantIndex { offset: o2, min_length: _, from_end: true }, + ) => { if o1 == o2 { debug!("place_element_conflict: DISJOINT-OR-EQ-ARRAY-CONSTANT-INDEX"); Overlap::EqualOrDisjoint @@ -479,14 +482,30 @@ fn place_projection_conflict<'tcx>( Overlap::Disjoint } } - (ProjectionElem::ConstantIndex { - offset: offset_from_begin, min_length: min_length1, from_end: false }, + ( ProjectionElem::ConstantIndex { - offset: offset_from_end, min_length: min_length2, from_end: true }) - | (ProjectionElem::ConstantIndex { - offset: offset_from_end, min_length: min_length1, from_end: true }, - ProjectionElem::ConstantIndex { - offset: offset_from_begin, min_length: min_length2, from_end: false }) => { + offset: offset_from_begin, + min_length: min_length1, + from_end: false, + }, + ProjectionElem::ConstantIndex { + offset: offset_from_end, + min_length: min_length2, + from_end: true, + }, + ) + | ( + ProjectionElem::ConstantIndex { + offset: offset_from_end, + min_length: min_length1, + from_end: true, + }, + ProjectionElem::ConstantIndex { + offset: offset_from_begin, + min_length: min_length2, + from_end: false, + }, + ) => { // both patterns matched so it must be at least the greater of the two let min_length = max(min_length1, min_length2); // `offset_from_end` can be in range `[1..min_length]`, 1 indicates the last @@ -503,11 +522,11 @@ fn place_projection_conflict<'tcx>( } ( ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false }, - ProjectionElem::Subslice { from, to, from_end: false } + ProjectionElem::Subslice { from, to, from_end: false }, ) | ( ProjectionElem::Subslice { from, to, from_end: false }, - ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false } + ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false }, ) => { if (from..to).contains(&offset) { debug!("place_element_conflict: DISJOINT-OR-EQ-ARRAY-CONSTANT-INDEX-SUBSLICE"); @@ -517,26 +536,35 @@ fn place_projection_conflict<'tcx>( Overlap::Disjoint } } - (ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false }, - ProjectionElem::Subslice {from, .. }) - | (ProjectionElem::Subslice {from, .. }, - ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false }) => { + ( + ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false }, + ProjectionElem::Subslice { from, .. }, + ) + | ( + ProjectionElem::Subslice { from, .. }, + ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false }, + ) => { if offset >= from { - debug!( - "place_element_conflict: DISJOINT-OR-EQ-SLICE-CONSTANT-INDEX-SUBSLICE"); + debug!("place_element_conflict: DISJOINT-OR-EQ-SLICE-CONSTANT-INDEX-SUBSLICE"); Overlap::EqualOrDisjoint } else { debug!("place_element_conflict: DISJOINT-SLICE-CONSTANT-INDEX-SUBSLICE"); Overlap::Disjoint } } - (ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true }, - ProjectionElem::Subslice { to, from_end: true, .. }) - | (ProjectionElem::Subslice { to, from_end: true, .. }, - ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true }) => { + ( + ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true }, + ProjectionElem::Subslice { to, from_end: true, .. }, + ) + | ( + ProjectionElem::Subslice { to, from_end: true, .. }, + ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true }, + ) => { if offset > to { - debug!("place_element_conflict: \ - DISJOINT-OR-EQ-SLICE-CONSTANT-INDEX-SUBSLICE-FE"); + debug!( + "place_element_conflict: \ + DISJOINT-OR-EQ-SLICE-CONSTANT-INDEX-SUBSLICE-FE" + ); Overlap::EqualOrDisjoint } else { debug!("place_element_conflict: DISJOINT-SLICE-CONSTANT-INDEX-SUBSLICE-FE"); @@ -545,7 +573,7 @@ fn place_projection_conflict<'tcx>( } ( ProjectionElem::Subslice { from: f1, to: t1, from_end: false }, - ProjectionElem::Subslice { from: f2, to: t2, from_end: false } + ProjectionElem::Subslice { from: f2, to: t2, from_end: false }, ) => { if f2 >= t1 || f1 >= t2 { debug!("place_element_conflict: DISJOINT-ARRAY-SUBSLICES"); @@ -557,7 +585,7 @@ fn place_projection_conflict<'tcx>( } (ProjectionElem::Subslice { .. }, ProjectionElem::Subslice { .. }) => { debug!("place_element_conflict: DISJOINT-OR-EQ-SLICE-SUBSLICES"); - Overlap::EqualOrDisjoint + Overlap::EqualOrDisjoint } (ProjectionElem::Deref, _) | (ProjectionElem::Field(..), _) diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs index 5b9ce7cb5fd8d..b994bafb0c97f 100644 --- a/src/librustc_mir/borrow_check/prefixes.rs +++ b/src/librustc_mir/borrow_check/prefixes.rs @@ -10,8 +10,8 @@ use super::MirBorrowckCtxt; use rustc::hir; -use rustc::ty::{self, TyCtxt}; use rustc::mir::{Place, PlaceBase, PlaceRef, ProjectionElem, ReadOnlyBodyAndCache}; +use rustc::ty::{self, TyCtxt}; pub trait IsPrefixOf<'cx, 'tcx> { fn is_prefix_of(&self, other: PlaceRef<'cx, 'tcx>) -> bool; @@ -53,12 +53,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { place_ref: PlaceRef<'cx, 'tcx>, kind: PrefixSet, ) -> Prefixes<'cx, 'tcx> { - Prefixes { - next: Some(place_ref), - kind, - body: self.body, - tcx: self.infcx.tcx, - } + Prefixes { next: Some(place_ref), kind, body: self.body, tcx: self.infcx.tcx } } } diff --git a/src/librustc_mir/borrow_check/region_infer/dump_mir.rs b/src/librustc_mir/borrow_check/region_infer/dump_mir.rs index d4f6ce8801e63..b236ffe807485 100644 --- a/src/librustc_mir/borrow_check/region_infer/dump_mir.rs +++ b/src/librustc_mir/borrow_check/region_infer/dump_mir.rs @@ -3,9 +3,9 @@ //! state of region inference. This code handles emitting the region //! context internal state. +use super::{OutlivesConstraint, RegionInferenceContext}; use rustc::infer::NLLRegionVariableOrigin; use std::io::{self, Write}; -use super::{OutlivesConstraint, RegionInferenceContext}; // Room for "'_#NNNNr" before things get misaligned. // Easy enough to fix if this ever doesn't seem like @@ -19,10 +19,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { for region in self.regions() { if let NLLRegionVariableOrigin::FreeRegion = self.definitions[region].origin { - let classification = self - .universal_regions - .region_classification(region) - .unwrap(); + let classification = self.universal_regions.region_classification(region).unwrap(); let outlived_by = self.universal_region_relations.regions_outlived_by(region); writeln!( out, @@ -74,19 +71,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { let mut constraints: Vec<_> = self.constraints.outlives().iter().collect(); constraints.sort(); for constraint in &constraints { - let OutlivesConstraint { - sup, - sub, - locations, - category, - } = constraint; - with_msg(&format!( - "{:?}: {:?} due to {:?} at {:?}", - sup, - sub, - category, - locations, - ))?; + let OutlivesConstraint { sup, sub, locations, category } = constraint; + with_msg(&format!("{:?}: {:?} due to {:?} at {:?}", sup, sub, category, locations,))?; } Ok(()) diff --git a/src/librustc_mir/borrow_check/region_infer/graphviz.rs b/src/librustc_mir/borrow_check/region_infer/graphviz.rs index 29c6f32526390..39b396ba4e7d3 100644 --- a/src/librustc_mir/borrow_check/region_infer/graphviz.rs +++ b/src/librustc_mir/borrow_check/region_infer/graphviz.rs @@ -16,10 +16,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Write out the region constraint graph. crate fn dump_graphviz_scc_constraints(&self, mut w: &mut dyn Write) -> io::Result<()> { - let mut nodes_per_scc: IndexVec = self.constraint_sccs - .all_sccs() - .map(|_| Vec::new()) - .collect(); + let mut nodes_per_scc: IndexVec = + self.constraint_sccs.all_sccs().map(|_| Vec::new()).collect(); for region in self.definitions.indices() { let scc = self.constraint_sccs.scc(region); @@ -112,7 +110,8 @@ impl<'a, 'this, 'tcx> dot::GraphWalk<'this> for SccConstraints<'a, 'tcx> { vids.into() } fn edges(&'this self) -> dot::Edges<'this, (ConstraintSccIndex, ConstraintSccIndex)> { - let edges: Vec<_> = self.regioncx + let edges: Vec<_> = self + .regioncx .constraint_sccs .all_sccs() .flat_map(|scc_a| { diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index dedc6b9b09af2..6d732238c4768 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -12,33 +12,28 @@ use rustc::mir::{ use rustc::ty::{self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable}; use rustc::util::common::ErrorReported; use rustc_data_structures::binary_search_util; -use rustc_index::bit_set::BitSet; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::graph::WithSuccessors; use rustc_data_structures::graph::scc::Sccs; use rustc_data_structures::graph::vec_graph::VecGraph; -use rustc_index::vec::IndexVec; +use rustc_data_structures::graph::WithSuccessors; use rustc_errors::{Diagnostic, DiagnosticBuilder}; -use syntax_pos::Span; +use rustc_index::bit_set::BitSet; +use rustc_index::vec::IndexVec; use syntax_pos::symbol::Symbol; +use syntax_pos::Span; use crate::borrow_check::{ constraints::{ - graph::NormalConstraintGraph, - ConstraintSccIndex, - OutlivesConstraint, - OutlivesConstraintSet, + graph::NormalConstraintGraph, ConstraintSccIndex, OutlivesConstraint, OutlivesConstraintSet, }, + diagnostics::{OutlivesSuggestionBuilder, RegionErrorNamingCtx}, member_constraints::{MemberConstraintSet, NllMemberConstraintIndex}, + nll::{PoloniusOutput, ToRegionVid}, region_infer::values::{ - PlaceholderIndices, RegionElement, ToElementIndex, LivenessValues, RegionValueElements, - RegionValues, + LivenessValues, PlaceholderIndices, RegionElement, RegionValueElements, RegionValues, + ToElementIndex, }, type_check::{free_region_relations::UniversalRegionRelations, Locations}, - diagnostics::{ - OutlivesSuggestionBuilder, RegionErrorNamingCtx, - }, - nll::{ToRegionVid, PoloniusOutput}, universal_regions::UniversalRegions, Upvar, }; @@ -76,8 +71,7 @@ pub struct RegionInferenceContext<'tcx> { /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` /// exists if `B: A`. Computed lazilly. - pub(in crate::borrow_check) rev_constraint_graph: - Option>>, + pub(in crate::borrow_check) rev_constraint_graph: Option>>, /// The "R0 member of [R1..Rn]" constraints, indexed by SCC. pub(in crate::borrow_check) member_constraints: @@ -96,8 +90,7 @@ pub struct RegionInferenceContext<'tcx> { /// Contains the minimum universe of any variable within the same /// SCC. We will ensure that no SCC contains values that are not /// visible from this index. - pub(in crate::borrow_check) scc_universes: - IndexVec, + pub(in crate::borrow_check) scc_universes: IndexVec, /// Contains a "representative" from each SCC. This will be the /// minimal RegionVid belonging to that universe. It is used as a @@ -106,8 +99,7 @@ pub struct RegionInferenceContext<'tcx> { /// of its SCC and be sure that -- if they have the same repr -- /// they *must* be equal (though not having the same repr does not /// mean they are unequal). - pub(in crate::borrow_check) scc_representatives: - IndexVec, + pub(in crate::borrow_check) scc_representatives: IndexVec, /// The final inferred values of the region variables; we compute /// one value per SCC. To get the value for any given *region*, @@ -119,12 +111,11 @@ pub struct RegionInferenceContext<'tcx> { /// Information about the universally quantified regions in scope /// on this function. - pub (in crate::borrow_check) universal_regions: Rc>, + pub(in crate::borrow_check) universal_regions: Rc>, /// Information about how the universally quantified regions in /// scope on this function relate to one another. - pub(in crate::borrow_check) universal_region_relations: - Rc>, + pub(in crate::borrow_check) universal_region_relations: Rc>, } /// Each time that `apply_member_constraint` is successful, it appends @@ -460,7 +451,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// the member constraints that were applied to the value of a given /// region `r`. See `AppliedMemberConstraint`. pub(in crate::borrow_check) fn applied_member_constraints( - &self, r: impl ToRegionVid + &self, + r: impl ToRegionVid, ) -> &[AppliedMemberConstraint] { let scc = self.constraint_sccs.scc(r.to_region_vid()); binary_search_util::binary_search_slice( @@ -490,8 +482,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // to store those. Otherwise, we'll pass in `None` to the // functions below, which will trigger them to report errors // eagerly. - let mut outlives_requirements = - infcx.tcx.is_closure(mir_def_id).then(|| vec![]); + let mut outlives_requirements = infcx.tcx.is_closure(mir_def_id).then(|| vec![]); self.check_type_tests( infcx, @@ -624,11 +615,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Now take member constraints into account. let member_constraints = self.member_constraints.clone(); for m_c_i in member_constraints.indices(scc_a) { - self.apply_member_constraint( - scc_a, - m_c_i, - member_constraints.choice_regions(m_c_i), - ); + self.apply_member_constraint(scc_a, m_c_i, member_constraints.choice_regions(m_c_i)); } debug!( @@ -752,8 +739,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let min_choice_scc = self.constraint_sccs.scc(min_choice); debug!( "apply_member_constraint: min_choice={:?} best_choice_scc={:?}", - min_choice, - min_choice_scc, + min_choice, min_choice_scc, ); if self.scc_values.add_region(scc, min_choice_scc) { self.member_constraints_applied.push(AppliedMemberConstraint { @@ -784,9 +770,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Compute and return the reverse SCC-based constraint graph (lazilly). - fn rev_constraint_graph( - &mut self, - ) -> Rc> { + fn rev_constraint_graph(&mut self) -> Rc> { if let Some(g) = &self.rev_constraint_graph { return g.clone(); } @@ -1138,7 +1122,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// include the CFG anyhow. /// - For each `end('x)` element in `'r`, compute the mutual LUB, yielding /// a result `'y`. - pub (in crate::borrow_check) fn universal_upper_bound(&self, r: RegionVid) -> RegionVid { + pub(in crate::borrow_check) fn universal_upper_bound(&self, r: RegionVid) -> RegionVid { debug!("universal_upper_bound(r={:?}={})", r, self.region_value_str(r)); // Find the smallest universal region that contains all other @@ -1429,8 +1413,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { subset_errors.dedup(); for (longer_fr, shorter_fr) in subset_errors.into_iter() { - debug!("check_polonius_subset_errors: subset_error longer_fr={:?},\ - shorter_fr={:?}", longer_fr, shorter_fr); + debug!( + "check_polonius_subset_errors: subset_error longer_fr={:?},\ + shorter_fr={:?}", + longer_fr, shorter_fr + ); let propagated = self.try_propagate_universal_region_error( *longer_fr, @@ -1633,20 +1620,22 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Shrink `longer_fr` until we find a non-local region (if we do). // We'll call it `fr-` -- it's ever so slightly smaller than // `longer_fr`. - if let Some(fr_minus) = - self.universal_region_relations.non_local_lower_bound(longer_fr) { + if let Some(fr_minus) = self.universal_region_relations.non_local_lower_bound(longer_fr) + { debug!("try_propagate_universal_region_error: fr_minus={:?}", fr_minus); - let blame_span_category = - self.find_outlives_blame_span(body, longer_fr, - NLLRegionVariableOrigin::FreeRegion,shorter_fr); + let blame_span_category = self.find_outlives_blame_span( + body, + longer_fr, + NLLRegionVariableOrigin::FreeRegion, + shorter_fr, + ); // Grow `shorter_fr` until we find some non-local regions. (We // always will.) We'll call them `shorter_fr+` -- they're ever // so slightly larger than `shorter_fr`. - let shorter_fr_plus = self - .universal_region_relations - .non_local_upper_bounds(&shorter_fr); + let shorter_fr_plus = + self.universal_region_relations.non_local_upper_bounds(&shorter_fr); debug!( "try_propagate_universal_region_error: shorter_fr_plus={:?}", shorter_fr_plus @@ -1712,7 +1701,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Find the code to blame for the fact that `longer_fr` outlives `error_fr`. let (_, span) = self.find_outlives_blame_span( - body, longer_fr, NLLRegionVariableOrigin::Placeholder(placeholder), error_region + body, + longer_fr, + NLLRegionVariableOrigin::Placeholder(placeholder), + error_region, ); // Obviously, this error message is far from satisfactory. @@ -1744,9 +1736,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!("check_member_constraint: choice_regions={:?}", choice_regions); // Did the member region wind up equal to any of the option regions? - if let Some(o) = choice_regions.iter().find(|&&o_r| { - self.eval_equal(o_r, m_c.member_region_vid) - }) { + if let Some(o) = + choice_regions.iter().find(|&&o_r| self.eval_equal(o_r, m_c.member_region_vid)) + { debug!("check_member_constraint: evaluated as equal to {:?}", o); continue; } diff --git a/src/librustc_mir/borrow_check/region_infer/values.rs b/src/librustc_mir/borrow_check/region_infer/values.rs index 0bf0cd37cd843..e17efebfef824 100644 --- a/src/librustc_mir/borrow_check/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/region_infer/values.rs @@ -1,7 +1,7 @@ -use rustc::mir::{BasicBlock, Location, Body, ReadOnlyBodyAndCache}; +use rustc::mir::{BasicBlock, Body, Location, ReadOnlyBodyAndCache}; use rustc::ty::{self, RegionVid}; -use rustc_index::bit_set::{HybridBitSet, SparseBitMatrix}; use rustc_data_structures::fx::FxHashMap; +use rustc_index::bit_set::{HybridBitSet, SparseBitMatrix}; use rustc_index::vec::Idx; use rustc_index::vec::IndexVec; use std::fmt::Debug; @@ -22,7 +22,8 @@ crate struct RegionValueElements { impl RegionValueElements { crate fn new(body: &Body<'_>) -> Self { let mut num_points = 0; - let statements_before_block: IndexVec = body.basic_blocks() + let statements_before_block: IndexVec = body + .basic_blocks() .iter() .map(|block_data| { let v = num_points; @@ -30,10 +31,7 @@ impl RegionValueElements { v }) .collect(); - debug!( - "RegionValueElements: statements_before_block={:#?}", - statements_before_block - ); + debug!("RegionValueElements: statements_before_block={:#?}", statements_before_block); debug!("RegionValueElements: num_points={:#?}", num_points); let mut basic_blocks = IndexVec::with_capacity(num_points); @@ -41,11 +39,7 @@ impl RegionValueElements { basic_blocks.extend((0..=bb_data.statements.len()).map(|_| bb)); } - Self { - statements_before_block, - basic_blocks, - num_points, - } + Self { statements_before_block, basic_blocks, num_points } } /// Total number of point indices @@ -55,10 +49,7 @@ impl RegionValueElements { /// Converts a `Location` into a `PointIndex`. O(1). crate fn point_from_location(&self, location: Location) -> PointIndex { - let Location { - block, - statement_index, - } = location; + let Location { block, statement_index } = location; let start_index = self.statements_before_block[block]; PointIndex::new(start_index + statement_index) } @@ -75,10 +66,7 @@ impl RegionValueElements { let block = self.basic_blocks[index]; let start_index = self.statements_before_block[block]; let statement_index = index.index() - start_index; - Location { - block, - statement_index, - } + Location { block, statement_index } } /// Sometimes we get point-indices back from bitsets that may be @@ -96,10 +84,7 @@ impl RegionValueElements { index: PointIndex, stack: &mut Vec, ) { - let Location { - block, - statement_index, - } = self.to_location(index); + let Location { block, statement_index } = self.to_location(index); if statement_index == 0 { // If this is a basic block head, then the predecessors are // the terminators of other basic blocks @@ -155,14 +140,11 @@ impl LivenessValues { /// Each of the regions in num_region_variables will be initialized with an /// empty set of points and no causal information. crate fn new(elements: Rc) -> Self { - Self { - points: SparseBitMatrix::new(elements.num_points), - elements: elements, - } + Self { points: SparseBitMatrix::new(elements.num_points), elements: elements } } /// Iterate through each region that has a value in this set. - crate fn rows(&self) -> impl Iterator { + crate fn rows(&self) -> impl Iterator { self.points.rows() } @@ -177,10 +159,7 @@ impl LivenessValues { /// Adds all the elements in the given bit array into the given /// region. Returns whether any of them are newly added. crate fn add_elements(&mut self, row: N, locations: &HybridBitSet) -> bool { - debug!( - "LivenessValues::add_elements(row={:?}, locations={:?})", - row, locations - ); + debug!("LivenessValues::add_elements(row={:?}, locations={:?})", row, locations); self.points.union_into_row(row, locations) } @@ -220,13 +199,8 @@ crate struct PlaceholderIndices { impl PlaceholderIndices { crate fn insert(&mut self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex { - let PlaceholderIndices { - to_index, - from_index, - } = self; - *to_index - .entry(placeholder) - .or_insert_with(|| from_index.push(placeholder)) + let PlaceholderIndices { to_index, from_index } = self; + *to_index.entry(placeholder).or_insert_with(|| from_index.push(placeholder)) } crate fn lookup_index(&self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex { @@ -355,10 +329,7 @@ impl RegionValues { &'a self, r: N, ) -> impl Iterator + 'a { - self.free_regions - .row(r) - .into_iter() - .flat_map(|set| set.iter()) + self.free_regions.row(r).into_iter().flat_map(|set| set.iter()) } /// Returns all the elements contained in a given region's value. @@ -377,15 +348,13 @@ impl RegionValues { crate fn elements_contained_in<'a>(&'a self, r: N) -> impl Iterator + 'a { let points_iter = self.locations_outlived_by(r).map(RegionElement::Location); - let free_regions_iter = self.universal_regions_outlived_by(r) - .map(RegionElement::RootUniversalRegion); + let free_regions_iter = + self.universal_regions_outlived_by(r).map(RegionElement::RootUniversalRegion); - let placeholder_universes_iter = self.placeholders_contained_in(r) - .map(RegionElement::PlaceholderRegion); + let placeholder_universes_iter = + self.placeholders_contained_in(r).map(RegionElement::PlaceholderRegion); - points_iter - .chain(free_regions_iter) - .chain(placeholder_universes_iter) + points_iter.chain(free_regions_iter).chain(placeholder_universes_iter) } /// Returns a "pretty" string value of the region. Meant for debugging. diff --git a/src/librustc_mir/borrow_check/renumber.rs b/src/librustc_mir/borrow_check/renumber.rs index ba323b113e9eb..ab08cb0a3190a 100644 --- a/src/librustc_mir/borrow_check/renumber.rs +++ b/src/librustc_mir/borrow_check/renumber.rs @@ -1,8 +1,8 @@ +use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; +use rustc::mir::visit::{MutVisitor, TyContext}; +use rustc::mir::{BodyAndCache, Location, PlaceElem, Promoted}; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; -use rustc::mir::{BodyAndCache, Location, PlaceElem, Promoted}; -use rustc::mir::visit::{MutVisitor, TyContext}; -use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; use rustc_index::vec::IndexVec; /// Replaces all free regions appearing in the MIR with fresh @@ -32,12 +32,10 @@ where { debug!("renumber_regions(value={:?})", value); - infcx - .tcx - .fold_regions(value, &mut false, |_region, _depth| { - let origin = NLLRegionVariableOrigin::Existential { from_forall: false }; - infcx.next_nll_region_var(origin) - }) + infcx.tcx.fold_regions(value, &mut false, |_region, _depth| { + let origin = NLLRegionVariableOrigin::Existential { from_forall: false }; + infcx.next_nll_region_var(origin) + }) } struct NLLVisitor<'a, 'tcx> { @@ -66,10 +64,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> { debug!("visit_ty: ty={:?}", ty); } - fn process_projection_elem( - &mut self, - elem: &PlaceElem<'tcx>, - ) -> Option> { + fn process_projection_elem(&mut self, elem: &PlaceElem<'tcx>) -> Option> { if let PlaceElem::Field(field, ty) = elem { let new_ty = self.renumber_regions(ty); diff --git a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs b/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs index 334477dff2362..957ee94460355 100644 --- a/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs +++ b/src/librustc_mir/borrow_check/type_check/constraint_conversion.rs @@ -1,5 +1,5 @@ -use rustc::infer::canonical::QueryRegionConstraints; use rustc::infer::canonical::QueryOutlivesConstraint; +use rustc::infer::canonical::QueryRegionConstraints; use rustc::infer::outlives::env::RegionBoundPairs; use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate}; use rustc::infer::region_constraints::{GenericKind, VerifyBound}; @@ -11,10 +11,10 @@ use syntax_pos::DUMMY_SP; use crate::borrow_check::{ constraints::OutlivesConstraint, + nll::ToRegionVid, region_infer::TypeTest, type_check::{Locations, MirTypeckRegionConstraints}, universal_regions::UniversalRegions, - nll::ToRegionVid, }; crate struct ConstraintConversion<'a, 'tcx> { @@ -62,15 +62,10 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { // `self.constraints`, but we also want to be mutating // `self.member_constraints`. For now, just swap out the value // we want and replace at the end. - let mut tmp = std::mem::replace( - &mut self.constraints.member_constraints, - Default::default(), - ); + let mut tmp = + std::mem::replace(&mut self.constraints.member_constraints, Default::default()); for member_constraint in member_constraints { - tmp.push_constraint( - member_constraint, - |r| self.to_region_vid(r), - ); + tmp.push_constraint(member_constraint, |r| self.to_region_vid(r)); } self.constraints.member_constraints = tmp; @@ -84,24 +79,16 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { // Extract out various useful fields we'll need below. let ConstraintConversion { - tcx, - region_bound_pairs, - implicit_region_bound, - param_env, - .. + tcx, region_bound_pairs, implicit_region_bound, param_env, .. } = *self; // At the moment, we never generate any "higher-ranked" // region constraints like `for<'a> 'a: 'b`. At some point // when we move to universes, we will, and this assertion // will start to fail. - let ty::OutlivesPredicate(k1, r2) = - query_constraint.no_bound_vars().unwrap_or_else(|| { - bug!( - "query_constraint {:?} contained bound vars", - query_constraint, - ); - }); + let ty::OutlivesPredicate(k1, r2) = query_constraint.no_bound_vars().unwrap_or_else(|| { + bug!("query_constraint {:?} contained bound vars", query_constraint,); + }); match k1.unpack() { GenericArgKind::Lifetime(r1) => { @@ -121,7 +108,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { region_bound_pairs, implicit_region_bound, param_env, - ).type_must_outlive(origin, t1, r2); + ) + .type_must_outlive(origin, t1, r2); } GenericArgKind::Const(_) => { @@ -139,33 +127,24 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { ) -> TypeTest<'tcx> { let lower_bound = self.to_region_vid(region); - TypeTest { - generic_kind, - lower_bound, - locations: self.locations, - verify_bound, - } + TypeTest { generic_kind, lower_bound, locations: self.locations, verify_bound } } fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid { if let ty::RePlaceholder(placeholder) = r { - self.constraints - .placeholder_region(self.infcx, *placeholder) - .to_region_vid() + self.constraints.placeholder_region(self.infcx, *placeholder).to_region_vid() } else { self.universal_regions.to_region_vid(r) } } fn add_outlives(&mut self, sup: ty::RegionVid, sub: ty::RegionVid) { - self.constraints - .outlives_constraints - .push(OutlivesConstraint { - locations: self.locations, - category: self.category, - sub, - sup, - }); + self.constraints.outlives_constraints.push(OutlivesConstraint { + locations: self.locations, + category: self.category, + sub, + sup, + }); } fn add_type_test(&mut self, type_test: TypeTest<'tcx>) { diff --git a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs index 03a7f97ac51f1..344a762fe9410 100644 --- a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs +++ b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs @@ -11,10 +11,10 @@ use std::rc::Rc; use syntax_pos::DUMMY_SP; use crate::borrow_check::{ + nll::ToRegionVid, type_check::constraint_conversion, type_check::{Locations, MirTypeckRegionConstraints}, universal_regions::UniversalRegions, - nll::ToRegionVid, }; #[derive(Debug)] @@ -76,7 +76,8 @@ crate fn create( outlives: Default::default(), inverse_outlives: Default::default(), }, - }.create() + } + .create() } impl UniversalRegionRelations<'tcx> { @@ -84,10 +85,7 @@ impl UniversalRegionRelations<'tcx> { /// `inverse_outlives_relation`) that `fr_a: fr_b`. Invoked by the /// builder below. fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) { - debug!( - "relate_universal_regions: fr_a={:?} outlives fr_b={:?}", - fr_a, fr_b - ); + debug!("relate_universal_regions: fr_a={:?} outlives fr_b={:?}", fr_a, fr_b); self.outlives.add(fr_a, fr_b); self.inverse_outlives.add(fr_b, fr_a); } @@ -126,9 +124,7 @@ impl UniversalRegionRelations<'tcx> { // In case we find more than one, reduce to one for // convenience. This is to prevent us from generating more // complex constraints, but it will cause spurious errors. - let post_dom = self - .inverse_outlives - .mutual_immediate_postdominator(upper_bounds); + let post_dom = self.inverse_outlives.mutual_immediate_postdominator(upper_bounds); debug!("non_local_bound: post_dom={:?}", post_dom); @@ -145,7 +141,6 @@ impl UniversalRegionRelations<'tcx> { .unwrap_or(self.universal_regions.fr_static) } - /// Finds a "lower bound" for `fr` that is not local. In other /// words, returns the largest (*) known region `fr1` that (a) is /// outlived by `fr` and (b) is not local. @@ -159,22 +154,19 @@ impl UniversalRegionRelations<'tcx> { // In case we find more than one, reduce to one for // convenience. This is to prevent us from generating more // complex constraints, but it will cause spurious errors. - let post_dom = self - .outlives - .mutual_immediate_postdominator(lower_bounds); + let post_dom = self.outlives.mutual_immediate_postdominator(lower_bounds); debug!("non_local_bound: post_dom={:?}", post_dom); - post_dom - .and_then(|&post_dom| { - // If the mutual immediate postdom is not local, then - // there is no non-local result we can return. - if !self.universal_regions.is_local_free_region(post_dom) { - Some(post_dom) - } else { - None - } - }) + post_dom.and_then(|&post_dom| { + // If the mutual immediate postdom is not local, then + // there is no non-local result we can return. + if !self.universal_regions.is_local_free_region(post_dom) { + Some(post_dom) + } else { + None + } + }) } /// Helper for `non_local_upper_bounds` and `non_local_lower_bounds`. @@ -222,7 +214,7 @@ impl UniversalRegionRelations<'tcx> { } /// Returns the _non-transitive_ set of known `outlives` constraints between free regions. - crate fn known_outlives(&self) -> impl Iterator { + crate fn known_outlives(&self) -> impl Iterator { self.outlives.base_edges() } } @@ -268,9 +260,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { .unwrap_or_else(|_| bug!("failed to normalize {:?}", ty)); let constraints2 = self.add_implied_bounds(ty); normalized_inputs_and_output.push(ty); - constraints1 - .into_iter() - .chain(constraints2) + constraints1.into_iter().chain(constraints2) }) .collect(); @@ -286,10 +276,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { let fr_static = self.universal_regions.fr_static; let fr_fn_body = self.universal_regions.fr_fn_body; for fr in self.universal_regions.universal_regions() { - debug!( - "build: relating free region {:?} to itself and to 'static", - fr - ); + debug!("build: relating free region {:?} to itself and to 'static", fr); self.relations.relate_universal_regions(fr, fr); self.relations.relate_universal_regions(fr_static, fr); self.relations.relate_universal_regions(fr, fr_fn_body); @@ -305,7 +292,8 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { Locations::All(DUMMY_SP), ConstraintCategory::Internal, &mut self.constraints, - ).convert_all(data); + ) + .convert_all(data); } CreateResult { @@ -321,8 +309,8 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { /// from this local. fn add_implied_bounds(&mut self, ty: Ty<'tcx>) -> Option>> { debug!("add_implied_bounds(ty={:?})", ty); - let (bounds, constraints) = - self.param_env + let (bounds, constraints) = self + .param_env .and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty }) .fully_perform(self.infcx) .unwrap_or_else(|_| bug!("failed to compute implied bounds {:?}", ty)); @@ -356,13 +344,11 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { } OutlivesBound::RegionSubParam(r_a, param_b) => { - self.region_bound_pairs - .push((r_a, GenericKind::Param(param_b))); + self.region_bound_pairs.push((r_a, GenericKind::Param(param_b))); } OutlivesBound::RegionSubProjection(r_a, projection_b) => { - self.region_bound_pairs - .push((r_a, GenericKind::Projection(projection_b))); + self.region_bound_pairs.push((r_a, GenericKind::Projection(projection_b))); } } } diff --git a/src/librustc_mir/borrow_check/type_check/input_output.rs b/src/librustc_mir/borrow_check/type_check/input_output.rs index 3df04909d0d2f..f705d073b6409 100644 --- a/src/librustc_mir/borrow_check/type_check/input_output.rs +++ b/src/librustc_mir/borrow_check/type_check/input_output.rs @@ -69,10 +69,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // In MIR, argument N is stored in local N+1. let local = Local::new(argument_index + 1); - debug!( - "equate_inputs_and_outputs: normalized_input_ty = {:?}", - normalized_input_ty - ); + debug!("equate_inputs_and_outputs: normalized_input_ty = {:?}", normalized_input_ty); let mir_input_ty = body.local_decls[local].ty; let mir_input_span = body.local_decls[local].source_info.span; @@ -145,7 +142,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { user_provided_output_ty, self.mir_def_id, Locations::All(output_span), - ConstraintCategory::BoringNoLocation + ConstraintCategory::BoringNoLocation, ) { span_mirbug!( self, @@ -162,12 +159,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn equate_normalized_input_or_output(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, span: Span) { debug!("equate_normalized_input_or_output(a={:?}, b={:?})", a, b); - if let Err(terr) = self.eq_types( - a, - b, - Locations::All(span), - ConstraintCategory::BoringNoLocation, - ) { + if let Err(terr) = + self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation) + { span_mirbug!( self, Location::START, diff --git a/src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs b/src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs index 75e4f61245f5f..7bf355ddbf612 100644 --- a/src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs +++ b/src/librustc_mir/borrow_check/type_check/liveness/local_use_map.rs @@ -1,7 +1,7 @@ use rustc::mir::visit::{PlaceContext, Visitor}; use rustc::mir::{Local, Location, ReadOnlyBodyAndCache}; -use rustc_index::vec::{Idx, IndexVec}; use rustc_data_structures::vec_linked_list as vll; +use rustc_index::vec::{Idx, IndexVec}; use crate::util::liveness::{categorize, DefUse}; diff --git a/src/librustc_mir/borrow_check/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/type_check/liveness/mod.rs index ee3d89e741a54..e461ce739a7cd 100644 --- a/src/librustc_mir/borrow_check/type_check/liveness/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/liveness/mod.rs @@ -8,12 +8,12 @@ use crate::dataflow::FlowAtLocation; use crate::dataflow::MaybeInitializedPlaces; use crate::borrow_check::{ - location::LocationTable, constraints::OutlivesConstraintSet, facts::{AllFacts, AllFactsExt}, + location::LocationTable, + nll::ToRegionVid, region_infer::values::RegionValueElements, universal_regions::UniversalRegions, - nll::ToRegionVid, }; use super::TypeChecker; @@ -50,13 +50,7 @@ pub(super) fn generate<'tcx>( let polonius_drop_used = if facts_enabled { let mut drop_used = Vec::new(); - polonius::populate_access_facts( - typeck, - body, - location_table, - move_data, - &mut drop_used, - ); + polonius::populate_access_facts(typeck, body, location_table, move_data, &mut drop_used); Some(drop_used) } else { None diff --git a/src/librustc_mir/borrow_check/type_check/liveness/polonius.rs b/src/librustc_mir/borrow_check/type_check/liveness/polonius.rs index 0354b0d6b92c5..055415f287222 100644 --- a/src/librustc_mir/borrow_check/type_check/liveness/polonius.rs +++ b/src/librustc_mir/borrow_check/type_check/liveness/polonius.rs @@ -103,9 +103,9 @@ pub(super) fn populate_access_facts( }; extractor.visit_body(body); - facts.var_drop_used.extend(drop_used.iter().map(|&(local, location)| { - (local, location_table.mid_index(location)) - })); + facts.var_drop_used.extend( + drop_used.iter().map(|&(local, location)| (local, location_table.mid_index(location))), + ); for (local, local_decl) in body.local_decls.iter_enumerated() { debug!("add var_uses_regions facts - local={:?}, type={:?}", local, local_decl.ty); diff --git a/src/librustc_mir/borrow_check/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/type_check/liveness/trace.rs index 9afd25a0f7f7e..ebb925ae0cb56 100644 --- a/src/librustc_mir/borrow_check/type_check/liveness/trace.rs +++ b/src/librustc_mir/borrow_check/type_check/liveness/trace.rs @@ -4,8 +4,8 @@ use rustc::traits::query::dropck_outlives::DropckOutlivesResult; use rustc::traits::query::type_op::outlives::DropckOutlives; use rustc::traits::query::type_op::TypeOp; use rustc::ty::{Ty, TypeFoldable}; -use rustc_index::bit_set::HybridBitSet; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_index::bit_set::HybridBitSet; use std::rc::Rc; use crate::dataflow::indexes::MovePathIndex; @@ -171,12 +171,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> { if !live_locals.contains(&local) { let local_ty = self.cx.body.local_decls[local].ty; if local_ty.has_free_regions() { - self.cx.add_drop_live_facts_for( - local, - local_ty, - &[location], - &locations, - ); + self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations); } } } diff --git a/src/librustc_mir/borrow_check/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/type_check/relate_tys.rs index 80da8a82c51ed..edbcd715159ac 100644 --- a/src/librustc_mir/borrow_check/type_check/relate_tys.rs +++ b/src/librustc_mir/borrow_check/type_check/relate_tys.rs @@ -1,4 +1,4 @@ -use rustc::infer::nll_relate::{TypeRelating, TypeRelatingDelegate, NormalizationStrategy}; +use rustc::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; use rustc::mir::ConstraintCategory; use rustc::traits::query::Fallible; @@ -30,8 +30,9 @@ pub(super) fn relate_types<'tcx>( TypeRelating::new( infcx, NllTypeRelatingDelegate::new(infcx, borrowck_context, locations, category), - v - ).relate(&a, &b)?; + v, + ) + .relate(&a, &b)?; Ok(()) } @@ -53,12 +54,7 @@ impl NllTypeRelatingDelegate<'me, 'bccx, 'tcx> { locations: Locations, category: ConstraintCategory, ) -> Self { - Self { - infcx, - borrowck_context, - locations, - category, - } + Self { infcx, borrowck_context, locations, category } } } @@ -76,10 +72,7 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> { } } - fn next_placeholder_region( - &mut self, - placeholder: ty::PlaceholderRegion - ) -> ty::Region<'tcx> { + fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> { if let Some(borrowck_context) = &mut self.borrowck_context { borrowck_context.constraints.placeholder_region(self.infcx, placeholder) } else { @@ -88,25 +81,22 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> { } fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> { - self.infcx - .next_nll_region_var_in_universe(NLLRegionVariableOrigin::Existential { - from_forall: false - }, universe) + self.infcx.next_nll_region_var_in_universe( + NLLRegionVariableOrigin::Existential { from_forall: false }, + universe, + ) } fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) { if let Some(borrowck_context) = &mut self.borrowck_context { let sub = borrowck_context.universal_regions.to_region_vid(sub); let sup = borrowck_context.universal_regions.to_region_vid(sup); - borrowck_context - .constraints - .outlives_constraints - .push(OutlivesConstraint { - sup, - sub, - locations: self.locations, - category: self.category, - }); + borrowck_context.constraints.outlives_constraints.push(OutlivesConstraint { + sup, + sub, + locations: self.locations, + category: self.category, + }); } } diff --git a/src/librustc_mir/borrow_check/universal_regions.rs b/src/librustc_mir/borrow_check/universal_regions.rs index c0353039b680c..141289bd2b2d3 100644 --- a/src/librustc_mir/borrow_check/universal_regions.rs +++ b/src/librustc_mir/borrow_check/universal_regions.rs @@ -18,11 +18,11 @@ use rustc::hir::{self, BodyOwnerKind, HirId}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; use rustc::middle::lang_items; use rustc::ty::fold::TypeFoldable; -use rustc::ty::subst::{InternalSubsts, SubstsRef, Subst}; +use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc::ty::{self, RegionVid, Ty, TyCtxt}; use rustc::util::nodemap::FxHashMap; -use rustc_index::vec::{Idx, IndexVec}; use rustc_errors::DiagnosticBuilder; +use rustc_index::vec::{Idx, IndexVec}; use std::iter; use crate::borrow_check::nll::ToRegionVid; @@ -109,9 +109,9 @@ impl<'tcx> DefiningTy<'tcx> { /// match up with the upvar order in the HIR, typesystem, and MIR. pub fn upvar_tys(self, tcx: TyCtxt<'tcx>) -> impl Iterator> + 'tcx { match self { - DefiningTy::Closure(def_id, substs) => Either::Left( - substs.as_closure().upvar_tys(def_id, tcx) - ), + DefiningTy::Closure(def_id, substs) => { + Either::Left(substs.as_closure().upvar_tys(def_id, tcx)) + } DefiningTy::Generator(def_id, substs, _) => { Either::Right(Either::Left(substs.as_generator().upvar_tys(def_id, tcx))) } @@ -203,12 +203,7 @@ impl<'tcx> UniversalRegions<'tcx> { ) -> Self { let tcx = infcx.tcx; let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id).unwrap(); - UniversalRegionsBuilder { - infcx, - mir_def_id, - mir_hir_id, - param_env, - }.build() + UniversalRegionsBuilder { infcx, mir_def_id, mir_hir_id, param_env }.build() } /// Given a reference to a closure type, extracts all the values @@ -324,10 +319,7 @@ impl<'tcx> UniversalRegions<'tcx> { // So we just include the region-vid. Annoying. let closure_base_def_id = tcx.closure_base_def_id(def_id); for_each_late_bound_region_defined_on(tcx, closure_base_def_id, |r| { - err.note(&format!( - "late-bound region is {:?}", - self.to_region_vid(r), - )); + err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),)); }); } DefiningTy::Generator(def_id, substs, _) => { @@ -342,10 +334,7 @@ impl<'tcx> UniversalRegions<'tcx> { // and so forth. let closure_base_def_id = tcx.closure_base_def_id(def_id); for_each_late_bound_region_defined_on(tcx, closure_base_def_id, |r| { - err.note(&format!( - "late-bound region is {:?}", - self.to_region_vid(r), - )); + err.note(&format!("late-bound region is {:?}", self.to_region_vid(r),)); }); } DefiningTy::FnDef(def_id, substs) => { @@ -404,8 +393,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { // let c = || { let x: &'a u32 = ...; } // } if self.mir_def_id != closure_base_def_id { - self.infcx - .replace_late_bound_regions_with_nll_infer_vars(self.mir_def_id, &mut indices) + self.infcx.replace_late_bound_regions_with_nll_infer_vars(self.mir_def_id, &mut indices) } let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty); @@ -435,17 +423,17 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { if self.infcx.tcx.fn_sig(def_id).c_variadic() { let va_list_did = self.infcx.tcx.require_lang_item( lang_items::VaListTypeLangItem, - Some(self.infcx.tcx.def_span(self.mir_def_id),), + Some(self.infcx.tcx.def_span(self.mir_def_id)), ); - let region = self.infcx.tcx.mk_region(ty::ReVar( - self.infcx.next_nll_region_var(FR).to_region_vid(), - )); - let va_list_ty = self.infcx.tcx.type_of(va_list_did) - .subst(self.infcx.tcx, &[region.into()]); + let region = self + .infcx + .tcx + .mk_region(ty::ReVar(self.infcx.next_nll_region_var(FR).to_region_vid())); + let va_list_ty = + self.infcx.tcx.type_of(va_list_did).subst(self.infcx.tcx, &[region.into()]); unnormalized_input_tys = self.infcx.tcx.mk_type_list( - unnormalized_input_tys.iter().copied() - .chain(iter::once(va_list_ty)), + unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)), ); } } @@ -453,18 +441,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let fr_fn_body = self.infcx.next_nll_region_var(FR).to_region_vid(); let num_universals = self.infcx.num_region_vars(); - debug!( - "build: global regions = {}..{}", - FIRST_GLOBAL_INDEX, first_extern_index - ); - debug!( - "build: extern regions = {}..{}", - first_extern_index, first_local_index - ); - debug!( - "build: local regions = {}..{}", - first_local_index, num_universals - ); + debug!("build: global regions = {}..{}", FIRST_GLOBAL_INDEX, first_extern_index); + debug!("build: extern regions = {}..{}", first_extern_index, first_local_index); + debug!("build: local regions = {}..{}", first_local_index, num_universals); let yield_ty = match defining_ty { DefiningTy::Generator(def_id, substs, _) => { @@ -494,8 +473,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id); match tcx.hir().body_owner_kind(self.mir_hir_id) { - BodyOwnerKind::Closure | - BodyOwnerKind::Fn => { + BodyOwnerKind::Closure | BodyOwnerKind::Fn => { let defining_ty = if self.mir_def_id == closure_base_def_id { tcx.type_of(closure_base_def_id) } else { @@ -505,8 +483,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { debug!("defining_ty (pre-replacement): {:?}", defining_ty); - let defining_ty = self.infcx - .replace_free_regions_with_nll_infer_vars(FR, &defining_ty); + let defining_ty = + self.infcx.replace_free_regions_with_nll_infer_vars(FR, &defining_ty); match defining_ty.kind { ty::Closure(def_id, substs) => DefiningTy::Closure(def_id, substs), @@ -526,8 +504,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { BodyOwnerKind::Const | BodyOwnerKind::Static(..) => { assert_eq!(closure_base_def_id, self.mir_def_id); let identity_substs = InternalSubsts::identity_for_item(tcx, closure_base_def_id); - let substs = self.infcx - .replace_free_regions_with_nll_infer_vars(FR, &identity_substs); + let substs = + self.infcx.replace_free_regions_with_nll_infer_vars(FR, &identity_substs); DefiningTy::Const(self.mir_def_id, substs) } } @@ -546,8 +524,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id); let identity_substs = InternalSubsts::identity_for_item(tcx, closure_base_def_id); let fr_substs = match defining_ty { - DefiningTy::Closure(_, ref substs) - | DefiningTy::Generator(_, ref substs, _) => { + DefiningTy::Closure(_, ref substs) | DefiningTy::Generator(_, ref substs, _) => { // In the case of closures, we rely on the fact that // the first N elements in the ClosureSubsts are // inherited from the `closure_base_def_id`. @@ -564,13 +541,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { }; let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static)); - let subst_mapping = identity_substs - .regions() - .zip(fr_substs.regions().map(|r| r.to_region_vid())); + let subst_mapping = + identity_substs.regions().zip(fr_substs.regions().map(|r| r.to_region_vid())); - UniversalRegionIndices { - indices: global_mapping.chain(subst_mapping).collect(), - } + UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect() } } fn compute_inputs_and_output( @@ -585,27 +559,23 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let closure_sig = substs.as_closure().sig_ty(def_id, tcx).fn_sig(tcx); let inputs_and_output = closure_sig.inputs_and_output(); let closure_ty = tcx.closure_env_ty(def_id, substs).unwrap(); - ty::Binder::fuse( - closure_ty, - inputs_and_output, - |closure_ty, inputs_and_output| { - // The "inputs" of the closure in the - // signature appear as a tuple. The MIR side - // flattens this tuple. - let (&output, tuplized_inputs) = inputs_and_output.split_last().unwrap(); - assert_eq!(tuplized_inputs.len(), 1, "multiple closure inputs"); - let inputs = match tuplized_inputs[0].kind { - ty::Tuple(inputs) => inputs, - _ => bug!("closure inputs not a tuple: {:?}", tuplized_inputs[0]), - }; - - tcx.mk_type_list( - iter::once(closure_ty) - .chain(inputs.iter().map(|k| k.expect_ty())) - .chain(iter::once(output)), - ) - }, - ) + ty::Binder::fuse(closure_ty, inputs_and_output, |closure_ty, inputs_and_output| { + // The "inputs" of the closure in the + // signature appear as a tuple. The MIR side + // flattens this tuple. + let (&output, tuplized_inputs) = inputs_and_output.split_last().unwrap(); + assert_eq!(tuplized_inputs.len(), 1, "multiple closure inputs"); + let inputs = match tuplized_inputs[0].kind { + ty::Tuple(inputs) => inputs, + _ => bug!("closure inputs not a tuple: {:?}", tuplized_inputs[0]), + }; + + tcx.mk_type_list( + iter::once(closure_ty) + .chain(inputs.iter().map(|k| k.expect_ty())) + .chain(iter::once(output)), + ) + }) } DefiningTy::Generator(def_id, substs, movability) => { @@ -669,9 +639,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { where T: TypeFoldable<'tcx>, { - self.tcx.fold_regions(value, &mut false, |_region, _depth| { - self.next_nll_region_var(origin) - }) + self.tcx.fold_regions(value, &mut false, |_region, _depth| self.next_nll_region_var(origin)) } fn replace_bound_regions_with_nll_infer_vars( @@ -719,10 +687,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { mir_def_id: DefId, indices: &mut UniversalRegionIndices<'tcx>, ) { - debug!( - "replace_late_bound_regions_with_nll_infer_vars(mir_def_id={:?})", - mir_def_id - ); + debug!("replace_late_bound_regions_with_nll_infer_vars(mir_def_id={:?})", mir_def_id); let closure_base_def_id = self.tcx.closure_base_def_id(mir_def_id); for_each_late_bound_region_defined_on(self.tcx, closure_base_def_id, |r| { debug!("replace_late_bound_regions_with_nll_infer_vars: r={:?}", r); @@ -757,7 +722,8 @@ impl<'tcx> UniversalRegionIndices<'tcx> { if let ty::ReVar(..) = r { r.to_region_vid() } else { - *self.indices + *self + .indices .get(&r) .unwrap_or_else(|| bug!("cannot convert `{:?}` to a region vid", r)) } @@ -784,10 +750,7 @@ fn for_each_late_bound_region_defined_on<'tcx>( ) { if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.index) { for late_bound in late_bounds.iter() { - let hir_id = HirId { - owner: fn_def_id.index, - local_id: *late_bound, - }; + let hir_id = HirId { owner: fn_def_id.index, local_id: *late_bound }; let name = tcx.hir().name(hir_id); let region_def_id = tcx.hir().local_def_id(hir_id); let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs index 95471afb7884f..608a2436bf3d3 100644 --- a/src/librustc_mir/borrow_check/used_muts.rs +++ b/src/librustc_mir/borrow_check/used_muts.rs @@ -64,30 +64,22 @@ impl GatherUsedMutsVisitor<'_, '_, '_> { } impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tcx> { - fn visit_terminator_kind( - &mut self, - kind: &TerminatorKind<'tcx>, - _location: Location, - ) { + fn visit_terminator_kind(&mut self, kind: &TerminatorKind<'tcx>, _location: Location) { debug!("visit_terminator_kind: kind={:?}", kind); match &kind { TerminatorKind::Call { destination: Some((into, _)), .. } => { self.remove_never_initialized_mut_locals(&into); - }, + } TerminatorKind::DropAndReplace { location, .. } => { self.remove_never_initialized_mut_locals(&location); - }, - _ => {}, + } + _ => {} } } - fn visit_statement( - &mut self, - statement: &Statement<'tcx>, - _location: Location, - ) { + fn visit_statement(&mut self, statement: &Statement<'tcx>, _location: Location) { match &statement.kind { - StatementKind::Assign(box(into, _)) => { + StatementKind::Assign(box (into, _)) => { if let PlaceBase::Local(local) = into.base { debug!( "visit_statement: statement={:?} local={:?} \ @@ -96,17 +88,12 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc ); } self.remove_never_initialized_mut_locals(into); - }, - _ => {}, + } + _ => {} } } - fn visit_local( - &mut self, - local: &Local, - place_context: PlaceContext, - location: Location, - ) { + fn visit_local(&mut self, local: &Local, place_context: PlaceContext, location: Location) { if place_context.is_place_assignment() && self.temporary_used_locals.contains(local) { // Propagate the Local assigned at this Location as a used mutable local variable for moi in &self.mbcx.move_data.loc_map[location] { diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index aceed09757e7e..077854c8ed594 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -1,18 +1,19 @@ -use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; -use crate::build::ForGuard::OutsideGuard; use crate::build::matches::ArmHasGuard; +use crate::build::ForGuard::OutsideGuard; +use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use crate::hair::*; -use rustc::mir::*; use rustc::hir; +use rustc::mir::*; use syntax_pos::Span; impl<'a, 'tcx> Builder<'a, 'tcx> { - pub fn ast_block(&mut self, - destination: &Place<'tcx>, - block: BasicBlock, - ast_block: &'tcx hir::Block, - source_info: SourceInfo) - -> BlockAnd<()> { + pub fn ast_block( + &mut self, + destination: &Place<'tcx>, + block: BasicBlock, + ast_block: &'tcx hir::Block, + source_info: SourceInfo, + ) -> BlockAnd<()> { let Block { region_scope, opt_destruction_scope, @@ -20,37 +21,35 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { stmts, expr, targeted_by_break, - safety_mode - } = - self.hir.mirror(ast_block); - self.in_opt_scope(opt_destruction_scope.map(|de|(de, source_info)), move |this| { + safety_mode, + } = self.hir.mirror(ast_block); + self.in_opt_scope(opt_destruction_scope.map(|de| (de, source_info)), move |this| { this.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| { if targeted_by_break { // This is a `break`-able block let exit_block = this.cfg.start_new_block(); - let block_exit = this.in_breakable_scope( - None, exit_block, destination.clone(), |this| { - this.ast_block_stmts(destination, block, span, stmts, expr, - safety_mode) + let block_exit = + this.in_breakable_scope(None, exit_block, destination.clone(), |this| { + this.ast_block_stmts(destination, block, span, stmts, expr, safety_mode) }); this.cfg.goto(unpack!(block_exit), source_info, exit_block); exit_block.unit() } else { - this.ast_block_stmts(destination, block, span, stmts, expr, - safety_mode) + this.ast_block_stmts(destination, block, span, stmts, expr, safety_mode) } }) }) } - fn ast_block_stmts(&mut self, - destination: &Place<'tcx>, - mut block: BasicBlock, - span: Span, - stmts: Vec>, - expr: Option>, - safety_mode: BlockSafety) - -> BlockAnd<()> { + fn ast_block_stmts( + &mut self, + destination: &Place<'tcx>, + mut block: BasicBlock, + span: Span, + stmts: Vec>, + expr: Option>, + safety_mode: BlockSafety, + ) -> BlockAnd<()> { let this = self; // This convoluted structure is to avoid using recursion as we walk down a list @@ -81,27 +80,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match kind { StmtKind::Expr { scope, expr } => { this.block_context.push(BlockFrame::Statement { ignores_expr_result: true }); - unpack!(block = this.in_opt_scope( - opt_destruction_scope.map(|de|(de, source_info)), |this| { - let si = (scope, source_info); - this.in_scope(si, LintLevel::Inherited, |this| { - let expr = this.hir.mirror(expr); - this.stmt_expr(block, expr, Some(scope)) - }) - })); + unpack!( + block = this.in_opt_scope( + opt_destruction_scope.map(|de| (de, source_info)), + |this| { + let si = (scope, source_info); + this.in_scope(si, LintLevel::Inherited, |this| { + let expr = this.hir.mirror(expr); + this.stmt_expr(block, expr, Some(scope)) + }) + } + ) + ); } - StmtKind::Let { - remainder_scope, - init_scope, - pattern, - initializer, - lint_level - } => { - let ignores_expr_result = if let PatKind::Wild = *pattern.kind { - true - } else { - false - }; + StmtKind::Let { remainder_scope, init_scope, pattern, initializer, lint_level } => { + let ignores_expr_result = + if let PatKind::Wild = *pattern.kind { true } else { false }; this.block_context.push(BlockFrame::Statement { ignores_expr_result }); // Enter the remainder scope, i.e., the bindings' destruction scope. @@ -109,8 +103,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let_scope_stack.push(remainder_scope); // Declare the bindings, which may create a source scope. - let remainder_span = remainder_scope.span(this.hir.tcx(), - &this.hir.region_scope_tree); + let remainder_span = + remainder_scope.span(this.hir.tcx(), &this.hir.region_scope_tree); let visibility_scope = Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None)); @@ -119,20 +113,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if let Some(init) = initializer { let initializer_span = init.span(); - unpack!(block = this.in_opt_scope( - opt_destruction_scope.map(|de|(de, source_info)), |this| { - let scope = (init_scope, source_info); - this.in_scope(scope, lint_level, |this| { - this.declare_bindings( - visibility_scope, - remainder_span, - &pattern, - ArmHasGuard(false), - Some((None, initializer_span)), - ); - this.expr_into_pattern(block, pattern, init) - }) - })); + unpack!( + block = this.in_opt_scope( + opt_destruction_scope.map(|de| (de, source_info)), + |this| { + let scope = (init_scope, source_info); + this.in_scope(scope, lint_level, |this| { + this.declare_bindings( + visibility_scope, + remainder_span, + &pattern, + ArmHasGuard(false), + Some((None, initializer_span)), + ); + this.expr_into_pattern(block, pattern, init) + }) + } + ) + ); } else { let scope = (init_scope, source_info); unpack!(this.in_scope(scope, lint_level, |this| { @@ -153,7 +151,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut |this, _, _, _, node, span, _, _| { this.storage_live_binding(block, node, span, OutsideGuard); this.schedule_drop_for_binding(node, span, OutsideGuard); - }) + }, + ) } // Enter the visibility scope, after evaluating the initializer. @@ -164,7 +163,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } let popped = this.block_context.pop(); - assert!(popped.map_or(false, |bf|bf.is_statement())); + assert!(popped.map_or(false, |bf| bf.is_statement())); } // Then, the block may have an optional trailing expression which is a “return” value @@ -172,14 +171,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let tcx = this.hir.tcx(); let destination_ty = destination.ty(&this.local_decls, tcx).ty; if let Some(expr) = expr { - let tail_result_is_ignored = destination_ty.is_unit() || - this.block_context.currently_ignores_tail_results(); + let tail_result_is_ignored = + destination_ty.is_unit() || this.block_context.currently_ignores_tail_results(); this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored }); unpack!(block = this.into(destination, block, expr)); let popped = this.block_context.pop(); - assert!(popped.map_or(false, |bf|bf.is_tail_expr())); + assert!(popped.map_or(false, |bf| bf.is_tail_expr())); } else { // If a block has no trailing expression, then it is given an implicit return type. // This return type is usually `()`, unless the block is diverging, in which case the @@ -204,10 +203,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } /// If we are changing the safety mode, create a new source scope - fn update_source_scope_for_safety_mode(&mut self, - span: Span, - safety_mode: BlockSafety) - { + fn update_source_scope_for_safety_mode(&mut self, span: Span, safety_mode: BlockSafety) { debug!("update_source_scope_for({:?}, {:?})", span, safety_mode); let new_unsafety = match safety_mode { BlockSafety::Safe => None, @@ -215,7 +211,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { assert_eq!(self.push_unsafe_count, 0); match self.unpushed_unsafe { Safety::Safe => {} - _ => return + _ => return, } self.unpushed_unsafe = Safety::ExplicitUnsafe(hir_id); Some(Safety::ExplicitUnsafe(hir_id)) @@ -225,21 +221,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Some(Safety::BuiltinUnsafe) } BlockSafety::PopUnsafe => { - self.push_unsafe_count = - self.push_unsafe_count.checked_sub(1).unwrap_or_else(|| { - span_bug!(span, "unsafe count underflow") - }); - if self.push_unsafe_count == 0 { - Some(self.unpushed_unsafe) - } else { - None - } + self.push_unsafe_count = self + .push_unsafe_count + .checked_sub(1) + .unwrap_or_else(|| span_bug!(span, "unsafe count underflow")); + if self.push_unsafe_count == 0 { Some(self.unpushed_unsafe) } else { None } } }; if let Some(unsafety) = new_unsafety { - self.source_scope = self.new_source_scope( - span, LintLevel::Inherited, Some(unsafety)); + self.source_scope = self.new_source_scope(span, LintLevel::Inherited, Some(unsafety)); } } } diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs index 0e685486c3f99..553701c91eead 100644 --- a/src/librustc_mir/build/cfg.rs +++ b/src/librustc_mir/build/cfg.rs @@ -30,33 +30,41 @@ impl<'tcx> CFG<'tcx> { self.block_data_mut(block).statements.push(statement); } - pub fn push_assign(&mut self, - block: BasicBlock, - source_info: SourceInfo, - place: &Place<'tcx>, - rvalue: Rvalue<'tcx>) { - self.push(block, Statement { - source_info, - kind: StatementKind::Assign(box(place.clone(), rvalue)) - }); + pub fn push_assign( + &mut self, + block: BasicBlock, + source_info: SourceInfo, + place: &Place<'tcx>, + rvalue: Rvalue<'tcx>, + ) { + self.push( + block, + Statement { source_info, kind: StatementKind::Assign(box (place.clone(), rvalue)) }, + ); } - pub fn push_assign_constant(&mut self, - block: BasicBlock, - source_info: SourceInfo, - temp: &Place<'tcx>, - constant: Constant<'tcx>) { - self.push_assign(block, source_info, temp, - Rvalue::Use(Operand::Constant(box constant))); + pub fn push_assign_constant( + &mut self, + block: BasicBlock, + source_info: SourceInfo, + temp: &Place<'tcx>, + constant: Constant<'tcx>, + ) { + self.push_assign(block, source_info, temp, Rvalue::Use(Operand::Constant(box constant))); } - pub fn push_assign_unit(&mut self, - block: BasicBlock, - source_info: SourceInfo, - place: &Place<'tcx>) { - self.push_assign(block, source_info, place, Rvalue::Aggregate( - box AggregateKind::Tuple, vec![] - )); + pub fn push_assign_unit( + &mut self, + block: BasicBlock, + source_info: SourceInfo, + place: &Place<'tcx>, + ) { + self.push_assign( + block, + source_info, + place, + Rvalue::Aggregate(box AggregateKind::Tuple, vec![]), + ); } pub fn push_fake_read( @@ -71,19 +79,20 @@ impl<'tcx> CFG<'tcx> { self.push(block, stmt); } - pub fn terminate(&mut self, - block: BasicBlock, - source_info: SourceInfo, - kind: TerminatorKind<'tcx>) { + pub fn terminate( + &mut self, + block: BasicBlock, + source_info: SourceInfo, + kind: TerminatorKind<'tcx>, + ) { debug!("terminating block {:?} <- {:?}", block, kind); - debug_assert!(self.block_data(block).terminator.is_none(), - "terminate: block {:?}={:?} already has a terminator set", - block, - self.block_data(block)); - self.block_data_mut(block).terminator = Some(Terminator { - source_info, - kind, - }); + debug_assert!( + self.block_data(block).terminator.is_none(), + "terminate: block {:?}={:?} already has a terminator set", + block, + self.block_data(block) + ); + self.block_data_mut(block).terminator = Some(Terminator { source_info, kind }); } /// In the `origin` block, push a `goto -> target` terminator. diff --git a/src/librustc_mir/build/expr/as_constant.rs b/src/librustc_mir/build/expr/as_constant.rs index 6db7ec65096ec..ceac2a0cd030f 100644 --- a/src/librustc_mir/build/expr/as_constant.rs +++ b/src/librustc_mir/build/expr/as_constant.rs @@ -18,18 +18,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn expr_as_constant(&mut self, expr: Expr<'tcx>) -> Constant<'tcx> { let this = self; - let Expr { - ty, - temp_lifetime: _, - span, - kind, - } = expr; + let Expr { ty, temp_lifetime: _, span, kind } = expr; match kind { - ExprKind::Scope { - region_scope: _, - lint_level: _, - value, - } => this.as_constant(value), + ExprKind::Scope { region_scope: _, lint_level: _, value } => this.as_constant(value), ExprKind::Literal { literal, user_ty } => { let user_ty = user_ty.map(|user_ty| { this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { @@ -39,19 +30,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }) }); assert_eq!(literal.ty, ty); - Constant { - span, - user_ty, - literal, - } - }, - ExprKind::StaticRef { literal, .. } => { - Constant { - span, - user_ty: None, - literal, - } + Constant { span, user_ty, literal } } + ExprKind::StaticRef { literal, .. } => Constant { span, user_ty: None, literal }, _ => span_bug!(span, "expression is not a valid constant {:?}", kind), } } diff --git a/src/librustc_mir/build/expr/as_operand.rs b/src/librustc_mir/build/expr/as_operand.rs index 207399fbdcf0e..b969932a73646 100644 --- a/src/librustc_mir/build/expr/as_operand.rs +++ b/src/librustc_mir/build/expr/as_operand.rs @@ -49,24 +49,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug!("expr_as_operand(block={:?}, expr={:?})", block, expr); let this = self; - if let ExprKind::Scope { - region_scope, - lint_level, - value, - } = expr.kind - { + if let ExprKind::Scope { region_scope, lint_level, value } = expr.kind { let source_info = this.source_info(expr.span); let region_scope = (region_scope, source_info); - return this.in_scope(region_scope, lint_level, |this| { - this.as_operand(block, scope, value) - }); + return this + .in_scope(region_scope, lint_level, |this| this.as_operand(block, scope, value)); } let category = Category::of(&expr.kind).unwrap(); - debug!( - "expr_as_operand: category={:?} for={:?}", - category, expr.kind - ); + debug!("expr_as_operand: category={:?} for={:?}", category, expr.kind); match category { Category::Constant => { let constant = this.as_constant(expr); diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 15c7c92d7db51..a39ab747094be 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -5,7 +5,7 @@ use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::hair::*; use rustc::middle::region; -use rustc::mir::interpret::{PanicInfo::BoundsCheck}; +use rustc::mir::interpret::PanicInfo::BoundsCheck; use rustc::mir::*; use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, Variance}; use syntax_pos::Span; @@ -26,10 +26,7 @@ struct PlaceBuilder<'tcx> { impl PlaceBuilder<'tcx> { fn into_place(self, tcx: TyCtxt<'tcx>) -> Place<'tcx> { - Place { - base: self.base, - projection: tcx.intern_place_elems(&self.projection), - } + Place { base: self.base, projection: tcx.intern_place_elems(&self.projection) } } fn field(self, f: Field, ty: Ty<'tcx>) -> Self { @@ -52,19 +49,13 @@ impl PlaceBuilder<'tcx> { impl From for PlaceBuilder<'tcx> { fn from(local: Local) -> Self { - Self { - base: local.into(), - projection: Vec::new(), - } + Self { base: local.into(), projection: Vec::new() } } } impl From> for PlaceBuilder<'tcx> { fn from(base: PlaceBase<'tcx>) -> Self { - Self { - base, - projection: Vec::new(), - } + Self { base, projection: Vec::new() } } } @@ -137,55 +128,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { mutability: Mutability, fake_borrow_temps: Option<&mut Vec>, ) -> BlockAnd> { - debug!( - "expr_as_place(block={:?}, expr={:?}, mutability={:?})", - block, expr, mutability - ); + debug!("expr_as_place(block={:?}, expr={:?}, mutability={:?})", block, expr, mutability); let this = self; let expr_span = expr.span; let source_info = this.source_info(expr_span); match expr.kind { - ExprKind::Scope { - region_scope, - lint_level, - value, - } => this.in_scope((region_scope, source_info), lint_level, |this| { - let value = this.hir.mirror(value); - this.expr_as_place(block, value, mutability, fake_borrow_temps) - }), + ExprKind::Scope { region_scope, lint_level, value } => { + this.in_scope((region_scope, source_info), lint_level, |this| { + let value = this.hir.mirror(value); + this.expr_as_place(block, value, mutability, fake_borrow_temps) + }) + } ExprKind::Field { lhs, name } => { let lhs = this.hir.mirror(lhs); - let place_builder = unpack!(block = this.expr_as_place( - block, - lhs, - mutability, - fake_borrow_temps, - )); + let place_builder = + unpack!(block = this.expr_as_place(block, lhs, mutability, fake_borrow_temps,)); block.and(place_builder.field(name, expr.ty)) } ExprKind::Deref { arg } => { let arg = this.hir.mirror(arg); - let place_builder = unpack!(block = this.expr_as_place( - block, - arg, - mutability, - fake_borrow_temps, - )); + let place_builder = + unpack!(block = this.expr_as_place(block, arg, mutability, fake_borrow_temps,)); block.and(place_builder.deref()) } - ExprKind::Index { lhs, index } => { - this.lower_index_expression( - block, - lhs, - index, - mutability, - fake_borrow_temps, - expr.temp_lifetime, - expr_span, - source_info, - ) - } + ExprKind::Index { lhs, index } => this.lower_index_expression( + block, + lhs, + index, + mutability, + fake_borrow_temps, + expr.temp_lifetime, + expr_span, + source_info, + ), ExprKind::SelfRef => block.and(PlaceBuilder::from(Local::new(1))), ExprKind::VarRef { id } => { let place_builder = if this.is_bound_var_in_guard(id) { @@ -200,20 +176,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ExprKind::PlaceTypeAscription { source, user_ty } => { let source = this.hir.mirror(source); - let place_builder = unpack!(block = this.expr_as_place( - block, - source, - mutability, - fake_borrow_temps, - )); + let place_builder = unpack!( + block = this.expr_as_place(block, source, mutability, fake_borrow_temps,) + ); if let Some(user_ty) = user_ty { - let annotation_index = this.canonical_user_type_annotations.push( - CanonicalUserTypeAnnotation { + let annotation_index = + this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { span: source_info.span, user_ty, inferred_ty: expr.ty, - } - ); + }); let place = place_builder.clone().into_place(this.hir.tcx()); this.cfg.push( @@ -221,9 +193,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Statement { source_info, kind: StatementKind::AscribeUserType( - box( + box ( place, - UserTypeProjection { base: annotation_index, projs: vec![], } + UserTypeProjection { base: annotation_index, projs: vec![] }, ), Variance::Invariant, ), @@ -234,25 +206,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ExprKind::ValueTypeAscription { source, user_ty } => { let source = this.hir.mirror(source); - let temp = unpack!( - block = this.as_temp(block, source.temp_lifetime, source, mutability) - ); + let temp = + unpack!(block = this.as_temp(block, source.temp_lifetime, source, mutability)); if let Some(user_ty) = user_ty { - let annotation_index = this.canonical_user_type_annotations.push( - CanonicalUserTypeAnnotation { + let annotation_index = + this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { span: source_info.span, user_ty, inferred_ty: expr.ty, - } - ); + }); this.cfg.push( block, Statement { source_info, kind: StatementKind::AscribeUserType( - box( + box ( Place::from(temp.clone()), - UserTypeProjection { base: annotation_index, projs: vec![], }, + UserTypeProjection { base: annotation_index, projs: vec![] }, ), Variance::Invariant, ), @@ -319,7 +289,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fake_borrow_temps: Option<&mut Vec>, temp_lifetime: Option, expr_span: Span, - source_info: SourceInfo + source_info: SourceInfo, ) -> BlockAnd> { let lhs = self.hir.mirror(base); @@ -327,22 +297,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let is_outermost_index = fake_borrow_temps.is_none(); let fake_borrow_temps = fake_borrow_temps.unwrap_or(base_fake_borrow_temps); - let base_place = unpack!(block = self.expr_as_place( - block, - lhs, - mutability, - Some(fake_borrow_temps), - )); + let base_place = + unpack!(block = self.expr_as_place(block, lhs, mutability, Some(fake_borrow_temps),)); // Making this a *fresh* temporary means we do not have to worry about // the index changing later: Nothing will ever change this temporary. // The "retagging" transformation (for Stacked Borrows) relies on this. - let idx = unpack!(block = self.as_temp( - block, - temp_lifetime, - index, - Mutability::Not, - )); + let idx = unpack!(block = self.as_temp(block, temp_lifetime, index, Mutability::Not,)); block = self.bounds_check( block, @@ -382,12 +343,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let lt = self.temp(bool_ty, expr_span); // len = len(slice) - self.cfg.push_assign( - block, - source_info, - &len, - Rvalue::Len(slice), - ); + self.cfg.push_assign(block, source_info, &len, Rvalue::Len(slice)); // lt = idx < len self.cfg.push_assign( block, @@ -399,10 +355,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Operand::Copy(len.clone()), ), ); - let msg = BoundsCheck { - len: Operand::Move(len), - index: Operand::Copy(Place::from(index)), - }; + let msg = BoundsCheck { len: Operand::Move(len), index: Operand::Copy(Place::from(index)) }; // assert!(lt, "...") self.assert(block, Operand::Move(lt), true, msg, expr_span) } @@ -416,12 +369,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_info: SourceInfo, ) { let tcx = self.hir.tcx(); - let place_ty = Place::ty_from( - &base_place.base, - &base_place.projection, - &self.local_decls, - tcx, - ); + let place_ty = + Place::ty_from(&base_place.base, &base_place.projection, &self.local_decls, tcx); if let ty::Slice(_) = place_ty.ty.kind { // We need to create fake borrows to ensure that the bounds // check that we just did stays valid. Since we can't assign to @@ -435,14 +384,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &base_place.projection[..idx], &self.local_decls, tcx, - ).ty; - let fake_borrow_ty = tcx.mk_imm_ref( - tcx.lifetimes.re_erased, - fake_borrow_deref_ty, - ); - let fake_borrow_temp = self.local_decls.push( - LocalDecl::new_temp(fake_borrow_ty, expr_span) - ); + ) + .ty; + let fake_borrow_ty = + tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty); + let fake_borrow_temp = + self.local_decls.push(LocalDecl::new_temp(fake_borrow_ty, expr_span)); let projection = tcx.intern_place_elems(&base_place.projection[..idx]); self.cfg.push_assign( block, @@ -451,10 +398,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Rvalue::Ref( tcx.lifetimes.re_erased, BorrowKind::Shallow, - Place { - base: base_place.base.clone(), - projection, - } + Place { base: base_place.base.clone(), projection }, ), ); fake_borrow_temps.push(fake_borrow_temp); diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index 4dad9ab498f63..d2269f91ae25e 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -1,7 +1,7 @@ //! See docs in build/expr/mod.rs -use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::build::scope::DropKind; +use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::hair::*; use rustc::hir; use rustc::middle::region; @@ -40,12 +40,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let expr_span = expr.span; let source_info = this.source_info(expr_span); - if let ExprKind::Scope { - region_scope, - lint_level, - value, - } = expr.kind - { + if let ExprKind::Scope { region_scope, lint_level, value } = expr.kind { return this.in_scope((region_scope, source_info), lint_level, |this| { this.as_temp(block, temp_lifetime, value, mutability) }); @@ -66,7 +61,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } if let ExprKind::StaticRef { def_id, .. } = expr.kind { let is_thread_local = this.hir.tcx().has_attr(def_id, sym::thread_local); - local_decl.local_info = LocalInfo::StaticRef {def_id, is_thread_local }; + local_decl.local_info = LocalInfo::StaticRef { def_id, is_thread_local }; } this.local_decls.push(local_decl) }; @@ -75,20 +70,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match expr.kind { // Don't bother with StorageLive and Dead for these temporaries, // they are never assigned. - ExprKind::Break { .. } | - ExprKind::Continue { .. } | - ExprKind::Return { .. } => (), - ExprKind::Block { - body: hir::Block { expr: None, targeted_by_break: false, .. } - } if expr_ty.is_never() => (), + ExprKind::Break { .. } | ExprKind::Continue { .. } | ExprKind::Return { .. } => (), + ExprKind::Block { body: hir::Block { expr: None, targeted_by_break: false, .. } } + if expr_ty.is_never() => + { + () + } _ => { - this.cfg.push( - block, - Statement { - source_info, - kind: StatementKind::StorageLive(temp), - }, - ); + this.cfg + .push(block, Statement { source_info, kind: StatementKind::StorageLive(temp) }); // In constants, `temp_lifetime` is `None` for temporaries that // live for the `'static` lifetime. Thus we do not drop these @@ -104,12 +94,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // `bar(&foo())` or anything within a block will keep the // regular drops just like runtime code. if let Some(temp_lifetime) = temp_lifetime { - this.schedule_drop( - expr_span, - temp_lifetime, - temp, - DropKind::Storage, - ); + this.schedule_drop(expr_span, temp_lifetime, temp, DropKind::Storage); } } } @@ -117,12 +102,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { unpack!(block = this.into(temp_place, block, expr)); if let Some(temp_lifetime) = temp_lifetime { - this.schedule_drop( - expr_span, - temp_lifetime, - temp, - DropKind::Value, - ); + this.schedule_drop(expr_span, temp_lifetime, temp, DropKind::Value); } block.and(temp) diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs index 4d0039b2e8cec..b35616c11fbd0 100644 --- a/src/librustc_mir/build/expr/category.rs +++ b/src/librustc_mir/build/expr/category.rs @@ -66,8 +66,7 @@ impl Category { | ExprKind::Yield { .. } | ExprKind::InlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)), - ExprKind::Literal { .. } - | ExprKind::StaticRef { .. } => Some(Category::Constant), + ExprKind::Literal { .. } | ExprKind::StaticRef { .. } => Some(Category::Constant), ExprKind::Loop { .. } | ExprKind::Block { .. } diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index a9fa7cfa04a89..2c61ac3ed928a 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -20,10 +20,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { mut block: BasicBlock, expr: Expr<'tcx>, ) -> BlockAnd<()> { - debug!( - "into_expr(destination={:?}, block={:?}, expr={:?})", - destination, block, expr - ); + debug!("into_expr(destination={:?}, block={:?}, expr={:?})", destination, block, expr); // since we frequently have to reference `self` from within a // closure, where `self` would be shadowed, it's easier to @@ -43,15 +40,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } let block_and = match expr.kind { - ExprKind::Scope { - region_scope, - lint_level, - value, - } => { + ExprKind::Scope { region_scope, lint_level, value } => { let region_scope = (region_scope, source_info); - this.in_scope(region_scope, lint_level, |this| { - this.into(destination, block, value) - }) + this.in_scope(region_scope, lint_level, |this| this.into(destination, block, value)) } ExprKind::Block { body: ast_block } => { this.ast_block(destination, block, ast_block, source_info) @@ -68,20 +59,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // (#66975) Source could be a const of type `!`, so has to // exist in the generated MIR. - unpack!(block = this.as_temp( - block, - this.local_scope(), - source, - Mutability::Mut, - )); + unpack!(block = this.as_temp(block, this.local_scope(), source, Mutability::Mut,)); // This is an optimization. If the expression was a call then we already have an // unreachable block. Don't bother to terminate it and create a new one. if is_call { block.unit() } else { - this.cfg - .terminate(block, source_info, TerminatorKind::Unreachable); + this.cfg.terminate(block, source_info, TerminatorKind::Unreachable); let end_block = this.cfg.start_new_block(); end_block.unit() } @@ -122,22 +107,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { true_block, source_info, destination, - Constant { - span: expr_span, - user_ty: None, - literal: this.hir.true_literal(), - }, + Constant { span: expr_span, user_ty: None, literal: this.hir.true_literal() }, ); this.cfg.push_assign_constant( false_block, source_info, destination, - Constant { - span: expr_span, - user_ty: None, - literal: this.hir.false_literal(), - }, + Constant { span: expr_span, user_ty: None, literal: this.hir.false_literal() }, ); // Link up both branches: @@ -259,9 +236,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { success.unit() } } - ExprKind::Use { source } => { - this.into(destination, block, source) - } + ExprKind::Use { source } => this.into(destination, block, source), ExprKind::Borrow { arg, borrow_kind } => { // We don't do this in `as_rvalue` because we use `as_place` // for borrow expressions, so we cannot create an `RValue` that @@ -272,18 +247,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { BorrowKind::Shared => unpack!(block = this.as_read_only_place(block, arg)), _ => unpack!(block = this.as_place(block, arg)), }; - let borrow = Rvalue::Ref( - this.hir.tcx().lifetimes.re_erased, - borrow_kind, - arg_place, - ); + let borrow = + Rvalue::Ref(this.hir.tcx().lifetimes.re_erased, borrow_kind, arg_place); this.cfg.push_assign(block, source_info, destination, borrow); block.unit() } - ExprKind::AddressOf { - mutability, - arg, - } => { + ExprKind::AddressOf { mutability, arg } => { let place = match mutability { hir::Mutability::Not => this.as_read_only_place(block, arg), hir::Mutability::Mut => this.as_place(block, arg), @@ -292,59 +261,43 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.cfg.push_assign(block, source_info, destination, address_of); block.unit() } - ExprKind::Adt { - adt_def, - variant_index, - substs, - user_ty, - fields, - base, - } => { + ExprKind::Adt { adt_def, variant_index, substs, user_ty, fields, base } => { // See the notes for `ExprKind::Array` in `as_rvalue` and for // `ExprKind::Borrow` above. let is_union = adt_def.is_union(); - let active_field_index = if is_union { - Some(fields[0].name.index()) - } else { - None - }; + let active_field_index = if is_union { Some(fields[0].name.index()) } else { None }; - let scope = this.local_scope(); + let scope = this.local_scope(); // first process the set of fields that were provided // (evaluating them in order given by user) let fields_map: FxHashMap<_, _> = fields .into_iter() - .map(|f| { - ( - f.name, - unpack!(block = this.as_operand(block, scope, f.expr)), - ) - }).collect(); + .map(|f| (f.name, unpack!(block = this.as_operand(block, scope, f.expr)))) + .collect(); let field_names = this.hir.all_fields(adt_def, variant_index); - let fields = if let Some(FruInfo { base, field_types }) = base { - let base = unpack!(block = this.as_place(block, base)); - - // MIR does not natively support FRU, so for each - // base-supplied field, generate an operand that - // reads it from the base. - field_names - .into_iter() - .zip(field_types.into_iter()) - .map(|(n, ty)| match fields_map.get(&n) { - Some(v) => v.clone(), - None => this.consume_by_copy_or_move( - this.hir.tcx().mk_place_field(base.clone(), n, ty), - ), - }).collect() - } else { - field_names - .iter() - .filter_map(|n| fields_map.get(n).cloned()) - .collect() - }; + let fields = + if let Some(FruInfo { base, field_types }) = base { + let base = unpack!(block = this.as_place(block, base)); + + // MIR does not natively support FRU, so for each + // base-supplied field, generate an operand that + // reads it from the base. + field_names + .into_iter() + .zip(field_types.into_iter()) + .map(|(n, ty)| match fields_map.get(&n) { + Some(v) => v.clone(), + None => this.consume_by_copy_or_move( + this.hir.tcx().mk_place_field(base.clone(), n, ty), + ), + }) + .collect() + } else { + field_names.iter().filter_map(|n| fields_map.get(n).cloned()).collect() + }; let inferred_ty = expr.ty; let user_ty = user_ty.map(|ty| { @@ -365,12 +318,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, source_info, destination, - Rvalue::Aggregate(adt, fields) + Rvalue::Aggregate(adt, fields), ); block.unit() } - // These cases don't actually need a destination ExprKind::Assign { .. } | ExprKind::AssignOp { .. } @@ -384,16 +336,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } // Avoid creating a temporary - ExprKind::VarRef { .. } | - ExprKind::SelfRef | - ExprKind::PlaceTypeAscription { .. } | - ExprKind::ValueTypeAscription { .. } => { + ExprKind::VarRef { .. } + | ExprKind::SelfRef + | ExprKind::PlaceTypeAscription { .. } + | ExprKind::ValueTypeAscription { .. } => { debug_assert!(Category::of(&expr.kind) == Some(Category::Place)); let place = unpack!(block = this.as_place(block, expr)); let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place)); - this.cfg - .push_assign(block, source_info, destination, rvalue); + this.cfg.push_assign(block, source_info, destination, rvalue); block.unit() } ExprKind::Index { .. } | ExprKind::Deref { .. } | ExprKind::Field { .. } => { @@ -403,16 +354,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // value is Sized. Usually, this is caught in type checking, but // in the case of box expr there is no such check. if !destination.projection.is_empty() { - this.local_decls - .push(LocalDecl::new_temp(expr.ty, expr.span)); + this.local_decls.push(LocalDecl::new_temp(expr.ty, expr.span)); } debug_assert!(Category::of(&expr.kind) == Some(Category::Place)); let place = unpack!(block = this.as_place(block, expr)); let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place)); - this.cfg - .push_assign(block, source_info, destination, rvalue); + this.cfg.push_assign(block, source_info, destination, rvalue); block.unit() } diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs index 0cd32acdb665b..9f37e776404ee 100644 --- a/src/librustc_mir/build/expr/stmt.rs +++ b/src/librustc_mir/build/expr/stmt.rs @@ -23,11 +23,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // avoids needing a mountain of temporary `()` variables. let expr2 = expr.clone(); match expr.kind { - ExprKind::Scope { - region_scope, - lint_level, - value, - } => { + ExprKind::Scope { region_scope, lint_level, value } => { let value = this.hir.mirror(value); this.in_scope((region_scope, source_info), lint_level, |this| { this.stmt_expr(block, value, statement_scope) @@ -106,11 +102,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ExprKind::Return { value } => { this.break_scope(block, value, BreakableTarget::Return, source_info) } - ExprKind::InlineAsm { - asm, - outputs, - inputs, - } => { + ExprKind::InlineAsm { asm, outputs, inputs } => { debug!("stmt_expr InlineAsm block_context.push(SubExpr) : {:?}", expr2); this.block_context.push(BlockFrame::SubExpr); let outputs = outputs @@ -121,11 +113,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let inputs = inputs .into_iter() .map(|input| { - ( - input.span(), - unpack!(block = this.as_local_operand(block, input)), - ) - }).collect::>() + (input.span(), unpack!(block = this.as_local_operand(block, input))) + }) + .collect::>() .into_boxed_slice(); this.cfg.push( block, @@ -166,17 +156,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { break; } } - this.block_context.push(BlockFrame::TailExpr { - tail_result_is_ignored: true - }); + this.block_context + .push(BlockFrame::TailExpr { tail_result_is_ignored: true }); return Some(expr.span); } } None })(); - let temp = unpack!(block = - this.as_temp(block, statement_scope, expr, Mutability::Not)); + let temp = + unpack!(block = this.as_temp(block, statement_scope, expr, Mutability::Not)); if let Some(span) = adjusted_span { this.local_decls[temp].source_info.span = span; diff --git a/src/librustc_mir/build/into.rs b/src/librustc_mir/build/into.rs index 077840c9ccf17..9c3ea5f7c5619 100644 --- a/src/librustc_mir/build/into.rs +++ b/src/librustc_mir/build/into.rs @@ -18,12 +18,9 @@ pub(in crate::build) trait EvalInto<'tcx> { } impl<'a, 'tcx> Builder<'a, 'tcx> { - pub fn into(&mut self, - destination: &Place<'tcx>, - block: BasicBlock, - expr: E) - -> BlockAnd<()> - where E: EvalInto<'tcx> + pub fn into(&mut self, destination: &Place<'tcx>, block: BasicBlock, expr: E) -> BlockAnd<()> + where + E: EvalInto<'tcx>, { expr.eval_into(self, destination, block) } diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index 3e71b871801d1..bbb555a58e69f 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -12,20 +12,19 @@ //! sort of test: for example, testing which variant an enum is, or //! testing a value against a constant. +use crate::build::matches::{Ascription, Binding, Candidate, MatchPair}; use crate::build::Builder; -use crate::build::matches::{Ascription, Binding, MatchPair, Candidate}; use crate::hair::{self, *}; +use rustc::hir::RangeEnd; +use rustc::mir::interpret::truncate; use rustc::ty; use rustc::ty::layout::{Integer, IntegerExt, Size}; use syntax::attr::{SignedInt, UnsignedInt}; -use rustc::hir::RangeEnd; -use rustc::mir::interpret::truncate; use std::mem; impl<'a, 'tcx> Builder<'a, 'tcx> { - pub fn simplify_candidate<'pat>(&mut self, - candidate: &mut Candidate<'pat, 'tcx>) { + pub fn simplify_candidate<'pat>(&mut self, candidate: &mut Candidate<'pat, 'tcx>) { // repeatedly simplify match pairs until fixed point is reached loop { let match_pairs = mem::take(&mut candidate.match_pairs); @@ -51,19 +50,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// have been pushed into the candidate. If no simplification is /// possible, `Err` is returned and no changes are made to /// candidate. - fn simplify_match_pair<'pat>(&mut self, - match_pair: MatchPair<'pat, 'tcx>, - candidate: &mut Candidate<'pat, 'tcx>) - -> Result<(), MatchPair<'pat, 'tcx>> { + fn simplify_match_pair<'pat>( + &mut self, + match_pair: MatchPair<'pat, 'tcx>, + candidate: &mut Candidate<'pat, 'tcx>, + ) -> Result<(), MatchPair<'pat, 'tcx>> { let tcx = self.hir.tcx(); match *match_pair.pattern.kind { PatKind::AscribeUserType { ref subpattern, - ascription: hair::pattern::Ascription { - variance, - ref user_ty, - user_ty_span, - }, + ascription: hair::pattern::Ascription { variance, ref user_ty, user_ty_span }, } => { // Apply the type ascription to the value at `match_pair.place`, which is the // value being matched, taking the variance field into account. @@ -147,11 +143,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { PatKind::Slice { ref prefix, ref slice, ref suffix } => { if prefix.is_empty() && slice.is_some() && suffix.is_empty() { // irrefutable - self.prefix_slice_suffix(&mut candidate.match_pairs, - &match_pair.place, - prefix, - slice.as_ref(), - suffix); + self.prefix_slice_suffix( + &mut candidate.match_pairs, + &match_pair.place, + prefix, + slice.as_ref(), + suffix, + ); Ok(()) } else { Err(match_pair) @@ -161,10 +159,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { PatKind::Variant { adt_def, substs, variant_index, ref subpatterns } => { let irrefutable = adt_def.variants.iter_enumerated().all(|(i, v)| { i == variant_index || { - self.hir.tcx().features().exhaustive_patterns && - !v.uninhabited_from(self.hir.tcx(), substs, adt_def.adt_kind()).is_empty() + self.hir.tcx().features().exhaustive_patterns + && !v + .uninhabited_from(self.hir.tcx(), substs, adt_def.adt_kind()) + .is_empty() } - }) && (adt_def.did.is_local() || !adt_def.is_variant_list_non_exhaustive()); + }) && (adt_def.did.is_local() + || !adt_def.is_variant_list_non_exhaustive()); if irrefutable { let place = tcx.mk_place_downcast(match_pair.place, adt_def, variant_index); candidate.match_pairs.extend(self.field_match_pairs(place, subpatterns)); @@ -175,18 +176,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } PatKind::Array { ref prefix, ref slice, ref suffix } => { - self.prefix_slice_suffix(&mut candidate.match_pairs, - &match_pair.place, - prefix, - slice.as_ref(), - suffix); + self.prefix_slice_suffix( + &mut candidate.match_pairs, + &match_pair.place, + prefix, + slice.as_ref(), + suffix, + ); Ok(()) } PatKind::Leaf { ref subpatterns } => { // tuple struct, match subpats (if any) - candidate.match_pairs - .extend(self.field_match_pairs(match_pair.place, subpatterns)); + candidate.match_pairs.extend(self.field_match_pairs(match_pair.place, subpatterns)); Ok(()) } @@ -196,9 +198,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Ok(()) } - PatKind::Or { .. } => { - Err(match_pair) - } + PatKind::Or { .. } => Err(match_pair), } } } diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index bdc1bdd5b9855..cdb27099c28f4 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -5,17 +5,17 @@ // identify what tests are needed, perform the tests, and then filter // the candidates based on the result. -use crate::build::Builder; use crate::build::matches::{Candidate, MatchPair, Test, TestKind}; -use crate::hair::*; +use crate::build::Builder; use crate::hair::pattern::compare_const_vals; -use rustc_index::bit_set::BitSet; -use rustc_data_structures::fx::FxHashMap; -use rustc::ty::{self, Ty, adjustment::PointerCast}; -use rustc::ty::util::IntTypeExt; -use rustc::ty::layout::VariantIdx; -use rustc::mir::*; +use crate::hair::*; use rustc::hir::RangeEnd; +use rustc::mir::*; +use rustc::ty::layout::VariantIdx; +use rustc::ty::util::IntTypeExt; +use rustc::ty::{self, adjustment::PointerCast, Ty}; +use rustc_data_structures::fx::FxHashMap; +use rustc_index::bit_set::BitSet; use syntax_pos::symbol::sym; use std::cmp::Ordering; @@ -26,15 +26,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// It is a bug to call this with a simplifiable pattern. pub fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> { match *match_pair.pattern.kind { - PatKind::Variant { ref adt_def, substs: _, variant_index: _, subpatterns: _ } => { - Test { - span: match_pair.pattern.span, - kind: TestKind::Switch { - adt_def, - variants: BitSet::new_empty(adt_def.variants.len()), - }, - } - } + PatKind::Variant { ref adt_def, substs: _, variant_index: _, subpatterns: _ } => Test { + span: match_pair.pattern.span, + kind: TestKind::Switch { + adt_def, + variants: BitSet::new_empty(adt_def.variants.len()), + }, + }, PatKind::Constant { .. } if is_switch_ty(match_pair.pattern.ty) => { // For integers, we use a `SwitchInt` match, which allows @@ -48,82 +46,66 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // added below in add_cases_to_switch options: vec![], indices: Default::default(), - } + }, } } - PatKind::Constant { value } => { - Test { - span: match_pair.pattern.span, - kind: TestKind::Eq { - value, - ty: match_pair.pattern.ty.clone() - } - } - } + PatKind::Constant { value } => Test { + span: match_pair.pattern.span, + kind: TestKind::Eq { value, ty: match_pair.pattern.ty.clone() }, + }, PatKind::Range(range) => { assert_eq!(range.lo.ty, match_pair.pattern.ty); assert_eq!(range.hi.ty, match_pair.pattern.ty); - Test { - span: match_pair.pattern.span, - kind: TestKind::Range(range), - } + Test { span: match_pair.pattern.span, kind: TestKind::Range(range) } } PatKind::Slice { ref prefix, ref slice, ref suffix } => { let len = prefix.len() + suffix.len(); - let op = if slice.is_some() { - BinOp::Ge - } else { - BinOp::Eq - }; + let op = if slice.is_some() { BinOp::Ge } else { BinOp::Eq }; Test { span: match_pair.pattern.span, kind: TestKind::Len { len: len as u64, op: op }, } } - PatKind::Or { .. } => { - self.hir.tcx().sess.span_fatal( - match_pair.pattern.span, - "or-patterns are not fully implemented yet" - ) - } - - PatKind::AscribeUserType { .. } | - PatKind::Array { .. } | - PatKind::Wild | - PatKind::Binding { .. } | - PatKind::Leaf { .. } | - PatKind::Deref { .. } => { - self.error_simplifyable(match_pair) - } + PatKind::Or { .. } => self + .hir + .tcx() + .sess + .span_fatal(match_pair.pattern.span, "or-patterns are not fully implemented yet"), + + PatKind::AscribeUserType { .. } + | PatKind::Array { .. } + | PatKind::Wild + | PatKind::Binding { .. } + | PatKind::Leaf { .. } + | PatKind::Deref { .. } => self.error_simplifyable(match_pair), } } - pub fn add_cases_to_switch<'pat>(&mut self, - test_place: &Place<'tcx>, - candidate: &Candidate<'pat, 'tcx>, - switch_ty: Ty<'tcx>, - options: &mut Vec, - indices: &mut FxHashMap<&'tcx ty::Const<'tcx>, usize>) - -> bool - { + pub fn add_cases_to_switch<'pat>( + &mut self, + test_place: &Place<'tcx>, + candidate: &Candidate<'pat, 'tcx>, + switch_ty: Ty<'tcx>, + options: &mut Vec, + indices: &mut FxHashMap<&'tcx ty::Const<'tcx>, usize>, + ) -> bool { let match_pair = match candidate.match_pairs.iter().find(|mp| mp.place == *test_place) { Some(match_pair) => match_pair, - _ => { return false; } + _ => { + return false; + } }; match *match_pair.pattern.kind { PatKind::Constant { value } => { - indices.entry(value) - .or_insert_with(|| { - options.push(value.eval_bits( - self.hir.tcx(), self.hir.param_env, switch_ty, - )); - options.len() - 1 - }); + indices.entry(value).or_insert_with(|| { + options.push(value.eval_bits(self.hir.tcx(), self.hir.param_env, switch_ty)); + options.len() - 1 + }); true } PatKind::Variant { .. } => { @@ -131,36 +113,37 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } PatKind::Range(range) => { // Check that none of the switch values are in the range. - self.values_not_contained_in_range(range, indices) - .unwrap_or(false) + self.values_not_contained_in_range(range, indices).unwrap_or(false) } - PatKind::Slice { .. } | - PatKind::Array { .. } | - PatKind::Wild | - PatKind::Or { .. } | - PatKind::Binding { .. } | - PatKind::AscribeUserType { .. } | - PatKind::Leaf { .. } | - PatKind::Deref { .. } => { + PatKind::Slice { .. } + | PatKind::Array { .. } + | PatKind::Wild + | PatKind::Or { .. } + | PatKind::Binding { .. } + | PatKind::AscribeUserType { .. } + | PatKind::Leaf { .. } + | PatKind::Deref { .. } => { // don't know how to add these patterns to a switch false } } } - pub fn add_variants_to_switch<'pat>(&mut self, - test_place: &Place<'tcx>, - candidate: &Candidate<'pat, 'tcx>, - variants: &mut BitSet) - -> bool - { + pub fn add_variants_to_switch<'pat>( + &mut self, + test_place: &Place<'tcx>, + candidate: &Candidate<'pat, 'tcx>, + variants: &mut BitSet, + ) -> bool { let match_pair = match candidate.match_pairs.iter().find(|mp| mp.place == *test_place) { Some(match_pair) => match_pair, - _ => { return false; } + _ => { + return false; + } }; match *match_pair.pattern.kind { - PatKind::Variant { adt_def: _ , variant_index, .. } => { + PatKind::Variant { adt_def: _, variant_index, .. } => { // We have a pattern testing for variant `variant_index` // set the corresponding index to true variants.insert(variant_index); @@ -180,11 +163,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { test: &Test<'tcx>, make_target_blocks: impl FnOnce(&mut Self) -> Vec, ) { - debug!("perform_test({:?}, {:?}: {:?}, {:?})", - block, - place, - place.ty(&self.local_decls, self.hir.tcx()), - test); + debug!( + "perform_test({:?}, {:?}: {:?}, {:?})", + block, + place, + place.ty(&self.local_decls, self.hir.tcx()), + test + ); let source_info = self.source_info(test.span); match test.kind { @@ -218,19 +203,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } targets.push(otherwise_block); - debug!("num_enum_variants: {}, tested variants: {:?}, variants: {:?}", - num_enum_variants, values, variants); + debug!( + "num_enum_variants: {}, tested variants: {:?}, variants: {:?}", + num_enum_variants, values, variants + ); let discr_ty = adt_def.repr.discr_type().to_ty(tcx); let discr = self.temp(discr_ty, test.span); - self.cfg.push_assign(block, source_info, &discr, - Rvalue::Discriminant(place.clone())); + self.cfg.push_assign( + block, + source_info, + &discr, + Rvalue::Discriminant(place.clone()), + ); assert_eq!(values.len() + 1, targets.len()); - self.cfg.terminate(block, source_info, TerminatorKind::SwitchInt { - discr: Operand::Move(discr), - switch_ty: discr_ty, - values: From::from(values), - targets, - }); + self.cfg.terminate( + block, + source_info, + TerminatorKind::SwitchInt { + discr: Operand::Move(discr), + switch_ty: discr_ty, + values: From::from(values), + targets, + }, + ); } TestKind::SwitchInt { switch_ty, ref options, indices: _ } => { @@ -241,7 +236,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let (true_bb, false_bb) = match options[0] { 1 => (first_bb, second_bb), 0 => (second_bb, first_bb), - v => span_bug!(test.span, "expected boolean value but got {:?}", v) + v => span_bug!(test.span, "expected boolean value but got {:?}", v), }; TerminatorKind::if_( self.hir.tcx(), @@ -325,8 +320,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let actual = self.temp(usize_ty, test.span); // actual = len(place) - self.cfg.push_assign(block, source_info, - &actual, Rvalue::Len(place.clone())); + self.cfg.push_assign(block, source_info, &actual, Rvalue::Len(place.clone())); // expected = let expected = self.push_usize(block, source_info, len); @@ -365,23 +359,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let result = self.temp(bool_ty, source_info.span); // result = op(left, right) - self.cfg.push_assign( - block, - source_info, - &result, - Rvalue::BinaryOp(op, left, right), - ); + self.cfg.push_assign(block, source_info, &result, Rvalue::BinaryOp(op, left, right)); // branch based on result self.cfg.terminate( block, source_info, - TerminatorKind::if_( - self.hir.tcx(), - Operand::Move(result), - success_block, - fail_block, - ), + TerminatorKind::if_(self.hir.tcx(), Operand::Move(result), success_block, fail_block), ); } @@ -417,31 +401,32 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let opt_ref_test_ty = unsize(value.ty); match (opt_ref_ty, opt_ref_test_ty) { // nothing to do, neither is an array - (None, None) => {}, - (Some((region, elem_ty, _)), _) | - (None, Some((region, elem_ty, _))) => { + (None, None) => {} + (Some((region, elem_ty, _)), _) | (None, Some((region, elem_ty, _))) => { let tcx = self.hir.tcx(); // make both a slice ty = tcx.mk_imm_ref(region, tcx.mk_slice(elem_ty)); if opt_ref_ty.is_some() { let temp = self.temp(ty, source_info.span); self.cfg.push_assign( - block, source_info, &temp, Rvalue::Cast( - CastKind::Pointer(PointerCast::Unsize), val, ty - ) + block, + source_info, + &temp, + Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), val, ty), ); val = Operand::Move(temp); } if opt_ref_test_ty.is_some() { let slice = self.temp(ty, source_info.span); self.cfg.push_assign( - block, source_info, &slice, Rvalue::Cast( - CastKind::Pointer(PointerCast::Unsize), expect, ty - ) + block, + source_info, + &slice, + Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), expect, ty), ); expect = Operand::Move(slice); } - }, + } } let deref_ty = match ty.kind { @@ -456,23 +441,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let eq_result = self.temp(bool_ty, source_info.span); let eq_block = self.cfg.start_new_block(); let cleanup = self.diverge_cleanup(); - self.cfg.terminate(block, source_info, TerminatorKind::Call { - func: Operand::Constant(box Constant { - span: source_info.span, - - // FIXME(#54571): This constant comes from user input (a - // constant in a pattern). Are there forms where users can add - // type annotations here? For example, an associated constant? - // Need to experiment. - user_ty: None, - - literal: method, - }), - args: vec![val, expect], - destination: Some((eq_result.clone(), eq_block)), - cleanup: Some(cleanup), - from_hir_call: false, - }); + self.cfg.terminate( + block, + source_info, + TerminatorKind::Call { + func: Operand::Constant(box Constant { + span: source_info.span, + + // FIXME(#54571): This constant comes from user input (a + // constant in a pattern). Are there forms where users can add + // type annotations here? For example, an associated constant? + // Need to experiment. + user_ty: None, + + literal: method, + }), + args: vec![val, expect], + destination: Some((eq_result.clone(), eq_block)), + cleanup: Some(cleanup), + from_hir_call: false, + }, + ); if let [success_block, fail_block] = *make_target_blocks(self) { // check the result @@ -530,22 +519,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // than one, but it'd be very unusual to have two sides that // both require tests; you'd expect one side to be simplified // away.) - let (match_pair_index, match_pair) = candidate.match_pairs - .iter() - .enumerate() - .find(|&(_, mp)| mp.place == *test_place)?; + let (match_pair_index, match_pair) = + candidate.match_pairs.iter().enumerate().find(|&(_, mp)| mp.place == *test_place)?; match (&test.kind, &*match_pair.pattern.kind) { // If we are performing a variant switch, then this // informs variant patterns, but nothing else. - (&TestKind::Switch { adt_def: tested_adt_def, .. }, - &PatKind::Variant { adt_def, variant_index, ref subpatterns, .. }) => { + ( + &TestKind::Switch { adt_def: tested_adt_def, .. }, + &PatKind::Variant { adt_def, variant_index, ref subpatterns, .. }, + ) => { assert_eq!(adt_def, tested_adt_def); - self.candidate_after_variant_switch(match_pair_index, - adt_def, - variant_index, - subpatterns, - candidate); + self.candidate_after_variant_switch( + match_pair_index, + adt_def, + variant_index, + subpatterns, + candidate, + ); Some(variant_index.as_usize()) } @@ -556,19 +547,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // // FIXME(#29623) we could use PatKind::Range to rule // things out here, in some cases. - (&TestKind::SwitchInt { switch_ty: _, options: _, ref indices }, - &PatKind::Constant { ref value }) - if is_switch_ty(match_pair.pattern.ty) => { + ( + &TestKind::SwitchInt { switch_ty: _, options: _, ref indices }, + &PatKind::Constant { ref value }, + ) if is_switch_ty(match_pair.pattern.ty) => { let index = indices[value]; self.candidate_without_match_pair(match_pair_index, candidate); Some(index) } - (&TestKind::SwitchInt { switch_ty: _, ref options, ref indices }, - &PatKind::Range(range)) => { - let not_contained = self - .values_not_contained_in_range(range, indices) - .unwrap_or(false); + ( + &TestKind::SwitchInt { switch_ty: _, ref options, ref indices }, + &PatKind::Range(range), + ) => { + let not_contained = + self.values_not_contained_in_range(range, indices).unwrap_or(false); if not_contained { // No switch values are contained in the pattern range, @@ -582,18 +575,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { (&TestKind::SwitchInt { .. }, _) => None, - (&TestKind::Len { len: test_len, op: BinOp::Eq }, - &PatKind::Slice { ref prefix, ref slice, ref suffix }) => { + ( + &TestKind::Len { len: test_len, op: BinOp::Eq }, + &PatKind::Slice { ref prefix, ref slice, ref suffix }, + ) => { let pat_len = (prefix.len() + suffix.len()) as u64; match (test_len.cmp(&pat_len), slice) { (Ordering::Equal, &None) => { // on true, min_len = len = $actual_length, // on false, len != $actual_length - self.candidate_after_slice_test(match_pair_index, - candidate, - prefix, - slice.as_ref(), - suffix); + self.candidate_after_slice_test( + match_pair_index, + candidate, + prefix, + slice.as_ref(), + suffix, + ); Some(0) } (Ordering::Less, _) => { @@ -615,19 +612,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - (&TestKind::Len { len: test_len, op: BinOp::Ge }, - &PatKind::Slice { ref prefix, ref slice, ref suffix }) => { + ( + &TestKind::Len { len: test_len, op: BinOp::Ge }, + &PatKind::Slice { ref prefix, ref slice, ref suffix }, + ) => { // the test is `$actual_len >= test_len` let pat_len = (prefix.len() + suffix.len()) as u64; match (test_len.cmp(&pat_len), slice) { - (Ordering::Equal, &Some(_)) => { + (Ordering::Equal, &Some(_)) => { // $actual_len >= test_len = pat_len, // so we can match. - self.candidate_after_slice_test(match_pair_index, - candidate, - prefix, - slice.as_ref(), - suffix); + self.candidate_after_slice_test( + match_pair_index, + candidate, + prefix, + slice.as_ref(), + suffix, + ); Some(0) } (Ordering::Less, _) | (Ordering::Equal, &None) => { @@ -649,19 +650,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - (&TestKind::Range(test), - &PatKind::Range(pat)) => { + (&TestKind::Range(test), &PatKind::Range(pat)) => { if test == pat { - self.candidate_without_match_pair( - match_pair_index, - candidate, - ); + self.candidate_without_match_pair(match_pair_index, candidate); return Some(0); } let no_overlap = (|| { - use std::cmp::Ordering::*; use rustc::hir::RangeEnd::*; + use std::cmp::Ordering::*; let tcx = self.hir.tcx(); @@ -701,8 +698,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { (&TestKind::Range { .. }, _) => None, - (&TestKind::Eq { .. }, _) | - (&TestKind::Len { .. }, _) => { + (&TestKind::Eq { .. }, _) | (&TestKind::Len { .. }, _) => { // These are all binary tests. // // FIXME(#29623) we can be more clever here @@ -725,19 +721,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate.match_pairs.remove(match_pair_index); } - fn candidate_after_slice_test<'pat>(&mut self, - match_pair_index: usize, - candidate: &mut Candidate<'pat, 'tcx>, - prefix: &'pat [Pat<'tcx>], - opt_slice: Option<&'pat Pat<'tcx>>, - suffix: &'pat [Pat<'tcx>]) { + fn candidate_after_slice_test<'pat>( + &mut self, + match_pair_index: usize, + candidate: &mut Candidate<'pat, 'tcx>, + prefix: &'pat [Pat<'tcx>], + opt_slice: Option<&'pat Pat<'tcx>>, + suffix: &'pat [Pat<'tcx>], + ) { let removed_place = candidate.match_pairs.remove(match_pair_index).place; self.prefix_slice_suffix( &mut candidate.match_pairs, &removed_place, prefix, opt_slice, - suffix); + suffix, + ); } fn candidate_after_variant_switch<'pat>( @@ -755,7 +754,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // we want to create a set of derived match-patterns like // `(x as Variant).0 @ P1` and `(x as Variant).1 @ P1`. let elem = ProjectionElem::Downcast( - Some(adt_def.variants[variant_index].ident.name), variant_index); + Some(adt_def.variants[variant_index].ident.name), + variant_index, + ); let downcast_place = tcx.mk_place_elem(match_pair.place, elem); // `(x as Variant)` let consequent_match_pairs = subpatterns.iter().map(|subpattern| { // e.g., `(x as Variant).0` @@ -769,9 +770,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } fn error_simplifyable<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> ! { - span_bug!(match_pair.pattern.span, - "simplifyable pattern found: {:?}", - match_pair.pattern) + span_bug!(match_pair.pattern.span, "simplifyable pattern found: {:?}", match_pair.pattern) } fn const_range_contains( @@ -787,8 +786,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let b = compare_const_vals(tcx, value, range.hi, self.hir.param_env, range.lo.ty)?; match (b, range.end) { - (Less, _) | - (Equal, RangeEnd::Included) if a != Greater => Some(true), + (Less, _) | (Equal, RangeEnd::Included) if a != Greater => Some(true), _ => Some(false), } } @@ -811,9 +809,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { impl Test<'_> { pub(super) fn targets(&self) -> usize { match self.kind { - TestKind::Eq { .. } | TestKind::Range(_) | TestKind::Len { .. } => { - 2 - } + TestKind::Eq { .. } | TestKind::Range(_) | TestKind::Len { .. } => 2, TestKind::Switch { adt_def, .. } => { // While the switch that we generate doesn't test for all // variants, we have a target for each variant and the diff --git a/src/librustc_mir/build/matches/util.rs b/src/librustc_mir/build/matches/util.rs index 87481d1d69bc7..b6e643a65105b 100644 --- a/src/librustc_mir/build/matches/util.rs +++ b/src/librustc_mir/build/matches/util.rs @@ -1,11 +1,11 @@ -use crate::build::Builder; use crate::build::matches::MatchPair; +use crate::build::Builder; use crate::hair::*; use rustc::mir::*; use rustc::ty; use smallvec::SmallVec; -use std::u32; use std::convert::TryInto; +use std::u32; impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn field_match_pairs<'pat>( @@ -26,37 +26,28 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .collect() } - pub fn prefix_slice_suffix<'pat>(&mut self, - match_pairs: &mut SmallVec<[MatchPair<'pat, 'tcx>; 1]>, - place: &Place<'tcx>, - prefix: &'pat [Pat<'tcx>], - opt_slice: Option<&'pat Pat<'tcx>>, - suffix: &'pat [Pat<'tcx>]) { + pub fn prefix_slice_suffix<'pat>( + &mut self, + match_pairs: &mut SmallVec<[MatchPair<'pat, 'tcx>; 1]>, + place: &Place<'tcx>, + prefix: &'pat [Pat<'tcx>], + opt_slice: Option<&'pat Pat<'tcx>>, + suffix: &'pat [Pat<'tcx>], + ) { let tcx = self.hir.tcx(); let (min_length, exact_size) = match place.ty(&self.local_decls, tcx).ty.kind { - ty::Array(_, length) => ( - length.eval_usize(tcx, self.hir.param_env).try_into().unwrap(), - true - ), - _ => ( - (prefix.len() + suffix.len()).try_into().unwrap(), - false, - ), + ty::Array(_, length) => { + (length.eval_usize(tcx, self.hir.param_env).try_into().unwrap(), true) + } + _ => ((prefix.len() + suffix.len()).try_into().unwrap(), false), }; - match_pairs.extend( - prefix.iter() - .enumerate() - .map(|(idx, subpattern)| { - let elem = ProjectionElem::ConstantIndex { - offset: idx as u32, - min_length, - from_end: false, - }; - let place = tcx.mk_place_elem(place.clone(), elem); - MatchPair::new(place, subpattern) - }) - ); + match_pairs.extend(prefix.iter().enumerate().map(|(idx, subpattern)| { + let elem = + ProjectionElem::ConstantIndex { offset: idx as u32, min_length, from_end: false }; + let place = tcx.mk_place_elem(place.clone(), elem); + MatchPair::new(place, subpattern) + })); if let Some(subslice_pat) = opt_slice { let suffix_len = suffix.len() as u32; @@ -71,21 +62,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match_pairs.push(MatchPair::new(subslice, subslice_pat)); } - match_pairs.extend( - suffix.iter() - .rev() - .enumerate() - .map(|(idx, subpattern)| { - let end_offset = (idx + 1) as u32; - let elem = ProjectionElem::ConstantIndex { - offset: if exact_size { min_length - end_offset } else { end_offset }, - min_length, - from_end: !exact_size, - }; - let place = tcx.mk_place_elem(place.clone(), elem); - MatchPair::new(place, subpattern) - }) - ); + match_pairs.extend(suffix.iter().rev().enumerate().map(|(idx, subpattern)| { + let end_offset = (idx + 1) as u32; + let elem = ProjectionElem::ConstantIndex { + offset: if exact_size { min_length - end_offset } else { end_offset }, + min_length, + from_end: !exact_size, + }; + let place = tcx.mk_place_elem(place.clone(), elem); + MatchPair::new(place, subpattern) + })); } /// Creates a false edge to `imaginary_target` and a real edge to @@ -97,16 +83,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { real_target: BasicBlock, imaginary_target: Option, source_info: SourceInfo, - ) { + ) { match imaginary_target { Some(target) if target != real_target => { self.cfg.terminate( from_block, source_info, - TerminatorKind::FalseEdges { - real_target, - imaginary_target: target, - }, + TerminatorKind::FalseEdges { real_target, imaginary_target: target }, ); } _ => self.cfg.goto(from_block, source_info, real_target), @@ -116,9 +99,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { pub fn new(place: Place<'tcx>, pattern: &'pat Pat<'tcx>) -> MatchPair<'pat, 'tcx> { - MatchPair { - place, - pattern, - } + MatchPair { place, pattern } } } diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs index d038310dd4454..e8ee71149cc0f 100644 --- a/src/librustc_mir/build/misc.rs +++ b/src/librustc_mir/build/misc.rs @@ -17,22 +17,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx> { let temp = self.local_decls.push(LocalDecl::new_temp(ty, span)); let place = Place::from(temp); - debug!("temp: created temp {:?} with type {:?}", - place, self.local_decls[temp].ty); + debug!("temp: created temp {:?} with type {:?}", place, self.local_decls[temp].ty); place } /// Convenience function for creating a literal operand, one /// without any user type annotation. - pub fn literal_operand(&mut self, - span: Span, - literal: &'tcx ty::Const<'tcx>) - -> Operand<'tcx> { - let constant = box Constant { - span, - user_ty: None, - literal, - }; + pub fn literal_operand(&mut self, span: Span, literal: &'tcx ty::Const<'tcx>) -> Operand<'tcx> { + let constant = box Constant { span, user_ty: None, literal }; Operand::Constant(constant) } @@ -48,20 +40,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.literal_operand(span, literal) } - pub fn push_usize(&mut self, - block: BasicBlock, - source_info: SourceInfo, - value: u64) - -> Place<'tcx> { + pub fn push_usize( + &mut self, + block: BasicBlock, + source_info: SourceInfo, + value: u64, + ) -> Place<'tcx> { let usize_ty = self.hir.usize_ty(); let temp = self.temp(usize_ty, source_info.span); self.cfg.push_assign_constant( - block, source_info, &temp, + block, + source_info, + &temp, Constant { span: source_info.span, user_ty: None, literal: self.hir.usize_literal(value), - }); + }, + ); temp } diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 9c5966263dfc0..fba80562fd82d 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -84,14 +84,14 @@ should go to. use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder, CFG}; use crate::hair::{Expr, ExprRef, LintLevel}; -use rustc::middle::region; use rustc::hir; +use rustc::hir::GeneratorKind; +use rustc::middle::region; use rustc::mir::*; -use syntax_pos::{DUMMY_SP, Span}; use rustc_data_structures::fx::FxHashMap; use std::collections::hash_map::Entry; use std::mem; -use rustc::hir::GeneratorKind; +use syntax_pos::{Span, DUMMY_SP}; #[derive(Debug)] struct Scope { @@ -195,19 +195,11 @@ impl CachedBlock { } fn get(&self, generator_drop: bool) -> Option { - if generator_drop { - self.generator_drop - } else { - self.unwind - } + if generator_drop { self.generator_drop } else { self.unwind } } fn ref_mut(&mut self, generator_drop: bool) -> &mut Option { - if generator_drop { - &mut self.generator_drop - } else { - &mut self.unwind - } + if generator_drop { &mut self.generator_drop } else { &mut self.unwind } } } @@ -224,7 +216,7 @@ impl Scope { &mut self, storage_only: bool, generator_kind: Option, - this_scope_only: bool + this_scope_only: bool, ) { // FIXME: maybe do shared caching of `cached_exits` etc. to handle functions // with lots of `try!`? @@ -249,13 +241,9 @@ impl Scope { /// Given a span and this scope's source scope, make a SourceInfo. fn source_info(&self, span: Span) -> SourceInfo { - SourceInfo { - span, - scope: self.source_scope - } + SourceInfo { span, scope: self.source_scope } } - /// Whether there's anything to do for the cleanup path, that is, /// when unwinding through this scope. This includes destructors, /// but not StorageDead statements, which don't get emitted at all @@ -300,8 +288,8 @@ impl<'tcx> Scopes<'tcx> { ) -> (Scope, Option) { let scope = self.scopes.pop().unwrap(); assert_eq!(scope.region_scope, region_scope.0); - let unwind_to = self.scopes.last() - .and_then(|next_scope| next_scope.cached_unwind.get(false)); + let unwind_to = + self.scopes.last().and_then(|next_scope| next_scope.cached_unwind.get(false)); (scope, unwind_to) } @@ -319,7 +307,8 @@ impl<'tcx> Scopes<'tcx> { ) -> (BasicBlock, region::Scope, Option>) { let get_scope = |scope: region::Scope| { // find the loop-scope by its `region::Scope`. - self.breakable_scopes.iter() + self.breakable_scopes + .iter() .rfind(|breakable_scope| breakable_scope.region_scope == scope) .unwrap_or_else(|| span_bug!(span, "no enclosing breakable scope found")) }; @@ -337,7 +326,8 @@ impl<'tcx> Scopes<'tcx> { } BreakableTarget::Continue(scope) => { let scope = get_scope(scope); - let continue_block = scope.continue_block + let continue_block = scope + .continue_block .unwrap_or_else(|| span_bug!(span, "missing `continue` block")); (continue_block, scope.region_scope, None) } @@ -345,21 +335,22 @@ impl<'tcx> Scopes<'tcx> { } fn num_scopes_above(&self, region_scope: region::Scope, span: Span) -> usize { - let scope_count = self.scopes.iter().rev() + let scope_count = self + .scopes + .iter() + .rev() .position(|scope| scope.region_scope == region_scope) - .unwrap_or_else(|| { - span_bug!(span, "region_scope {:?} does not enclose", region_scope) - }); + .unwrap_or_else(|| span_bug!(span, "region_scope {:?} does not enclose", region_scope)); let len = self.len(); assert!(scope_count < len, "should not use `exit_scope` to pop ALL scopes"); scope_count } - fn iter_mut(&mut self) -> impl DoubleEndedIterator + '_ { + fn iter_mut(&mut self) -> impl DoubleEndedIterator + '_ { self.scopes.iter_mut().rev() } - fn top_scopes(&mut self, count: usize) -> impl DoubleEndedIterator + '_ { + fn top_scopes(&mut self, count: usize) -> impl DoubleEndedIterator + '_ { let len = self.len(); self.scopes[len - count..].iter_mut() } @@ -380,12 +371,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // ========================== // Start a breakable scope, which tracks where `continue`, `break` and // `return` should branch to. - pub fn in_breakable_scope(&mut self, - loop_block: Option, - break_block: BasicBlock, - break_destination: Place<'tcx>, - f: F) -> R - where F: FnOnce(&mut Builder<'a, 'tcx>) -> R + pub fn in_breakable_scope( + &mut self, + loop_block: Option, + break_block: BasicBlock, + break_destination: Place<'tcx>, + f: F, + ) -> R + where + F: FnOnce(&mut Builder<'a, 'tcx>) -> R, { let region_scope = self.scopes.topmost(); let scope = BreakableScope { @@ -401,14 +395,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { res } - pub fn in_opt_scope(&mut self, - opt_scope: Option<(region::Scope, SourceInfo)>, - f: F) - -> BlockAnd - where F: FnOnce(&mut Builder<'a, 'tcx>) -> BlockAnd + pub fn in_opt_scope( + &mut self, + opt_scope: Option<(region::Scope, SourceInfo)>, + f: F, + ) -> BlockAnd + where + F: FnOnce(&mut Builder<'a, 'tcx>) -> BlockAnd, { debug!("in_opt_scope(opt_scope={:?})", opt_scope); - if let Some(region_scope) = opt_scope { self.push_scope(region_scope); } + if let Some(region_scope) = opt_scope { + self.push_scope(region_scope); + } let mut block; let rv = unpack!(block = f(self)); if let Some(region_scope) = opt_scope { @@ -420,12 +418,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Convenience wrapper that pushes a scope and then executes `f` /// to build its contents, popping the scope afterwards. - pub fn in_scope(&mut self, - region_scope: (region::Scope, SourceInfo), - lint_level: LintLevel, - f: F) - -> BlockAnd - where F: FnOnce(&mut Builder<'a, 'tcx>) -> BlockAnd + pub fn in_scope( + &mut self, + region_scope: (region::Scope, SourceInfo), + lint_level: LintLevel, + f: F, + ) -> BlockAnd + where + F: FnOnce(&mut Builder<'a, 'tcx>) -> BlockAnd, { debug!("in_scope(region_scope={:?})", region_scope); let source_scope = self.source_scope; @@ -436,23 +436,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // We estimate the true lint roots here to avoid creating a lot of source scopes. let parent_root = tcx.maybe_lint_level_root_bounded( - self.source_scopes[source_scope] - .local_data - .as_ref() - .assert_crate_local() - .lint_root, + self.source_scopes[source_scope].local_data.as_ref().assert_crate_local().lint_root, self.hir.root_lint_level, ); - let current_root = tcx.maybe_lint_level_root_bounded( - current_hir_id, - self.hir.root_lint_level - ); + let current_root = + tcx.maybe_lint_level_root_bounded(current_hir_id, self.hir.root_lint_level); if parent_root != current_root { self.source_scope = self.new_source_scope( region_scope.1.span, LintLevel::Explicit(current_root), - None + None, ); } } @@ -476,10 +470,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Pops a scope, which should have region scope `region_scope`, /// adding any drops onto the end of `block` that are needed. /// This must match 1-to-1 with `push_scope`. - pub fn pop_scope(&mut self, - region_scope: (region::Scope, SourceInfo), - mut block: BasicBlock) - -> BlockAnd<()> { + pub fn pop_scope( + &mut self, + region_scope: (region::Scope, SourceInfo), + mut block: BasicBlock, + ) -> BlockAnd<()> { debug!("pop_scope({:?}, {:?})", region_scope, block); // If we are emitting a `drop` statement, we need to have the cached // diverge cleanup pads ready in case that drop panics. @@ -489,16 +484,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let (scope, unwind_to) = self.scopes.pop_scope(region_scope); let unwind_to = unwind_to.unwrap_or_else(|| self.resume_block()); - unpack!(block = build_scope_drops( - &mut self.cfg, - self.generator_kind, - &scope, - block, - unwind_to, - self.arg_count, - false, // not generator - false, // not unwind path - )); + unpack!( + block = build_scope_drops( + &mut self.cfg, + self.generator_kind, + &scope, + block, + unwind_to, + self.arg_count, + false, // not generator + false, // not unwind path + ) + ); block.unit() } @@ -510,8 +507,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scope: BreakableTarget, source_info: SourceInfo, ) -> BlockAnd<()> { - let (mut target_block, region_scope, destination) - = self.scopes.find_breakable_scope(source_info.span, scope); + let (mut target_block, region_scope, destination) = + self.scopes.find_breakable_scope(source_info.span, scope); if let BreakableTarget::Return = scope { // We call this now, rather than when we start lowering the // function so that the return block doesn't precede the entire @@ -538,13 +535,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Branch out of `block` to `target`, exiting all scopes up to /// and including `region_scope`. This will insert whatever drops are /// needed. See module comment for details. - pub fn exit_scope(&mut self, - span: Span, - region_scope: region::Scope, - mut block: BasicBlock, - target: BasicBlock) { - debug!("exit_scope(region_scope={:?}, block={:?}, target={:?})", - region_scope, block, target); + pub fn exit_scope( + &mut self, + span: Span, + region_scope: region::Scope, + mut block: BasicBlock, + target: BasicBlock, + ) { + debug!( + "exit_scope(region_scope={:?}, block={:?}, target={:?})", + region_scope, block, target + ); let scope_count = self.scopes.num_scopes_above(region_scope, span); // If we are emitting a `drop` statement, we need to have the cached @@ -580,16 +581,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { START_BLOCK }); - unpack!(block = build_scope_drops( - &mut self.cfg, - self.generator_kind, - scope, - block, - unwind_to, - self.arg_count, - false, // not generator - false, // not unwind path - )); + unpack!( + block = build_scope_drops( + &mut self.cfg, + self.generator_kind, + scope, + block, + unwind_to, + self.arg_count, + false, // not generator + false, // not unwind path + ) + ); scope = next_scope; } @@ -622,22 +625,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { b }; - let unwind_to = scopes.peek().as_ref().map(|scope| { - scope.cached_unwind.get(true).unwrap_or_else(|| { - span_bug!(src_info.span, "cached block not present?") + let unwind_to = scopes + .peek() + .as_ref() + .map(|scope| { + scope + .cached_unwind + .get(true) + .unwrap_or_else(|| span_bug!(src_info.span, "cached block not present?")) }) - }).unwrap_or(resume_block); - - unpack!(block = build_scope_drops( - &mut self.cfg, - self.generator_kind, - scope, - block, - unwind_to, - self.arg_count, - true, // is generator - true, // is cached path - )); + .unwrap_or(resume_block); + + unpack!( + block = build_scope_drops( + &mut self.cfg, + self.generator_kind, + scope, + block, + unwind_to, + self.arg_count, + true, // is generator + true, // is cached path + ) + ); } self.cfg.terminate(block, src_info, TerminatorKind::GeneratorDrop); @@ -646,14 +656,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } /// Creates a new source scope, nested in the current one. - pub fn new_source_scope(&mut self, - span: Span, - lint_level: LintLevel, - safety: Option) -> SourceScope { + pub fn new_source_scope( + &mut self, + span: Span, + lint_level: LintLevel, + safety: Option, + ) -> SourceScope { let parent = self.source_scope; - debug!("new_source_scope({:?}, {:?}, {:?}) - parent({:?})={:?}", - span, lint_level, safety, - parent, self.source_scopes.get(parent)); + debug!( + "new_source_scope({:?}, {:?}, {:?}) - parent({:?})={:?}", + span, + lint_level, + safety, + parent, + self.source_scopes.get(parent) + ); let scope_local_data = SourceScopeLocalData { lint_root: if let LintLevel::Explicit(lint_root) = lint_level { lint_root @@ -662,7 +679,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }, safety: safety.unwrap_or_else(|| { self.source_scopes[parent].local_data.as_ref().assert_crate_local().safety - }) + }), }; self.source_scopes.push(SourceScopeData { span, @@ -673,10 +690,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Given a span and the current source scope, make a SourceInfo. pub fn source_info(&self, span: Span) -> SourceInfo { - SourceInfo { - span, - scope: self.source_scope - } + SourceInfo { span, scope: self.source_scope } } // Finding scopes @@ -705,13 +719,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// intermediate values do not have to be dropped in that case. pub fn local_scope(&self) -> Option { match self.hir.body_owner_kind { - hir::BodyOwnerKind::Const | - hir::BodyOwnerKind::Static(_) => - // No need to free storage in this context. - None, - hir::BodyOwnerKind::Closure | - hir::BodyOwnerKind::Fn => - Some(self.scopes.topmost()), + hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => + // No need to free storage in this context. + { + None + } + hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => Some(self.scopes.topmost()), } } @@ -750,13 +763,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) { let needs_drop = match drop_kind { DropKind::Value => { - if !self.hir.needs_drop(self.local_decls[local].ty) { return } + if !self.hir.needs_drop(self.local_decls[local].ty) { + return; + } true - }, + } DropKind::Storage => { if local.index() <= self.arg_count { span_bug!( - span, "`schedule_drop` called with local {:?} and arg_count {}", + span, + "`schedule_drop` called with local {:?} and arg_count {}", local, self.arg_count, ) @@ -815,8 +831,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // cache of outer scope stays intact. scope.invalidate_cache(!needs_drop, self.generator_kind, this_scope); if this_scope { - let region_scope_span = region_scope.span(self.hir.tcx(), - &self.hir.region_scope_tree); + let region_scope_span = + region_scope.span(self.hir.tcx(), &self.hir.region_scope_tree); // Attribute scope exit drops to scope's closing brace. let scope_end = self.hir.tcx().sess.source_map().end_point(region_scope_span); @@ -868,20 +884,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// spurious borrow-check errors -- the problem, ironically, is /// not the `DROP(_X)` itself, but the (spurious) unwind pathways /// that it creates. See #64391 for an example. - pub fn record_operands_moved( - &mut self, - operands: &[Operand<'tcx>], - ) { + pub fn record_operands_moved(&mut self, operands: &[Operand<'tcx>]) { let scope = match self.local_scope() { None => { // if there is no local scope, operands won't be dropped anyway return; } - Some(local_scope) => { - self.scopes.iter_mut().find(|scope| scope.region_scope == local_scope) - .unwrap_or_else(|| bug!("scope {:?} not found in scope list!", local_scope)) - } + Some(local_scope) => self + .scopes + .iter_mut() + .find(|scope| scope.region_scope == local_scope) + .unwrap_or_else(|| bug!("scope {:?} not found in scope list!", local_scope)), }; // look for moves of a local variable, like `MOVE(_X)` @@ -916,12 +930,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let cond = unpack!(block = self.as_local_operand(block, condition)); let true_block = self.cfg.start_new_block(); let false_block = self.cfg.start_new_block(); - let term = TerminatorKind::if_( - self.hir.tcx(), - cond.clone(), - true_block, - false_block, - ); + let term = TerminatorKind::if_(self.hir.tcx(), cond.clone(), true_block, false_block); self.cfg.terminate(block, source_info, term); match cond { @@ -930,8 +939,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // If constants and statics, we don't generate StorageLive for this // temporary, so don't try to generate StorageDead for it either. _ if self.local_scope().is_none() => (), - Operand::Copy(place) - | Operand::Move(place) => { + Operand::Copy(place) | Operand::Move(place) => { if let Some(cond_temp) = place.as_local() { // Manually drop the condition on both branches. let top_scope = self.scopes.scopes.last_mut().unwrap(); @@ -947,17 +955,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { assert_eq!(local, cond_temp, "Drop scheduled on top of condition"); self.cfg.push( true_block, - Statement { - source_info, - kind: StatementKind::StorageDead(local) - }, + Statement { source_info, kind: StatementKind::StorageDead(local) }, ); self.cfg.push( false_block, - Statement { - source_info, - kind: StatementKind::StorageDead(local) - }, + Statement { source_info, kind: StatementKind::StorageDead(local) }, ); } } @@ -985,12 +987,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { target } else { let resumeblk = self.cfg.start_new_cleanup_block(); - self.cfg.terminate(resumeblk, - SourceInfo { - scope: OUTERMOST_SOURCE_SCOPE, - span: self.fn_span - }, - TerminatorKind::Resume); + self.cfg.terminate( + resumeblk, + SourceInfo { scope: OUTERMOST_SOURCE_SCOPE, span: self.fn_span }, + TerminatorKind::Resume, + ); self.cached_resume_block = Some(resumeblk); resumeblk } @@ -1010,63 +1011,78 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Find the last cached block debug!("diverge_cleanup_gen(self.scopes = {:?})", self.scopes); - let cached_cleanup = self.scopes.iter_mut().enumerate() - .find_map(|(idx, ref scope)| { - let cached_block = scope.cached_unwind.get(generator_drop)?; - Some((cached_block, idx)) - }); - let (mut target, first_uncached) = cached_cleanup - .unwrap_or_else(|| (self.resume_block(), self.scopes.len())); + let cached_cleanup = self.scopes.iter_mut().enumerate().find_map(|(idx, ref scope)| { + let cached_block = scope.cached_unwind.get(generator_drop)?; + Some((cached_block, idx)) + }); + let (mut target, first_uncached) = + cached_cleanup.unwrap_or_else(|| (self.resume_block(), self.scopes.len())); for scope in self.scopes.top_scopes(first_uncached) { - target = build_diverge_scope(&mut self.cfg, scope.region_scope_span, - scope, target, generator_drop, self.generator_kind); + target = build_diverge_scope( + &mut self.cfg, + scope.region_scope_span, + scope, + target, + generator_drop, + self.generator_kind, + ); } target } /// Utility function for *non*-scope code to build their own drops - pub fn build_drop_and_replace(&mut self, - block: BasicBlock, - span: Span, - location: Place<'tcx>, - value: Operand<'tcx>) -> BlockAnd<()> { + pub fn build_drop_and_replace( + &mut self, + block: BasicBlock, + span: Span, + location: Place<'tcx>, + value: Operand<'tcx>, + ) -> BlockAnd<()> { let source_info = self.source_info(span); let next_target = self.cfg.start_new_block(); let diverge_target = self.diverge_cleanup(); - self.cfg.terminate(block, source_info, - TerminatorKind::DropAndReplace { - location, - value, - target: next_target, - unwind: Some(diverge_target), - }); + self.cfg.terminate( + block, + source_info, + TerminatorKind::DropAndReplace { + location, + value, + target: next_target, + unwind: Some(diverge_target), + }, + ); next_target.unit() } /// Creates an Assert terminator and return the success block. /// If the boolean condition operand is not the expected value, /// a runtime panic will be caused with the given message. - pub fn assert(&mut self, block: BasicBlock, - cond: Operand<'tcx>, - expected: bool, - msg: AssertMessage<'tcx>, - span: Span) - -> BasicBlock { + pub fn assert( + &mut self, + block: BasicBlock, + cond: Operand<'tcx>, + expected: bool, + msg: AssertMessage<'tcx>, + span: Span, + ) -> BasicBlock { let source_info = self.source_info(span); let success_block = self.cfg.start_new_block(); let cleanup = self.diverge_cleanup(); - self.cfg.terminate(block, source_info, - TerminatorKind::Assert { - cond, - expected, - msg, - target: success_block, - cleanup: Some(cleanup), - }); + self.cfg.terminate( + block, + source_info, + TerminatorKind::Assert { + cond, + expected, + msg, + target: success_block, + cleanup: Some(cleanup), + }, + ); success_block } @@ -1138,20 +1154,21 @@ fn build_scope_drops<'tcx>( .unwrap_or(last_unwind_to); let next = cfg.start_new_block(); - cfg.terminate(block, source_info, TerminatorKind::Drop { - location: local.into(), - target: next, - unwind: Some(unwind_to) - }); + cfg.terminate( + block, + source_info, + TerminatorKind::Drop { + location: local.into(), + target: next, + unwind: Some(unwind_to), + }, + ); block = next; } DropKind::Storage => { // Only temps and vars need their storage dead. assert!(local.index() > arg_count); - cfg.push(block, Statement { - source_info, - kind: StatementKind::StorageDead(local) - }); + cfg.push(block, Statement { source_info, kind: StatementKind::StorageDead(local) }); } } } @@ -1183,14 +1200,14 @@ fn get_unwind_to( None } -fn build_diverge_scope<'tcx>(cfg: &mut CFG<'tcx>, - span: Span, - scope: &mut Scope, - mut target: BasicBlock, - generator_drop: bool, - generator_kind: Option) - -> BasicBlock -{ +fn build_diverge_scope<'tcx>( + cfg: &mut CFG<'tcx>, + span: Span, + scope: &mut Scope, + mut target: BasicBlock, + generator_drop: bool, + generator_kind: Option, +) -> BasicBlock { // Build up the drops in **reverse** order. The end result will // look like: // @@ -1202,10 +1219,7 @@ fn build_diverge_scope<'tcx>(cfg: &mut CFG<'tcx>, // left reading the cached results but never create anything. let source_scope = scope.source_scope; - let source_info = |span| SourceInfo { - span, - scope: source_scope - }; + let source_info = |span| SourceInfo { span, scope: source_scope }; // We keep track of StorageDead statements to prepend to our current block // and store them here, in reverse order. @@ -1231,7 +1245,7 @@ fn build_diverge_scope<'tcx>(cfg: &mut CFG<'tcx>, DropKind::Storage if generator_kind.is_some() => { storage_deads.push(Statement { source_info: source_info(drop_data.span), - kind: StatementKind::StorageDead(drop_data.local) + kind: StatementKind::StorageDead(drop_data.local), }); if !target_built_by_us { // We cannot add statements to an existing block, so we create a new @@ -1260,7 +1274,7 @@ fn build_diverge_scope<'tcx>(cfg: &mut CFG<'tcx>, TerminatorKind::Drop { location: drop_data.local.into(), target, - unwind: None + unwind: None, }, ); *cached_block = Some(block); @@ -1279,14 +1293,20 @@ fn build_diverge_scope<'tcx>(cfg: &mut CFG<'tcx>, target } -fn push_storage_deads(cfg: &mut CFG<'tcx>, - target: BasicBlock, - storage_deads: &mut Vec>) { - if storage_deads.is_empty() { return; } +fn push_storage_deads( + cfg: &mut CFG<'tcx>, + target: BasicBlock, + storage_deads: &mut Vec>, +) { + if storage_deads.is_empty() { + return; + } let statements = &mut cfg.block_data_mut(target).statements; storage_deads.reverse(); - debug!("push_storage_deads({:?}), storage_deads={:?}, statements={:?}", - target, storage_deads, statements); + debug!( + "push_storage_deads({:?}), storage_deads={:?}, statements={:?}", + target, storage_deads, statements + ); storage_deads.append(statements); mem::swap(statements, storage_deads); assert!(storage_deads.is_empty()); diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs index e0ca10535237b..c6d29211d45a8 100644 --- a/src/librustc_mir/dataflow/at_location.rs +++ b/src/librustc_mir/dataflow/at_location.rs @@ -4,11 +4,11 @@ use rustc::mir::{BasicBlock, Location}; use rustc_index::bit_set::{BitIter, BitSet, HybridBitSet}; -use crate::dataflow::{BitDenotation, DataflowResults, GenKillSet}; use crate::dataflow::move_paths::{HasMoveData, MovePathIndex}; +use crate::dataflow::{BitDenotation, DataflowResults, GenKillSet}; -use std::iter; use std::borrow::Borrow; +use std::iter; /// A trait for "cartesian products" of multiple FlowAtLocation. /// @@ -98,11 +98,7 @@ where let bits_per_block = results.borrow().sets().bits_per_block(); let curr_state = BitSet::new_empty(bits_per_block); let stmt_trans = GenKillSet::from_elem(HybridBitSet::new_empty(bits_per_block)); - FlowAtLocation { - base_results: results, - curr_state, - stmt_trans, - } + FlowAtLocation { base_results: results, curr_state, stmt_trans } } /// Access the underlying operator. @@ -154,30 +150,18 @@ where fn reconstruct_statement_effect(&mut self, loc: Location) { self.stmt_trans.clear(); - self.base_results - .borrow() - .operator() - .before_statement_effect(&mut self.stmt_trans, loc); + self.base_results.borrow().operator().before_statement_effect(&mut self.stmt_trans, loc); self.stmt_trans.apply(&mut self.curr_state); - self.base_results - .borrow() - .operator() - .statement_effect(&mut self.stmt_trans, loc); + self.base_results.borrow().operator().statement_effect(&mut self.stmt_trans, loc); } fn reconstruct_terminator_effect(&mut self, loc: Location) { self.stmt_trans.clear(); - self.base_results - .borrow() - .operator() - .before_terminator_effect(&mut self.stmt_trans, loc); + self.base_results.borrow().operator().before_terminator_effect(&mut self.stmt_trans, loc); self.stmt_trans.apply(&mut self.curr_state); - self.base_results - .borrow() - .operator() - .terminator_effect(&mut self.stmt_trans, loc); + self.base_results.borrow().operator().terminator_effect(&mut self.stmt_trans, loc); } fn apply_local_effect(&mut self, _loc: Location) { @@ -185,7 +169,6 @@ where } } - impl<'tcx, T, DR> FlowAtLocation<'tcx, T, DR> where T: HasMoveData<'tcx> + BitDenotation<'tcx, Idx = MovePathIndex>, diff --git a/src/librustc_mir/dataflow/drop_flag_effects.rs b/src/librustc_mir/dataflow/drop_flag_effects.rs index 0fe58c07b1b86..720b17e7ff85b 100644 --- a/src/librustc_mir/dataflow/drop_flag_effects.rs +++ b/src/librustc_mir/dataflow/drop_flag_effects.rs @@ -1,23 +1,25 @@ +use crate::util::elaborate_drops::DropFlagState; use rustc::mir::{self, Body, Location}; use rustc::ty::{self, TyCtxt}; -use crate::util::elaborate_drops::DropFlagState; -use super::{MoveDataParamEnv}; use super::indexes::MovePathIndex; -use super::move_paths::{MoveData, LookupResult, InitKind}; +use super::move_paths::{InitKind, LookupResult, MoveData}; +use super::MoveDataParamEnv; -pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>, - path: MovePathIndex, - mut cond: F) - -> Option - where F: FnMut(&mir::PlaceElem<'tcx>) -> bool +pub fn move_path_children_matching<'tcx, F>( + move_data: &MoveData<'tcx>, + path: MovePathIndex, + mut cond: F, +) -> Option +where + F: FnMut(&mir::PlaceElem<'tcx>) -> bool, { let mut next_child = move_data.move_paths[path].first_child; while let Some(child_index) = next_child { let move_path_children = &move_data.move_paths[child_index]; if let Some(elem) = move_path_children.place.projection.last() { if cond(elem) { - return Some(child_index) + return Some(child_index); } } next_child = move_path_children.next_sibling; @@ -52,23 +54,27 @@ fn place_contents_drop_state_cannot_differ<'tcx>( let ty = place.ty(body, tcx).ty; match ty.kind { ty::Array(..) => { - debug!("place_contents_drop_state_cannot_differ place: {:?} ty: {:?} => false", - place, ty); + debug!( + "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} => false", + place, ty + ); false } ty::Slice(..) | ty::Ref(..) | ty::RawPtr(..) => { - debug!("place_contents_drop_state_cannot_differ place: {:?} ty: {:?} refd => true", - place, ty); + debug!( + "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} refd => true", + place, ty + ); true } ty::Adt(def, _) if (def.has_dtor(tcx) && !def.is_box()) || def.is_union() => { - debug!("place_contents_drop_state_cannot_differ place: {:?} ty: {:?} Drop => true", - place, ty); + debug!( + "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} Drop => true", + place, ty + ); true } - _ => { - false - } + _ => false, } } @@ -85,9 +91,7 @@ pub(crate) fn on_lookup_result_bits<'tcx, F>( LookupResult::Parent(..) => { // access to untracked value - do not touch children } - LookupResult::Exact(e) => { - on_all_children_bits(tcx, body, move_data, e, each_child) - } + LookupResult::Exact(e) => on_all_children_bits(tcx, body, move_data, e, each_child), } } @@ -106,8 +110,7 @@ pub(crate) fn on_all_children_bits<'tcx, F>( move_data: &MoveData<'tcx>, path: MovePathIndex, ) -> bool { - place_contents_drop_state_cannot_differ( - tcx, body, &move_data.move_paths[path].place) + place_contents_drop_state_cannot_differ(tcx, body, &move_data.move_paths[path].place) } fn on_all_children_bits<'tcx, F>( @@ -122,7 +125,7 @@ pub(crate) fn on_all_children_bits<'tcx, F>( each_child(move_path_index); if is_terminal_path(tcx, body, move_data, move_path_index) { - return + return; } let mut next_child_index = move_data.move_paths[move_path_index].first_child; @@ -169,9 +172,9 @@ pub(crate) fn drop_flag_effects_for_function_entry<'tcx, F>( for arg in body.args_iter() { let place = mir::Place::from(arg); let lookup_result = move_data.rev_lookup.find(place.as_ref()); - on_lookup_result_bits(tcx, body, move_data, - lookup_result, - |mpi| callback(mpi, DropFlagState::Present)); + on_lookup_result_bits(tcx, body, move_data, lookup_result, |mpi| { + callback(mpi, DropFlagState::Present) + }); } } @@ -192,20 +195,12 @@ pub(crate) fn drop_flag_effects_for_location<'tcx, F>( let path = mi.move_path_index(move_data); debug!("moving out of path {:?}", move_data.move_paths[path]); - on_all_children_bits(tcx, body, move_data, - path, - |mpi| callback(mpi, DropFlagState::Absent)) + on_all_children_bits(tcx, body, move_data, path, |mpi| callback(mpi, DropFlagState::Absent)) } debug!("drop_flag_effects: assignment for location({:?})", loc); - for_location_inits( - tcx, - body, - move_data, - loc, - |mpi| callback(mpi, DropFlagState::Present) - ); + for_location_inits(tcx, body, move_data, loc, |mpi| callback(mpi, DropFlagState::Present)); } pub(crate) fn for_location_inits<'tcx, F>( @@ -223,10 +218,8 @@ pub(crate) fn for_location_inits<'tcx, F>( InitKind::Deep => { let path = init.path; - on_all_children_bits(tcx, body, move_data, - path, - &mut callback) - }, + on_all_children_bits(tcx, body, move_data, path, &mut callback) + } InitKind::Shallow => { let mpi = init.path; callback(mpi); diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs index dd6238b80d174..659ebeab65022 100644 --- a/src/librustc_mir/dataflow/generic.rs +++ b/src/librustc_mir/dataflow/generic.rs @@ -195,8 +195,7 @@ impl CursorPosition { } } -type ResultsRefCursor<'a, 'mir, 'tcx, A> = - ResultsCursor<'mir, 'tcx, A, &'a Results<'tcx, A>>; +type ResultsRefCursor<'a, 'mir, 'tcx, A> = ResultsCursor<'mir, 'tcx, A, &'a Results<'tcx, A>>; /// Inspect the results of dataflow analysis. /// @@ -291,11 +290,9 @@ where let term = self.body.basic_blocks()[target.block].terminator(); if let mir::TerminatorKind::Call { - destination: Some((return_place, _)), - func, - args, - .. - } = &term.kind { + destination: Some((return_place, _)), func, args, .. + } = &term.kind + { if !self.is_call_return_effect_applied { self.is_call_return_effect_applied = true; self.results.borrow().analysis.apply_call_return_effect( @@ -321,7 +318,7 @@ where if let CursorPosition::After(Location { statement_index: curr_index, .. }) = self.pos { match curr_index.cmp(&target_index) { Ordering::Equal => return, - Ordering::Less => {}, + Ordering::Less => {} Ordering::Greater => self.seek_to_block_start(target_block), } } @@ -401,15 +398,7 @@ where let mut entry_sets = IndexVec::from_elem(bottom_value_set, body.basic_blocks()); analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]); - Engine { - analysis, - bits_per_block, - tcx, - body, - def_id, - dead_unwinds, - entry_sets, - } + Engine { analysis, bits_per_block, tcx, body, def_id, dead_unwinds, entry_sets } } pub fn iterate_to_fixpoint(mut self) -> Results<'tcx, A> { @@ -442,14 +431,7 @@ where ); } - let Engine { - tcx, - body, - def_id, - analysis, - entry_sets, - .. - } = self; + let Engine { tcx, body, def_id, analysis, entry_sets, .. } = self; let results = Results { analysis, entry_sets }; @@ -570,8 +552,8 @@ fn get_dataflow_graphviz_output_path( .filter(|attr| attr.check_name(sym::rustc_mir)) .flat_map(|attr| attr.meta_item_list().into_iter().flat_map(|v| v.into_iter())); - let borrowck_graphviz_postflow = rustc_mir_attrs - .find(|attr| attr.check_name(sym::borrowck_graphviz_postflow))?; + let borrowck_graphviz_postflow = + rustc_mir_attrs.find(|attr| attr.check_name(sym::borrowck_graphviz_postflow))?; let path_and_suffix = match borrowck_graphviz_postflow.value_str() { Some(p) => p, @@ -601,7 +583,7 @@ fn write_dataflow_graphviz_results>( body: &mir::Body<'tcx>, def_id: DefId, path: &Path, - results: &Results<'tcx, A> + results: &Results<'tcx, A>, ) -> io::Result<()> { debug!("printing dataflow results for {:?} to {}", def_id, path.display()); diff --git a/src/librustc_mir/dataflow/generic/graphviz.rs b/src/librustc_mir/dataflow/generic/graphviz.rs index 47ace8f33ecac..399a839c11c6d 100644 --- a/src/librustc_mir/dataflow/generic/graphviz.rs +++ b/src/librustc_mir/dataflow/generic/graphviz.rs @@ -7,8 +7,8 @@ use rustc::mir::{self, BasicBlock, Body, Location}; use rustc_index::bit_set::{BitSet, HybridBitSet}; use rustc_index::vec::Idx; -use crate::util::graphviz_safe_def_name; use super::{Analysis, Results, ResultsRefCursor}; +use crate::util::graphviz_safe_def_name; pub struct Formatter<'a, 'tcx, A> where @@ -25,22 +25,14 @@ impl Formatter<'a, 'tcx, A> where A: Analysis<'tcx>, { - pub fn new( - body: &'a Body<'tcx>, - def_id: DefId, - results: &'a Results<'tcx, A>, - ) -> Self { + pub fn new(body: &'a Body<'tcx>, def_id: DefId, results: &'a Results<'tcx, A>) -> Self { let block_formatter = BlockFormatter { bg: Background::Light, prev_state: BitSet::new_empty(results.analysis.bits_per_block(body)), results: ResultsRefCursor::new(body, results), }; - Formatter { - body, - def_id, - block_formatter: RefCell::new(block_formatter), - } + Formatter { body, def_id, block_formatter: RefCell::new(block_formatter) } } } @@ -78,10 +70,7 @@ where fn node_label(&self, block: &Self::Node) -> dot::LabelText<'_> { let mut label = Vec::new(); - self.block_formatter - .borrow_mut() - .write_node_label(&mut label, self.body, *block) - .unwrap(); + self.block_formatter.borrow_mut().write_node_label(&mut label, self.body, *block).unwrap(); dot::LabelText::html(String::from_utf8(label).unwrap()) } @@ -90,12 +79,7 @@ where } fn edge_label(&self, e: &Self::Edge) -> dot::LabelText<'_> { - let label = &self.body - [e.source] - .terminator() - .kind - .fmt_successor_labels() - [e.index]; + let label = &self.body[e.source].terminator().kind.fmt_successor_labels()[e.index]; dot::LabelText::label(label.clone()) } } @@ -108,11 +92,7 @@ where type Edge = CfgEdge; fn nodes(&self) -> dot::Nodes<'_, Self::Node> { - self.body - .basic_blocks() - .indices() - .collect::>() - .into() + self.body.basic_blocks().indices().collect::>().into() } fn edges(&self) -> dot::Edges<'_, Self::Edge> { @@ -129,13 +109,7 @@ where } fn target(&self, edge: &Self::Edge) -> Self::Node { - self.body - [edge.source] - .terminator() - .successors() - .nth(edge.index) - .copied() - .unwrap() + self.body[edge.source].terminator().successors().nth(edge.index).copied().unwrap() } } @@ -240,7 +214,7 @@ where self.prev_state.overwrite(self.results.get()); // F: Exit state - if let mir::TerminatorKind::Call { destination: Some(_), .. } = &terminator.kind { + if let mir::TerminatorKind::Call { destination: Some(_), .. } = &terminator.kind { self.write_row_with_curr_state(w, "", "(on unwind)")?; self.results.seek_after_assume_call_returns(location); @@ -354,10 +328,7 @@ impl BitSetDiff { }; } - BitSetDiff { - set, - clear, - } + BitSetDiff { set, clear } } } diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs index b0d8581784606..89a0a08a5c6c8 100644 --- a/src/librustc_mir/dataflow/graphviz.rs +++ b/src/librustc_mir/dataflow/graphviz.rs @@ -10,9 +10,9 @@ use std::path::Path; use crate::util::graphviz_safe_def_name; -use super::{BitDenotation, DataflowState}; use super::DataflowBuilder; use super::DebugFormatted; +use super::{BitDenotation, DataflowState}; pub trait MirWithFlowState<'tcx> { type BD: BitDenotation<'tcx>; @@ -22,16 +22,24 @@ pub trait MirWithFlowState<'tcx> { } impl<'a, 'tcx, BD> MirWithFlowState<'tcx> for DataflowBuilder<'a, 'tcx, BD> - where BD: BitDenotation<'tcx> +where + BD: BitDenotation<'tcx>, { type BD = BD; - fn def_id(&self) -> DefId { self.def_id } - fn body(&self) -> &Body<'tcx> { self.flow_state.body() } - fn flow_state(&self) -> &DataflowState<'tcx, Self::BD> { &self.flow_state.flow_state } + fn def_id(&self) -> DefId { + self.def_id + } + fn body(&self) -> &Body<'tcx> { + self.flow_state.body() + } + fn flow_state(&self) -> &DataflowState<'tcx, Self::BD> { + &self.flow_state.flow_state + } } -struct Graph<'a, 'tcx, MWF, P> where - MWF: MirWithFlowState<'tcx> +struct Graph<'a, 'tcx, MWF, P> +where + MWF: MirWithFlowState<'tcx>, { mbcx: &'a MWF, phantom: PhantomData<&'tcx ()>, @@ -41,32 +49,37 @@ struct Graph<'a, 'tcx, MWF, P> where pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>( mbcx: &DataflowBuilder<'a, 'tcx, BD>, path: &Path, - render_idx: P) - -> io::Result<()> - where BD: BitDenotation<'tcx>, - P: Fn(&BD, BD::Idx) -> DebugFormatted, + render_idx: P, +) -> io::Result<()> +where + BD: BitDenotation<'tcx>, + P: Fn(&BD, BD::Idx) -> DebugFormatted, { let g = Graph { mbcx, phantom: PhantomData, render_idx }; let mut v = Vec::new(); dot::render(&g, &mut v)?; - debug!("print_borrowck_graph_to path: {} def_id: {:?}", - path.display(), mbcx.def_id); + debug!("print_borrowck_graph_to path: {} def_id: {:?}", path.display(), mbcx.def_id); fs::write(path, v) } pub type Node = BasicBlock; #[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub struct Edge { source: BasicBlock, index: usize } +pub struct Edge { + source: BasicBlock, + index: usize, +} fn outgoing(body: &Body<'_>, bb: BasicBlock) -> Vec { (0..body[bb].terminator().successors().count()) - .map(|index| Edge { source: bb, index: index}).collect() + .map(|index| Edge { source: bb, index: index }) + .collect() } impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P> - where MWF: MirWithFlowState<'tcx>, - P: Fn(&MWF::BD, >::Idx) -> DebugFormatted, +where + MWF: MirWithFlowState<'tcx>, + P: Fn(&MWF::BD, >::Idx) -> DebugFormatted, { type Node = Node; type Edge = Edge; @@ -76,8 +89,7 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P> } fn node_id(&self, n: &Node) -> dot::Id<'_> { - dot::Id::new(format!("bb_{}", n.index())) - .unwrap() + dot::Id::new(format!("bb_{}", n.index())).unwrap() } fn node_label(&self, n: &Node) -> dot::LabelText<'_> { @@ -103,7 +115,6 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P> dot::LabelText::html(String::from_utf8(v).unwrap()) } - fn node_shape(&self, _n: &Node) -> Option> { Some(dot::LabelText::label("none")) } @@ -116,15 +127,18 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P> } impl<'a, 'tcx, MWF, P> Graph<'a, 'tcx, MWF, P> -where MWF: MirWithFlowState<'tcx>, - P: Fn(&MWF::BD, >::Idx) -> DebugFormatted, +where + MWF: MirWithFlowState<'tcx>, + P: Fn(&MWF::BD, >::Idx) -> DebugFormatted, { /// Generate the node label - fn node_label_internal(&self, - n: &Node, - w: &mut W, - block: BasicBlock, - body: &Body<'_>) -> io::Result<()> { + fn node_label_internal( + &self, + n: &Node, + w: &mut W, + block: BasicBlock, + body: &Body<'_>, + ) -> io::Result<()> { // Header rows const HDRS: [&str; 4] = ["ENTRY", "MIR", "BLOCK GENS", "BLOCK KILLS"]; const HDR_FMT: &str = "bgcolor=\"grey\""; @@ -145,12 +159,13 @@ where MWF: MirWithFlowState<'tcx>, } /// Builds the verbose row: full MIR data, and detailed gen/kill/entry sets. - fn node_label_verbose_row(&self, - n: &Node, - w: &mut W, - block: BasicBlock, - body: &Body<'_>) - -> io::Result<()> { + fn node_label_verbose_row( + &self, + n: &Node, + w: &mut W, + block: BasicBlock, + body: &Body<'_>, + ) -> io::Result<()> { let i = n.index(); macro_rules! dump_set_for { @@ -158,14 +173,13 @@ where MWF: MirWithFlowState<'tcx>, write!(w, "")?; let flow = self.mbcx.flow_state(); - let entry_interp = flow.$interpret(&flow.operator, - flow.sets.$set(i), - &self.render_idx); + let entry_interp = + flow.$interpret(&flow.operator, flow.sets.$set(i), &self.render_idx); for e in &entry_interp { write!(w, "{:?}
", e)?; } write!(w, "")?; - } + }; } write!(w, "")?; @@ -177,8 +191,11 @@ where MWF: MirWithFlowState<'tcx>, { let data = &body[block]; for (i, statement) in data.statements.iter().enumerate() { - write!(w, "{}
", - dot::escape_html(&format!("{:3}: {:?}", i, statement)))?; + write!( + w, + "{}
", + dot::escape_html(&format!("{:3}: {:?}", i, statement)) + )?; } } write!(w, "")?; @@ -195,12 +212,13 @@ where MWF: MirWithFlowState<'tcx>, } /// Builds the summary row: terminator, gen/kill/entry bit sets. - fn node_label_final_row(&self, - n: &Node, - w: &mut W, - block: BasicBlock, - body: &Body<'_>) - -> io::Result<()> { + fn node_label_final_row( + &self, + n: &Node, + w: &mut W, + block: BasicBlock, + body: &Body<'_>, + ) -> io::Result<()> { let i = n.index(); let flow = self.mbcx.flow_state(); @@ -233,26 +251,19 @@ where MWF: MirWithFlowState<'tcx>, } impl<'a, 'tcx, MWF, P> dot::GraphWalk<'a> for Graph<'a, 'tcx, MWF, P> - where MWF: MirWithFlowState<'tcx> +where + MWF: MirWithFlowState<'tcx>, { type Node = Node; type Edge = Edge; fn nodes(&self) -> dot::Nodes<'_, Node> { - self.mbcx.body() - .basic_blocks() - .indices() - .collect::>() - .into() + self.mbcx.body().basic_blocks().indices().collect::>().into() } fn edges(&self) -> dot::Edges<'_, Edge> { let body = self.mbcx.body(); - body.basic_blocks() - .indices() - .flat_map(|bb| outgoing(body, bb)) - .collect::>() - .into() + body.basic_blocks().indices().flat_map(|bb| outgoing(body, bb)).collect::>().into() } fn source(&self, edge: &Edge) -> Node { diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs index 1c43a553cc3c9..65976908f597e 100644 --- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs +++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs @@ -1,8 +1,8 @@ pub use super::*; -use rustc::mir::*; -use rustc::mir::visit::Visitor; use crate::dataflow::{BitDenotation, GenKillSet}; +use rustc::mir::visit::Visitor; +use rustc::mir::*; /// This calculates if any part of a MIR local could have previously been borrowed. /// This means that once a local has been borrowed, its bit will be set @@ -16,8 +16,7 @@ pub struct HaveBeenBorrowedLocals<'a, 'tcx> { } impl<'a, 'tcx> HaveBeenBorrowedLocals<'a, 'tcx> { - pub fn new(body: &'a Body<'tcx>) - -> Self { + pub fn new(body: &'a Body<'tcx>) -> Self { HaveBeenBorrowedLocals { body } } @@ -28,7 +27,9 @@ impl<'a, 'tcx> HaveBeenBorrowedLocals<'a, 'tcx> { impl<'a, 'tcx> BitDenotation<'tcx> for HaveBeenBorrowedLocals<'a, 'tcx> { type Idx = Local; - fn name() -> &'static str { "has_been_borrowed_locals" } + fn name() -> &'static str { + "has_been_borrowed_locals" + } fn bits_per_block(&self) -> usize { self.body.local_decls.len() } @@ -37,14 +38,10 @@ impl<'a, 'tcx> BitDenotation<'tcx> for HaveBeenBorrowedLocals<'a, 'tcx> { // Nothing is borrowed on function entry } - fn statement_effect(&self, - trans: &mut GenKillSet, - loc: Location) { + fn statement_effect(&self, trans: &mut GenKillSet, loc: Location) { let stmt = &self.body[loc.block].statements[loc.statement_index]; - BorrowedLocalsVisitor { - trans, - }.visit_statement(stmt, loc); + BorrowedLocalsVisitor { trans }.visit_statement(stmt, loc); // StorageDead invalidates all borrows and raw pointers to a local match stmt.kind { @@ -53,17 +50,13 @@ impl<'a, 'tcx> BitDenotation<'tcx> for HaveBeenBorrowedLocals<'a, 'tcx> { } } - fn terminator_effect(&self, - trans: &mut GenKillSet, - loc: Location) { + fn terminator_effect(&self, trans: &mut GenKillSet, loc: Location) { let terminator = self.body[loc.block].terminator(); - BorrowedLocalsVisitor { - trans, - }.visit_terminator(terminator, loc); + BorrowedLocalsVisitor { trans }.visit_terminator(terminator, loc); match &terminator.kind { // Drop terminators borrows the location - TerminatorKind::Drop { location, .. } | - TerminatorKind::DropAndReplace { location, .. } => { + TerminatorKind::Drop { location, .. } + | TerminatorKind::DropAndReplace { location, .. } => { if let Some(local) = find_local(location) { trans.gen(local); } @@ -100,9 +93,7 @@ fn find_local(place: &Place<'_>) -> Option { } impl<'tcx> Visitor<'tcx> for BorrowedLocalsVisitor<'_> { - fn visit_rvalue(&mut self, - rvalue: &Rvalue<'tcx>, - location: Location) { + fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { if let Rvalue::Ref(_, _, ref place) = *rvalue { if let Some(local) = find_local(place) { self.trans.gen(local); diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 5433b7f5f74f7..30eccebd3315f 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -1,14 +1,14 @@ -use rustc::mir::{self, Location, Place, PlaceBase, Body}; -use rustc::ty::{self, TyCtxt}; +use rustc::mir::{self, Body, Location, Place, PlaceBase}; use rustc::ty::RegionVid; +use rustc::ty::{self, TyCtxt}; -use rustc_index::bit_set::BitSet; use rustc_data_structures::fx::FxHashMap; +use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; use crate::borrow_check::{ - ToRegionVid, BorrowSet, BorrowData, RegionInferenceContext, PlaceExt, PlaceConflictBias, - places_conflict, + places_conflict, BorrowData, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext, + ToRegionVid, }; use crate::dataflow::{BitDenotation, BottomValue, GenKillSet}; @@ -43,7 +43,7 @@ struct StackEntry { bb: mir::BasicBlock, lo: usize, hi: usize, - first_part_only: bool + first_part_only: bool, } fn precompute_borrows_out_of_scope<'tcx>( @@ -77,16 +77,13 @@ fn precompute_borrows_out_of_scope<'tcx>( while let Some(StackEntry { bb, lo, hi, first_part_only }) = stack.pop() { let mut finished_early = first_part_only; - for i in lo ..= hi { + for i in lo..=hi { let location = Location { block: bb, statement_index: i }; // If region does not contain a point at the location, then add to list and skip // successor locations. if !regioncx.region_contains(borrow_region, location) { debug!("borrow {:?} gets killed at {:?}", borrow_index, location); - borrows_out_of_scope_at_location - .entry(location) - .or_default() - .push(borrow_index); + borrows_out_of_scope_at_location.entry(location).or_default().push(borrow_index); finished_early = true; break; } @@ -97,7 +94,8 @@ fn precompute_borrows_out_of_scope<'tcx>( let bb_data = &body[bb]; assert!(hi == bb_data.statements.len()); for &succ_bb in bb_data.terminator().successors() { - visited.entry(succ_bb) + visited + .entry(succ_bb) .and_modify(|lo| { // `succ_bb` has been seen before. If it wasn't // fully processed, add its first part to `stack` @@ -145,9 +143,14 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { let borrow_region = borrow_data.region.to_region_vid(); let location = borrow_set.borrows[borrow_index].reserve_location; - precompute_borrows_out_of_scope(body, &nonlexical_regioncx, - &mut borrows_out_of_scope_at_location, - borrow_index, borrow_region, location); + precompute_borrows_out_of_scope( + body, + &nonlexical_regioncx, + &mut borrows_out_of_scope_at_location, + borrow_index, + borrow_region, + location, + ); } Borrows { @@ -160,7 +163,9 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { } } - crate fn borrows(&self) -> &IndexVec> { &self.borrow_set.borrows } + crate fn borrows(&self) -> &IndexVec> { + &self.borrow_set.borrows + } pub fn location(&self, idx: BorrowIndex) -> &Location { &self.borrow_set.borrows[idx].reserve_location @@ -168,9 +173,11 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { /// Add all borrows to the kill set, if those borrows are out of scope at `location`. /// That means they went out of a nonlexical scope - fn kill_loans_out_of_scope_at_location(&self, - trans: &mut GenKillSet, - location: Location) { + fn kill_loans_out_of_scope_at_location( + &self, + trans: &mut GenKillSet, + location: Location, + ) { // NOTE: The state associated with a given `location` // reflects the dataflow on entry to the statement. // Iterate over each of the borrows that we've precomputed @@ -188,20 +195,12 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { } /// Kill any borrows that conflict with `place`. - fn kill_borrows_on_place( - &self, - trans: &mut GenKillSet, - place: &Place<'tcx> - ) { + fn kill_borrows_on_place(&self, trans: &mut GenKillSet, place: &Place<'tcx>) { debug!("kill_borrows_on_place: place={:?}", place); if let PlaceBase::Local(local) = place.base { - let other_borrows_of_local = self - .borrow_set - .local_map - .get(&local) - .into_iter() - .flat_map(|bs| bs.into_iter()); + let other_borrows_of_local = + self.borrow_set.local_map.get(&local).into_iter().flat_map(|bs| bs.into_iter()); // If the borrowed place is a local with no projections, all other borrows of this // local must conflict. This is purely an optimization so we don't have to call @@ -217,16 +216,16 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { // pair of array indices are unequal, so that when `places_conflict` returns true, we // will be assured that two places being compared definitely denotes the same sets of // locations. - let definitely_conflicting_borrows = other_borrows_of_local - .filter(|&&i| { - places_conflict( - self.tcx, - self.param_env, - self.body, - &self.borrow_set.borrows[i].borrowed_place, - place, - PlaceConflictBias::NoOverlap) - }); + let definitely_conflicting_borrows = other_borrows_of_local.filter(|&&i| { + places_conflict( + self.tcx, + self.param_env, + self.body, + &self.borrow_set.borrows[i].borrowed_place, + place, + PlaceConflictBias::NoOverlap, + ) + }); trans.kill_all(definitely_conflicting_borrows); } @@ -235,7 +234,9 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { impl<'a, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'tcx> { type Idx = BorrowIndex; - fn name() -> &'static str { "borrows" } + fn name() -> &'static str { + "borrows" + } fn bits_per_block(&self) -> usize { self.borrow_set.borrows.len() * 2 } @@ -245,19 +246,13 @@ impl<'a, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'tcx> { // function execution, so this method has no effect. } - fn before_statement_effect(&self, - trans: &mut GenKillSet, - location: Location) { - debug!("Borrows::before_statement_effect trans: {:?} location: {:?}", - trans, location); + fn before_statement_effect(&self, trans: &mut GenKillSet, location: Location) { + debug!("Borrows::before_statement_effect trans: {:?} location: {:?}", trans, location); self.kill_loans_out_of_scope_at_location(trans, location); } - fn statement_effect(&self, - trans: &mut GenKillSet, - location: Location) { - debug!("Borrows::statement_effect: trans={:?} location={:?}", - trans, location); + fn statement_effect(&self, trans: &mut GenKillSet, location: Location) { + debug!("Borrows::statement_effect: trans={:?} location={:?}", trans, location); let block = &self.body.basic_blocks().get(location.block).unwrap_or_else(|| { panic!("could not find block at location {:?}", location); @@ -268,7 +263,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'tcx> { debug!("Borrows::statement_effect: stmt={:?}", stmt); match stmt.kind { - mir::StatementKind::Assign(box(ref lhs, ref rhs)) => { + mir::StatementKind::Assign(box (ref lhs, ref rhs)) => { if let mir::Rvalue::Ref(_, _, ref place) = *rhs { if place.ignore_borrow( self.tcx, @@ -303,27 +298,21 @@ impl<'a, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'tcx> { } } - mir::StatementKind::FakeRead(..) | - mir::StatementKind::SetDiscriminant { .. } | - mir::StatementKind::StorageLive(..) | - mir::StatementKind::Retag { .. } | - mir::StatementKind::AscribeUserType(..) | - mir::StatementKind::Nop => {} - + mir::StatementKind::FakeRead(..) + | mir::StatementKind::SetDiscriminant { .. } + | mir::StatementKind::StorageLive(..) + | mir::StatementKind::Retag { .. } + | mir::StatementKind::AscribeUserType(..) + | mir::StatementKind::Nop => {} } } - fn before_terminator_effect(&self, - trans: &mut GenKillSet, - location: Location) { - debug!("Borrows::before_terminator_effect: trans={:?} location={:?}", - trans, location); + fn before_terminator_effect(&self, trans: &mut GenKillSet, location: Location) { + debug!("Borrows::before_terminator_effect: trans={:?} location={:?}", trans, location); self.kill_loans_out_of_scope_at_location(trans, location); } - fn terminator_effect(&self, - _: &mut GenKillSet, - _: Location) {} + fn terminator_effect(&self, _: &mut GenKillSet, _: Location) {} fn propagate_call_return( &self, diff --git a/src/librustc_mir/dataflow/impls/indirect_mutation.rs b/src/librustc_mir/dataflow/impls/indirect_mutation.rs index bc09e32717926..8b05a36beb3a5 100644 --- a/src/librustc_mir/dataflow/impls/indirect_mutation.rs +++ b/src/librustc_mir/dataflow/impls/indirect_mutation.rs @@ -33,19 +33,16 @@ impl<'mir, 'tcx> IndirectlyMutableLocals<'mir, 'tcx> { &self, trans: &'a mut GenKillSet, ) -> TransferFunction<'a, 'mir, 'tcx> { - TransferFunction { - body: self.body, - tcx: self.tcx, - param_env: self.param_env, - trans - } + TransferFunction { body: self.body, tcx: self.tcx, param_env: self.param_env, trans } } } impl<'mir, 'tcx> dataflow::BitDenotation<'tcx> for IndirectlyMutableLocals<'mir, 'tcx> { type Idx = Local; - fn name() -> &'static str { "mut_borrowed_locals" } + fn name() -> &'static str { + "mut_borrowed_locals" + } fn bits_per_block(&self) -> usize { self.body.local_decls.len() @@ -55,20 +52,12 @@ impl<'mir, 'tcx> dataflow::BitDenotation<'tcx> for IndirectlyMutableLocals<'mir, // Nothing is borrowed on function entry } - fn statement_effect( - &self, - trans: &mut GenKillSet, - loc: Location, - ) { + fn statement_effect(&self, trans: &mut GenKillSet, loc: Location) { let stmt = &self.body[loc.block].statements[loc.statement_index]; self.transfer_function(trans).visit_statement(stmt, loc); } - fn terminator_effect( - &self, - trans: &mut GenKillSet, - loc: Location, - ) { + fn terminator_effect(&self, trans: &mut GenKillSet, loc: Location) { let terminator = self.body[loc.block].terminator(); self.transfer_function(trans).visit_terminator(terminator, loc); } @@ -107,28 +96,25 @@ impl<'tcx> TransferFunction<'_, '_, 'tcx> { match kind { mir::BorrowKind::Mut { .. } => true, - | mir::BorrowKind::Shared - | mir::BorrowKind::Shallow - | mir::BorrowKind::Unique - => !borrowed_place - .ty(self.body, self.tcx) - .ty - .is_freeze(self.tcx, self.param_env, DUMMY_SP), + mir::BorrowKind::Shared | mir::BorrowKind::Shallow | mir::BorrowKind::Unique => { + !borrowed_place.ty(self.body, self.tcx).ty.is_freeze( + self.tcx, + self.param_env, + DUMMY_SP, + ) + } } } } impl<'tcx> Visitor<'tcx> for TransferFunction<'_, '_, 'tcx> { - fn visit_rvalue( - &mut self, - rvalue: &mir::Rvalue<'tcx>, - location: Location, - ) { + fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) { if let mir::Rvalue::Ref(_, kind, ref borrowed_place) = *rvalue { if self.borrow_allows_mutation(kind, borrowed_place) { match borrowed_place.base { - mir::PlaceBase::Local(borrowed_local) if !borrowed_place.is_indirect() - => self.trans.gen(borrowed_local), + mir::PlaceBase::Local(borrowed_local) if !borrowed_place.is_indirect() => { + self.trans.gen(borrowed_local) + } _ => (), } @@ -138,7 +124,6 @@ impl<'tcx> Visitor<'tcx> for TransferFunction<'_, '_, 'tcx> { self.super_rvalue(rvalue, location); } - fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) { // This method purposely does nothing except call `super_terminator`. It exists solely to // document the subtleties around drop terminators. @@ -146,7 +131,7 @@ impl<'tcx> Visitor<'tcx> for TransferFunction<'_, '_, 'tcx> { self.super_terminator(terminator, location); if let mir::TerminatorKind::Drop { location: _, .. } - | mir::TerminatorKind::DropAndReplace { location: _, .. } = &terminator.kind + | mir::TerminatorKind::DropAndReplace { location: _, .. } = &terminator.kind { // Although drop terminators mutably borrow the location being dropped, that borrow // cannot live beyond the drop terminator because the dropped location is invalidated. diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs index 0fb912b5fcbd8..6b66406338d1e 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/src/librustc_mir/dataflow/impls/mod.rs @@ -2,8 +2,8 @@ //! bitvectors attached to each basic block, represented via a //! zero-sized structure. -use rustc::ty::TyCtxt; use rustc::mir::{self, Body, Location}; +use rustc::ty::TyCtxt; use rustc_index::bit_set::BitSet; use rustc_index::vec::Idx; @@ -11,7 +11,7 @@ use super::MoveDataParamEnv; use crate::util::elaborate_drops::DropFlagState; -use super::move_paths::{HasMoveData, MoveData, MovePathIndex, InitIndex, InitKind}; +use super::move_paths::{HasMoveData, InitIndex, InitKind, MoveData, MovePathIndex}; use super::{BitDenotation, BottomValue, GenKillSet}; use super::drop_flag_effects_for_function_entry; @@ -76,7 +76,9 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { } impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> { - fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data } + fn move_data(&self) -> &MoveData<'tcx> { + &self.mdpe.move_data + } } /// `MaybeUninitializedPlaces` tracks all places that might be @@ -127,7 +129,9 @@ impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> { } impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> { - fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data } + fn move_data(&self) -> &MoveData<'tcx> { + &self.mdpe.move_data + } } /// `DefinitelyInitializedPlaces` tracks all places that are definitely @@ -177,7 +181,9 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> { } impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { - fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data } + fn move_data(&self) -> &MoveData<'tcx> { + &self.mdpe.move_data + } } /// `EverInitializedPlaces` tracks all places that might have ever been @@ -222,14 +228,17 @@ impl<'a, 'tcx> EverInitializedPlaces<'a, 'tcx> { } impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, 'tcx> { - fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data } + fn move_data(&self) -> &MoveData<'tcx> { + &self.mdpe.move_data + } } impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { - fn update_bits(trans: &mut GenKillSet, - path: MovePathIndex, - state: DropFlagState) - { + fn update_bits( + trans: &mut GenKillSet, + path: MovePathIndex, + state: DropFlagState, + ) { match state { DropFlagState::Absent => trans.kill(path), DropFlagState::Present => trans.gen(path), @@ -238,10 +247,11 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { } impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> { - fn update_bits(trans: &mut GenKillSet, - path: MovePathIndex, - state: DropFlagState) - { + fn update_bits( + trans: &mut GenKillSet, + path: MovePathIndex, + state: DropFlagState, + ) { match state { DropFlagState::Absent => trans.gen(path), DropFlagState::Present => trans.kill(path), @@ -250,10 +260,11 @@ impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> { } impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> { - fn update_bits(trans: &mut GenKillSet, - path: MovePathIndex, - state: DropFlagState) - { + fn update_bits( + trans: &mut GenKillSet, + path: MovePathIndex, + state: DropFlagState, + ) { match state { DropFlagState::Absent => trans.kill(path), DropFlagState::Present => trans.gen(path), @@ -263,40 +274,30 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> { impl<'a, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'tcx> { type Idx = MovePathIndex; - fn name() -> &'static str { "maybe_init" } + fn name() -> &'static str { + "maybe_init" + } fn bits_per_block(&self) -> usize { self.move_data().move_paths.len() } fn start_block_effect(&self, entry_set: &mut BitSet) { - drop_flag_effects_for_function_entry( - self.tcx, self.body, self.mdpe, - |path, s| { - assert!(s == DropFlagState::Present); - entry_set.insert(path); - }); - } - - fn statement_effect(&self, - trans: &mut GenKillSet, - location: Location) - { - drop_flag_effects_for_location( - self.tcx, self.body, self.mdpe, - location, - |path, s| Self::update_bits(trans, path, s) - ) - } - - fn terminator_effect(&self, - trans: &mut GenKillSet, - location: Location) - { - drop_flag_effects_for_location( - self.tcx, self.body, self.mdpe, - location, - |path, s| Self::update_bits(trans, path, s) - ) + drop_flag_effects_for_function_entry(self.tcx, self.body, self.mdpe, |path, s| { + assert!(s == DropFlagState::Present); + entry_set.insert(path); + }); + } + + fn statement_effect(&self, trans: &mut GenKillSet, location: Location) { + drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| { + Self::update_bits(trans, path, s) + }) + } + + fn terminator_effect(&self, trans: &mut GenKillSet, location: Location) { + drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| { + Self::update_bits(trans, path, s) + }) } fn propagate_call_return( @@ -308,15 +309,23 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'tcx> { ) { // when a call returns successfully, that means we need to set // the bits for that dest_place to 1 (initialized). - on_lookup_result_bits(self.tcx, self.body, self.move_data(), - self.move_data().rev_lookup.find(dest_place.as_ref()), - |mpi| { in_out.insert(mpi); }); + on_lookup_result_bits( + self.tcx, + self.body, + self.move_data(), + self.move_data().rev_lookup.find(dest_place.as_ref()), + |mpi| { + in_out.insert(mpi); + }, + ); } } impl<'a, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> { type Idx = MovePathIndex; - fn name() -> &'static str { "maybe_uninit" } + fn name() -> &'static str { + "maybe_uninit" + } fn bits_per_block(&self) -> usize { self.move_data().move_paths.len() } @@ -327,34 +336,22 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> { assert!(self.bits_per_block() == entry_set.domain_size()); entry_set.insert_all(); - drop_flag_effects_for_function_entry( - self.tcx, self.body, self.mdpe, - |path, s| { - assert!(s == DropFlagState::Present); - entry_set.remove(path); - }); + drop_flag_effects_for_function_entry(self.tcx, self.body, self.mdpe, |path, s| { + assert!(s == DropFlagState::Present); + entry_set.remove(path); + }); } - fn statement_effect(&self, - trans: &mut GenKillSet, - location: Location) - { - drop_flag_effects_for_location( - self.tcx, self.body, self.mdpe, - location, - |path, s| Self::update_bits(trans, path, s) - ) + fn statement_effect(&self, trans: &mut GenKillSet, location: Location) { + drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| { + Self::update_bits(trans, path, s) + }) } - fn terminator_effect(&self, - trans: &mut GenKillSet, - location: Location) - { - drop_flag_effects_for_location( - self.tcx, self.body, self.mdpe, - location, - |path, s| Self::update_bits(trans, path, s) - ) + fn terminator_effect(&self, trans: &mut GenKillSet, location: Location) { + drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| { + Self::update_bits(trans, path, s) + }) } fn propagate_call_return( @@ -366,15 +363,23 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> { ) { // when a call returns successfully, that means we need to set // the bits for that dest_place to 0 (initialized). - on_lookup_result_bits(self.tcx, self.body, self.move_data(), - self.move_data().rev_lookup.find(dest_place.as_ref()), - |mpi| { in_out.remove(mpi); }); + on_lookup_result_bits( + self.tcx, + self.body, + self.move_data(), + self.move_data().rev_lookup.find(dest_place.as_ref()), + |mpi| { + in_out.remove(mpi); + }, + ); } } impl<'a, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { type Idx = MovePathIndex; - fn name() -> &'static str { "definite_init" } + fn name() -> &'static str { + "definite_init" + } fn bits_per_block(&self) -> usize { self.move_data().move_paths.len() } @@ -383,34 +388,22 @@ impl<'a, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { fn start_block_effect(&self, entry_set: &mut BitSet) { entry_set.clear(); - drop_flag_effects_for_function_entry( - self.tcx, self.body, self.mdpe, - |path, s| { - assert!(s == DropFlagState::Present); - entry_set.insert(path); - }); + drop_flag_effects_for_function_entry(self.tcx, self.body, self.mdpe, |path, s| { + assert!(s == DropFlagState::Present); + entry_set.insert(path); + }); } - fn statement_effect(&self, - trans: &mut GenKillSet, - location: Location) - { - drop_flag_effects_for_location( - self.tcx, self.body, self.mdpe, - location, - |path, s| Self::update_bits(trans, path, s) - ) + fn statement_effect(&self, trans: &mut GenKillSet, location: Location) { + drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| { + Self::update_bits(trans, path, s) + }) } - fn terminator_effect(&self, - trans: &mut GenKillSet, - location: Location) - { - drop_flag_effects_for_location( - self.tcx, self.body, self.mdpe, - location, - |path, s| Self::update_bits(trans, path, s) - ) + fn terminator_effect(&self, trans: &mut GenKillSet, location: Location) { + drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| { + Self::update_bits(trans, path, s) + }) } fn propagate_call_return( @@ -422,15 +415,23 @@ impl<'a, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { ) { // when a call returns successfully, that means we need to set // the bits for that dest_place to 1 (initialized). - on_lookup_result_bits(self.tcx, self.body, self.move_data(), - self.move_data().rev_lookup.find(dest_place.as_ref()), - |mpi| { in_out.insert(mpi); }); + on_lookup_result_bits( + self.tcx, + self.body, + self.move_data(), + self.move_data().rev_lookup.find(dest_place.as_ref()), + |mpi| { + in_out.insert(mpi); + }, + ); } } impl<'a, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'tcx> { type Idx = InitIndex; - fn name() -> &'static str { "ever_init" } + fn name() -> &'static str { + "ever_init" + } fn bits_per_block(&self) -> usize { self.move_data().inits.len() } @@ -441,17 +442,17 @@ impl<'a, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'tcx> { } } - fn statement_effect(&self, - trans: &mut GenKillSet, - location: Location) { + fn statement_effect(&self, trans: &mut GenKillSet, location: Location) { let (_, body, move_data) = (self.tcx, self.body, self.move_data()); let stmt = &body[location.block].statements[location.statement_index]; let init_path_map = &move_data.init_path_map; let init_loc_map = &move_data.init_loc_map; let rev_lookup = &move_data.rev_lookup; - debug!("statement {:?} at loc {:?} initializes move_indexes {:?}", - stmt, location, &init_loc_map[location]); + debug!( + "statement {:?} at loc {:?} initializes move_indexes {:?}", + stmt, location, &init_loc_map[location] + ); trans.gen_all(&init_loc_map[location]); match stmt.kind { @@ -459,27 +460,28 @@ impl<'a, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'tcx> { // End inits for StorageDead, so that an immutable variable can // be reinitialized on the next iteration of the loop. let move_path_index = rev_lookup.find_local(local); - debug!("stmt {:?} at loc {:?} clears the ever initialized status of {:?}", - stmt, location, &init_path_map[move_path_index]); + debug!( + "stmt {:?} at loc {:?} clears the ever initialized status of {:?}", + stmt, location, &init_path_map[move_path_index] + ); trans.kill_all(&init_path_map[move_path_index]); } _ => {} } } - fn terminator_effect(&self, - trans: &mut GenKillSet, - location: Location) - { + fn terminator_effect(&self, trans: &mut GenKillSet, location: Location) { let (body, move_data) = (self.body, self.move_data()); let term = body[location.block].terminator(); let init_loc_map = &move_data.init_loc_map; - debug!("terminator {:?} at loc {:?} initializes move_indexes {:?}", - term, location, &init_loc_map[location]); + debug!( + "terminator {:?} at loc {:?} initializes move_indexes {:?}", + term, location, &init_loc_map[location] + ); trans.gen_all( init_loc_map[location].iter().filter(|init_index| { move_data.inits[**init_index].kind != InitKind::NonPanicPathOnly - }) + }), ); } @@ -494,10 +496,8 @@ impl<'a, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'tcx> { let bits_per_block = self.bits_per_block(); let init_loc_map = &move_data.init_loc_map; - let call_loc = Location { - block: call_bb, - statement_index: self.body[call_bb].statements.len(), - }; + let call_loc = + Location { block: call_bb, statement_index: self.body[call_bb].statements.len() }; for init_index in &init_loc_map[call_loc] { assert!(init_index.index() < bits_per_block); in_out.insert(*init_index); diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs index b8abe6d70edbd..17f71e83cfd21 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs @@ -1,13 +1,11 @@ pub use super::*; -use rustc::mir::*; -use rustc::mir::visit::{ - PlaceContext, Visitor, NonMutatingUseContext, -}; -use std::cell::RefCell; use crate::dataflow::BitDenotation; use crate::dataflow::HaveBeenBorrowedLocals; use crate::dataflow::{DataflowResults, DataflowResultsCursor, DataflowResultsRefCursor}; +use rustc::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; +use rustc::mir::*; +use std::cell::RefCell; #[derive(Copy, Clone)] pub struct MaybeStorageLive<'a, 'tcx> { @@ -15,8 +13,7 @@ pub struct MaybeStorageLive<'a, 'tcx> { } impl<'a, 'tcx> MaybeStorageLive<'a, 'tcx> { - pub fn new(body: &'a Body<'tcx>) - -> Self { + pub fn new(body: &'a Body<'tcx>) -> Self { MaybeStorageLive { body } } @@ -27,7 +24,9 @@ impl<'a, 'tcx> MaybeStorageLive<'a, 'tcx> { impl<'a, 'tcx> BitDenotation<'tcx> for MaybeStorageLive<'a, 'tcx> { type Idx = Local; - fn name() -> &'static str { "maybe_storage_live" } + fn name() -> &'static str { + "maybe_storage_live" + } fn bits_per_block(&self) -> usize { self.body.local_decls.len() } @@ -38,9 +37,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeStorageLive<'a, 'tcx> { assert_eq!(1, self.body.arg_count); } - fn statement_effect(&self, - trans: &mut GenKillSet, - loc: Location) { + fn statement_effect(&self, trans: &mut GenKillSet, loc: Location) { let stmt = &self.body[loc.block].statements[loc.statement_index]; match stmt.kind { @@ -50,9 +47,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeStorageLive<'a, 'tcx> { } } - fn terminator_effect(&self, - _trans: &mut GenKillSet, - _loc: Location) { + fn terminator_effect(&self, _trans: &mut GenKillSet, _loc: Location) { // Terminators have no effect } @@ -87,9 +82,7 @@ impl<'mir, 'tcx: 'mir> RequiresStorage<'mir, 'tcx> { ) -> Self { RequiresStorage { body, - borrowed_locals: RefCell::new( - DataflowResultsCursor::new(borrowed_locals, *body) - ), + borrowed_locals: RefCell::new(DataflowResultsCursor::new(borrowed_locals, *body)), } } @@ -100,7 +93,9 @@ impl<'mir, 'tcx: 'mir> RequiresStorage<'mir, 'tcx> { impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { type Idx = Local; - fn name() -> &'static str { "requires_storage" } + fn name() -> &'static str { + "requires_storage" + } fn bits_per_block(&self) -> usize { self.body.local_decls.len() } @@ -119,7 +114,7 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { let stmt = &self.body[loc.block].statements[loc.statement_index]; match stmt.kind { StatementKind::StorageDead(l) => sets.kill(l), - StatementKind::Assign(box(ref place, _)) + StatementKind::Assign(box (ref place, _)) | StatementKind::SetDiscriminant { box ref place, .. } => { if let PlaceBase::Local(local) = place.base { sets.gen(local); @@ -148,7 +143,8 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { if let TerminatorKind::Call { destination: Some((Place { base: PlaceBase::Local(local), .. }, _)), .. - } = self.body[loc.block].terminator().kind { + } = self.body[loc.block].terminator().kind + { sets.gen(local); } } @@ -158,10 +154,9 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { // and after the call returns successfully, but not after a panic. // Since `propagate_call_unwind` doesn't exist, we have to kill the // destination here, and then gen it again in `propagate_call_return`. - if let TerminatorKind::Call { - destination: Some((ref place, _)), - .. - } = self.body[loc.block].terminator().kind { + if let TerminatorKind::Call { destination: Some((ref place, _)), .. } = + self.body[loc.block].terminator().kind + { if let Some(local) = place.as_local() { sets.kill(local); } @@ -185,10 +180,7 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> { impl<'mir, 'tcx> RequiresStorage<'mir, 'tcx> { /// Kill locals that are fully moved and have not been borrowed. fn check_for_move(&self, sets: &mut GenKillSet, loc: Location) { - let mut visitor = MoveVisitor { - sets, - borrowed_locals: &self.borrowed_locals, - }; + let mut visitor = MoveVisitor { sets, borrowed_locals: &self.borrowed_locals }; visitor.visit_location(self.body, loc); } diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index ad0f75d772548..fe18f6066bf72 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -1,16 +1,16 @@ use syntax::ast::{self, MetaItem}; use syntax::print::pprust; -use syntax::symbol::{Symbol, sym}; +use syntax::symbol::{sym, Symbol}; +use rustc_data_structures::work_queue::WorkQueue; use rustc_index::bit_set::{BitSet, HybridBitSet}; use rustc_index::vec::Idx; -use rustc_data_structures::work_queue::WorkQueue; use rustc::hir::def_id::DefId; -use rustc::ty::{self, TyCtxt}; -use rustc::mir::{self, Body, BasicBlock, BasicBlockData, Location, Statement, Terminator}; use rustc::mir::traversal; +use rustc::mir::{self, BasicBlock, BasicBlockData, Body, Location, Statement, Terminator}; use rustc::session::Session; +use rustc::ty::{self, TyCtxt}; use std::borrow::Borrow; use std::fmt; @@ -18,15 +18,15 @@ use std::io; use std::path::PathBuf; use std::usize; -pub use self::impls::{MaybeStorageLive, RequiresStorage}; -pub use self::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; +pub use self::at_location::{FlowAtLocation, FlowsAtLocation}; +pub(crate) use self::drop_flag_effects::*; +pub use self::impls::borrows::Borrows; pub use self::impls::DefinitelyInitializedPlaces; pub use self::impls::EverInitializedPlaces; -pub use self::impls::borrows::Borrows; pub use self::impls::HaveBeenBorrowedLocals; pub use self::impls::IndirectlyMutableLocals; -pub use self::at_location::{FlowAtLocation, FlowsAtLocation}; -pub(crate) use self::drop_flag_effects::*; +pub use self::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; +pub use self::impls::{MaybeStorageLive, RequiresStorage}; use self::move_paths::MoveData; @@ -39,8 +39,8 @@ pub mod move_paths; pub(crate) mod indexes { pub(crate) use super::{ - move_paths::{MovePathIndex, MoveOutIndex, InitIndex}, impls::borrows::BorrowIndex, + move_paths::{InitIndex, MoveOutIndex, MovePathIndex}, }; } @@ -76,7 +76,10 @@ impl fmt::Debug for DebugFormatted { pub trait Dataflow<'tcx, BD: BitDenotation<'tcx>> { /// Sets up and runs the dataflow problem, using `p` to render results if /// implementation so chooses. - fn dataflow

(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> DebugFormatted { + fn dataflow

(&mut self, p: P) + where + P: Fn(&BD, BD::Idx) -> DebugFormatted, + { let _ = p; // default implementation does not instrument process. self.build_sets(); self.propagate(); @@ -93,15 +96,22 @@ impl<'a, 'tcx, BD> Dataflow<'tcx, BD> for DataflowBuilder<'a, 'tcx, BD> where BD: BitDenotation<'tcx>, { - fn dataflow

(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> DebugFormatted { + fn dataflow

(&mut self, p: P) + where + P: Fn(&BD, BD::Idx) -> DebugFormatted, + { self.flow_state.build_sets(); - self.pre_dataflow_instrumentation(|c,i| p(c,i)).unwrap(); + self.pre_dataflow_instrumentation(|c, i| p(c, i)).unwrap(); self.flow_state.propagate(); - self.post_dataflow_instrumentation(|c,i| p(c,i)).unwrap(); + self.post_dataflow_instrumentation(|c, i| p(c, i)).unwrap(); } - fn build_sets(&mut self) { self.flow_state.build_sets(); } - fn propagate(&mut self) { self.flow_state.propagate(); } + fn build_sets(&mut self) { + self.flow_state.build_sets(); + } + fn propagate(&mut self) { + self.flow_state.propagate(); + } } pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: Symbol) -> Option { @@ -111,7 +121,7 @@ pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: Symbol) -> Opti for item in items.iter().flat_map(|l| l.iter()) { match item.meta_item() { Some(mi) if mi.check_name(name) => return Some(mi.clone()), - _ => continue + _ => continue, } } } @@ -158,7 +168,7 @@ where let name_found = |sess: &Session, attrs: &[ast::Attribute], name| -> Option { if let Some(item) = has_rustc_mir_with(attrs, name) { if let Some(s) = item.value_str() { - return Some(s.to_string()) + return Some(s.to_string()); } else { let path = pprust::path_to_string(&item.path); sess.span_err(item.span, &format!("{} attribute requires a path", path)); @@ -171,10 +181,8 @@ where let print_preflow_to = name_found(tcx.sess, attributes, sym::borrowck_graphviz_preflow); let print_postflow_to = name_found(tcx.sess, attributes, sym::borrowck_graphviz_postflow); - let mut mbcx = DataflowBuilder { - def_id, - print_preflow_to, print_postflow_to, flow_state: self, - }; + let mut mbcx = + DataflowBuilder { def_id, print_preflow_to, print_postflow_to, flow_state: self }; mbcx.dataflow(p); mbcx.flow_state.results() @@ -194,9 +202,7 @@ where { fn propagate(&mut self) { let mut temp = BitSet::new_empty(self.flow_state.sets.bits_per_block); - let mut propcx = PropagationContext { - builder: self, - }; + let mut propcx = PropagationContext { builder: self }; propcx.walk_cfg(&mut temp); } @@ -257,7 +263,10 @@ where let bb_data = &body[bb]; self.builder.propagate_bits_into_graph_successors_of( - in_out, (bb, bb_data), &mut dirty_queue); + in_out, + (bb, bb_data), + &mut dirty_queue, + ); } } } @@ -277,7 +286,8 @@ where BD: BitDenotation<'tcx>, { fn pre_dataflow_instrumentation

(&self, p: P) -> io::Result<()> - where P: Fn(&BD, BD::Idx) -> DebugFormatted + where + P: Fn(&BD, BD::Idx) -> DebugFormatted, { if let Some(ref path_str) = self.print_preflow_to { let path = dataflow_path(BD::name(), path_str); @@ -288,7 +298,8 @@ where } fn post_dataflow_instrumentation

(&self, p: P) -> io::Result<()> - where P: Fn(&BD, BD::Idx) -> DebugFormatted + where + P: Fn(&BD, BD::Idx) -> DebugFormatted, { if let Some(ref path_str) = self.print_postflow_to { let path = dataflow_path(BD::name(), path_str); @@ -310,19 +321,23 @@ pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> { type FlowState: FlowsAtLocation; // Observation Hooks: override (at least one of) these to get analysis feedback. - fn visit_block_entry(&mut self, - _bb: BasicBlock, - _flow_state: &Self::FlowState) {} + fn visit_block_entry(&mut self, _bb: BasicBlock, _flow_state: &Self::FlowState) {} - fn visit_statement_entry(&mut self, - _loc: Location, - _stmt: &'a Statement<'tcx>, - _flow_state: &Self::FlowState) {} + fn visit_statement_entry( + &mut self, + _loc: Location, + _stmt: &'a Statement<'tcx>, + _flow_state: &Self::FlowState, + ) { + } - fn visit_terminator_entry(&mut self, - _loc: Location, - _term: &'a Terminator<'tcx>, - _flow_state: &Self::FlowState) {} + fn visit_terminator_entry( + &mut self, + _loc: Location, + _term: &'a Terminator<'tcx>, + _flow_state: &Self::FlowState, + ) { + } // Main entry point: this drives the processing of results. @@ -337,8 +352,7 @@ pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> { fn process_basic_block(&mut self, bb: BasicBlock, flow_state: &mut Self::FlowState) { self.visit_block_entry(bb, flow_state); - let BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = - self.body()[bb]; + let BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = self.body()[bb]; let mut location = Location { block: bb, statement_index: 0 }; for stmt in statements.iter() { flow_state.reconstruct_statement_effect(location); @@ -388,11 +402,7 @@ where DR: Borrow>, { pub fn new(result: DR, body: &'mir Body<'tcx>) -> Self { - DataflowResultsCursor { - flow_state: FlowAtLocation::new(result), - curr_loc: None, - body, - } + DataflowResultsCursor { flow_state: FlowAtLocation::new(result), curr_loc: None, body } } /// Seek to the given location in MIR. This method is fast if you are @@ -414,8 +424,9 @@ where let start_index; let should_reset = match self.curr_loc { None => true, - Some(cur) - if loc.block != cur.block || loc.statement_index < cur.statement_index => true, + Some(cur) if loc.block != cur.block || loc.statement_index < cur.statement_index => { + true + } _ => false, }; if should_reset { @@ -478,10 +489,14 @@ where DataflowResults(self.flow_state) } - pub fn body(&self) -> &'a Body<'tcx> { self.body } + pub fn body(&self) -> &'a Body<'tcx> { + self.body + } } -pub struct DataflowResults<'tcx, O>(pub(crate) DataflowState<'tcx, O>) where O: BitDenotation<'tcx>; +pub struct DataflowResults<'tcx, O>(pub(crate) DataflowState<'tcx, O>) +where + O: BitDenotation<'tcx>; impl<'tcx, O: BitDenotation<'tcx>> DataflowResults<'tcx, O> { pub fn sets(&self) -> &AllSets { @@ -495,8 +510,7 @@ impl<'tcx, O: BitDenotation<'tcx>> DataflowResults<'tcx, O> { /// State of a dataflow analysis; couples a collection of bit sets /// with operator used to initialize and merge bits during analysis. -pub struct DataflowState<'tcx, O: BitDenotation<'tcx>> -{ +pub struct DataflowState<'tcx, O: BitDenotation<'tcx>> { /// All the sets for the analysis. (Factored into its /// own structure so that we can borrow it mutably /// on its own separate from other fields.) @@ -507,22 +521,26 @@ pub struct DataflowState<'tcx, O: BitDenotation<'tcx>> } impl<'tcx, O: BitDenotation<'tcx>> DataflowState<'tcx, O> { - pub(crate) fn interpret_set<'c, P>(&self, - o: &'c O, - set: &BitSet, - render_idx: &P) - -> Vec - where P: Fn(&O, O::Idx) -> DebugFormatted + pub(crate) fn interpret_set<'c, P>( + &self, + o: &'c O, + set: &BitSet, + render_idx: &P, + ) -> Vec + where + P: Fn(&O, O::Idx) -> DebugFormatted, { set.iter().map(|i| render_idx(o, i)).collect() } - pub(crate) fn interpret_hybrid_set<'c, P>(&self, - o: &'c O, - set: &HybridBitSet, - render_idx: &P) - -> Vec - where P: Fn(&O, O::Idx) -> DebugFormatted + pub(crate) fn interpret_hybrid_set<'c, P>( + &self, + o: &'c O, + set: &HybridBitSet, + render_idx: &P, + ) -> Vec + where + P: Fn(&O, O::Idx) -> DebugFormatted, { set.iter().map(|i| render_idx(o, i)).collect() } @@ -548,16 +566,14 @@ pub type GenKillSet = GenKill>; impl GenKill { /// Creates a new tuple where `gen_set == kill_set == elem`. pub(crate) fn from_elem(elem: T) -> Self - where T: Clone + where + T: Clone, { - GenKill { - gen_set: elem.clone(), - kill_set: elem, - } + GenKill { gen_set: elem.clone(), kill_set: elem } } } -impl GenKillSet { +impl GenKillSet { pub fn clear(&mut self) { self.gen_set.clear(); self.kill_set.clear(); @@ -608,8 +624,10 @@ pub struct AllSets { trans: Vec>, } -impl AllSets { - pub fn bits_per_block(&self) -> usize { self.bits_per_block } +impl AllSets { + pub fn bits_per_block(&self) -> usize { + self.bits_per_block + } pub fn get_mut(&mut self, block_idx: usize) -> (&mut BitSet, &mut GenKillSet) { (&mut self.on_entry[block_idx], &mut self.trans[block_idx]) @@ -703,9 +721,7 @@ pub trait BitDenotation<'tcx>: BottomValue { /// Both the before-statement and after-statement effects are /// applied, in that order, before moving for the next /// statement. - fn before_statement_effect(&self, - _trans: &mut GenKillSet, - _location: Location) {} + fn before_statement_effect(&self, _trans: &mut GenKillSet, _location: Location) {} /// Mutates the block-sets (the flow sets for the given /// basic block) according to the effects of evaluating statement. @@ -717,9 +733,7 @@ pub trait BitDenotation<'tcx>: BottomValue { /// The statement is identified as `bb_data[idx_stmt]`, where /// `bb_data` is the sequence of statements identified by `bb` in /// the MIR. - fn statement_effect(&self, - trans: &mut GenKillSet, - location: Location); + fn statement_effect(&self, trans: &mut GenKillSet, location: Location); /// Similar to `terminator_effect`, except it applies /// *just before* the terminator rather than *just after* it. @@ -732,9 +746,7 @@ pub trait BitDenotation<'tcx>: BottomValue { /// Both the before-terminator and after-terminator effects are /// applied, in that order, before moving for the next /// terminator. - fn before_terminator_effect(&self, - _trans: &mut GenKillSet, - _location: Location) {} + fn before_terminator_effect(&self, _trans: &mut GenKillSet, _location: Location) {} /// Mutates the block-sets (the flow sets for the given /// basic block) according to the effects of evaluating @@ -746,9 +758,7 @@ pub trait BitDenotation<'tcx>: BottomValue { /// /// The effects applied here cannot depend on which branch the /// terminator took. - fn terminator_effect(&self, - trans: &mut GenKillSet, - location: Location); + fn terminator_effect(&self, trans: &mut GenKillSet, location: Location); /// Mutates the block-sets according to the (flow-dependent) /// effect of a successful return from a Call terminator. @@ -778,11 +788,15 @@ pub trait BitDenotation<'tcx>: BottomValue { ); } -impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation<'tcx> +impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> +where + D: BitDenotation<'tcx>, { - pub fn new(body: &'a Body<'tcx>, - dead_unwinds: &'a BitSet, - denotation: D) -> Self { + pub fn new( + body: &'a Body<'tcx>, + dead_unwinds: &'a BitSet, + denotation: D, + ) -> Self { let bits_per_block = denotation.bits_per_block(); let num_blocks = body.basic_blocks().len(); @@ -797,13 +811,9 @@ impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation<'tcx> body, dead_unwinds, flow_state: DataflowState { - sets: AllSets { - bits_per_block, - on_entry, - trans: vec![nop; num_blocks], - }, + sets: AllSets { bits_per_block, on_entry, trans: vec![nop; num_blocks] }, operator: denotation, - } + }, } } } @@ -829,31 +839,33 @@ where &mut self, in_out: &mut BitSet, (bb, bb_data): (mir::BasicBlock, &mir::BasicBlockData<'tcx>), - dirty_list: &mut WorkQueue) - { + dirty_list: &mut WorkQueue, + ) { match bb_data.terminator().kind { - mir::TerminatorKind::Return | - mir::TerminatorKind::Resume | - mir::TerminatorKind::Abort | - mir::TerminatorKind::GeneratorDrop | - mir::TerminatorKind::Unreachable => {} - mir::TerminatorKind::Goto { target } | - mir::TerminatorKind::Assert { target, cleanup: None, .. } | - mir::TerminatorKind::Yield { resume: target, drop: None, .. } | - mir::TerminatorKind::Drop { target, location: _, unwind: None } | - mir::TerminatorKind::DropAndReplace { - target, value: _, location: _, unwind: None - } => { + mir::TerminatorKind::Return + | mir::TerminatorKind::Resume + | mir::TerminatorKind::Abort + | mir::TerminatorKind::GeneratorDrop + | mir::TerminatorKind::Unreachable => {} + mir::TerminatorKind::Goto { target } + | mir::TerminatorKind::Assert { target, cleanup: None, .. } + | mir::TerminatorKind::Yield { resume: target, drop: None, .. } + | mir::TerminatorKind::Drop { target, location: _, unwind: None } + | mir::TerminatorKind::DropAndReplace { target, value: _, location: _, unwind: None } => + { self.propagate_bits_into_entry_set_for(in_out, target, dirty_list); } mir::TerminatorKind::Yield { resume: target, drop: Some(drop), .. } => { self.propagate_bits_into_entry_set_for(in_out, target, dirty_list); self.propagate_bits_into_entry_set_for(in_out, drop, dirty_list); } - mir::TerminatorKind::Assert { target, cleanup: Some(unwind), .. } | - mir::TerminatorKind::Drop { target, location: _, unwind: Some(unwind) } | - mir::TerminatorKind::DropAndReplace { - target, value: _, location: _, unwind: Some(unwind) + mir::TerminatorKind::Assert { target, cleanup: Some(unwind), .. } + | mir::TerminatorKind::Drop { target, location: _, unwind: Some(unwind) } + | mir::TerminatorKind::DropAndReplace { + target, + value: _, + location: _, + unwind: Some(unwind), } => { self.propagate_bits_into_entry_set_for(in_out, target, dirty_list); if !self.dead_unwinds.contains(bb) { @@ -874,8 +886,7 @@ where if let Some((ref dest_place, dest_bb)) = *destination { // N.B.: This must be done *last*, after all other // propagation, as documented in comment above. - self.flow_state.operator.propagate_call_return( - in_out, bb, dest_bb, dest_place); + self.flow_state.operator.propagate_call_return(in_out, bb, dest_bb, dest_place); self.propagate_bits_into_entry_set_for(in_out, dest_bb, dirty_list); } } @@ -894,10 +905,12 @@ where } } - fn propagate_bits_into_entry_set_for(&mut self, - in_out: &BitSet, - bb: mir::BasicBlock, - dirty_queue: &mut WorkQueue) { + fn propagate_bits_into_entry_set_for( + &mut self, + in_out: &BitSet, + bb: mir::BasicBlock, + dirty_queue: &mut WorkQueue, + ) { let entry_set = self.flow_state.sets.entry_set_mut_for(bb.index()); let set_changed = self.flow_state.operator.join(entry_set, &in_out); if set_changed { diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index 0b8f41f51a1ee..c05f7f8959dbf 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -117,7 +117,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { let place_ty = Place::ty_from(&place.base, proj_base, body, tcx).ty; match place_ty.kind { ty::Ref(..) | ty::RawPtr(..) => { - let proj = &place.projection[..i+1]; + let proj = &place.projection[..i + 1]; return Err(MoveError::cannot_move_out_of( self.loc, BorrowedContent { @@ -162,11 +162,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { }; if union_path.is_none() { - base = self.add_move_path(base, elem, |tcx| { - Place { - base: place.base.clone(), - projection: tcx.intern_place_elems(&place.projection[..i+1]), - } + base = self.add_move_path(base, elem, |tcx| Place { + base: place.base.clone(), + projection: tcx.intern_place_elems(&place.projection[..i + 1]), }); } } @@ -190,18 +188,16 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { tcx, .. } = self.builder; - *rev_lookup.projections - .entry((base, elem.lift())) - .or_insert_with(move || { - let path = MoveDataBuilder::new_move_path( - move_paths, - path_map, - init_path_map, - Some(base), - mk_place(*tcx), - ); - path - }) + *rev_lookup.projections.entry((base, elem.lift())).or_insert_with(move || { + let path = MoveDataBuilder::new_move_path( + move_paths, + path_map, + init_path_map, + Some(base), + mk_place(*tcx), + ); + path + }) } fn create_move_path(&mut self, place: &Place<'tcx>) { @@ -289,7 +285,7 @@ struct Gatherer<'b, 'a, 'tcx> { impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { fn gather_statement(&mut self, stmt: &Statement<'tcx>) { match stmt.kind { - StatementKind::Assign(box(ref place, ref rval)) => { + StatementKind::Assign(box (ref place, ref rval)) => { self.create_move_path(place); if let RvalueInitializationState::Shallow = rval.initialization_state() { // Box starts out uninitialized - need to create a separate @@ -433,10 +429,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { fn gather_move(&mut self, place: &Place<'tcx>) { debug!("gather_move({:?}, {:?})", self.loc, place); - if let [ - ref base @ .., - ProjectionElem::Subslice { from, to, from_end: false }, - ] = **place.projection { + if let [ref base @ .., ProjectionElem::Subslice { from, to, from_end: false }] = + **place.projection + { // Split `Subslice` patterns into the corresponding list of // `ConstIndex` patterns. This is done to ensure that all move paths // are disjoint, which is expected by drop elaboration. @@ -459,23 +454,18 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { let len: u32 = match base_ty.kind { ty::Array(_, size) => { let length = size.eval_usize(self.builder.tcx, self.builder.param_env); - length.try_into().expect( - "slice pattern of array with more than u32::MAX elements" - ) + length + .try_into() + .expect("slice pattern of array with more than u32::MAX elements") } _ => bug!("from_end: false slice pattern of non-array type"), }; for offset in from..to { - let elem = ProjectionElem::ConstantIndex { - offset, - min_length: len, - from_end: false, - }; - let path = self.add_move_path( - base_path, - &elem, - |tcx| tcx.mk_place_elem(base_place.clone(), elem), - ); + let elem = + ProjectionElem::ConstantIndex { offset, min_length: len, from_end: false }; + let path = self.add_move_path(base_path, &elem, |tcx| { + tcx.mk_place_elem(base_place.clone(), elem) + }); self.record_move(place, path); } } else { diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 89ef9b245ce8f..436b3ca055dd4 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -1,6 +1,6 @@ use core::slice::Iter; use rustc::mir::*; -use rustc::ty::{Ty, TyCtxt, ParamEnv}; +use rustc::ty::{ParamEnv, Ty, TyCtxt}; use rustc::util::nodemap::FxHashMap; use rustc_index::vec::{Enumerated, Idx, IndexVec}; use smallvec::SmallVec; diff --git a/src/librustc_mir/hair/constant.rs b/src/librustc_mir/hair/constant.rs index 1abdcde10ab0f..cb7e02031c40c 100644 --- a/src/librustc_mir/hair/constant.rs +++ b/src/librustc_mir/hair/constant.rs @@ -1,7 +1,7 @@ +use rustc::mir::interpret::{ConstValue, Scalar}; +use rustc::ty::{self, layout::Size, ParamEnv, Ty, TyCtxt}; use syntax::ast; -use rustc::ty::{self, Ty, TyCtxt, ParamEnv, layout::Size}; use syntax_pos::symbol::Symbol; -use rustc::mir::interpret::{ConstValue, Scalar}; #[derive(PartialEq)] crate enum LitToConstError { @@ -33,22 +33,22 @@ crate fn lit_to_const<'tcx>( let allocation = Allocation::from_byte_aligned_bytes(s.as_bytes()); let allocation = tcx.intern_const_alloc(allocation); ConstValue::Slice { data: allocation, start: 0, end: s.len() } - }, + } LitKind::ByteStr(ref data) => { let id = tcx.allocate_bytes(data); ConstValue::Scalar(Scalar::Ptr(id.into())) - }, + } LitKind::Byte(n) => ConstValue::Scalar(Scalar::from_uint(n, Size::from_bytes(1))), LitKind::Int(n, _) if neg => { let n = n as i128; let n = n.overflowing_neg().0; trunc(n as u128)? - }, + } LitKind::Int(n, _) => trunc(n)?, LitKind::Float(n, _) => { let fty = match ty.kind { ty::Float(fty) => fty, - _ => bug!() + _ => bug!(), }; parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)? } @@ -59,13 +59,9 @@ crate fn lit_to_const<'tcx>( Ok(tcx.mk_const(ty::Const { val: ty::ConstKind::Value(lit), ty })) } -fn parse_float<'tcx>( - num: Symbol, - fty: ast::FloatTy, - neg: bool, -) -> Result, ()> { +fn parse_float<'tcx>(num: Symbol, fty: ast::FloatTy, neg: bool) -> Result, ()> { let num = num.as_str(); - use rustc_apfloat::ieee::{Single, Double}; + use rustc_apfloat::ieee::{Double, Single}; let scalar = match fty { ast::FloatTy::F32 => { num.parse::().map_err(|_| ())?; diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index 8dda51cd77172..85adb6a005699 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -1,9 +1,9 @@ -use crate::hair::{self, *}; -use crate::hair::cx::Cx; use crate::hair::cx::to_ref::ToRef; +use crate::hair::cx::Cx; +use crate::hair::{self, *}; -use rustc::middle::region; use rustc::hir; +use rustc::middle::region; use rustc::ty; use rustc_index::vec::Idx; @@ -19,23 +19,16 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block { cx.region_scope_tree.opt_destruction_scope(self.hir_id.local_id); Block { targeted_by_break: self.targeted_by_break, - region_scope: region::Scope { - id: self.hir_id.local_id, - data: region::ScopeData::Node - }, + region_scope: region::Scope { id: self.hir_id.local_id, data: region::ScopeData::Node }, opt_destruction_scope, span: self.span, stmts, expr: self.expr.to_ref(), safety_mode: match self.rules { - hir::BlockCheckMode::DefaultBlock => - BlockSafety::Safe, - hir::BlockCheckMode::UnsafeBlock(..) => - BlockSafety::ExplicitUnsafe(self.hir_id), - hir::BlockCheckMode::PushUnsafeBlock(..) => - BlockSafety::PushUnsafe, - hir::BlockCheckMode::PopUnsafeBlock(..) => - BlockSafety::PopUnsafe + hir::BlockCheckMode::DefaultBlock => BlockSafety::Safe, + hir::BlockCheckMode::UnsafeBlock(..) => BlockSafety::ExplicitUnsafe(self.hir_id), + hir::BlockCheckMode::PushUnsafeBlock(..) => BlockSafety::PushUnsafe, + hir::BlockCheckMode::PopUnsafeBlock(..) => BlockSafety::PopUnsafe, }, } } @@ -51,14 +44,10 @@ fn mirror_stmts<'a, 'tcx>( let hir_id = stmt.hir_id; let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id); match stmt.kind { - hir::StmtKind::Expr(ref expr) | - hir::StmtKind::Semi(ref expr) => { + hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => { result.push(StmtRef::Mirror(Box::new(Stmt { kind: StmtKind::Expr { - scope: region::Scope { - id: hir_id.local_id, - data: region::ScopeData::Node - }, + scope: region::Scope { id: hir_id.local_id, data: region::ScopeData::Node }, expr: expr.to_ref(), }, opt_destruction_scope: opt_dxn_ext, @@ -70,8 +59,7 @@ fn mirror_stmts<'a, 'tcx>( hir::StmtKind::Local(ref local) => { let remainder_scope = region::Scope { id: block_id, - data: region::ScopeData::Remainder( - region::FirstStatementIndex::new(index)), + data: region::ScopeData::Remainder(region::FirstStatementIndex::new(index)), }; let mut pattern = cx.pattern_from_hir(&local.pat); @@ -89,7 +77,7 @@ fn mirror_stmts<'a, 'tcx>( variance: ty::Variance::Covariant, }, subpattern: pattern, - }) + }), }; } } @@ -99,7 +87,7 @@ fn mirror_stmts<'a, 'tcx>( remainder_scope: remainder_scope, init_scope: region::Scope { id: hir_id.local_id, - data: region::ScopeData::Node + data: region::ScopeData::Node, }, pattern, initializer: local.init.to_ref(), @@ -113,10 +101,7 @@ fn mirror_stmts<'a, 'tcx>( return result; } -pub fn to_expr_ref<'a, 'tcx>( - cx: &mut Cx<'a, 'tcx>, - block: &'tcx hir::Block, -) -> ExprRef<'tcx> { +pub fn to_expr_ref<'a, 'tcx>(cx: &mut Cx<'a, 'tcx>, block: &'tcx hir::Block) -> ExprRef<'tcx> { let block_ty = cx.tables().node_type(block.hir_id); let temp_lifetime = cx.region_scope_tree.temporary_scope(block.hir_id.local_id); let expr = Expr { diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 589016a2ca253..bfeb3c40e28e8 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -1,17 +1,17 @@ -use crate::hair::*; -use crate::hair::cx::Cx; use crate::hair::cx::block; use crate::hair::cx::to_ref::ToRef; +use crate::hair::cx::Cx; use crate::hair::util::UserAnnotatedTyHelpers; -use rustc_index::vec::Idx; -use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind}; -use rustc::mir::interpret::{ErrorHandled, Scalar}; -use rustc::ty::{self, AdtKind, Ty}; -use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability, PointerCast}; -use rustc::ty::subst::{InternalSubsts, SubstsRef}; +use crate::hair::*; use rustc::hir; +use rustc::hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc::hir::def_id::LocalDefId; +use rustc::mir::interpret::{ErrorHandled, Scalar}; use rustc::mir::BorrowKind; +use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast}; +use rustc::ty::subst::{InternalSubsts, SubstsRef}; +use rustc::ty::{self, AdtKind, Ty}; +use rustc_index::vec::Idx; use syntax_pos::Span; impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { @@ -19,10 +19,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { fn make_mirror(self, cx: &mut Cx<'_, 'tcx>) -> Expr<'tcx> { let temp_lifetime = cx.region_scope_tree.temporary_scope(self.hir_id.local_id); - let expr_scope = region::Scope { - id: self.hir_id.local_id, - data: region::ScopeData::Node - }; + let expr_scope = region::Scope { id: self.hir_id.local_id, data: region::ScopeData::Node }; debug!("Expr::make_mirror(): id={}, span={:?}", self.hir_id, self.span); @@ -30,9 +27,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { // Now apply adjustments, if any. for adjustment in cx.tables().expr_adjustments(self) { - debug!("make_mirror: expr={:?} applying adjustment={:?}", - expr, - adjustment); + debug!("make_mirror: expr={:?} applying adjustment={:?}", expr, adjustment); expr = apply_adjustment(cx, self, expr, adjustment); } @@ -49,19 +44,19 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { }; // Finally, create a destruction scope, if any. - if let Some(region_scope) = - cx.region_scope_tree.opt_destruction_scope(self.hir_id.local_id) { - expr = Expr { - temp_lifetime, - ty: expr.ty, - span: self.span, - kind: ExprKind::Scope { - region_scope, - value: expr.to_ref(), - lint_level: LintLevel::Inherited, - }, - }; - } + if let Some(region_scope) = cx.region_scope_tree.opt_destruction_scope(self.hir_id.local_id) + { + expr = Expr { + temp_lifetime, + ty: expr.ty, + span: self.span, + kind: ExprKind::Scope { + region_scope, + value: expr.to_ref(), + lint_level: LintLevel::Inherited, + }, + }; + } // OK, all done! expr @@ -72,7 +67,7 @@ fn apply_adjustment<'a, 'tcx>( cx: &mut Cx<'a, 'tcx>, hir_expr: &'tcx hir::Expr, mut expr: Expr<'tcx>, - adjustment: &Adjustment<'tcx> + adjustment: &Adjustment<'tcx>, ) -> Expr<'tcx> { let Expr { temp_lifetime, mut span, .. } = expr; @@ -100,12 +95,8 @@ fn apply_adjustment<'a, 'tcx>( adjust_span(&mut expr); ExprKind::Pointer { cast: PointerCast::Unsize, source: expr.to_ref() } } - Adjust::Pointer(cast) => { - ExprKind::Pointer { cast, source: expr.to_ref() } - } - Adjust::NeverToAny => { - ExprKind::NeverToAny { source: expr.to_ref() } - } + Adjust::Pointer(cast) => ExprKind::Pointer { cast, source: expr.to_ref() }, + Adjust::NeverToAny => ExprKind::NeverToAny { source: expr.to_ref() }, Adjust::Deref(None) => { adjust_span(&mut expr); ExprKind::Deref { arg: expr.to_ref() } @@ -117,11 +108,7 @@ fn apply_adjustment<'a, 'tcx>( expr = Expr { temp_lifetime, - ty: cx.tcx.mk_ref(deref.region, - ty::TypeAndMut { - ty: expr.ty, - mutbl: deref.mutbl, - }), + ty: cx.tcx.mk_ref(deref.region, ty::TypeAndMut { ty: expr.ty, mutbl: deref.mutbl }), span, kind: ExprKind::Borrow { borrow_kind: deref.mutbl.to_borrow_kind(), @@ -132,31 +119,17 @@ fn apply_adjustment<'a, 'tcx>( overloaded_place(cx, hir_expr, adjustment.target, Some(call), vec![expr.to_ref()]) } Adjust::Borrow(AutoBorrow::Ref(_, m)) => { - ExprKind::Borrow { - borrow_kind: m.to_borrow_kind(), - arg: expr.to_ref(), - } + ExprKind::Borrow { borrow_kind: m.to_borrow_kind(), arg: expr.to_ref() } } Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => { - ExprKind::AddressOf { - mutability, - arg: expr.to_ref(), - } + ExprKind::AddressOf { mutability, arg: expr.to_ref() } } }; - Expr { - temp_lifetime, - ty: adjustment.target, - span, - kind, - } + Expr { temp_lifetime, ty: adjustment.target, span, kind } } -fn make_mirror_unadjusted<'a, 'tcx>( - cx: &mut Cx<'a, 'tcx>, - expr: &'tcx hir::Expr, -) -> Expr<'tcx> { +fn make_mirror_unadjusted<'a, 'tcx>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr) -> Expr<'tcx> { let expr_ty = cx.tables().expr_ty(expr); let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id); @@ -164,16 +137,9 @@ fn make_mirror_unadjusted<'a, 'tcx>( // Here comes the interesting stuff: hir::ExprKind::MethodCall(_, method_span, ref args) => { // Rewrite a.b(c) into UFCS form like Trait::b(a, c) - let expr = method_callee(cx, expr, method_span,None); - let args = args.iter() - .map(|e| e.to_ref()) - .collect(); - ExprKind::Call { - ty: expr.ty, - fun: expr.to_ref(), - args, - from_hir_call: true, - } + let expr = method_callee(cx, expr, method_span, None); + let args = args.iter().map(|e| e.to_ref()).collect(); + ExprKind::Call { ty: expr.ty, fun: expr.to_ref(), args, from_hir_call: true } } hir::ExprKind::Call(ref fun, ref args) => { @@ -185,7 +151,7 @@ fn make_mirror_unadjusted<'a, 'tcx>( // rewrite f(u, v) into FnOnce::call_once(f, (u, v)) - let method = method_callee(cx, expr, fun.span,None); + let method = method_callee(cx, expr, fun.span, None); let arg_tys = args.iter().map(|e| cx.tables().expr_ty_adjusted(e)); let tupled_args = Expr { @@ -202,27 +168,24 @@ fn make_mirror_unadjusted<'a, 'tcx>( from_hir_call: true, } } else { - let adt_data = if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = - fun.kind - { - // Tuple-like ADTs are represented as ExprKind::Call. We convert them here. - expr_ty.ty_adt_def().and_then(|adt_def| { - match path.res { - Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => - Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id))), + let adt_data = + if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = fun.kind { + // Tuple-like ADTs are represented as ExprKind::Call. We convert them here. + expr_ty.ty_adt_def().and_then(|adt_def| match path.res { + Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => { + Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id))) + } Res::SelfCtor(..) => Some((adt_def, VariantIdx::new(0))), _ => None, - } - }) - } else { - None - }; + }) + } else { + None + }; if let Some((adt_def, index)) = adt_data { let substs = cx.tables().node_substs(fun.hir_id); let user_provided_types = cx.tables().user_provided_types(); - let user_ty = user_provided_types.get(fun.hir_id) - .map(|u_ty| *u_ty) - .map(|mut u_ty| { + let user_ty = + user_provided_types.get(fun.hir_id).map(|u_ty| *u_ty).map(|mut u_ty| { if let UserType::TypeOf(ref mut did, _) = &mut u_ty.value { *did = adt_def.did; } @@ -230,14 +193,10 @@ fn make_mirror_unadjusted<'a, 'tcx>( }); debug!("make_mirror_unadjusted: (call) user_ty={:?}", user_ty); - let field_refs = args.iter() + let field_refs = args + .iter() .enumerate() - .map(|(idx, e)| { - FieldExprRef { - name: Field::new(idx), - expr: e.to_ref(), - } - }) + .map(|(idx, e)| FieldExprRef { name: Field::new(idx), expr: e.to_ref() }) .collect(); ExprKind::Adt { adt_def, @@ -259,37 +218,24 @@ fn make_mirror_unadjusted<'a, 'tcx>( } hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mutbl, ref arg) => { - ExprKind::Borrow { - borrow_kind: mutbl.to_borrow_kind(), - arg: arg.to_ref(), - } + ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg: arg.to_ref() } } hir::ExprKind::AddrOf(hir::BorrowKind::Raw, mutability, ref arg) => { - ExprKind::AddressOf { - mutability, - arg: arg.to_ref(), - } + ExprKind::AddressOf { mutability, arg: arg.to_ref() } } hir::ExprKind::Block(ref blk, _) => ExprKind::Block { body: &blk }, hir::ExprKind::Assign(ref lhs, ref rhs) => { - ExprKind::Assign { - lhs: lhs.to_ref(), - rhs: rhs.to_ref(), - } + ExprKind::Assign { lhs: lhs.to_ref(), rhs: rhs.to_ref() } } hir::ExprKind::AssignOp(op, ref lhs, ref rhs) => { if cx.tables().is_method_call(expr) { overloaded_operator(cx, expr, vec![lhs.to_ref(), rhs.to_ref()]) } else { - ExprKind::AssignOp { - op: bin_op(op.node), - lhs: lhs.to_ref(), - rhs: rhs.to_ref(), - } + ExprKind::AssignOp { op: bin_op(op.node), lhs: lhs.to_ref(), rhs: rhs.to_ref() } } } @@ -308,52 +254,30 @@ fn make_mirror_unadjusted<'a, 'tcx>( (hir::BinOpKind::And, hir::Constness::Const) if !cx.tcx.features().const_if_match => { - cx.control_flow_destroyed.push(( - op.span, - "`&&` operator".into(), - )); - ExprKind::Binary { - op: BinOp::BitAnd, - lhs: lhs.to_ref(), - rhs: rhs.to_ref(), - } + cx.control_flow_destroyed.push((op.span, "`&&` operator".into())); + ExprKind::Binary { op: BinOp::BitAnd, lhs: lhs.to_ref(), rhs: rhs.to_ref() } } (hir::BinOpKind::Or, hir::Constness::Const) if !cx.tcx.features().const_if_match => { - cx.control_flow_destroyed.push(( - op.span, - "`||` operator".into(), - )); - ExprKind::Binary { - op: BinOp::BitOr, - lhs: lhs.to_ref(), - rhs: rhs.to_ref(), - } + cx.control_flow_destroyed.push((op.span, "`||` operator".into())); + ExprKind::Binary { op: BinOp::BitOr, lhs: lhs.to_ref(), rhs: rhs.to_ref() } } - (hir::BinOpKind::And, _) => { - ExprKind::LogicalOp { - op: LogicalOp::And, - lhs: lhs.to_ref(), - rhs: rhs.to_ref(), - } - } - (hir::BinOpKind::Or, _) => { - ExprKind::LogicalOp { - op: LogicalOp::Or, - lhs: lhs.to_ref(), - rhs: rhs.to_ref(), - } - } + (hir::BinOpKind::And, _) => ExprKind::LogicalOp { + op: LogicalOp::And, + lhs: lhs.to_ref(), + rhs: rhs.to_ref(), + }, + (hir::BinOpKind::Or, _) => ExprKind::LogicalOp { + op: LogicalOp::Or, + lhs: lhs.to_ref(), + rhs: rhs.to_ref(), + }, _ => { let op = bin_op(op.node); - ExprKind::Binary { - op, - lhs: lhs.to_ref(), - rhs: rhs.to_ref(), - } + ExprKind::Binary { op, lhs: lhs.to_ref(), rhs: rhs.to_ref() } } } } @@ -363,10 +287,7 @@ fn make_mirror_unadjusted<'a, 'tcx>( if cx.tables().is_method_call(expr) { overloaded_place(cx, expr, expr_ty, None, vec![lhs.to_ref(), index.to_ref()]) } else { - ExprKind::Index { - lhs: lhs.to_ref(), - index: index.to_ref(), - } + ExprKind::Index { lhs: lhs.to_ref(), index: index.to_ref() } } } @@ -382,10 +303,7 @@ fn make_mirror_unadjusted<'a, 'tcx>( if cx.tables().is_method_call(expr) { overloaded_operator(cx, expr, vec![arg.to_ref()]) } else { - ExprKind::Unary { - op: UnOp::Not, - arg: arg.to_ref(), - } + ExprKind::Unary { op: UnOp::Not, arg: arg.to_ref() } } } @@ -399,81 +317,63 @@ fn make_mirror_unadjusted<'a, 'tcx>( user_ty: None, } } else { - ExprKind::Unary { - op: UnOp::Neg, - arg: arg.to_ref(), - } + ExprKind::Unary { op: UnOp::Neg, arg: arg.to_ref() } } } } - hir::ExprKind::Struct(ref qpath, ref fields, ref base) => { - match expr_ty.kind { - ty::Adt(adt, substs) => { - match adt.adt_kind() { - AdtKind::Struct | AdtKind::Union => { + hir::ExprKind::Struct(ref qpath, ref fields, ref base) => match expr_ty.kind { + ty::Adt(adt, substs) => match adt.adt_kind() { + AdtKind::Struct | AdtKind::Union => { + let user_provided_types = cx.tables().user_provided_types(); + let user_ty = user_provided_types.get(expr.hir_id).map(|u_ty| *u_ty); + debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty); + ExprKind::Adt { + adt_def: adt, + variant_index: VariantIdx::new(0), + substs, + user_ty, + fields: field_refs(cx, fields), + base: base.as_ref().map(|base| FruInfo { + base: base.to_ref(), + field_types: cx.tables().fru_field_types()[expr.hir_id].clone(), + }), + } + } + AdtKind::Enum => { + let res = cx.tables().qpath_res(qpath, expr.hir_id); + match res { + Res::Def(DefKind::Variant, variant_id) => { + assert!(base.is_none()); + + let index = adt.variant_index_with_id(variant_id); let user_provided_types = cx.tables().user_provided_types(); let user_ty = user_provided_types.get(expr.hir_id).map(|u_ty| *u_ty); - debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty); + debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty); ExprKind::Adt { adt_def: adt, - variant_index: VariantIdx::new(0), + variant_index: index, substs, user_ty, fields: field_refs(cx, fields), - base: base.as_ref().map(|base| { - FruInfo { - base: base.to_ref(), - field_types: cx.tables() - .fru_field_types()[expr.hir_id] - .clone(), - } - }), + base: None, } } - AdtKind::Enum => { - let res = cx.tables().qpath_res(qpath, expr.hir_id); - match res { - Res::Def(DefKind::Variant, variant_id) => { - assert!(base.is_none()); - - let index = adt.variant_index_with_id(variant_id); - let user_provided_types = cx.tables().user_provided_types(); - let user_ty = user_provided_types.get(expr.hir_id) - .map(|u_ty| *u_ty); - debug!( - "make_mirror_unadjusted: (variant) user_ty={:?}", - user_ty - ); - ExprKind::Adt { - adt_def: adt, - variant_index: index, - substs, - user_ty, - fields: field_refs(cx, fields), - base: None, - } - } - _ => { - span_bug!(expr.span, "unexpected res: {:?}", res); - } - } + _ => { + span_bug!(expr.span, "unexpected res: {:?}", res); } } } - _ => { - span_bug!(expr.span, - "unexpected type for struct literal: {:?}", - expr_ty); - } + }, + _ => { + span_bug!(expr.span, "unexpected type for struct literal: {:?}", expr_ty); } - } + }, hir::ExprKind::Closure(..) => { let closure_ty = cx.tables().expr_ty(expr); let (def_id, substs, movability) = match closure_ty.kind { - ty::Closure(def_id, substs) => (def_id, - UpvarSubsts::Closure(substs), None), + ty::Closure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs), None), ty::Generator(def_id, substs, movability) => { (def_id, UpvarSubsts::Generator(substs), Some(movability)) } @@ -481,17 +381,15 @@ fn make_mirror_unadjusted<'a, 'tcx>( span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty); } }; - let upvars = cx.tcx.upvars(def_id).iter() + let upvars = cx + .tcx + .upvars(def_id) + .iter() .flat_map(|upvars| upvars.iter()) .zip(substs.upvar_tys(def_id, cx.tcx)) .map(|((&var_hir_id, _), ty)| capture_upvar(cx, expr, var_hir_id, ty)) .collect(); - ExprKind::Closure { - closure_id: def_id, - substs, - upvars, - movability, - } + ExprKind::Closure { closure_id: def_id, substs, upvars, movability } } hir::ExprKind::Path(ref qpath) => { @@ -499,78 +397,54 @@ fn make_mirror_unadjusted<'a, 'tcx>( convert_path_expr(cx, expr, res) } - hir::ExprKind::InlineAsm(ref asm) => { - ExprKind::InlineAsm { - asm: &asm.inner, - outputs: asm.outputs_exprs.to_ref(), - inputs: asm.inputs_exprs.to_ref(), - } - } + hir::ExprKind::InlineAsm(ref asm) => ExprKind::InlineAsm { + asm: &asm.inner, + outputs: asm.outputs_exprs.to_ref(), + inputs: asm.inputs_exprs.to_ref(), + }, // Now comes the rote stuff: hir::ExprKind::Repeat(ref v, ref count) => { let def_id = cx.tcx.hir().local_def_id(count.hir_id); let substs = InternalSubsts::identity_for_item(cx.tcx, def_id); let span = cx.tcx.def_span(def_id); - let count = match cx.tcx.const_eval_resolve(cx.param_env, - def_id, - substs, - Some(span)) { + let count = match cx.tcx.const_eval_resolve(cx.param_env, def_id, substs, Some(span)) { Ok(cv) => cv.eval_usize(cx.tcx, cx.param_env), Err(ErrorHandled::Reported) => 0, Err(ErrorHandled::TooGeneric) => { let span = cx.tcx.def_span(def_id); cx.tcx.sess.span_err(span, "array lengths can't depend on generic parameters"); 0 - }, + } }; - ExprKind::Repeat { - value: v.to_ref(), - count, - } + ExprKind::Repeat { value: v.to_ref(), count } } hir::ExprKind::Ret(ref v) => ExprKind::Return { value: v.to_ref() }, - hir::ExprKind::Break(dest, ref value) => { - match dest.target_id { - Ok(target_id) => ExprKind::Break { - label: region::Scope { - id: target_id.local_id, - data: region::ScopeData::Node - }, - value: value.to_ref(), - }, - Err(err) => bug!("invalid loop id for break: {}", err) - } - } - hir::ExprKind::Continue(dest) => { - match dest.target_id { - Ok(loop_id) => ExprKind::Continue { - label: region::Scope { - id: loop_id.local_id, - data: region::ScopeData::Node - }, - }, - Err(err) => bug!("invalid loop id for continue: {}", err) - } - } - hir::ExprKind::Match(ref discr, ref arms, _) => { - ExprKind::Match { - scrutinee: discr.to_ref(), - arms: arms.iter().map(|a| convert_arm(cx, a)).collect(), - } - } + hir::ExprKind::Break(dest, ref value) => match dest.target_id { + Ok(target_id) => ExprKind::Break { + label: region::Scope { id: target_id.local_id, data: region::ScopeData::Node }, + value: value.to_ref(), + }, + Err(err) => bug!("invalid loop id for break: {}", err), + }, + hir::ExprKind::Continue(dest) => match dest.target_id { + Ok(loop_id) => ExprKind::Continue { + label: region::Scope { id: loop_id.local_id, data: region::ScopeData::Node }, + }, + Err(err) => bug!("invalid loop id for continue: {}", err), + }, + hir::ExprKind::Match(ref discr, ref arms, _) => ExprKind::Match { + scrutinee: discr.to_ref(), + arms: arms.iter().map(|a| convert_arm(cx, a)).collect(), + }, hir::ExprKind::Loop(ref body, _, _) => { - ExprKind::Loop { - body: block::to_expr_ref(cx, body), - } - } - hir::ExprKind::Field(ref source, ..) => { - ExprKind::Field { - lhs: source.to_ref(), - name: Field::new(cx.tcx.field_index(expr.hir_id, cx.tables)), - } + ExprKind::Loop { body: block::to_expr_ref(cx, body) } } + hir::ExprKind::Field(ref source, ..) => ExprKind::Field { + lhs: source.to_ref(), + name: Field::new(cx.tcx.field_index(expr.hir_id, cx.tables)), + }, hir::ExprKind::Cast(ref source, ref cast_ty) => { // Check for a user-given type annotation on this `cast` let user_provided_types = cx.tables.user_provided_types(); @@ -578,9 +452,7 @@ fn make_mirror_unadjusted<'a, 'tcx>( debug!( "cast({:?}) has ty w/ hir_id {:?} and user provided ty {:?}", - expr, - cast_ty.hir_id, - user_ty, + expr, cast_ty.hir_id, user_ty, ); // Check to see if this cast is a "coercion cast", where the cast is actually done @@ -607,12 +479,8 @@ fn make_mirror_unadjusted<'a, 'tcx>( // so we wouldn't have to compute and store the actual value let var = if let hir::ExprKind::Path(ref qpath) = source.kind { let res = cx.tables().qpath_res(qpath, source.hir_id); - cx - .tables() - .node_type(source.hir_id) - .ty_adt_def() - .and_then(|adt_def| { - match res { + cx.tables().node_type(source.hir_id).ty_adt_def().and_then( + |adt_def| match res { Res::Def( DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id, @@ -625,22 +493,22 @@ fn make_mirror_unadjusted<'a, 'tcx>( Some((d, o, ty)) } _ => None, - } - }) + }, + ) } else { None }; let source = if let Some((did, offset, var_ty)) = var { - let mk_const = |literal| Expr { - temp_lifetime, - ty: var_ty, - span: expr.span, - kind: ExprKind::Literal { - literal, - user_ty: None - }, - }.to_ref(); + let mk_const = |literal| { + Expr { + temp_lifetime, + ty: var_ty, + span: expr.span, + kind: ExprKind::Literal { literal, user_ty: None }, + } + .to_ref() + }; let offset = mk_const(ty::Const::from_bits( cx.tcx, offset as u128, @@ -655,18 +523,9 @@ fn make_mirror_unadjusted<'a, 'tcx>( val: ty::ConstKind::Unevaluated(did, substs), ty: var_ty, })); - let bin = ExprKind::Binary { - op: BinOp::Add, - lhs, - rhs: offset, - }; - Expr { - temp_lifetime, - ty: var_ty, - span: expr.span, - kind: bin, - }.to_ref() - }, + let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset }; + Expr { temp_lifetime, ty: var_ty, span: expr.span, kind: bin }.to_ref() + } None => offset, } } else { @@ -679,12 +538,7 @@ fn make_mirror_unadjusted<'a, 'tcx>( if let Some(user_ty) = user_ty { // NOTE: Creating a new Expr and wrapping a Cast inside of it may be // inefficient, revisit this when performance becomes an issue. - let cast_expr = Expr { - temp_lifetime, - ty: expr_ty, - span: expr.span, - kind: cast, - }; + let cast_expr = Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind: cast }; debug!("make_mirror_unadjusted: (cast) user_ty={:?}", user_ty); ExprKind::ValueTypeAscription { @@ -700,25 +554,13 @@ fn make_mirror_unadjusted<'a, 'tcx>( let user_ty = user_provided_types.get(ty.hir_id).map(|u_ty| *u_ty); debug!("make_mirror_unadjusted: (type) user_ty={:?}", user_ty); if source.is_syntactic_place_expr() { - ExprKind::PlaceTypeAscription { - source: source.to_ref(), - user_ty, - } + ExprKind::PlaceTypeAscription { source: source.to_ref(), user_ty } } else { - ExprKind::ValueTypeAscription { - source: source.to_ref(), - user_ty, - } - } - } - hir::ExprKind::DropTemps(ref source) => { - ExprKind::Use { source: source.to_ref() } - } - hir::ExprKind::Box(ref value) => { - ExprKind::Box { - value: value.to_ref(), + ExprKind::ValueTypeAscription { source: source.to_ref(), user_ty } } } + hir::ExprKind::DropTemps(ref source) => ExprKind::Use { source: source.to_ref() }, + hir::ExprKind::Box(ref value) => ExprKind::Box { value: value.to_ref() }, hir::ExprKind::Array(ref fields) => ExprKind::Array { fields: fields.to_ref() }, hir::ExprKind::Tup(ref fields) => ExprKind::Tuple { fields: fields.to_ref() }, @@ -726,12 +568,7 @@ fn make_mirror_unadjusted<'a, 'tcx>( hir::ExprKind::Err => unreachable!(), }; - Expr { - temp_lifetime, - ty: expr_ty, - span: expr.span, - kind, - } + Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind } } fn user_substs_applied_to_res( @@ -744,26 +581,26 @@ fn user_substs_applied_to_res( // A reference to something callable -- e.g., a fn, method, or // a tuple-struct or tuple-variant. This has the type of a // `Fn` but with the user-given substitutions. - Res::Def(DefKind::Fn, _) | - Res::Def(DefKind::Method, _) | - Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) | - Res::Def(DefKind::Const, _) | - Res::Def(DefKind::AssocConst, _) => - cx.tables().user_provided_types().get(hir_id).map(|u_ty| *u_ty), + Res::Def(DefKind::Fn, _) + | Res::Def(DefKind::Method, _) + | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) + | Res::Def(DefKind::Const, _) + | Res::Def(DefKind::AssocConst, _) => { + cx.tables().user_provided_types().get(hir_id).map(|u_ty| *u_ty) + } // A unit struct/variant which is used as a value (e.g., // `None`). This has the type of the enum/struct that defines // this variant -- but with the substitutions given by the // user. - Res::Def(DefKind::Ctor(_, CtorKind::Const), _) => - cx.user_substs_applied_to_ty_of_hir_id(hir_id), + Res::Def(DefKind::Ctor(_, CtorKind::Const), _) => { + cx.user_substs_applied_to_ty_of_hir_id(hir_id) + } // `Self` is used in expression as a tuple struct constructor or an unit struct constructor - Res::SelfCtor(_) => - cx.user_substs_applied_to_ty_of_hir_id(hir_id), + Res::SelfCtor(_) => cx.user_substs_applied_to_ty_of_hir_id(hir_id), - _ => - bug!("user_substs_applied_to_res: unexpected res {:?} at {:?}", res, hir_id) + _ => bug!("user_substs_applied_to_res: unexpected res {:?} at {:?}", res, hir_id), }; debug!("user_substs_applied_to_res: user_provided_type={:?}", user_provided_type); user_provided_type @@ -779,10 +616,10 @@ fn method_callee<'a, 'tcx>( let (def_id, substs, user_ty) = match overloaded_callee { Some((def_id, substs)) => (def_id, substs, None), None => { - let (kind, def_id) = cx.tables().type_dependent_def(expr.hir_id) - .unwrap_or_else(|| { - span_bug!(expr.span, "no type-dependent def for method callee") - }); + let (kind, def_id) = cx + .tables() + .type_dependent_def(expr.hir_id) + .unwrap_or_else(|| span_bug!(expr.span, "no type-dependent def for method callee")); let user_ty = user_substs_applied_to_res(cx, expr.hir_id, Res::Def(kind, def_id)); debug!("method_callee: user_ty={:?}", user_ty); (def_id, cx.tables().node_substs(expr.hir_id), user_ty) @@ -793,24 +630,24 @@ fn method_callee<'a, 'tcx>( temp_lifetime, ty, span, - kind: ExprKind::Literal { - literal: ty::Const::zero_sized(cx.tcx(), ty), - user_ty, - }, + kind: ExprKind::Literal { literal: ty::Const::zero_sized(cx.tcx(), ty), user_ty }, } } -trait ToBorrowKind { fn to_borrow_kind(&self) -> BorrowKind; } +trait ToBorrowKind { + fn to_borrow_kind(&self) -> BorrowKind; +} impl ToBorrowKind for AutoBorrowMutability { fn to_borrow_kind(&self) -> BorrowKind { use rustc::ty::adjustment::AllowTwoPhase; match *self { - AutoBorrowMutability::Mut { allow_two_phase_borrow } => - BorrowKind::Mut { allow_two_phase_borrow: match allow_two_phase_borrow { + AutoBorrowMutability::Mut { allow_two_phase_borrow } => BorrowKind::Mut { + allow_two_phase_borrow: match allow_two_phase_borrow { AllowTwoPhase::Yes => true, - AllowTwoPhase::No => false - }}, + AllowTwoPhase::No => false, + }, + }, AutoBorrowMutability::Not => BorrowKind::Shared, } } @@ -829,15 +666,12 @@ fn convert_arm<'tcx>(cx: &mut Cx<'_, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> { Arm { pattern: cx.pattern_from_hir(&arm.pat), guard: match arm.guard { - Some(hir::Guard::If(ref e)) => Some(Guard::If(e.to_ref())), - _ => None, - }, + Some(hir::Guard::If(ref e)) => Some(Guard::If(e.to_ref())), + _ => None, + }, body: arm.body.to_ref(), lint_level: LintLevel::Explicit(arm.hir_id), - scope: region::Scope { - id: arm.hir_id.local_id, - data: region::ScopeData::Node - }, + scope: region::Scope { id: arm.hir_id.local_id, data: region::ScopeData::Node }, span: arm.span, } } @@ -850,17 +684,14 @@ fn convert_path_expr<'a, 'tcx>( let substs = cx.tables().node_substs(expr.hir_id); match res { // A regular function, constructor function or a constant. - Res::Def(DefKind::Fn, _) | - Res::Def(DefKind::Method, _) | - Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) | - Res::SelfCtor(..) => { + Res::Def(DefKind::Fn, _) + | Res::Def(DefKind::Method, _) + | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) + | Res::SelfCtor(..) => { let user_ty = user_substs_applied_to_res(cx, expr.hir_id, res); debug!("convert_path_expr: user_ty={:?}", user_ty); ExprKind::Literal { - literal: ty::Const::zero_sized( - cx.tcx, - cx.tables().node_type(expr.hir_id), - ), + literal: ty::Const::zero_sized(cx.tcx, cx.tables().node_type(expr.hir_id)), user_ty, } } @@ -875,18 +706,12 @@ fn convert_path_expr<'a, 'tcx>( let name = cx.tcx.hir().name(hir_id); let val = ty::ConstKind::Param(ty::ParamConst::new(index, name)); ExprKind::Literal { - literal: cx.tcx.mk_const( - ty::Const { - val, - ty: cx.tables().node_type(expr.hir_id), - } - ), + literal: cx.tcx.mk_const(ty::Const { val, ty: cx.tables().node_type(expr.hir_id) }), user_ty: None, } } - Res::Def(DefKind::Const, def_id) | - Res::Def(DefKind::AssocConst, def_id) => { + Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssocConst, def_id) => { let user_ty = user_substs_applied_to_res(cx, expr.hir_id, res); debug!("convert_path_expr: (const) user_ty={:?}", user_ty); ExprKind::Literal { @@ -896,7 +721,7 @@ fn convert_path_expr<'a, 'tcx>( }), user_ty, } - }, + } Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => { let user_provided_types = cx.tables.user_provided_types(); @@ -906,16 +731,14 @@ fn convert_path_expr<'a, 'tcx>( match ty.kind { // A unit struct/variant which is used as a value. // We return a completely different ExprKind here to account for this special case. - ty::Adt(adt_def, substs) => { - ExprKind::Adt { - adt_def, - variant_index: adt_def.variant_index_with_ctor_id(def_id), - substs, - user_ty: user_provided_type, - fields: vec![], - base: None, - } - } + ty::Adt(adt_def, substs) => ExprKind::Adt { + adt_def, + variant_index: adt_def.variant_index_with_ctor_id(def_id), + substs, + user_ty: user_provided_type, + fields: vec![], + base: None, + }, _ => bug!("unexpected ty: {:?}", ty), } } @@ -926,16 +749,19 @@ fn convert_path_expr<'a, 'tcx>( let ty = cx.tcx.static_ptr_ty(id); let ptr = cx.tcx.alloc_map.lock().create_static_alloc(id); let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id); - ExprKind::Deref { arg: Expr { - ty, - temp_lifetime, - span: expr.span, - kind: ExprKind::StaticRef { - literal: ty::Const::from_scalar(cx.tcx, Scalar::Ptr(ptr.into()), ty), - def_id: id, + ExprKind::Deref { + arg: Expr { + ty, + temp_lifetime, + span: expr.span, + kind: ExprKind::StaticRef { + literal: ty::Const::from_scalar(cx.tcx, Scalar::Ptr(ptr.into()), ty), + def_id: id, + }, } - }.to_ref() } - }, + .to_ref(), + } + } Res::Local(var_hir_id) => convert_var(cx, expr, var_hir_id), @@ -948,11 +774,16 @@ fn convert_var( expr: &'tcx hir::Expr, var_hir_id: hir::HirId, ) -> ExprKind<'tcx> { - let upvar_index = cx.tables().upvar_list.get(&cx.body_owner) + let upvar_index = cx + .tables() + .upvar_list + .get(&cx.body_owner) .and_then(|upvars| upvars.get_full(&var_hir_id).map(|(i, _, _)| i)); - debug!("convert_var({:?}): upvar_index={:?}, body_owner={:?}", - var_hir_id, upvar_index, cx.body_owner); + debug!( + "convert_var({:?}): upvar_index={:?}, body_owner={:?}", + var_hir_id, upvar_index, cx.body_owner + ); let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id); @@ -962,15 +793,15 @@ fn convert_var( Some(upvar_index) => { let closure_def_id = cx.body_owner; let upvar_id = ty::UpvarId { - var_path: ty::UpvarPath {hir_id: var_hir_id}, + var_path: ty::UpvarPath { hir_id: var_hir_id }, closure_expr_id: LocalDefId::from_def_id(closure_def_id), }; let var_ty = cx.tables().node_type(var_hir_id); // FIXME free regions in closures are not right - let closure_ty = cx.tables().node_type( - cx.tcx.hir().local_def_id_to_hir_id(upvar_id.closure_expr_id), - ); + let closure_ty = cx + .tables() + .node_type(cx.tcx.hir().local_def_id_to_hir_id(upvar_id.closure_expr_id)); // FIXME we're just hard-coding the idea that the // signature will be &self or &mut self and hence will @@ -984,11 +815,10 @@ fn convert_var( let self_expr = if let ty::Closure(_, closure_substs) = closure_ty.kind { match cx.infcx.closure_kind(closure_def_id, closure_substs).unwrap() { ty::ClosureKind::Fn => { - let ref_closure_ty = cx.tcx.mk_ref(region, - ty::TypeAndMut { - ty: closure_ty, - mutbl: hir::Mutability::Not, - }); + let ref_closure_ty = cx.tcx.mk_ref( + region, + ty::TypeAndMut { ty: closure_ty, mutbl: hir::Mutability::Not }, + ); Expr { ty: closure_ty, temp_lifetime, @@ -1005,11 +835,10 @@ fn convert_var( } } ty::ClosureKind::FnMut => { - let ref_closure_ty = cx.tcx.mk_ref(region, - ty::TypeAndMut { - ty: closure_ty, - mutbl: hir::Mutability::Mut, - }); + let ref_closure_ty = cx.tcx.mk_ref( + region, + ty::TypeAndMut { ty: closure_ty, mutbl: hir::Mutability::Mut }, + ); Expr { ty: closure_ty, temp_lifetime, @@ -1020,58 +849,47 @@ fn convert_var( temp_lifetime, span: expr.span, kind: ExprKind::SelfRef, - }.to_ref(), + } + .to_ref(), }, } } - ty::ClosureKind::FnOnce => { - Expr { - ty: closure_ty, - temp_lifetime, - span: expr.span, - kind: ExprKind::SelfRef, - } - } + ty::ClosureKind::FnOnce => Expr { + ty: closure_ty, + temp_lifetime, + span: expr.span, + kind: ExprKind::SelfRef, + }, } } else { - Expr { - ty: closure_ty, - temp_lifetime, - span: expr.span, - kind: ExprKind::SelfRef, - } + Expr { ty: closure_ty, temp_lifetime, span: expr.span, kind: ExprKind::SelfRef } }; // at this point we have `self.n`, which loads up the upvar - let field_kind = ExprKind::Field { - lhs: self_expr.to_ref(), - name: Field::new(upvar_index), - }; + let field_kind = + ExprKind::Field { lhs: self_expr.to_ref(), name: Field::new(upvar_index) }; // ...but the upvar might be an `&T` or `&mut T` capture, at which // point we need an implicit deref match cx.tables().upvar_capture(upvar_id) { ty::UpvarCapture::ByValue => field_kind, - ty::UpvarCapture::ByRef(borrow) => { - ExprKind::Deref { - arg: Expr { - temp_lifetime, - ty: cx.tcx.mk_ref(borrow.region, - ty::TypeAndMut { - ty: var_ty, - mutbl: borrow.kind.to_mutbl_lossy(), - }), - span: expr.span, - kind: field_kind, - }.to_ref(), + ty::UpvarCapture::ByRef(borrow) => ExprKind::Deref { + arg: Expr { + temp_lifetime, + ty: cx.tcx.mk_ref( + borrow.region, + ty::TypeAndMut { ty: var_ty, mutbl: borrow.kind.to_mutbl_lossy() }, + ), + span: expr.span, + kind: field_kind, } - } + .to_ref(), + }, } } } } - fn bin_op(op: hir::BinOpKind) -> BinOp { match op { hir::BinOpKind::Add => BinOp::Add, @@ -1097,15 +915,10 @@ fn bin_op(op: hir::BinOpKind) -> BinOp { fn overloaded_operator<'a, 'tcx>( cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr, - args: Vec> + args: Vec>, ) -> ExprKind<'tcx> { let fun = method_callee(cx, expr, expr.span, None); - ExprKind::Call { - ty: fun.ty, - fun: fun.to_ref(), - args, - from_hir_call: false, - } + ExprKind::Call { ty: fun.ty, fun: fun.to_ref(), args, from_hir_call: false } } fn overloaded_place<'a, 'tcx>( @@ -1121,7 +934,7 @@ fn overloaded_place<'a, 'tcx>( let recv_ty = match args[0] { ExprRef::Hair(e) => cx.tables().expr_ty_adjusted(e), - ExprRef::Mirror(ref e) => e.ty + ExprRef::Mirror(ref e) => e.ty, }; // Reconstruct the output assuming it's a reference with the @@ -1131,10 +944,7 @@ fn overloaded_place<'a, 'tcx>( ty::Ref(region, _, mutbl) => (region, mutbl), _ => span_bug!(expr.span, "overloaded_place: receiver is not a reference"), }; - let ref_ty = cx.tcx.mk_ref(region, ty::TypeAndMut { - ty: place_ty, - mutbl, - }); + let ref_ty = cx.tcx.mk_ref(region, ty::TypeAndMut { ty: place_ty, mutbl }); // construct the complete expression `foo()` for the overloaded call, // which will yield the &T type @@ -1144,12 +954,7 @@ fn overloaded_place<'a, 'tcx>( temp_lifetime, ty: ref_ty, span: expr.span, - kind: ExprKind::Call { - ty: fun.ty, - fun: fun.to_ref(), - args, - from_hir_call: false, - }, + kind: ExprKind::Call { ty: fun.ty, fun: fun.to_ref(), args, from_hir_call: false }, }; // construct and return a deref wrapper `*foo()` @@ -1160,7 +965,7 @@ fn capture_upvar<'tcx>( cx: &mut Cx<'_, 'tcx>, closure_expr: &'tcx hir::Expr, var_hir_id: hir::HirId, - upvar_ty: Ty<'tcx> + upvar_ty: Ty<'tcx>, ) -> ExprRef<'tcx> { let upvar_id = ty::UpvarId { var_path: ty::UpvarPath { hir_id: var_hir_id }, @@ -1181,17 +986,15 @@ fn capture_upvar<'tcx>( let borrow_kind = match upvar_borrow.kind { ty::BorrowKind::ImmBorrow => BorrowKind::Shared, ty::BorrowKind::UniqueImmBorrow => BorrowKind::Unique, - ty::BorrowKind::MutBorrow => BorrowKind::Mut { allow_two_phase_borrow: false } + ty::BorrowKind::MutBorrow => BorrowKind::Mut { allow_two_phase_borrow: false }, }; Expr { temp_lifetime, ty: upvar_ty, span: closure_expr.span, - kind: ExprKind::Borrow { - borrow_kind, - arg: captured_var.to_ref(), - }, - }.to_ref() + kind: ExprKind::Borrow { borrow_kind, arg: captured_var.to_ref() }, + } + .to_ref() } } } @@ -1199,14 +1002,13 @@ fn capture_upvar<'tcx>( /// Converts a list of named fields (i.e., for struct-like struct/enum ADTs) into FieldExprRef. fn field_refs<'a, 'tcx>( cx: &mut Cx<'a, 'tcx>, - fields: &'tcx [hir::Field] + fields: &'tcx [hir::Field], ) -> Vec> { - fields.iter() - .map(|field| { - FieldExprRef { - name: Field::new(cx.tcx.field_index(field.hir_id, cx.tables)), - expr: field.expr.to_ref(), - } + fields + .iter() + .map(|field| FieldExprRef { + name: Field::new(cx.tcx.field_index(field.hir_id, cx.tables)), + expr: field.expr.to_ref(), }) .collect() } diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index e120b496d3d09..dbabfb1b1614c 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -2,23 +2,23 @@ //! structures into the HAIR. The `builder` is generally ignorant of the tcx, //! etc., and instead goes through the `Cx` for most of its work. -use crate::hair::*; use crate::hair::util::UserAnnotatedTyHelpers; +use crate::hair::*; -use rustc_index::vec::Idx; +use crate::hair::constant::{lit_to_const, LitToConstError}; +use rustc::hir; use rustc::hir::def_id::DefId; use rustc::hir::Node; -use rustc::middle::region; use rustc::infer::InferCtxt; +use rustc::middle::region; +use rustc::ty::layout::VariantIdx; use rustc::ty::subst::Subst; -use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::{GenericArg, InternalSubsts}; -use rustc::ty::layout::VariantIdx; +use rustc::ty::{self, Ty, TyCtxt}; +use rustc_index::vec::Idx; use syntax::ast; use syntax::attr; -use syntax::symbol::{Symbol, sym}; -use rustc::hir; -use crate::hair::constant::{lit_to_const, LitToConstError}; +use syntax::symbol::{sym, Symbol}; #[derive(Clone)] pub struct Cx<'a, 'tcx> { @@ -59,10 +59,8 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { let body_owner_kind = tcx.hir().body_owner_kind(src_id); let constness = match body_owner_kind { - hir::BodyOwnerKind::Const | - hir::BodyOwnerKind::Static(_) => hir::Constness::Const, - hir::BodyOwnerKind::Closure | - hir::BodyOwnerKind::Fn => hir::Constness::NotConst, + hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => hir::Constness::Const, + hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => hir::Constness::NotConst, }; let attrs = tcx.hir().attrs(src_id); @@ -145,7 +143,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { self.tcx.sess.span_err(sp, "could not evaluate float literal (see issue #31407)"); // create a dummy value and continue compiling Const::from_bits(self.tcx, 0, self.param_env.and(ty)) - }, + } Err(LitToConstError::Reported) => { // create a dummy value and continue compiling Const::from_bits(self.tcx, 0, self.param_env.and(ty)) @@ -156,17 +154,18 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { pub fn pattern_from_hir(&mut self, p: &hir::Pat) -> Pat<'tcx> { let p = match self.tcx.hir().get(p.hir_id) { Node::Pat(p) | Node::Binding(p) => p, - node => bug!("pattern became {:?}", node) + node => bug!("pattern became {:?}", node), }; Pat::from_hir(self.tcx, self.param_env.and(self.identity_substs), self.tables(), p) } - pub fn trait_method(&mut self, - trait_def_id: DefId, - method_name: Symbol, - self_ty: Ty<'tcx>, - params: &[GenericArg<'tcx>]) - -> &'tcx ty::Const<'tcx> { + pub fn trait_method( + &mut self, + trait_def_id: DefId, + method_name: Symbol, + self_ty: Ty<'tcx>, + params: &[GenericArg<'tcx>], + ) -> &'tcx ty::Const<'tcx> { let substs = self.tcx.mk_substs_trait(self_ty, params); for item in self.tcx.associated_items(trait_def_id) { if item.kind == ty::AssocKind::Method && item.ident.name == method_name { @@ -180,9 +179,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { } pub fn all_fields(&mut self, adt_def: &ty::AdtDef, variant_index: VariantIdx) -> Vec { - (0..adt_def.variants[variant_index].fields.len()) - .map(Field::new) - .collect() + (0..adt_def.variants[variant_index].fields.len()).map(Field::new).collect() } pub fn needs_drop(&mut self, ty: Ty<'tcx>) -> bool { diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 46e0d2a17b32d..188c73e105a49 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -4,31 +4,31 @@ //! unit-tested and separated from the Rust source and compiler data //! structures. -use rustc::mir::{BinOp, BorrowKind, Field, UnOp}; +use self::cx::Cx; +use rustc::hir; use rustc::hir::def_id::DefId; use rustc::infer::canonical::Canonical; use rustc::middle::region; -use rustc::ty::subst::SubstsRef; -use rustc::ty::{AdtDef, UpvarSubsts, Ty, Const, UserType}; -use rustc::ty::adjustment::{PointerCast}; +use rustc::mir::{BinOp, BorrowKind, Field, UnOp}; +use rustc::ty::adjustment::PointerCast; use rustc::ty::layout::VariantIdx; -use rustc::hir; +use rustc::ty::subst::SubstsRef; +use rustc::ty::{AdtDef, Const, Ty, UpvarSubsts, UserType}; use syntax_pos::Span; -use self::cx::Cx; -pub mod cx; mod constant; +pub mod cx; pub mod pattern; -pub use self::pattern::{BindingMode, Pat, PatKind, PatRange, FieldPat}; pub(crate) use self::pattern::PatTyProj; +pub use self::pattern::{BindingMode, FieldPat, Pat, PatKind, PatRange}; mod util; #[derive(Copy, Clone, Debug)] pub enum LintLevel { Inherited, - Explicit(hir::HirId) + Explicit(hir::HirId), } #[derive(Clone, Debug)] @@ -47,7 +47,7 @@ pub enum BlockSafety { Safe, ExplicitUnsafe(hir::HirId), PushUnsafe, - PopUnsafe + PopUnsafe, } #[derive(Clone, Debug)] @@ -158,7 +158,7 @@ pub enum ExprKind<'tcx> { lhs: ExprRef<'tcx>, rhs: ExprRef<'tcx>, }, // NOT overloaded! - // LogicalOp is distinct from BinaryOp because of lazy evaluation of the operands. + // LogicalOp is distinct from BinaryOp because of lazy evaluation of the operands. Unary { op: UnOp, arg: ExprRef<'tcx>, @@ -247,7 +247,7 @@ pub enum ExprKind<'tcx> { user_ty: Option>>, fields: Vec>, - base: Option> + base: Option>, }, PlaceTypeAscription { source: ExprRef<'tcx>, @@ -280,7 +280,7 @@ pub enum ExprKind<'tcx> { InlineAsm { asm: &'tcx hir::InlineAsmInner, outputs: Vec>, - inputs: Vec> + inputs: Vec>, }, Yield { value: ExprRef<'tcx>, @@ -302,7 +302,7 @@ pub struct FieldExprRef<'tcx> { #[derive(Clone, Debug)] pub struct FruInfo<'tcx> { pub base: ExprRef<'tcx>, - pub field_types: Vec> + pub field_types: Vec>, } #[derive(Clone, Debug)] diff --git a/src/librustc_mir/hair/pattern/const_to_pat.rs b/src/librustc_mir/hair/pattern/const_to_pat.rs index bfc539639db1e..b9ec6ea5f97de 100644 --- a/src/librustc_mir/hair/pattern/const_to_pat.rs +++ b/src/librustc_mir/hair/pattern/const_to_pat.rs @@ -1,9 +1,9 @@ use crate::const_eval::const_variant_index; use rustc::hir; +use rustc::infer::InferCtxt; use rustc::lint; use rustc::mir::Field; -use rustc::infer::InferCtxt; use rustc::traits::{ObligationCause, PredicateObligation}; use rustc::ty::{self, Ty, TyCtxt}; @@ -11,7 +11,6 @@ use rustc_index::vec::Idx; use syntax_pos::Span; - use std::cell::Cell; use super::{FieldPat, Pat, PatCtxt, PatKind}; @@ -53,24 +52,30 @@ struct ConstToPat<'a, 'tcx> { } impl<'a, 'tcx> ConstToPat<'a, 'tcx> { - fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, - id: hir::HirId, - span: Span, - infcx: InferCtxt<'a, 'tcx>) -> Self { + fn new( + pat_ctxt: &PatCtxt<'_, 'tcx>, + id: hir::HirId, + span: Span, + infcx: InferCtxt<'a, 'tcx>, + ) -> Self { ConstToPat { - id, span, infcx, + id, + span, + infcx, param_env: pat_ctxt.param_env, include_lint_checks: pat_ctxt.include_lint_checks, saw_const_match_error: Cell::new(false), } } - fn tcx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } + fn tcx(&self) -> TyCtxt<'tcx> { + self.infcx.tcx + } - fn search_for_structural_match_violation(&self, - ty: Ty<'tcx>) - -> Option> - { + fn search_for_structural_match_violation( + &self, + ty: Ty<'tcx>, + ) -> Option> { ty::search_for_structural_match_violation(self.id, self.span, self.tcx(), ty) } @@ -93,20 +98,22 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // double-check that all types in the const implement `Structural`. let structural = self.search_for_structural_match_violation(cv.ty); - debug!("search_for_structural_match_violation cv.ty: {:?} returned: {:?}", - cv.ty, structural); + debug!( + "search_for_structural_match_violation cv.ty: {:?} returned: {:?}", + cv.ty, structural + ); if let Some(non_sm_ty) = structural { let adt_def = match non_sm_ty { ty::NonStructuralMatchTy::Adt(adt_def) => adt_def, - ty::NonStructuralMatchTy::Param => - bug!("use of constant whose type is a parameter inside a pattern"), + ty::NonStructuralMatchTy::Param => { + bug!("use of constant whose type is a parameter inside a pattern") + } }; let path = self.tcx().def_path_str(adt_def.did); let msg = format!( "to use a constant of type `{}` in a pattern, \ `{}` must be annotated with `#[derive(PartialEq, Eq)]`", - path, - path, + path, path, ); // double-check there even *is* a semantic `PartialEq` to dispatch to. @@ -122,14 +129,14 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // not *yet* implement `PartialEq`. So for now we leave this here. let ty_is_partial_eq: bool = { let partial_eq_trait_id = self.tcx().lang_items().eq_trait().unwrap(); - let obligation: PredicateObligation<'_> = - self.tcx().predicate_for_trait_def( - self.param_env, - ObligationCause::misc(self.span, self.id), - partial_eq_trait_id, - 0, - cv.ty, - &[]); + let obligation: PredicateObligation<'_> = self.tcx().predicate_for_trait_def( + self.param_env, + ObligationCause::misc(self.span, self.id), + partial_eq_trait_id, + 0, + cv.ty, + &[], + ); // FIXME: should this call a `predicate_must_hold` variant instead? self.infcx.predicate_may_hold(&obligation) }; @@ -138,10 +145,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { // span_fatal avoids ICE from resolution of non-existent method (rare case). self.tcx().sess.span_fatal(self.span, &msg); } else { - self.tcx().lint_hir(lint::builtin::INDIRECT_STRUCTURAL_MATCH, - self.id, - self.span, - &msg); + self.tcx().lint_hir( + lint::builtin::INDIRECT_STRUCTURAL_MATCH, + self.id, + self.span, + &msg, + ); } } } @@ -158,22 +167,18 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { let adt_subpattern = |i, variant_opt| { let field = Field::new(i); - let val = crate::const_eval::const_field( - tcx, param_env, variant_opt, field, cv - ); + let val = crate::const_eval::const_field(tcx, param_env, variant_opt, field, cv); self.recur(val) }; let adt_subpatterns = |n, variant_opt| { - (0..n).map(|i| { - let field = Field::new(i); - FieldPat { - field, - pattern: adt_subpattern(i, variant_opt), - } - }).collect::>() + (0..n) + .map(|i| { + let field = Field::new(i); + FieldPat { field, pattern: adt_subpattern(i, variant_opt) } + }) + .collect::>() }; - let kind = match cv.ty.kind { ty::Float(_) => { tcx.lint_hir( @@ -182,9 +187,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { span, "floating-point types cannot be used in patterns", ); - PatKind::Constant { - value: cv, - } + PatKind::Constant { value: cv } } ty::Adt(adt_def, _) if adt_def.is_union() => { // Matching on union fields is unsafe, we can't hide it in constants @@ -194,14 +197,12 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { } // keep old code until future-compat upgraded to errors. ty::Adt(adt_def, _) if !self.type_marked_structural(cv.ty) => { - debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", - adt_def, cv.ty); + debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, cv.ty); let path = tcx.def_path_str(adt_def.did); let msg = format!( "to use a constant of type `{}` in a pattern, \ `{}` must be annotated with `#[derive(PartialEq, Eq)]`", - path, - path, + path, path, ); self.saw_const_match_error.set(true); tcx.sess.span_err(span, &msg); @@ -211,14 +212,13 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { ty::Ref(_, adt_ty @ ty::TyS { kind: ty::Adt(_, _), .. }, _) if !self.type_marked_structural(adt_ty) => { - let adt_def = if let ty::Adt(adt_def, _) = adt_ty.kind { - adt_def - } else { - unreachable!() - }; + let adt_def = + if let ty::Adt(adt_def, _) = adt_ty.kind { adt_def } else { unreachable!() }; - debug!("adt_def {:?} has !type_marked_structural for adt_ty: {:?}", - adt_def, adt_ty); + debug!( + "adt_def {:?} has !type_marked_structural for adt_ty: {:?}", + adt_def, adt_ty + ); // HACK(estebank): Side-step ICE #53708, but anything other than erroring here // would be wrong. Returnging `PatKind::Wild` is not technically correct. @@ -226,8 +226,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { let msg = format!( "to use a constant of type `{}` in a pattern, \ `{}` must be annotated with `#[derive(PartialEq, Eq)]`", - path, - path, + path, path, ); self.saw_const_match_error.set(true); tcx.sess.span_err(span, &msg); @@ -239,44 +238,23 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { adt_def.variants[variant_index].fields.len(), Some(variant_index), ); - PatKind::Variant { - adt_def, - substs, - variant_index, - subpatterns, - } + PatKind::Variant { adt_def, substs, variant_index, subpatterns } } ty::Adt(adt_def, _) => { let struct_var = adt_def.non_enum_variant(); - PatKind::Leaf { - subpatterns: adt_subpatterns(struct_var.fields.len(), None), - } - } - ty::Tuple(fields) => { - PatKind::Leaf { - subpatterns: adt_subpatterns(fields.len(), None), - } - } - ty::Array(_, n) => { - PatKind::Array { - prefix: (0..n.eval_usize(tcx, self.param_env)) - .map(|i| adt_subpattern(i as usize, None)) - .collect(), - slice: None, - suffix: Vec::new(), - } - } - _ => { - PatKind::Constant { - value: cv, - } + PatKind::Leaf { subpatterns: adt_subpatterns(struct_var.fields.len(), None) } } + ty::Tuple(fields) => PatKind::Leaf { subpatterns: adt_subpatterns(fields.len(), None) }, + ty::Array(_, n) => PatKind::Array { + prefix: (0..n.eval_usize(tcx, self.param_env)) + .map(|i| adt_subpattern(i as usize, None)) + .collect(), + slice: None, + suffix: Vec::new(), + }, + _ => PatKind::Constant { value: cv }, }; - Pat { - span, - ty: cv.ty, - kind: Box::new(kind), - } + Pat { span, ty: cv.ty, kind: Box::new(kind) } } } diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index fdef6633925da..869aeeba418da 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -6,20 +6,20 @@ mod const_to_pat; pub(crate) use self::check_match::check_match; -use crate::hair::util::UserAnnotatedTyHelpers; use crate::hair::constant::*; +use crate::hair::util::UserAnnotatedTyHelpers; -use rustc::mir::{Field, BorrowKind, Mutability}; -use rustc::mir::{UserTypeProjection}; -use rustc::mir::interpret::{ConstValue, ErrorHandled, get_slice_bytes, sign_extend}; -use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, UserType, DefIdTree}; -use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations}; -use rustc::ty::subst::{SubstsRef, GenericArg}; -use rustc::ty::layout::VariantIdx; -use rustc::hir::{self, RangeEnd}; -use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind}; +use rustc::hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc::hir::ptr::P; +use rustc::hir::{self, RangeEnd}; +use rustc::mir::interpret::{get_slice_bytes, sign_extend, ConstValue, ErrorHandled}; +use rustc::mir::UserTypeProjection; +use rustc::mir::{BorrowKind, Field, Mutability}; +use rustc::ty::layout::VariantIdx; +use rustc::ty::subst::{GenericArg, SubstsRef}; +use rustc::ty::{self, AdtDef, DefIdTree, Region, Ty, TyCtxt, UserType}; +use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations}; use rustc_index::vec::Idx; @@ -70,9 +70,7 @@ pub struct PatTyProj<'tcx> { impl<'tcx> PatTyProj<'tcx> { pub(crate) fn from_user_type(user_annotation: CanonicalUserType<'tcx>) -> Self { - Self { - user_ty: user_annotation, - } + Self { user_ty: user_annotation } } pub(crate) fn user_ty( @@ -208,14 +206,16 @@ impl<'tcx> fmt::Display for Pat<'tcx> { match *self.kind { PatKind::Wild => write!(f, "_"), - PatKind::AscribeUserType { ref subpattern, .. } => - write!(f, "{}: _", subpattern), + PatKind::AscribeUserType { ref subpattern, .. } => write!(f, "{}: _", subpattern), PatKind::Binding { mutability, name, mode, ref subpattern, .. } => { let is_mut = match mode { BindingMode::ByValue => mutability == Mutability::Mut, BindingMode::ByRef(bk) => { write!(f, "ref ")?; - match bk { BorrowKind::Mut { .. } => true, _ => false } + match bk { + BorrowKind::Mut { .. } => true, + _ => false, + } } }; if is_mut { @@ -227,20 +227,21 @@ impl<'tcx> fmt::Display for Pat<'tcx> { } Ok(()) } - PatKind::Variant { ref subpatterns, .. } | - PatKind::Leaf { ref subpatterns } => { + PatKind::Variant { ref subpatterns, .. } | PatKind::Leaf { ref subpatterns } => { let variant = match *self.kind { PatKind::Variant { adt_def, variant_index, .. } => { Some(&adt_def.variants[variant_index]) } - _ => if let ty::Adt(adt, _) = self.ty.kind { - if !adt.is_enum() { - Some(&adt.variants[VariantIdx::new(0)]) + _ => { + if let ty::Adt(adt, _) = self.ty.kind { + if !adt.is_enum() { + Some(&adt.variants[VariantIdx::new(0)]) + } else { + None + } } else { None } - } else { - None } }; @@ -302,20 +303,18 @@ impl<'tcx> fmt::Display for Pat<'tcx> { ty::Ref(_, _, mutbl) => { write!(f, "&{}", mutbl.prefix_str())?; } - _ => bug!("{} is a bad Deref pattern type", self.ty) + _ => bug!("{} is a bad Deref pattern type", self.ty), } write!(f, "{}", subpattern) } - PatKind::Constant { value } => { - write!(f, "{}", value) - } + PatKind::Constant { value } => write!(f, "{}", value), PatKind::Range(PatRange { lo, hi, end }) => { write!(f, "{}", lo)?; write!(f, "{}", end)?; write!(f, "{}", hi) } - PatKind::Slice { ref prefix, ref slice, ref suffix } | - PatKind::Array { ref prefix, ref slice, ref suffix } => { + PatKind::Slice { ref prefix, ref slice, ref suffix } + | PatKind::Array { ref prefix, ref slice, ref suffix } => { write!(f, "[")?; for p in prefix { write!(f, "{}{}", start_or_comma(), p)?; @@ -324,7 +323,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> { write!(f, "{}", start_or_comma())?; match *slice.kind { PatKind::Wild => {} - _ => write!(f, "{}", slice)? + _ => write!(f, "{}", slice)?, } write!(f, "..")?; } @@ -412,21 +411,17 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // adjustments in *reverse order* (last-in-first-out, so that the last `Deref` inserted // gets the least-dereferenced type). let unadjusted_pat = self.lower_pattern_unadjusted(pat); - self.tables - .pat_adjustments() - .get(pat.hir_id) - .unwrap_or(&vec![]) - .iter() - .rev() - .fold(unadjusted_pat, |pat, ref_ty| { - debug!("{:?}: wrapping pattern with type {:?}", pat, ref_ty); - Pat { - span: pat.span, - ty: ref_ty, - kind: Box::new(PatKind::Deref { subpattern: pat }), - } - }, - ) + self.tables.pat_adjustments().get(pat.hir_id).unwrap_or(&vec![]).iter().rev().fold( + unadjusted_pat, + |pat, ref_ty| { + debug!("{:?}: wrapping pattern with type {:?}", pat, ref_ty); + Pat { + span: pat.span, + ty: ref_ty, + kind: Box::new(PatKind::Deref { subpattern: pat }), + } + }, + ) } fn lower_range_expr( @@ -463,16 +458,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { (PatKind::Constant { value: lo }, PatKind::Constant { value: hi }) => { assert_eq!(lo.ty, ty); assert_eq!(hi.ty, ty); - let cmp = compare_const_vals( - self.tcx, - lo, - hi, - self.param_env, - ty, - ); + let cmp = compare_const_vals(self.tcx, lo, hi, self.param_env, ty); match (end, cmp) { - (RangeEnd::Excluded, Some(Ordering::Less)) => - PatKind::Range(PatRange { lo, hi, end }), + (RangeEnd::Excluded, Some(Ordering::Less)) => { + PatKind::Range(PatRange { lo, hi, end }) + } (RangeEnd::Excluded, _) => { span_err!( self.tcx.sess, @@ -495,22 +485,21 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { E0030, "lower range bound must be less than or equal to upper" ); - err.span_label( - lo_expr.span, - "lower bound larger than upper bound", - ); + err.span_label(lo_expr.span, "lower bound larger than upper bound"); if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note("When matching against a range, the compiler \ + err.note( + "When matching against a range, the compiler \ verifies that the range is non-empty. Range \ patterns include both end-points, so this is \ equivalent to requiring the start of the range \ - to be less than or equal to the end of the range."); + to be less than or equal to the end of the range.", + ); } err.emit(); PatKind::Wild } } - }, + } ref pats => { self.tcx.sess.delay_span_bug( pat.span, @@ -521,7 +510,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { ); PatKind::Wild - }, + } }; // If we are handling a range with associated constants (e.g. @@ -531,7 +520,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { if let Some(ascription) = ascription { kind = PatKind::AscribeUserType { ascription: *ascription, - subpattern: Pat { span: pat.span, ty, kind: Box::new(kind), }, + subpattern: Pat { span: pat.span, ty, kind: Box::new(kind) }, }; } } @@ -543,8 +532,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { return self.lower_path(qpath, pat.hir_id, pat.span); } - hir::PatKind::Ref(ref subpattern, _) | - hir::PatKind::Box(ref subpattern) => { + hir::PatKind::Ref(ref subpattern, _) | hir::PatKind::Box(ref subpattern) => { PatKind::Deref { subpattern: self.lower_pattern(subpattern) } } @@ -562,16 +550,17 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } hir::PatKind::Binding(_, id, ident, ref sub) => { - let bm = *self.tables.pat_binding_modes().get(pat.hir_id) - .expect("missing binding mode"); + let bm = + *self.tables.pat_binding_modes().get(pat.hir_id).expect("missing binding mode"); let (mutability, mode) = match bm { ty::BindByValue(mutbl) => (mutbl, BindingMode::ByValue), - ty::BindByReference(hir::Mutability::Mut) => - (Mutability::Not, BindingMode::ByRef( - BorrowKind::Mut { allow_two_phase_borrow: false })), - ty::BindByReference(hir::Mutability::Not) => - (Mutability::Not, BindingMode::ByRef( - BorrowKind::Shared)), + ty::BindByReference(hir::Mutability::Mut) => ( + Mutability::Not, + BindingMode::ByRef(BorrowKind::Mut { allow_two_phase_borrow: false }), + ), + ty::BindByReference(hir::Mutability::Not) => { + (Mutability::Not, BindingMode::ByRef(BorrowKind::Shared)) + } }; // A ref x pattern is the same node used for x, and as such it has @@ -608,16 +597,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { hir::PatKind::Struct(ref qpath, ref fields, _) => { let res = self.tables.qpath_res(qpath, pat.hir_id); - let subpatterns = - fields.iter() - .map(|field| { - FieldPat { - field: Field::new(self.tcx.field_index(field.hir_id, - self.tables)), - pattern: self.lower_pattern(&field.pat), - } - }) - .collect(); + let subpatterns = fields + .iter() + .map(|field| FieldPat { + field: Field::new(self.tcx.field_index(field.hir_id, self.tables)), + pattern: self.lower_pattern(&field.pat), + }) + .collect(); self.lower_variant_or_leaf(res, pat.hir_id, pat.span, ty, subpatterns) } @@ -625,11 +611,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { hir::PatKind::Or(ref pats) => PatKind::Or { pats: self.lower_patterns(pats) }, }; - Pat { - span: pat.span, - ty, - kind: Box::new(kind), - } + Pat { span: pat.span, ty, kind: Box::new(kind) } } fn lower_tuple_subpats( @@ -642,7 +624,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { .enumerate_and_adjust(expected_len, gap_pos) .map(|(i, subpattern)| FieldPat { field: Field::new(i), - pattern: self.lower_pattern(subpattern) + pattern: self.lower_pattern(subpattern), }) .collect() } @@ -691,7 +673,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => { let variant_id = self.tcx.parent(variant_ctor_id).unwrap(); Res::Def(DefKind::Variant, variant_id) - }, + } res => res, }; @@ -701,9 +683,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let adt_def = self.tcx.adt_def(enum_id); if adt_def.is_enum() { let substs = match ty.kind { - ty::Adt(_, substs) | - ty::FnDef(_, substs) => substs, - ty::Error => { // Avoid ICE (#50585) + ty::Adt(_, substs) | ty::FnDef(_, substs) => substs, + ty::Error => { + // Avoid ICE (#50585) return PatKind::Wild; } _ => bug!("inappropriate type for def: {:?}", ty), @@ -725,9 +707,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { | Res::Def(DefKind::TyAlias, _) | Res::Def(DefKind::AssocTy, _) | Res::SelfTy(..) - | Res::SelfCtor(..) => { - PatKind::Leaf { subpatterns } - } + | Res::SelfCtor(..) => PatKind::Leaf { subpatterns }, _ => { self.errors.push(PatternError::NonConstPath(span)); @@ -738,11 +718,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { if let Some(user_ty) = self.user_substs_applied_to_ty_of_hir_id(hir_id) { debug!("lower_variant_or_leaf: kind={:?} user_ty={:?} span={:?}", kind, user_ty, span); kind = PatKind::AscribeUserType { - subpattern: Pat { - span, - ty, - kind: Box::new(kind), - }, + subpattern: Pat { span, ty, kind: Box::new(kind) }, ascription: Ascription { user_ty: PatTyProj::from_user_type(user_ty), user_ty_span: span, @@ -757,11 +733,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { /// Takes a HIR Path. If the path is a constant, evaluates it and feeds /// it to `const_to_pat`. Any other path (like enum variants without fields) /// is converted to the corresponding pattern via `lower_variant_or_leaf`. - fn lower_path(&mut self, - qpath: &hir::QPath, - id: hir::HirId, - span: Span) - -> Pat<'tcx> { + fn lower_path(&mut self, qpath: &hir::QPath, id: hir::HirId, span: Span) -> Pat<'tcx> { let ty = self.tables.node_type(id); let res = self.tables.qpath_res(qpath, id); let is_associated_const = match res { @@ -783,24 +755,22 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let user_ty = PatTyProj::from_user_type(*u_ty); Pat { span, - kind: Box::new( - PatKind::AscribeUserType { - subpattern: pattern, - ascription: Ascription { - /// Note that use `Contravariant` here. See the - /// `variance` field documentation for details. - variance: ty::Variance::Contravariant, - user_ty, - user_ty_span: span, - }, - } - ), + kind: Box::new(PatKind::AscribeUserType { + subpattern: pattern, + ascription: Ascription { + /// Note that use `Contravariant` here. See the + /// `variance` field documentation for details. + variance: ty::Variance::Contravariant, + user_ty, + user_ty_span: span, + }, + }), ty: value.ty, } } else { pattern - } - }, + }; + } Err(ErrorHandled::TooGeneric) => { self.errors.push(if is_associated_const { PatternError::AssocConstInPattern(span) @@ -808,12 +778,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { PatternError::StaticInPattern(span) }); PatKind::Wild - }, + } Err(_) => { - self.tcx.sess.span_err( - span, - "could not evaluate constant pattern", - ); + self.tcx.sess.span_err(span, "could not evaluate constant pattern"); PatKind::Wild } } @@ -821,11 +788,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { _ => self.lower_variant_or_leaf(res, id, span, ty, vec![]), }; - Pat { - span, - ty, - kind: Box::new(kind), - } + Pat { span, ty, kind: Box::new(kind) } } /// Converts literals, paths and negation of literals to patterns. @@ -837,16 +800,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { hir::ExprKind::Lit(ref lit) => { let ty = self.tables.expr_ty(expr); match lit_to_const(&lit.node, self.tcx, ty, false) { - Ok(val) => { - *self.const_to_pat(val, expr.hir_id, lit.span).kind - }, + Ok(val) => *self.const_to_pat(val, expr.hir_id, lit.span).kind, Err(LitToConstError::UnparseableFloat) => { self.errors.push(PatternError::FloatBug); PatKind::Wild - }, + } Err(LitToConstError::Reported) => PatKind::Wild, } - }, + } hir::ExprKind::Path(ref qpath) => *self.lower_path(qpath, expr.hir_id, expr.span).kind, hir::ExprKind::Unary(hir::UnNeg, ref expr) => { let ty = self.tables.expr_ty(expr); @@ -855,13 +816,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { _ => span_bug!(expr.span, "not a literal: {:?}", expr), }; match lit_to_const(&lit.node, self.tcx, ty, true) { - Ok(val) => { - *self.const_to_pat(val, expr.hir_id, lit.span).kind - }, + Ok(val) => *self.const_to_pat(val, expr.hir_id, lit.span).kind, Err(LitToConstError::UnparseableFloat) => { self.errors.push(PatternError::FloatBug); PatKind::Wild - }, + } Err(LitToConstError::Reported) => PatKind::Wild, } } @@ -880,8 +839,7 @@ impl UserAnnotatedTyHelpers<'tcx> for PatCtxt<'_, 'tcx> { } } - -pub trait PatternFoldable<'tcx> : Sized { +pub trait PatternFoldable<'tcx>: Sized { fn fold_with>(&self, folder: &mut F) -> Self { self.super_fold_with(folder) } @@ -889,7 +847,7 @@ pub trait PatternFoldable<'tcx> : Sized { fn super_fold_with>(&self, folder: &mut F) -> Self; } -pub trait PatternFolder<'tcx> : Sized { +pub trait PatternFolder<'tcx>: Sized { fn fold_pattern(&mut self, pattern: &Pat<'tcx>) -> Pat<'tcx> { pattern.super_fold_with(self) } @@ -899,7 +857,6 @@ pub trait PatternFolder<'tcx> : Sized { } } - impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Box { fn super_fold_with>(&self, folder: &mut F) -> Self { let content: T = (**self).fold_with(folder); @@ -914,7 +871,7 @@ impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Vec { } impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Option { - fn super_fold_with>(&self, folder: &mut F) -> Self{ + fn super_fold_with>(&self, folder: &mut F) -> Self { self.as_ref().map(|t| t.fold_with(folder)) } } @@ -931,7 +888,7 @@ macro_rules! CloneImpls { } } -CloneImpls!{ <'tcx> +CloneImpls! { <'tcx> Span, Field, Mutability, ast::Name, hir::HirId, usize, ty::Const<'tcx>, Region<'tcx>, Ty<'tcx>, BindingMode, &'tcx AdtDef, SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>, @@ -940,10 +897,7 @@ CloneImpls!{ <'tcx> impl<'tcx> PatternFoldable<'tcx> for FieldPat<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { - FieldPat { - field: self.field.fold_with(folder), - pattern: self.pattern.fold_with(folder) - } + FieldPat { field: self.field.fold_with(folder), pattern: self.pattern.fold_with(folder) } } } @@ -956,7 +910,7 @@ impl<'tcx> PatternFoldable<'tcx> for Pat<'tcx> { Pat { ty: self.ty.fold_with(folder), span: self.span.fold_with(folder), - kind: self.kind.fold_with(folder) + kind: self.kind.fold_with(folder), } } } @@ -971,11 +925,7 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> { PatKind::Wild => PatKind::Wild, PatKind::AscribeUserType { ref subpattern, - ascription: Ascription { - variance, - ref user_ty, - user_ty_span, - }, + ascription: Ascription { variance, ref user_ty, user_ty_span }, } => PatKind::AscribeUserType { subpattern: subpattern.fold_with(folder), ascription: Ascription { @@ -984,65 +934,41 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> { user_ty_span, }, }, - PatKind::Binding { - mutability, - name, - mode, - var, - ty, - ref subpattern, - } => PatKind::Binding { - mutability: mutability.fold_with(folder), - name: name.fold_with(folder), - mode: mode.fold_with(folder), - var: var.fold_with(folder), - ty: ty.fold_with(folder), - subpattern: subpattern.fold_with(folder), - }, - PatKind::Variant { - adt_def, - substs, - variant_index, - ref subpatterns, - } => PatKind::Variant { - adt_def: adt_def.fold_with(folder), - substs: substs.fold_with(folder), - variant_index, - subpatterns: subpatterns.fold_with(folder) - }, - PatKind::Leaf { - ref subpatterns, - } => PatKind::Leaf { - subpatterns: subpatterns.fold_with(folder), - }, - PatKind::Deref { - ref subpattern, - } => PatKind::Deref { - subpattern: subpattern.fold_with(folder), - }, - PatKind::Constant { - value - } => PatKind::Constant { - value, - }, + PatKind::Binding { mutability, name, mode, var, ty, ref subpattern } => { + PatKind::Binding { + mutability: mutability.fold_with(folder), + name: name.fold_with(folder), + mode: mode.fold_with(folder), + var: var.fold_with(folder), + ty: ty.fold_with(folder), + subpattern: subpattern.fold_with(folder), + } + } + PatKind::Variant { adt_def, substs, variant_index, ref subpatterns } => { + PatKind::Variant { + adt_def: adt_def.fold_with(folder), + substs: substs.fold_with(folder), + variant_index, + subpatterns: subpatterns.fold_with(folder), + } + } + PatKind::Leaf { ref subpatterns } => { + PatKind::Leaf { subpatterns: subpatterns.fold_with(folder) } + } + PatKind::Deref { ref subpattern } => { + PatKind::Deref { subpattern: subpattern.fold_with(folder) } + } + PatKind::Constant { value } => PatKind::Constant { value }, PatKind::Range(range) => PatKind::Range(range), - PatKind::Slice { - ref prefix, - ref slice, - ref suffix, - } => PatKind::Slice { + PatKind::Slice { ref prefix, ref slice, ref suffix } => PatKind::Slice { prefix: prefix.fold_with(folder), slice: slice.fold_with(folder), - suffix: suffix.fold_with(folder) + suffix: suffix.fold_with(folder), }, - PatKind::Array { - ref prefix, - ref slice, - ref suffix - } => PatKind::Array { + PatKind::Array { ref prefix, ref slice, ref suffix } => PatKind::Array { prefix: prefix.fold_with(folder), slice: slice.fold_with(folder), - suffix: suffix.fold_with(folder) + suffix: suffix.fold_with(folder), }, PatKind::Or { ref pats } => PatKind::Or { pats: pats.fold_with(folder) }, } @@ -1092,13 +1018,15 @@ pub fn compare_const_vals<'tcx>( Some((a as i128).cmp(&(b as i128))) } _ => Some(a.cmp(&b)), - } + }; } if let ty::Str = ty.kind { match (a.val, b.val) { - (ty::ConstKind::Value(a_val @ ConstValue::Slice { .. }), - ty::ConstKind::Value(b_val @ ConstValue::Slice { .. })) => { + ( + ty::ConstKind::Value(a_val @ ConstValue::Slice { .. }), + ty::ConstKind::Value(b_val @ ConstValue::Slice { .. }), + ) => { let a_bytes = get_slice_bytes(&tcx, a_val); let b_bytes = get_slice_bytes(&tcx, b_val); return from_bool(a_bytes == b_bytes); diff --git a/src/librustc_mir/hair/util.rs b/src/librustc_mir/hair/util.rs index d63541f7a3f56..53880b0d9b5fc 100644 --- a/src/librustc_mir/hair/util.rs +++ b/src/librustc_mir/hair/util.rs @@ -25,11 +25,7 @@ crate trait UserAnnotatedTyHelpers<'tcx> { Some(user_ty) } ty::FnDef(..) => Some(user_ty), - _ => bug!( - "ty: {:?} should not have user provided type {:?} recorded ", - ty, - user_ty - ), + _ => bug!("ty: {:?} should not have user provided type {:?} recorded ", ty, user_ty), } } } diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index e9602ecfa4c72..852b7bb4bd654 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -1,17 +1,15 @@ +use rustc::ty::adjustment::PointerCast; +use rustc::ty::layout::{self, Size, TyLayout}; use rustc::ty::{self, Ty, TypeAndMut, TypeFoldable}; -use rustc::ty::layout::{self, TyLayout, Size}; -use rustc::ty::adjustment::{PointerCast}; use syntax::ast::FloatTy; use syntax::symbol::sym; -use rustc_apfloat::ieee::{Single, Double}; -use rustc_apfloat::{Float, FloatConvert}; -use rustc::mir::interpret::{ - Scalar, InterpResult, PointerArithmetic, -}; +use rustc::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc::mir::CastKind; +use rustc_apfloat::ieee::{Double, Single}; +use rustc_apfloat::{Float, FloatConvert}; -use super::{InterpCx, Machine, PlaceTy, OpTy, ImmTy, Immediate, FnVal}; +use super::{FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, PlaceTy}; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn cast( @@ -52,7 +50,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env, def_id, substs, - ).ok_or_else(|| err_inval!(TooGeneric))?; + ) + .ok_or_else(|| err_inval!(TooGeneric))?; let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); self.write_scalar(fn_ptr, dest)?; @@ -107,55 +106,61 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match src.layout.ty.kind { // Floating point - Float(FloatTy::F32) => - return Ok(self.cast_from_float(src.to_scalar()?.to_f32()?, dest_layout.ty)?.into()), - Float(FloatTy::F64) => - return Ok(self.cast_from_float(src.to_scalar()?.to_f64()?, dest_layout.ty)?.into()), + Float(FloatTy::F32) => { + return Ok(self + .cast_from_float(src.to_scalar()?.to_f32()?, dest_layout.ty)? + .into()); + } + Float(FloatTy::F64) => { + return Ok(self + .cast_from_float(src.to_scalar()?.to_f64()?, dest_layout.ty)? + .into()); + } // The rest is integer/pointer-"like", including fn ptr casts and casts from enums that // are represented as integers. - _ => - assert!( - src.layout.ty.is_bool() || src.layout.ty.is_char() || - src.layout.ty.is_enum() || src.layout.ty.is_integral() || - src.layout.ty.is_any_ptr(), - "Unexpected cast from type {:?}", src.layout.ty - ) + _ => assert!( + src.layout.ty.is_bool() + || src.layout.ty.is_char() + || src.layout.ty.is_enum() + || src.layout.ty.is_integral() + || src.layout.ty.is_any_ptr(), + "Unexpected cast from type {:?}", + src.layout.ty + ), } // Handle cast from a univariant (ZST) enum. match src.layout.variants { layout::Variants::Single { index } => { - if let Some(discr) = - src.layout.ty.discriminant_for_variant(*self.tcx, index) - { + if let Some(discr) = src.layout.ty.discriminant_for_variant(*self.tcx, index) { assert!(src.layout.is_zst()); return Ok(Scalar::from_uint(discr.val, dest_layout.size).into()); } } - layout::Variants::Multiple { .. } => {}, + layout::Variants::Multiple { .. } => {} } // Handle casting the metadata away from a fat pointer. - if src.layout.ty.is_unsafe_ptr() && dest_layout.ty.is_unsafe_ptr() && - dest_layout.size != src.layout.size + if src.layout.ty.is_unsafe_ptr() + && dest_layout.ty.is_unsafe_ptr() + && dest_layout.size != src.layout.size { - assert_eq!(src.layout.size, 2*self.memory.pointer_size()); + assert_eq!(src.layout.size, 2 * self.memory.pointer_size()); assert_eq!(dest_layout.size, self.memory.pointer_size()); assert!(dest_layout.ty.is_unsafe_ptr()); match *src { - Immediate::ScalarPair(data, _) => - return Ok(data.into()), - Immediate::Scalar(..) => - bug!( - "{:?} input to a fat-to-thin cast ({:?} -> {:?})", - *src, src.layout.ty, dest_layout.ty - ), + Immediate::ScalarPair(data, _) => return Ok(data.into()), + Immediate::Scalar(..) => bug!( + "{:?} input to a fat-to-thin cast ({:?} -> {:?})", + *src, + src.layout.ty, + dest_layout.ty + ), }; } // Handle casting any ptr to raw ptr (might be a fat ptr). - if src.layout.ty.is_any_ptr() && dest_layout.ty.is_unsafe_ptr() - { + if src.layout.ty.is_any_ptr() && dest_layout.ty.is_unsafe_ptr() { // The only possible size-unequal case was handled above. assert_eq!(src.layout.size, dest_layout.size); return Ok(*src); @@ -177,11 +182,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx, Scalar> { // Let's make sure v is sign-extended *if* it has a signed type. let signed = src_layout.abi.is_signed(); - let v = if signed { - self.sign_extend(v, src_layout) - } else { - v - }; + let v = if signed { self.sign_extend(v, src_layout) } else { v }; trace!("cast_from_int: {}, {}, {}", v, src_layout.ty, dest_layout.ty); use rustc::ty::TyKind::*; match dest_layout.ty.kind { @@ -190,24 +191,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(Scalar::from_uint(v, dest_layout.size)) } - Float(FloatTy::F32) if signed => Ok(Scalar::from_f32( - Single::from_i128(v as i128).value - )), - Float(FloatTy::F64) if signed => Ok(Scalar::from_f64( - Double::from_i128(v as i128).value - )), - Float(FloatTy::F32) => Ok(Scalar::from_f32( - Single::from_u128(v).value - )), - Float(FloatTy::F64) => Ok(Scalar::from_f64( - Double::from_u128(v).value - )), + Float(FloatTy::F32) if signed => { + Ok(Scalar::from_f32(Single::from_i128(v as i128).value)) + } + Float(FloatTy::F64) if signed => { + Ok(Scalar::from_f64(Double::from_i128(v as i128).value)) + } + Float(FloatTy::F32) => Ok(Scalar::from_f32(Single::from_u128(v).value)), + Float(FloatTy::F64) => Ok(Scalar::from_f64(Double::from_u128(v).value)), Char => { // `u8` to `char` cast debug_assert_eq!(v as u8 as u128, v); Ok(Scalar::from_uint(v, Size::from_bytes(4))) - }, + } // Casts to bool are not permitted by rustc, no need to handle them here. _ => bug!("invalid int to {:?} cast", dest_layout.ty), @@ -217,9 +214,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { fn cast_from_float( &self, f: F, - dest_ty: Ty<'tcx> + dest_ty: Ty<'tcx>, ) -> InterpResult<'tcx, Scalar> - where F: Float + Into> + FloatConvert + FloatConvert + where + F: Float + Into> + FloatConvert + FloatConvert, { use rustc::ty::TyKind::*; match dest_ty.kind { @@ -229,19 +227,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let v = f.to_u128(width).value; // This should already fit the bit width Ok(Scalar::from_uint(v, Size::from_bits(width as u64))) - }, + } // float -> int Int(t) => { let width = t.bit_width().unwrap_or_else(|| self.pointer_size().bits() as usize); let v = f.to_i128(width).value; Ok(Scalar::from_int(v, Size::from_bits(width as u64))) - }, + } // float -> f32 - Float(FloatTy::F32) => - Ok(Scalar::from_f32(f.convert(&mut false).value)), + Float(FloatTy::F32) => Ok(Scalar::from_f32(f.convert(&mut false).value)), // float -> f64 - Float(FloatTy::F64) => - Ok(Scalar::from_f64(f.convert(&mut false).value)), + Float(FloatTy::F64) => Ok(Scalar::from_f64(f.convert(&mut false).value)), // That's it. _ => bug!("invalid float to {:?} cast", dest_ty), } @@ -296,10 +292,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx> { trace!("Unsizing {:?} into {:?}", src, dest); match (&src.layout.ty.kind, &dest.layout.ty.kind) { - (&ty::Ref(_, s, _), &ty::Ref(_, d, _)) | - (&ty::Ref(_, s, _), &ty::RawPtr(TypeAndMut { ty: d, .. })) | - (&ty::RawPtr(TypeAndMut { ty: s, .. }), - &ty::RawPtr(TypeAndMut { ty: d, .. })) => { + (&ty::Ref(_, s, _), &ty::Ref(_, d, _)) + | (&ty::Ref(_, s, _), &ty::RawPtr(TypeAndMut { ty: d, .. })) + | (&ty::RawPtr(TypeAndMut { ty: s, .. }), &ty::RawPtr(TypeAndMut { ty: d, .. })) => { self.unsize_into_ptr(src, dest, s, d) } (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { @@ -333,13 +328,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } Ok(()) } - _ => { - bug!( - "unsize_into: invalid conversion: {:?} -> {:?}", - src.layout, - dest.layout - ) - } + _ => bug!("unsize_into: invalid conversion: {:?} -> {:?}", src.layout, dest.layout), } } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 653718c462f07..ad2af8d7aca52 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -2,29 +2,26 @@ use std::cell::Cell; use std::fmt::Write; use std::mem; -use syntax::source_map::{self, Span, DUMMY_SP}; -use rustc::ich::StableHashingContext; -use rustc::hir::def_id::DefId; use rustc::hir::def::DefKind; +use rustc::hir::def_id::DefId; +use rustc::ich::StableHashingContext; use rustc::mir; -use rustc::ty::layout::{ - self, Size, Align, HasDataLayout, LayoutOf, TyLayout +use rustc::mir::interpret::{ + sign_extend, truncate, AllocId, FrameInfo, GlobalId, InterpResult, Pointer, Scalar, }; +use rustc::ty::layout::{self, Align, HasDataLayout, LayoutOf, Size, TyLayout}; +use rustc::ty::query::TyCtxtAt; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; -use rustc::ty::query::TyCtxtAt; -use rustc_index::vec::IndexVec; -use rustc::mir::interpret::{ - GlobalId, Scalar, Pointer, FrameInfo, AllocId, - InterpResult, truncate, sign_extend, -}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_index::vec::IndexVec; use rustc_macros::HashStable; +use syntax::source_map::{self, Span, DUMMY_SP}; use super::{ - Immediate, Operand, MemPlace, MPlaceTy, Place, PlaceTy, ScalarMaybeUndef, - Memory, Machine, StackPopInfo + Immediate, MPlaceTy, Machine, MemPlace, Memory, Operand, Place, PlaceTy, ScalarMaybeUndef, + StackPopInfo, }; pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { @@ -50,7 +47,7 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { /// A stack frame. #[derive(Clone)] -pub struct Frame<'mir, 'tcx, Tag=(), Extra=()> { +pub struct Frame<'mir, 'tcx, Tag = (), Extra = ()> { //////////////////////////////////////////////////////////////////////////////// // Function and callsite information //////////////////////////////////////////////////////////////////////////////// @@ -113,7 +110,7 @@ pub enum StackPopCleanup { /// State of a local variable including a memoized layout #[derive(Clone, PartialEq, Eq, HashStable)] -pub struct LocalState<'tcx, Tag=(), Id=AllocId> { +pub struct LocalState<'tcx, Tag = (), Id = AllocId> { pub value: LocalValue, /// Don't modify if `Some`, this is only used to prevent computing the layout twice #[stable_hasher(ignore)] @@ -122,7 +119,7 @@ pub struct LocalState<'tcx, Tag=(), Id=AllocId> { /// Current value of a local variable #[derive(Clone, PartialEq, Eq, Debug, HashStable)] // Miri debug-prints these -pub enum LocalValue { +pub enum LocalValue { /// This local is not currently alive, and cannot be used at all. Dead, /// This local is alive but not yet initialized. It can be written to @@ -142,8 +139,9 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { pub fn access(&self) -> InterpResult<'tcx, Operand> { match self.value { LocalValue::Dead => throw_unsup!(DeadLocal), - LocalValue::Uninitialized => - bug!("The type checker should prevent reading from a never-written local"), + LocalValue::Uninitialized => { + bug!("The type checker should prevent reading from a never-written local") + } LocalValue::Live(val) => Ok(val), } } @@ -156,10 +154,8 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { match self.value { LocalValue::Dead => throw_unsup!(DeadLocal), LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)), - ref mut local @ LocalValue::Live(Operand::Immediate(_)) | - ref mut local @ LocalValue::Uninitialized => { - Ok(Ok(local)) - } + ref mut local @ LocalValue::Live(Operand::Immediate(_)) + | ref mut local @ LocalValue::Uninitialized => Ok(Ok(local)), } } } @@ -245,7 +241,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn force_bits( &self, scalar: Scalar, - size: Size + size: Size, ) -> InterpResult<'tcx, u128> { self.memory.force_bits(scalar, size) } @@ -326,11 +322,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(self.tcx.promoted_mir(did)[promoted].unwrap_read_only()); } match instance { - ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) { - Ok(self.tcx.optimized_mir(did).unwrap_read_only()) - } else { - throw_unsup!(NoMirFor(self.tcx.def_path_str(def_id))) - }, + ty::InstanceDef::Item(def_id) => { + if self.tcx.is_mir_available(did) { + Ok(self.tcx.optimized_mir(did).unwrap_read_only()) + } else { + throw_unsup!(NoMirFor(self.tcx.def_path_str(def_id))) + } + } _ => Ok(self.tcx.instance_mir(instance)), } } @@ -352,17 +350,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub(super) fn resolve( &self, def_id: DefId, - substs: SubstsRef<'tcx> + substs: SubstsRef<'tcx>, ) -> InterpResult<'tcx, ty::Instance<'tcx>> { trace!("resolve: {:?}, {:#?}", def_id, substs); trace!("param_env: {:#?}", self.param_env); trace!("substs: {:#?}", substs); - ty::Instance::resolve( - *self.tcx, - self.param_env, - def_id, - substs, - ).ok_or_else(|| err_inval!(TooGeneric).into()) + ty::Instance::resolve(*self.tcx, self.param_env, def_id, substs) + .ok_or_else(|| err_inval!(TooGeneric).into()) } pub fn layout_of_local( @@ -436,7 +430,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // of `extern type`, this should be adapted. It is just a temporary hack // to get some code to work that probably ought to work. if sized_size == Size::ZERO { - return Ok(None) + return Ok(None); } else { bug!("Fields cannot be extern types, unless they are at offset 0") } @@ -463,8 +457,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Check if this brought us over the size limit. if size.bytes() >= self.tcx.data_layout().obj_size_bound() { - throw_ub_format!("wide pointer metadata contains invalid information: \ - total size is bigger than largest supported object"); + throw_ub_format!( + "wide pointer metadata contains invalid information: \ + total size is bigger than largest supported object" + ); } Ok(Some((size, align))) } @@ -475,19 +471,21 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } ty::Slice(_) | ty::Str => { - let len = metadata.expect("slice fat ptr must have length").to_machine_usize(self)?; + let len = + metadata.expect("slice fat ptr must have length").to_machine_usize(self)?; let elem = layout.field(self, 0)?; // Make sure the slice is not too big. - let size = elem.size.checked_mul(len, &*self.tcx) - .ok_or_else(|| err_ub_format!("invalid slice: \ - total size is bigger than largest supported object"))?; + let size = elem.size.checked_mul(len, &*self.tcx).ok_or_else(|| { + err_ub_format!( + "invalid slice: \ + total size is bigger than largest supported object" + ) + })?; Ok(Some((size, elem.align.abi))) } - ty::Foreign(_) => { - Ok(None) - } + ty::Foreign(_) => Ok(None), _ => bug!("size_and_align_of::<{:?}> not supported", layout.ty), } @@ -495,7 +493,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline] pub fn size_and_align_of_mplace( &self, - mplace: MPlaceTy<'tcx, M::PointerTag> + mplace: MPlaceTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx, Option<(Size, Align)>> { self.size_and_align_of(mplace.meta, mplace.layout) } @@ -532,10 +530,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // don't allocate at all for trivial constants if body.local_decls.len() > 1 { // Locals are initially uninitialized. - let dummy = LocalState { - value: LocalValue::Uninitialized, - layout: Cell::new(None), - }; + let dummy = LocalState { value: LocalValue::Uninitialized, layout: Cell::new(None) }; let mut locals = IndexVec::from_elem(dummy, &body.local_decls); // Return place is handled specially by the `eval_place` functions, and the // entry in `locals` should never be used. Make it dead, to be sure. @@ -543,24 +538,21 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Now mark those locals as dead that we do not want to initialize match self.tcx.def_kind(instance.def_id()) { // statics and constants don't have `Storage*` statements, no need to look for them - Some(DefKind::Static) - | Some(DefKind::Const) - | Some(DefKind::AssocConst) => {}, + Some(DefKind::Static) | Some(DefKind::Const) | Some(DefKind::AssocConst) => {} _ => { trace!("push_stack_frame: {:?}: num_bbs: {}", span, body.basic_blocks().len()); for block in body.basic_blocks() { for stmt in block.statements.iter() { use rustc::mir::StatementKind::{StorageDead, StorageLive}; match stmt.kind { - StorageLive(local) | - StorageDead(local) => { + StorageLive(local) | StorageDead(local) => { locals[local].value = LocalValue::Dead; } _ => {} } } } - }, + } } // done self.frame_mut().locals = locals; @@ -619,26 +611,25 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// `Drop` impls for any locals that have been initialized at this point. /// The cleanup block ends with a special `Resume` terminator, which will /// cause us to continue unwinding. - pub(super) fn pop_stack_frame( - &mut self, - unwinding: bool - ) -> InterpResult<'tcx> { - info!("LEAVING({}) {} (unwinding = {})", - self.cur_frame(), self.frame().instance, unwinding); + pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx> { + info!( + "LEAVING({}) {} (unwinding = {})", + self.cur_frame(), + self.frame().instance, + unwinding + ); // Sanity check `unwinding`. assert_eq!( unwinding, match self.frame().block { None => true, - Some(block) => self.body().basic_blocks()[block].is_cleanup + Some(block) => self.body().basic_blocks()[block].is_cleanup, } ); ::log_settings::settings().indentation -= 1; - let frame = self.stack.pop().expect( - "tried to pop a stack frame, but there were none", - ); + let frame = self.stack.pop().expect("tried to pop a stack frame, but there were none"); let stack_pop_info = M::stack_pop(self, frame.extra, unwinding)?; if let (false, StackPopInfo::StopUnwinding) = (unwinding, stack_pop_info) { bug!("Attempted to stop unwinding while there is no unwinding!"); @@ -647,11 +638,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Now where do we jump next? // Determine if we leave this function normally or via unwinding. - let cur_unwinding = if let StackPopInfo::StopUnwinding = stack_pop_info { - false - } else { - unwinding - }; + let cur_unwinding = + if let StackPopInfo::StopUnwinding = stack_pop_info { false } else { unwinding }; // Usually we want to clean up (deallocate locals), but in a few rare cases we don't. // In that case, we return early. We also avoid validation in that case, @@ -659,8 +647,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let (cleanup, next_block) = match frame.return_to_block { StackPopCleanup::Goto { ret, unwind } => { (true, Some(if cur_unwinding { unwind } else { ret })) - }, - StackPopCleanup::None { cleanup, .. } => (cleanup, None) + } + StackPopCleanup::None { cleanup, .. } => (cleanup, None), }; if !cleanup { @@ -675,9 +663,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.deallocate_local(local.value)?; } - - trace!("StackPopCleanup: {:?} StackPopInfo: {:?} cur_unwinding = {:?}", - frame.return_to_block, stack_pop_info, cur_unwinding); + trace!( + "StackPopCleanup: {:?} StackPopInfo: {:?} cur_unwinding = {:?}", + frame.return_to_block, + stack_pop_info, + cur_unwinding + ); if cur_unwinding { // Follow the unwind edge. let unwind = next_block.expect("Encounted StackPopCleanup::None when unwinding!"); @@ -695,11 +686,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // invariant -- that is, unless a function somehow has a ptr to // its return place... but the way MIR is currently generated, the // return place is always a local and then this cannot happen. - self.validate_operand( - self.place_to_op(return_place)?, - vec![], - None, - )?; + self.validate_operand(self.place_to_op(return_place)?, vec![], None)?; } } else { // Uh, that shouldn't happen... the function did not intend to return @@ -713,8 +700,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } if self.stack.len() > 0 { - info!("CONTINUING({}) {} (unwinding = {})", - self.cur_frame(), self.frame().instance, cur_unwinding); + info!( + "CONTINUING({}) {} (unwinding = {})", + self.cur_frame(), + self.frame().instance, + cur_unwinding + ); } Ok(()) @@ -724,7 +715,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Remember to deallocate that! pub fn storage_live( &mut self, - local: mir::Local + local: mir::Local, ) -> InterpResult<'tcx, LocalValue> { assert!(local != mir::RETURN_PLACE, "Cannot make return place live"); trace!("{:?} is now live", local); @@ -798,21 +789,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match self.stack[frame].locals[local].value { LocalValue::Dead => write!(msg, " is dead").unwrap(), LocalValue::Uninitialized => write!(msg, " is uninitialized").unwrap(), - LocalValue::Live(Operand::Indirect(mplace)) => { - match mplace.ptr { - Scalar::Ptr(ptr) => { - write!(msg, " by align({}){} ref:", - mplace.align.bytes(), - match mplace.meta { - Some(meta) => format!(" meta({:?})", meta), - None => String::new() - } - ).unwrap(); - allocs.push(ptr.alloc_id); - } - ptr => write!(msg, " by integral ref: {:?}", ptr).unwrap(), + LocalValue::Live(Operand::Indirect(mplace)) => match mplace.ptr { + Scalar::Ptr(ptr) => { + write!( + msg, + " by align({}){} ref:", + mplace.align.bytes(), + match mplace.meta { + Some(meta) => format!(" meta({:?})", meta), + None => String::new(), + } + ) + .unwrap(); + allocs.push(ptr.alloc_id); } - } + ptr => write!(msg, " by integral ref: {:?}", ptr).unwrap(), + }, LocalValue::Live(Operand::Immediate(Immediate::Scalar(val))) => { write!(msg, " {:?}", val).unwrap(); if let ScalarMaybeUndef::Scalar(Scalar::Ptr(ptr)) = val { @@ -833,15 +825,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { trace!("{}", msg); self.memory.dump_allocs(allocs); } - Place::Ptr(mplace) => { - match mplace.ptr { - Scalar::Ptr(ptr) => { - trace!("by align({}) ref:", mplace.align.bytes()); - self.memory.dump_alloc(ptr.alloc_id); - } - ptr => trace!(" integral by ref: {:?}", ptr), + Place::Ptr(mplace) => match mplace.ptr { + Scalar::Ptr(ptr) => { + trace!("by align({}) ref:", mplace.align.bytes()); + self.memory.dump_alloc(ptr.alloc_id); } - } + ptr => trace!(" integral by ref: {:?}", ptr), + }, } } @@ -877,9 +867,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } impl<'ctx, 'mir, 'tcx, Tag, Extra> HashStable> -for Frame<'mir, 'tcx, Tag, Extra> - where Extra: HashStable>, - Tag: HashStable> + for Frame<'mir, 'tcx, Tag, Extra> +where + Extra: HashStable>, + Tag: HashStable>, { fn hash_stable(&self, hcx: &mut StableHashingContext<'ctx>, hasher: &mut StableHasher) { self.body.hash_stable(hcx, hasher); diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index e4698303afe99..c99f39977fe2e 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -11,22 +11,19 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use syntax::ast::Mutability; -use super::{ - AllocId, Allocation, InterpCx, Machine, MemoryKind, MPlaceTy, Scalar, ValueVisitor, -}; +use super::{AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, Scalar, ValueVisitor}; -pub trait CompileTimeMachine<'mir, 'tcx> = - Machine< - 'mir, - 'tcx, - MemoryKinds = !, - PointerTag = (), - ExtraFnVal = !, - FrameExtra = (), - MemoryExtra = (), - AllocExtra = (), - MemoryMap = FxHashMap, Allocation)>, - >; +pub trait CompileTimeMachine<'mir, 'tcx> = Machine< + 'mir, + 'tcx, + MemoryKinds = !, + PointerTag = (), + ExtraFnVal = !, + FrameExtra = (), + MemoryExtra = (), + AllocExtra = (), + MemoryMap = FxHashMap, Allocation)>, +>; struct InternVisitor<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> { /// The ectx from which we intern. @@ -95,23 +92,19 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>( // treat dangling pointers like other statics // just to stop trying to recurse into them return Ok(Some(IsStaticOrFn)); - }, + } }; // This match is just a canary for future changes to `MemoryKind`, which most likely need // changes in this function. match kind { - MemoryKind::Stack | MemoryKind::Vtable | MemoryKind::CallerLocation => {}, + MemoryKind::Stack | MemoryKind::Vtable | MemoryKind::CallerLocation => {} } // Set allocation mutability as appropriate. This is used by LLVM to put things into // read-only memory, and also by Miri when evluating other constants/statics that // access this one. if mode == InternMode::Static { // When `ty` is `None`, we assume no interior mutability. - let frozen = ty.map_or(true, |ty| ty.is_freeze( - ecx.tcx.tcx, - ecx.param_env, - ecx.tcx.span, - )); + let frozen = ty.map_or(true, |ty| ty.is_freeze(ecx.tcx.tcx, ecx.param_env, ecx.tcx.span)); // For statics, allocation mutability is the combination of the place mutability and // the type mutability. // The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere. @@ -127,7 +120,8 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>( // initial value was computed. // Constants are never mutable. assert_eq!( - mutability, Mutability::Not, + mutability, + Mutability::Not, "Something went very wrong: mutability requested for a constant" ); alloc.mutability = Mutability::Not; @@ -146,21 +140,12 @@ impl<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> InternVisitor<'rt, 'mir mutability: Mutability, ty: Option>, ) -> InterpResult<'tcx, Option> { - intern_shallow( - self.ecx, - self.leftover_allocations, - self.mode, - alloc_id, - mutability, - ty, - ) + intern_shallow(self.ecx, self.leftover_allocations, self.mode, alloc_id, mutability, ty) } } -impl<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> - ValueVisitor<'mir, 'tcx, M> -for - InternVisitor<'rt, 'mir, 'tcx, M> +impl<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> + for InternVisitor<'rt, 'mir, 'tcx, M> { type V = MPlaceTy<'tcx>; @@ -172,7 +157,7 @@ for fn visit_aggregate( &mut self, mplace: MPlaceTy<'tcx>, - fields: impl Iterator>, + fields: impl Iterator>, ) -> InterpResult<'tcx> { if let Some(def) = mplace.layout.ty.ty_adt_def() { if Some(def.did) == self.ecx.tcx.lang_items().unsafe_cell_type() { @@ -181,7 +166,8 @@ for // allocations. let old = std::mem::replace(&mut self.mutability, Mutability::Mut); assert_ne!( - self.mode, InternMode::Const, + self.mode, + InternMode::Const, "UnsafeCells are not allowed behind references in constants. This should have \ been prevented statically by const qualification. If this were allowed one \ would be able to change a constant at one use site and other use sites could \ @@ -204,8 +190,7 @@ for let mplace = self.ecx.ref_to_mplace(value)?; // Handle trait object vtables if let ty::Dynamic(..) = - self.ecx.tcx.struct_tail_erasing_lifetimes( - referenced_ty, self.ecx.param_env).kind + self.ecx.tcx.struct_tail_erasing_lifetimes(referenced_ty, self.ecx.param_env).kind { if let Ok(vtable) = mplace.meta.unwrap().to_ptr() { // explitly choose `Immutable` here, since vtables are immutable, even @@ -223,23 +208,20 @@ for // const qualification enforces it. We can lift it in the future. match (self.mode, mutability) { // immutable references are fine everywhere - (_, hir::Mutability::Not) => {}, + (_, hir::Mutability::Not) => {} // all is "good and well" in the unsoundness of `static mut` // mutable references are ok in `static`. Either they are treated as immutable // because they are behind an immutable one, or they are behind an `UnsafeCell` // and thus ok. - (InternMode::Static, hir::Mutability::Mut) => {}, + (InternMode::Static, hir::Mutability::Mut) => {} // we statically prevent `&mut T` via `const_qualif` and double check this here - (InternMode::ConstBase, hir::Mutability::Mut) | - (InternMode::Const, hir::Mutability::Mut) => { - match referenced_ty.kind { - ty::Array(_, n) - if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {} - ty::Slice(_) - if mplace.meta.unwrap().to_machine_usize(self.ecx)? == 0 => {} - _ => bug!("const qualif failed to prevent mutable references"), - } + (InternMode::ConstBase, hir::Mutability::Mut) + | (InternMode::Const, hir::Mutability::Mut) => match referenced_ty.kind { + ty::Array(_, n) + if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {} + ty::Slice(_) if mplace.meta.unwrap().to_machine_usize(self.ecx)? == 0 => {} + _ => bug!("const qualif failed to prevent mutable references"), }, } // Compute the mutability with which we'll start visiting the allocation. This is @@ -260,7 +242,7 @@ for match self.intern_shallow(ptr.alloc_id, mutability, Some(mplace.layout.ty))? { // No need to recurse, these are interned already and statics may have // cycles, so we don't want to recurse there - Some(IsStaticOrFn) => {}, + Some(IsStaticOrFn) => {} // intern everything referenced by this value. The mutability is taken from the // reference. It is checked above that mutable references only happen in // `static mut` @@ -301,7 +283,7 @@ pub fn intern_const_alloc_recursive>( base_intern_mode, ret.ptr.to_ptr()?.alloc_id, base_mutability, - Some(ret.layout.ty) + Some(ret.layout.ty), )?; while let Some(((mplace, mutability, mode), _)) = ref_tracking.todo.pop() { @@ -311,7 +293,8 @@ pub fn intern_const_alloc_recursive>( mode, leftover_allocations, mutability, - }.visit_value(mplace); + } + .visit_value(mplace); if let Err(error) = interned { // This can happen when e.g. the tag of an enum is not a valid discriminant. We do have // to read enum discriminants in order to find references in enum variant fields. @@ -322,8 +305,7 @@ pub fn intern_const_alloc_recursive>( diag.note(crate::const_eval::note_on_undefined_behavior_error()); diag.emit(); } - Err(ErrorHandled::TooGeneric) | - Err(ErrorHandled::Reported) => {}, + Err(ErrorHandled::TooGeneric) | Err(ErrorHandled::Reported) => {} } } } diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 46782ef0a806b..8e4dc87451c32 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -2,21 +2,20 @@ //! looking at their MIR. Intrinsics/functions supported here are shared by CTFE //! and miri. -use syntax_pos::symbol::{sym, Symbol}; -use syntax_pos::Span; +use rustc::hir::def_id::DefId; +use rustc::mir::{ + self, + interpret::{ConstValue, InterpResult, Scalar}, + BinOp, +}; use rustc::ty; use rustc::ty::layout::{LayoutOf, Primitive, Size}; use rustc::ty::subst::SubstsRef; -use rustc::hir::def_id::DefId; use rustc::ty::TyCtxt; -use rustc::mir::{ - self, BinOp, - interpret::{InterpResult, Scalar, ConstValue} -}; +use syntax_pos::symbol::{sym, Symbol}; +use syntax_pos::Span; -use super::{ - Machine, PlaceTy, OpTy, InterpCx, ImmTy, -}; +use super::{ImmTy, InterpCx, Machine, OpTy, PlaceTy}; mod caller_location; mod type_name; @@ -63,11 +62,9 @@ crate fn eval_nullary_intrinsic<'tcx>( }), ty: tcx.mk_static_str(), }) - }, + } sym::needs_drop => ty::Const::from_bool(tcx, tp_ty.needs_drop(tcx, param_env)), - sym::size_of | - sym::min_align_of | - sym::pref_align_of => { + sym::size_of | sym::min_align_of | sym::pref_align_of => { let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?; let n = match name { sym::pref_align_of => layout.align.pref.bytes(), @@ -76,12 +73,10 @@ crate fn eval_nullary_intrinsic<'tcx>( _ => bug!(), }; ty::Const::from_usize(tcx, n) - }, - sym::type_id => ty::Const::from_bits( - tcx, - tcx.type_id_hash(tp_ty).into(), - param_env.and(tcx.types.u64), - ), + } + sym::type_id => { + ty::Const::from_bits(tcx, tcx.type_id_hash(tp_ty).into(), param_env.and(tcx.types.u64)) + } other => bug!("`{}` is not a zero arg intrinsic", other), }) } @@ -105,7 +100,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { None => match intrinsic_name { sym::transmute => throw_ub!(Unreachable), _ => return Ok(false), - } + }, }; // Keep the patterns in this match ordered the same as the list in @@ -117,20 +112,19 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_scalar(location.ptr, dest)?; } - sym::min_align_of | - sym::pref_align_of | - sym::needs_drop | - sym::size_of | - sym::type_id | - sym::type_name => { - let val = self.tcx.const_eval_instance(self.param_env, - instance, - Some(self.tcx.span))?; + sym::min_align_of + | sym::pref_align_of + | sym::needs_drop + | sym::size_of + | sym::type_id + | sym::type_name => { + let val = + self.tcx.const_eval_instance(self.param_env, instance, Some(self.tcx.span))?; let val = self.eval_const_to_op(val, None)?; self.copy_op(val, dest)?; } - | sym::ctpop + sym::ctpop | sym::cttz | sym::cttz_nonzero | sym::ctlz @@ -156,7 +150,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let out_val = numeric_intrinsic(intrinsic_name, bits, kind)?; self.write_scalar(out_val, dest)?; } - | sym::wrapping_add + sym::wrapping_add | sym::wrapping_sub | sym::wrapping_mul | sym::add_with_overflow @@ -171,7 +165,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { sym::add_with_overflow => (BinOp::Add, false), sym::sub_with_overflow => (BinOp::Sub, false), sym::mul_with_overflow => (BinOp::Mul, false), - _ => bug!("Already checked for int ops") + _ => bug!("Already checked for int ops"), }; if ignore_overflow { self.binop_ignore_overflow(bin_op, lhs, rhs, dest)?; @@ -183,11 +177,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let l = self.read_immediate(args[0])?; let r = self.read_immediate(args[1])?; let is_add = intrinsic_name == sym::saturating_add; - let (val, overflowed, _ty) = self.overflowing_binary_op(if is_add { - BinOp::Add - } else { - BinOp::Sub - }, l, r)?; + let (val, overflowed, _ty) = + self.overflowing_binary_op(if is_add { BinOp::Add } else { BinOp::Sub }, l, r)?; let val = if overflowed { let num_bits = l.layout.size.bits(); if l.layout.abi.is_signed() { @@ -196,24 +187,30 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // the fact that the operation has overflowed (if either is 0 no // overflow can occur) let first_term: u128 = self.force_bits(l.to_scalar()?, l.layout.size)?; - let first_term_positive = first_term & (1 << (num_bits-1)) == 0; + let first_term_positive = first_term & (1 << (num_bits - 1)) == 0; if first_term_positive { // Negative overflow not possible since the positive first term // can only increase an (in range) negative term for addition // or corresponding negated positive term for subtraction - Scalar::from_uint((1u128 << (num_bits - 1)) - 1, // max positive - Size::from_bits(num_bits)) + Scalar::from_uint( + (1u128 << (num_bits - 1)) - 1, // max positive + Size::from_bits(num_bits), + ) } else { // Positive overflow not possible for similar reason // max negative Scalar::from_uint(1u128 << (num_bits - 1), Size::from_bits(num_bits)) } - } else { // unsigned + } else { + // unsigned if is_add { // max unsigned - Scalar::from_uint(u128::max_value() >> (128 - num_bits), - Size::from_bits(num_bits)) - } else { // underflow to 0 + Scalar::from_uint( + u128::max_value() >> (128 - num_bits), + Size::from_bits(num_bits), + ) + } else { + // underflow to 0 Scalar::from_uint(0u128, Size::from_bits(num_bits)) } } @@ -228,7 +225,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let bin_op = match intrinsic_name { sym::unchecked_shl => BinOp::Shl, sym::unchecked_shr => BinOp::Shr, - _ => bug!("Already checked for int ops") + _ => bug!("Already checked for int ops"), }; let (val, overflowed, _ty) = self.overflowing_binary_op(bin_op, l, r)?; if overflowed { @@ -279,8 +276,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if a == b && a != 0 { self.write_scalar(Scalar::from_int(0, isize_layout.size), dest)?; true - } else { false } - } else { false }; + } else { + false + } + } else { + false + }; if !done { // General case: we need two pointers. @@ -295,9 +296,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let usize_layout = self.layout_of(self.tcx.types.usize)?; let a_offset = ImmTy::from_uint(a.offset.bytes(), usize_layout); let b_offset = ImmTy::from_uint(b.offset.bytes(), usize_layout); - let (val, _overflowed, _ty) = self.overflowing_binary_op( - BinOp::Sub, a_offset, b_offset, - )?; + let (val, _overflowed, _ty) = + self.overflowing_binary_op(BinOp::Sub, a_offset, b_offset)?; let pointee_layout = self.layout_of(substs.type_at(0))?; let val = ImmTy::from_scalar(val, isize_layout); let size = ImmTy::from_int(pointee_layout.size.bytes(), isize_layout); @@ -316,7 +316,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert!( index < len, "Index `{}` must be in bounds of vector type `{}`: `[0, {})`", - index, e_ty, len + index, + e_ty, + len ); assert_eq!( input.layout, dest.layout, @@ -331,11 +333,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { for i in 0..len { let place = self.place_field(dest, i)?; - let value = if i == index { - elem - } else { - self.operand_field(input, i)? - }; + let value = if i == index { elem } else { self.operand_field(input, i)? }; self.copy_op(value, place)?; } } @@ -345,7 +343,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert!( index < len, "index `{}` is out-of-bounds of vector type `{}` with length `{}`", - index, e_ty, len + index, + e_ty, + len ); assert_eq!( e_ty, dest.layout.ty, @@ -430,11 +430,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if b_scalar == minus1 { throw_ub_format!("exact_div: result of dividing MIN by -1 cannot be represented") } else { - throw_ub_format!( - "exact_div: {} cannot be divided by {} without remainder", - a, - b, - ) + throw_ub_format!("exact_div: {} cannot be divided by {} without remainder", a, b,) } } self.binop_ignore_overflow(BinOp::Div, a, b, dest) diff --git a/src/librustc_mir/interpret/intrinsics/caller_location.rs b/src/librustc_mir/interpret/intrinsics/caller_location.rs index ec843ef7a4d86..aff08feeeb026 100644 --- a/src/librustc_mir/interpret/intrinsics/caller_location.rs +++ b/src/librustc_mir/interpret/intrinsics/caller_location.rs @@ -1,9 +1,12 @@ use rustc::middle::lang_items::PanicLocationLangItem; use rustc::ty::subst::Subst; use rustc_target::abi::LayoutOf; -use syntax_pos::{Symbol, Span}; +use syntax_pos::{Span, Symbol}; -use crate::interpret::{Scalar, MemoryKind, MPlaceTy, intrinsics::{InterpCx, Machine}}; +use crate::interpret::{ + intrinsics::{InterpCx, Machine}, + MPlaceTy, MemoryKind, Scalar, +}; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Walks up the callstack from the intrinsic's callsite, searching for the first frame which is @@ -32,7 +35,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let col = Scalar::from_u32(col); // Allocate memory for `CallerLocation` struct. - let loc_ty = self.tcx.type_of(self.tcx.require_lang_item(PanicLocationLangItem, None)) + let loc_ty = self + .tcx + .type_of(self.tcx.require_lang_item(PanicLocationLangItem, None)) .subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_static.into()].iter())); let loc_layout = self.layout_of(loc_ty).unwrap(); let location = self.allocate(loc_layout, MemoryKind::CallerLocation); @@ -48,10 +53,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { location } - pub fn alloc_caller_location_for_span( - &mut self, - span: Span, - ) -> MPlaceTy<'tcx, M::PointerTag> { + pub fn alloc_caller_location_for_span(&mut self, span: Span) -> MPlaceTy<'tcx, M::PointerTag> { let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo()); self.alloc_caller_location( diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index f1f9fac08ca3a..659651e6165ef 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -1,13 +1,13 @@ +use rustc::hir::def_id::CrateNum; +use rustc::hir::map::{DefPathData, DisambiguatedDefPathData}; +use rustc::mir::interpret::Allocation; use rustc::ty::{ - TyCtxt, Ty, - subst::{GenericArgKind, GenericArg}, - print::{Printer, PrettyPrinter, Print}, self, + print::{PrettyPrinter, Print, Printer}, + subst::{GenericArg, GenericArgKind}, + Ty, TyCtxt, }; -use rustc::hir::map::{DefPathData, DisambiguatedDefPathData}; -use rustc::hir::def_id::CrateNum; use std::fmt::Write; -use rustc::mir::interpret::Allocation; struct AbsolutePathPrinter<'tcx> { tcx: TyCtxt<'tcx>, @@ -34,7 +34,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { fn print_type(mut self, ty: Ty<'tcx>) -> Result { match ty.kind { // Types without identity. - | ty::Bool + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) @@ -47,22 +47,16 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { | ty::FnPtr(_) | ty::Never | ty::Tuple(_) - | ty::Dynamic(_, _) - => self.pretty_print_type(ty), + | ty::Dynamic(_, _) => self.pretty_print_type(ty), // Placeholders (all printed as `_` to uniformize them). - | ty::Param(_) - | ty::Bound(..) - | ty::Placeholder(_) - | ty::Infer(_) - | ty::Error - => { + ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error => { write!(self, "_")?; Ok(self) } // Types with identity (print the module path). - | ty::Adt(&ty::AdtDef { did: def_id, .. }, substs) + ty::Adt(&ty::AdtDef { did: def_id, .. }, substs) | ty::FnDef(def_id, substs) | ty::Opaque(def_id, substs) | ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs }) @@ -71,16 +65,11 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { | ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs), ty::Foreign(def_id) => self.print_def_path(def_id, &[]), - ty::GeneratorWitness(_) => { - bug!("type_name: unexpected `GeneratorWitness`") - } + ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"), } } - fn print_const( - self, - _: &'tcx ty::Const<'tcx>, - ) -> Result { + fn print_const(self, _: &'tcx ty::Const<'tcx>) -> Result { // don't print constants to the user Ok(self) } @@ -158,11 +147,9 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { args: &[GenericArg<'tcx>], ) -> Result { self = print_prefix(self)?; - let args = args.iter().cloned().filter(|arg| { - match arg.unpack() { - GenericArgKind::Lifetime(_) => false, - _ => true, - } + let args = args.iter().cloned().filter(|arg| match arg.unpack() { + GenericArgKind::Lifetime(_) => false, + _ => true, }); if args.clone().next().is_some() { self.generic_delimiters(|cx| cx.comma_sep(args)) @@ -172,10 +159,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { } } impl PrettyPrinter<'tcx> for AbsolutePathPrinter<'tcx> { - fn region_should_not_be_omitted( - &self, - _region: ty::Region<'_>, - ) -> bool { + fn region_should_not_be_omitted(&self, _region: ty::Region<'_>) -> bool { false } fn comma_sep(mut self, mut elems: impl Iterator) -> Result @@ -213,10 +197,7 @@ impl Write for AbsolutePathPrinter<'_> { } /// Directly returns an `Allocation` containing an absolute path representation of the given type. -crate fn alloc_type_name<'tcx>( - tcx: TyCtxt<'tcx>, - ty: Ty<'tcx> -) -> &'tcx Allocation { +crate fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Allocation { let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path; let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes()); tcx.intern_const_alloc(alloc) diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 74206ad28739a..32de01d92086e 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -11,9 +11,8 @@ use rustc::ty::{self, Ty, TyCtxt}; use syntax_pos::Span; use super::{ - Allocation, AllocId, InterpResult, Scalar, AllocationExtra, AssertMessage, - InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory, - Frame, Operand, + AllocId, Allocation, AllocationExtra, AssertMessage, Frame, ImmTy, InterpCx, InterpResult, + Memory, MemoryKind, OpTy, Operand, PlaceTy, Pointer, Scalar, }; /// Data returned by Machine::stack_pop, @@ -28,7 +27,7 @@ pub enum StackPopInfo { /// Indicates that we should stop unwinding, /// as we've reached a catch frame - StopUnwinding + StopUnwinding, } /// Whether this kind of memory is allowed to leak @@ -42,14 +41,16 @@ pub trait AllocMap { /// Deliberately takes `&mut` because that is sufficient, and some implementations /// can be more efficient then (using `RefCell::get_mut`). fn contains_key(&mut self, k: &Q) -> bool - where K: Borrow; + where + K: Borrow; /// Inserts a new entry into the map. fn insert(&mut self, k: K, v: V) -> Option; /// Removes an entry from the map. fn remove(&mut self, k: &Q) -> Option - where K: Borrow; + where + K: Borrow; /// Returns data based the keys and values in the map. fn filter_map_collect(&self, f: impl FnMut(&K, &V) -> Option) -> Vec; @@ -57,20 +58,12 @@ pub trait AllocMap { /// Returns a reference to entry `k`. If no such entry exists, call /// `vacant` and either forward its error, or add its result to the map /// and return a reference to *that*. - fn get_or( - &self, - k: K, - vacant: impl FnOnce() -> Result - ) -> Result<&V, E>; + fn get_or(&self, k: K, vacant: impl FnOnce() -> Result) -> Result<&V, E>; /// Returns a mutable reference to entry `k`. If no such entry exists, call /// `vacant` and either forward its error, or add its result to the map /// and return a reference to *that*. - fn get_mut_or( - &mut self, - k: K, - vacant: impl FnOnce() -> Result - ) -> Result<&mut V, E>; + fn get_mut_or(&mut self, k: K, vacant: impl FnOnce() -> Result) -> Result<&mut V, E>; /// Read-only lookup. fn get(&self, k: K) -> Option<&V> { @@ -111,13 +104,11 @@ pub trait Machine<'mir, 'tcx>: Sized { type AllocExtra: AllocationExtra + 'static; /// Memory's allocation map - type MemoryMap: - AllocMap< + type MemoryMap: AllocMap< AllocId, - (MemoryKind, Allocation) - > + - Default + - Clone; + (MemoryKind, Allocation), + > + Default + + Clone; /// The memory kind to use for copied statics -- or None if statics should not be mutated /// and thus any such attempt will cause a `ModifiedStatic` error to be raised. @@ -221,9 +212,7 @@ pub trait Machine<'mir, 'tcx>: Sized { } /// Called before a `StaticKind::Static` value is accessed. - fn before_access_static( - _allocation: &Allocation, - ) -> InterpResult<'tcx> { + fn before_access_static(_allocation: &Allocation) -> InterpResult<'tcx> { Ok(()) } @@ -254,10 +243,7 @@ pub trait Machine<'mir, 'tcx>: Sized { /// Return the "base" tag for the given *static* allocation: the one that is used for direct /// accesses to this static/const/fn allocation. If `id` is not a static allocation, /// this will return an unusable tag (i.e., accesses will be UB)! - fn tag_static_base_pointer( - memory_extra: &Self::MemoryExtra, - id: AllocId, - ) -> Self::PointerTag; + fn tag_static_base_pointer(memory_extra: &Self::MemoryExtra, id: AllocId) -> Self::PointerTag; /// Executes a retagging operation #[inline] @@ -276,7 +262,7 @@ pub trait Machine<'mir, 'tcx>: Sized { fn stack_pop( _ecx: &mut InterpCx<'mir, 'tcx, Self>, _extra: Self::FrameExtra, - _unwinding: bool + _unwinding: bool, ) -> InterpResult<'tcx, StackPopInfo> { // By default, we do not support unwinding from panics Ok(StackPopInfo::Normal) @@ -290,7 +276,8 @@ pub trait Machine<'mir, 'tcx>: Sized { err_unsup!(InvalidNullPointerUsage) } else { err_unsup!(ReadBytesAsPointer) - }).into()) + }) + .into()) } fn ptr_to_int( diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index ba571043d3813..0ba79e4bba239 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -6,20 +6,19 @@ //! integer. It is crucial that these operations call `check_align` *before* //! short-circuiting the empty case! +use std::borrow::Cow; use std::collections::VecDeque; use std::ptr; -use std::borrow::Cow; -use rustc::ty::{self, Instance, ParamEnv, query::TyCtxtAt}; -use rustc::ty::layout::{Align, TargetDataLayout, Size, HasDataLayout}; -use rustc_data_structures::fx::{FxHashSet, FxHashMap}; +use rustc::ty::layout::{Align, HasDataLayout, Size, TargetDataLayout}; +use rustc::ty::{self, query::TyCtxtAt, Instance, ParamEnv}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use syntax::ast::Mutability; use super::{ - Pointer, AllocId, Allocation, GlobalId, AllocationExtra, - InterpResult, Scalar, GlobalAlloc, PointerArithmetic, - Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, + AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, ErrorHandled, GlobalAlloc, + GlobalId, InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Scalar, }; #[derive(Debug, PartialEq, Copy, Clone)] @@ -41,7 +40,7 @@ impl MayLeak for MemoryKind { MemoryKind::Stack => false, MemoryKind::Vtable => true, MemoryKind::CallerLocation => true, - MemoryKind::Machine(k) => k.may_leak() + MemoryKind::Machine(k) => k.may_leak(), } } } @@ -67,11 +66,10 @@ pub enum FnVal<'tcx, Other> { impl<'tcx, Other> FnVal<'tcx, Other> { pub fn as_instance(self) -> InterpResult<'tcx, Instance<'tcx>> { match self { - FnVal::Instance(instance) => - Ok(instance), - FnVal::Other(_) => throw_unsup_format!( - "'foreign' function pointers are not supported in this context" - ), + FnVal::Instance(instance) => Ok(instance), + FnVal::Other(_) => { + throw_unsup_format!("'foreign' function pointers are not supported in this context") + } } } } @@ -157,8 +155,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { pub fn create_fn_alloc( &mut self, fn_val: FnVal<'tcx, M::ExtraFnVal>, - ) -> Pointer - { + ) -> Pointer { let id = match fn_val { FnVal::Instance(instance) => self.tcx.alloc_map.lock().create_fn_alloc(instance), FnVal::Other(extra) => { @@ -197,8 +194,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { kind: MemoryKind, ) -> Pointer { let id = self.tcx.alloc_map.lock().reserve(); - debug_assert_ne!(Some(kind), M::STATIC_KIND.map(MemoryKind::Machine), - "dynamically allocating static memory"); + debug_assert_ne!( + Some(kind), + M::STATIC_KIND.map(MemoryKind::Machine), + "dynamically allocating static memory" + ); let (alloc, tag) = M::init_allocation_extra(&self.extra, id, Cow::Owned(alloc), Some(kind)); self.alloc_map.insert(id, (kind, alloc.into_owned())); Pointer::from(id).with_tag(tag) @@ -223,12 +223,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some((size, _align)) => size, None => self.get_raw(ptr.alloc_id)?.size, }; - self.copy( - ptr, - new_ptr, - old_size.min(new_size), - /*nonoverlapping*/ true, - )?; + self.copy(ptr, new_ptr, old_size.min(new_size), /*nonoverlapping*/ true)?; self.deallocate(ptr, old_size_and_align, kind)?; Ok(new_ptr) @@ -293,10 +288,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { AllocationExtra::memory_deallocated(&mut alloc, ptr, size)?; // Don't forget to remember size and align of this now-dead allocation - let old = self.dead_alloc_map.insert( - ptr.alloc_id, - (alloc.size, alloc.align) - ); + let old = self.dead_alloc_map.insert(ptr.alloc_id, (alloc.size, alloc.align)); if old.is_some() { bug!("Nothing can be deallocated twice"); } @@ -391,10 +383,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // got picked we might be aligned even if this check fails. // We instead have to fall back to converting to an integer and checking // the "real" alignment. - throw_unsup!(AlignmentCheckFailed { - has: alloc_align, - required: align, - }); + throw_unsup!(AlignmentCheckFailed { has: alloc_align, required: align }); } check_offset_align(ptr.offset.bytes(), align)?; } @@ -407,11 +396,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } /// Test if the pointer might be NULL. - pub fn ptr_may_be_null( - &self, - ptr: Pointer, - ) -> bool { - let (size, _align) = self.get_size_and_align(ptr.alloc_id, AllocCheck::MaybeDead) + pub fn ptr_may_be_null(&self, ptr: Pointer) -> bool { + let (size, _align) = self + .get_size_and_align(ptr.alloc_id, AllocCheck::MaybeDead) .expect("alloc info with MaybeDead cannot fail"); ptr.check_inbounds_alloc(size, CheckInAllocMsg::NullPointerTest).is_err() } @@ -440,12 +427,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { ) -> InterpResult<'tcx, Cow<'tcx, Allocation>> { let alloc = tcx.alloc_map.lock().get(id); let alloc = match alloc { - Some(GlobalAlloc::Memory(mem)) => - Cow::Borrowed(mem), - Some(GlobalAlloc::Function(..)) => - throw_unsup!(DerefFunctionPointer), - None => - throw_unsup!(DanglingPointerDeref), + Some(GlobalAlloc::Memory(mem)) => Cow::Borrowed(mem), + Some(GlobalAlloc::Function(..)) => throw_unsup!(DerefFunctionPointer), + None => throw_unsup!(DanglingPointerDeref), Some(GlobalAlloc::Static(def_id)) => { // We got a "lazy" static that has not been computed yet. if tcx.is_foreign_item(def_id) { @@ -454,22 +438,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } else { trace!("static_alloc: Need to compute {:?}", def_id); let instance = Instance::mono(tcx.tcx, def_id); - let gid = GlobalId { - instance, - promoted: None, - }; + let gid = GlobalId { instance, promoted: None }; // use the raw query here to break validation cycles. Later uses of the static // will call the full query anyway - let raw_const = tcx.const_eval_raw(ty::ParamEnv::reveal_all().and(gid)) - .map_err(|err| { + let raw_const = + tcx.const_eval_raw(ty::ParamEnv::reveal_all().and(gid)).map_err(|err| { // no need to report anything, the const_eval call takes care of that // for statics assert!(tcx.is_static(def_id)); match err { - ErrorHandled::Reported => - err_inval!(ReferencedConstant), - ErrorHandled::TooGeneric => - err_inval!(TooGeneric), + ErrorHandled::Reported => err_inval!(ReferencedConstant), + ErrorHandled::TooGeneric => err_inval!(TooGeneric), } })?; // Make sure we use the ID of the resolved memory, not the lazy one! @@ -514,7 +493,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // Need to put it into the map and return a ref to that let kind = M::STATIC_KIND.expect( "I got an owned allocation that I have to copy but the machine does \ - not expect that to happen" + not expect that to happen", ); Ok((MemoryKind::Machine(kind), alloc)) } @@ -523,7 +502,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // Now unpack that funny error type match a { Ok(a) => Ok(&a.1), - Err(a) => a + Err(a) => a, } } @@ -599,23 +578,27 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { let ty = self.tcx.type_of(did); let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); Ok((layout.size, layout.align.abi)) - }, + } Some(GlobalAlloc::Memory(alloc)) => - // Need to duplicate the logic here, because the global allocations have - // different associated types than the interpreter-local ones. - Ok((alloc.size, alloc.align)), - Some(GlobalAlloc::Function(_)) => - bug!("We already checked function pointers above"), + // Need to duplicate the logic here, because the global allocations have + // different associated types than the interpreter-local ones. + { + Ok((alloc.size, alloc.align)) + } + Some(GlobalAlloc::Function(_)) => bug!("We already checked function pointers above"), // The rest must be dead. - None => if let AllocCheck::MaybeDead = liveness { - // Deallocated pointers are allowed, we should be able to find - // them in the map. - Ok(*self.dead_alloc_map.get(&id) - .expect("deallocated pointers should all be recorded in \ - `dead_alloc_map`")) - } else { - throw_unsup!(DanglingPointerDeref) - }, + None => { + if let AllocCheck::MaybeDead = liveness { + // Deallocated pointers are allowed, we should be able to find + // them in the map. + Ok(*self.dead_alloc_map.get(&id).expect( + "deallocated pointers should all be recorded in \ + `dead_alloc_map`", + )) + } else { + throw_unsup!(DanglingPointerDeref) + } + } } } @@ -681,7 +664,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // Checked definedness (and thus range) and relocations. This access also doesn't // influence interpreter execution but is only for debugging. - let bytes = alloc.inspect_with_undef_and_ptr_outside_interpreter(i..i+1); + let bytes = alloc.inspect_with_undef_and_ptr_outside_interpreter(i..i + 1); write!(msg, "{:02x} ", bytes[0]).unwrap(); } else { msg.push_str("__ "); @@ -735,17 +718,23 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { MemoryKind::Machine(m) => format!(" ({:?})", m), }; self.dump_alloc_helper( - &mut allocs_seen, &mut allocs_to_print, - msg, alloc, extra + &mut allocs_seen, + &mut allocs_to_print, + msg, + alloc, + extra, ); - }, + } Err(()) => { // static alloc? match self.tcx.alloc_map.lock().get(id) { Some(GlobalAlloc::Memory(alloc)) => { self.dump_alloc_helper( - &mut allocs_seen, &mut allocs_to_print, - msg, alloc, " (immutable)".to_owned() + &mut allocs_seen, + &mut allocs_to_print, + msg, + alloc, + " (immutable)".to_owned(), ); } Some(GlobalAlloc::Function(func)) => { @@ -758,16 +747,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { eprintln!("{} (deallocated)", msg); } } - }, + } }; - } } pub fn leak_report(&self) -> usize { - let leaks: Vec<_> = self.alloc_map.filter_map_collect(|&id, &(kind, _)| { - if kind.may_leak() { None } else { Some(id) } - }); + let leaks: Vec<_> = self + .alloc_map + .filter_map_collect(|&id, &(kind, _)| if kind.may_leak() { None } else { Some(id) }); let n = leaks.len(); if n > 0 { eprintln!("### LEAK REPORT ###"); @@ -787,11 +775,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { /// Reads the given number of bytes from memory. Returns them as a slice. /// /// Performs appropriate bounds checks. - pub fn read_bytes( - &self, - ptr: Scalar, - size: Size, - ) -> InterpResult<'tcx, &[u8]> { + pub fn read_bytes(&self, ptr: Scalar, size: Size) -> InterpResult<'tcx, &[u8]> { let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(1).unwrap())? { Some(ptr) => ptr, None => return Ok(&[]), // zero-sized access @@ -813,9 +797,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { pub fn write_bytes( &mut self, ptr: Scalar, - src: impl IntoIterator, - ) -> InterpResult<'tcx> - { + src: impl IntoIterator, + ) -> InterpResult<'tcx> { let src = src.into_iter(); let size = Size::from_bytes(src.size_hint().0 as u64); // `write_bytes` checks that this lower bound matches the upper bound matches reality. @@ -852,18 +835,16 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // since we don't want to keep any relocations at the target. // (`get_bytes_with_undef_and_ptr` below checks that there are no // relocations overlapping the edges; those would not be handled correctly). - let relocations = self.get_raw(src.alloc_id)? - .prepare_relocation_copy(self, src, size, dest, length); + let relocations = + self.get_raw(src.alloc_id)?.prepare_relocation_copy(self, src, size, dest, length); let tcx = self.tcx.tcx; // This checks relocation edges on the src. - let src_bytes = self.get_raw(src.alloc_id)? - .get_bytes_with_undef_and_ptr(&tcx, src, size)? - .as_ptr(); - let dest_bytes = self.get_raw_mut(dest.alloc_id)? - .get_bytes_mut(&tcx, dest, size * length)? - .as_mut_ptr(); + let src_bytes = + self.get_raw(src.alloc_id)?.get_bytes_with_undef_and_ptr(&tcx, src, size)?.as_ptr(); + let dest_bytes = + self.get_raw_mut(dest.alloc_id)?.get_bytes_mut(&tcx, dest, size * length)?.as_mut_ptr(); // SAFE: The above indexing would have panicked if there weren't at least `size` bytes // behind `src` and `dest`. Also, we use the overlapping-safe `ptr::copy` if `src` and @@ -874,25 +855,27 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { assert_eq!(size.bytes() as usize as u64, size.bytes()); if src.alloc_id == dest.alloc_id { if nonoverlapping { - if (src.offset <= dest.offset && src.offset + size > dest.offset) || - (dest.offset <= src.offset && dest.offset + size > src.offset) + if (src.offset <= dest.offset && src.offset + size > dest.offset) + || (dest.offset <= src.offset && dest.offset + size > src.offset) { - throw_ub_format!( - "copy_nonoverlapping called on overlapping ranges" - ) + throw_ub_format!("copy_nonoverlapping called on overlapping ranges") } } for i in 0..length { - ptr::copy(src_bytes, - dest_bytes.offset((size.bytes() * i) as isize), - size.bytes() as usize); + ptr::copy( + src_bytes, + dest_bytes.offset((size.bytes() * i) as isize), + size.bytes() as usize, + ); } } else { for i in 0..length { - ptr::copy_nonoverlapping(src_bytes, - dest_bytes.offset((size.bytes() * i) as isize), - size.bytes() as usize); + ptr::copy_nonoverlapping( + src_bytes, + dest_bytes.offset((size.bytes() * i) as isize), + size.bytes() as usize, + ); } } } @@ -935,18 +918,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { ) -> InterpResult<'tcx, Pointer> { match scalar { Scalar::Ptr(ptr) => Ok(ptr), - _ => M::int_to_ptr(&self, scalar.to_machine_usize(self)?) + _ => M::int_to_ptr(&self, scalar.to_machine_usize(self)?), } } pub fn force_bits( &self, scalar: Scalar, - size: Size + size: Size, ) -> InterpResult<'tcx, u128> { match scalar.to_bits_or_ptr(size, self) { Ok(bits) => Ok(bits), - Err(ptr) => Ok(M::ptr_to_int(&self, ptr)? as u128) + Err(ptr) => Ok(M::ptr_to_int(&self, ptr)? as u128), } } } diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 520bd434faa25..0d35eae6ed08d 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -2,35 +2,33 @@ mod cast; mod eval_context; -mod place; -mod operand; +mod intern; +mod intrinsics; mod machine; mod memory; +mod operand; mod operator; +mod place; pub(crate) mod snapshot; // for const_eval mod step; mod terminator; mod traits; mod validity; -mod intrinsics; mod visitor; -mod intern; pub use rustc::mir::interpret::*; // have all the `interpret` symbols in one place: here -pub use self::eval_context::{ - InterpCx, Frame, StackPopCleanup, LocalState, LocalValue, -}; +pub use self::eval_context::{Frame, InterpCx, LocalState, LocalValue, StackPopCleanup}; -pub use self::place::{Place, PlaceTy, MemPlace, MPlaceTy}; +pub use self::place::{MPlaceTy, MemPlace, Place, PlaceTy}; -pub use self::memory::{Memory, MemoryKind, AllocCheck, FnVal}; +pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind}; -pub use self::machine::{Machine, AllocMap, MayLeak, StackPopInfo}; +pub use self::machine::{AllocMap, Machine, MayLeak, StackPopInfo}; -pub use self::operand::{ScalarMaybeUndef, Immediate, ImmTy, Operand, OpTy}; +pub use self::operand::{ImmTy, Immediate, OpTy, Operand, ScalarMaybeUndef}; -pub use self::visitor::{ValueVisitor, MutValueVisitor}; +pub use self::visitor::{MutValueVisitor, ValueVisitor}; pub use self::validity::RefTracking; diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 0af203079b153..a89abe71c654f 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -1,23 +1,18 @@ //! Functions concerning immediate values and operands, and reading from operands. //! All high-level functions to read from memory work on operands as sources. -use std::convert::{TryInto, TryFrom}; +use std::convert::{TryFrom, TryInto}; -use rustc::{mir, ty}; use rustc::ty::layout::{ - self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, PrimitiveExt, VariantIdx, + self, HasDataLayout, IntegerExt, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx, }; +use rustc::{mir, ty}; +use super::{InterpCx, MPlaceTy, Machine, MemPlace, Place, PlaceTy}; +pub use rustc::mir::interpret::ScalarMaybeUndef; use rustc::mir::interpret::{ - GlobalId, AllocId, - ConstValue, Pointer, Scalar, - InterpResult, sign_extend, truncate, -}; -use super::{ - InterpCx, Machine, - MemPlace, MPlaceTy, PlaceTy, Place, + sign_extend, truncate, AllocId, ConstValue, GlobalId, InterpResult, Pointer, Scalar, }; -pub use rustc::mir::interpret::ScalarMaybeUndef; use rustc_macros::HashStable; use syntax::ast; @@ -29,7 +24,7 @@ use syntax::ast; /// In particular, thanks to `ScalarPair`, arithmetic operations and casts can be entirely /// defined on `Immediate`, and do not have to work with a `Place`. #[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, Hash)] -pub enum Immediate { +pub enum Immediate { Scalar(ScalarMaybeUndef), ScalarPair(ScalarMaybeUndef, ScalarMaybeUndef), } @@ -56,11 +51,7 @@ impl From> for Immediate { } impl<'tcx, Tag> Immediate { - pub fn new_slice( - val: Scalar, - len: u64, - cx: &impl HasDataLayout - ) -> Self { + pub fn new_slice(val: Scalar, len: u64, cx: &impl HasDataLayout) -> Self { Immediate::ScalarPair( val.into(), Scalar::from_uint(len, cx.data_layout().pointer_size).into(), @@ -88,7 +79,7 @@ impl<'tcx, Tag> Immediate { pub fn to_scalar_pair(self) -> InterpResult<'tcx, (Scalar, Scalar)> { match self { Immediate::Scalar(..) => bug!("Got a thin pointer where a scalar pair was expected"), - Immediate::ScalarPair(a, b) => Ok((a.not_undef()?, b.not_undef()?)) + Immediate::ScalarPair(a, b) => Ok((a.not_undef()?, b.not_undef()?)), } } } @@ -96,7 +87,7 @@ impl<'tcx, Tag> Immediate { // ScalarPair needs a type to interpret, so we often have an immediate and a type together // as input for binary and cast operations. #[derive(Copy, Clone, Debug)] -pub struct ImmTy<'tcx, Tag=()> { +pub struct ImmTy<'tcx, Tag = ()> { pub(crate) imm: Immediate, pub layout: TyLayout<'tcx>, } @@ -108,27 +99,35 @@ impl std::fmt::Display for ImmTy<'tcx, Tag> { Immediate::Scalar(ScalarMaybeUndef::Scalar(s)) => match s.to_bits(self.layout.size) { Ok(s) => { match self.layout.ty.kind { - ty::Int(_) => return write!( - fmt, "{}", - super::sign_extend(s, self.layout.size) as i128, - ), + ty::Int(_) => { + return write!( + fmt, + "{}", + super::sign_extend(s, self.layout.size) as i128, + ); + } ty::Uint(_) => return write!(fmt, "{}", s), ty::Bool if s == 0 => return fmt.write_str("false"), ty::Bool if s == 1 => return fmt.write_str("true"), - ty::Char => if let Some(c) = - u32::try_from(s).ok().and_then(std::char::from_u32) { - return write!(fmt, "{}", c); - }, - ty::Float(ast::FloatTy::F32) => if let Ok(u) = u32::try_from(s) { - return write!(fmt, "{}", f32::from_bits(u)); - }, - ty::Float(ast::FloatTy::F64) => if let Ok(u) = u64::try_from(s) { - return write!(fmt, "{}", f64::from_bits(u)); - }, - _ => {}, + ty::Char => { + if let Some(c) = u32::try_from(s).ok().and_then(std::char::from_u32) { + return write!(fmt, "{}", c); + } + } + ty::Float(ast::FloatTy::F32) => { + if let Ok(u) = u32::try_from(s) { + return write!(fmt, "{}", f32::from_bits(u)); + } + } + ty::Float(ast::FloatTy::F64) => { + if let Ok(u) = u64::try_from(s) { + return write!(fmt, "{}", f64::from_bits(u)); + } + } + _ => {} } write!(fmt, "{:x}", s) - }, + } Err(_) => fmt.write_str("{pointer}"), }, Immediate::Scalar(ScalarMaybeUndef::Undef) => fmt.write_str("{undef}"), @@ -149,7 +148,7 @@ impl<'tcx, Tag> ::std::ops::Deref for ImmTy<'tcx, Tag> { /// or still in memory. The latter is an optimization, to delay reading that chunk of /// memory and to avoid having to store arbitrary-sized data here. #[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, Hash)] -pub enum Operand { +pub enum Operand { Immediate(Immediate), Indirect(MemPlace), } @@ -157,29 +156,29 @@ pub enum Operand { impl Operand { #[inline] pub fn assert_mem_place(self) -> MemPlace - where Tag: ::std::fmt::Debug + where + Tag: ::std::fmt::Debug, { match self { Operand::Indirect(mplace) => mplace, _ => bug!("assert_mem_place: expected Operand::Indirect, got {:?}", self), - } } #[inline] pub fn assert_immediate(self) -> Immediate - where Tag: ::std::fmt::Debug + where + Tag: ::std::fmt::Debug, { match self { Operand::Immediate(imm) => imm, _ => bug!("assert_immediate: expected Operand::Immediate, got {:?}", self), - } } } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -pub struct OpTy<'tcx, Tag=()> { +pub struct OpTy<'tcx, Tag = ()> { op: Operand, // Keep this private; it helps enforce invariants. pub layout: TyLayout<'tcx>, } @@ -195,20 +194,14 @@ impl<'tcx, Tag> ::std::ops::Deref for OpTy<'tcx, Tag> { impl<'tcx, Tag: Copy> From> for OpTy<'tcx, Tag> { #[inline(always)] fn from(mplace: MPlaceTy<'tcx, Tag>) -> Self { - OpTy { - op: Operand::Indirect(*mplace), - layout: mplace.layout - } + OpTy { op: Operand::Indirect(*mplace), layout: mplace.layout } } } impl<'tcx, Tag> From> for OpTy<'tcx, Tag> { #[inline(always)] fn from(val: ImmTy<'tcx, Tag>) -> Self { - OpTy { - op: Operand::Immediate(val.imm), - layout: val.layout - } + OpTy { op: Operand::Immediate(val.imm), layout: val.layout } } } @@ -248,16 +241,18 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> { #[inline(always)] pub(super) fn from_known_layout<'tcx>( layout: Option>, - compute: impl FnOnce() -> InterpResult<'tcx, TyLayout<'tcx>> + compute: impl FnOnce() -> InterpResult<'tcx, TyLayout<'tcx>>, ) -> InterpResult<'tcx, TyLayout<'tcx>> { match layout { None => compute(), Some(layout) => { if cfg!(debug_assertions) { let layout2 = compute()?; - assert_eq!(layout.details, layout2.details, + assert_eq!( + layout.details, layout2.details, "mismatch in layout of supposedly equal-layout types {:?} and {:?}", - layout.ty, layout2.ty); + layout.ty, layout2.ty + ); } Ok(layout) } @@ -289,25 +284,28 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(None); } - let ptr = match self.check_mplace_access(mplace, None) + let ptr = match self + .check_mplace_access(mplace, None) .expect("places should be checked on creation") { Some(ptr) => ptr, - None => return Ok(Some(ImmTy { // zero-sized type - imm: Scalar::zst().into(), - layout: mplace.layout, - })), + None => { + return Ok(Some(ImmTy { + // zero-sized type + imm: Scalar::zst().into(), + layout: mplace.layout, + })); + } }; match mplace.layout.abi { layout::Abi::Scalar(..) => { - let scalar = self.memory - .get_raw(ptr.alloc_id)? - .read_scalar(self, ptr, mplace.layout.size)?; - Ok(Some(ImmTy { - imm: scalar.into(), - layout: mplace.layout, - })) + let scalar = self.memory.get_raw(ptr.alloc_id)?.read_scalar( + self, + ptr, + mplace.layout.size, + )?; + Ok(Some(ImmTy { imm: scalar.into(), layout: mplace.layout })) } layout::Abi::ScalarPair(ref a, ref b) => { // We checked `ptr_align` above, so all fields will have the alignment they need. @@ -319,16 +317,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let b_offset = a_size.align_to(b.align(self).abi); assert!(b_offset.bytes() > 0); // we later use the offset to tell apart the fields let b_ptr = ptr.offset(b_offset, self)?; - let a_val = self.memory - .get_raw(ptr.alloc_id)? - .read_scalar(self, a_ptr, a_size)?; - let b_val = self.memory - .get_raw(ptr.alloc_id)? - .read_scalar(self, b_ptr, b_size)?; - Ok(Some(ImmTy { - imm: Immediate::ScalarPair(a_val, b_val), - layout: mplace.layout, - })) + let a_val = self.memory.get_raw(ptr.alloc_id)?.read_scalar(self, a_ptr, a_size)?; + let b_val = self.memory.get_raw(ptr.alloc_id)?.read_scalar(self, b_ptr, b_size)?; + Ok(Some(ImmTy { imm: Immediate::ScalarPair(a_val, b_val), layout: mplace.layout })) } _ => Ok(None), } @@ -351,7 +342,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { Err(mplace) } - }, + } Err(val) => Ok(val), }) } @@ -360,7 +351,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline(always)] pub fn read_immediate( &self, - op: OpTy<'tcx, M::PointerTag> + op: OpTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx, ImmTy<'tcx, M::PointerTag>> { if let Ok(imm) = self.try_read_immediate(op)? { Ok(imm) @@ -372,21 +363,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Read a scalar from a place pub fn read_scalar( &self, - op: OpTy<'tcx, M::PointerTag> + op: OpTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx, ScalarMaybeUndef> { Ok(self.read_immediate(op)?.to_scalar_or_undef()) } // Turn the wide MPlace into a string (must already be dereferenced!) - pub fn read_str( - &self, - mplace: MPlaceTy<'tcx, M::PointerTag>, - ) -> InterpResult<'tcx, &str> { + pub fn read_str(&self, mplace: MPlaceTy<'tcx, M::PointerTag>) -> InterpResult<'tcx, &str> { let len = mplace.len(self)?; let bytes = self.memory.read_bytes(mplace.ptr, Size::from_bytes(len as u64))?; - let str = ::std::str::from_utf8(bytes).map_err(|err| { - err_unsup!(ValidationFailure(err.to_string())) - })?; + let str = ::std::str::from_utf8(bytes) + .map_err(|err| err_unsup!(ValidationFailure(err.to_string())))?; Ok(str) } @@ -401,8 +388,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // The easy case let field = self.mplace_field(mplace, field)?; return Ok(field.into()); - }, - Err(value) => value + } + Err(value) => value, }; let field = field.try_into().unwrap(); @@ -419,9 +406,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Immediate::ScalarPair(a, b) => { let val = if offset.bytes() == 0 { a } else { b }; Immediate::from(val) - }, - Immediate::Scalar(val) => - bug!("field access on non aggregate {:#?}, {:#?}", val, op.layout), + } + Immediate::Scalar(val) => { + bug!("field access on non aggregate {:#?}, {:#?}", val, op.layout) + } }; Ok(OpTy { op: Operand::Immediate(immediate), layout: field_layout }) } @@ -433,9 +421,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { // Downcasts only change the layout Ok(match op.try_as_mplace() { - Ok(mplace) => { - self.mplace_downcast(mplace, variant)?.into() - }, + Ok(mplace) => self.mplace_downcast(mplace, variant)?.into(), Err(..) => { let layout = op.layout.for_variant(self, variant); OpTy { layout, ..op } @@ -473,7 +459,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { layout: self.layout_of(self.tcx.mk_array(elem_ty, (to - from) as u64))?, } } - Subslice { .. } | ConstantIndex { .. } | Index(_) => { + Subslice { .. } | ConstantIndex { .. } | Index(_) => { // The rest should only occur as mplace, we do not use Immediates for types // allowing such operations. This matches place_projection forcing an allocation. let mplace = base.assert_mem_place(); @@ -504,14 +490,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline(always)] pub fn place_to_op( &self, - place: PlaceTy<'tcx, M::PointerTag> + place: PlaceTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { let op = match *place { - Place::Ptr(mplace) => { - Operand::Indirect(mplace) - } - Place::Local { frame, local } => - *self.access_local(&self.stack[frame], local, None)? + Place::Ptr(mplace) => Operand::Indirect(mplace), + Place::Local { frame, local } => *self.access_local(&self.stack[frame], local, None)?, }; Ok(OpTy { op, layout: place.layout }) } @@ -526,29 +509,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { use rustc::mir::PlaceBase; let base_op = match &place.base { - PlaceBase::Local(mir::RETURN_PLACE) => - throw_unsup!(ReadFromReturnPointer), + PlaceBase::Local(mir::RETURN_PLACE) => throw_unsup!(ReadFromReturnPointer), PlaceBase::Local(local) => { // Do not use the layout passed in as argument if the base we are looking at // here is not the entire place. // FIXME use place_projection.is_empty() when is available - let layout = if place.projection.is_empty() { - layout - } else { - None - }; + let layout = if place.projection.is_empty() { layout } else { None }; self.access_local(self.frame(), *local, layout)? } - PlaceBase::Static(place_static) => { - self.eval_static_to_mplace(&place_static)?.into() - } + PlaceBase::Static(place_static) => self.eval_static_to_mplace(&place_static)?.into(), }; - let op = place.projection.iter().try_fold( - base_op, - |op, elem| self.operand_projection(op, elem) - )?; + let op = place + .projection + .iter() + .try_fold(base_op, |op, elem| self.operand_projection(op, elem))?; trace!("eval_place_to_op: got {:?}", *op); Ok(op) @@ -565,9 +541,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { use rustc::mir::Operand::*; let op = match *mir_op { // FIXME: do some more logic on `move` to invalidate the old location - Copy(ref place) | - Move(ref place) => - self.eval_place_to_op(place, layout)?, + Copy(ref place) | Move(ref place) => self.eval_place_to_op(place, layout)?, Constant(ref constant) => { let val = self.subst_from_frame_and_normalize_erasing_regions(constant.literal); @@ -583,9 +557,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &self, ops: &[mir::Operand<'tcx>], ) -> InterpResult<'tcx, Vec>> { - ops.into_iter() - .map(|op| self.eval_operand(op, None)) - .collect() + ops.into_iter().map(|op| self.eval_operand(op, None)).collect() } // Used when the miri-engine runs into a constant and for extracting information from constants @@ -603,25 +575,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; // Early-return cases. let val_val = match val.val { - ty::ConstKind::Param(_) => - throw_inval!(TooGeneric), + ty::ConstKind::Param(_) => throw_inval!(TooGeneric), ty::ConstKind::Unevaluated(def_id, substs) => { let instance = self.resolve(def_id, substs)?; - return Ok(OpTy::from(self.const_eval_raw(GlobalId { - instance, - promoted: None, - })?)); + return Ok(OpTy::from(self.const_eval_raw(GlobalId { instance, promoted: None })?)); + } + ty::ConstKind::Infer(..) + | ty::ConstKind::Bound(..) + | ty::ConstKind::Placeholder(..) => { + bug!("eval_const_to_op: Unexpected ConstKind {:?}", val) } - ty::ConstKind::Infer(..) | - ty::ConstKind::Bound(..) | - ty::ConstKind::Placeholder(..) => - bug!("eval_const_to_op: Unexpected ConstKind {:?}", val), ty::ConstKind::Value(val_val) => val_val, }; // Other cases need layout. - let layout = from_known_layout(layout, || { - self.layout_of(val.ty) - })?; + let layout = from_known_layout(layout, || self.layout_of(val.ty))?; let op = match val_val { ConstValue::ByRef { alloc, offset } => { let id = self.tcx.alloc_map.lock().create_memory_alloc(alloc); @@ -629,7 +596,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // where none should happen. let ptr = self.tag_static_base_pointer(Pointer::new(id, offset)); Operand::Indirect(MemPlace::from_ptr(ptr, layout.align.abi)) - }, + } ConstValue::Scalar(x) => Operand::Immediate(tag_scalar(x).into()), ConstValue::Slice { data, start, end } => { // We rely on mutability being set correctly in `data` to prevent writes @@ -657,9 +624,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let (discr_layout, discr_kind, discr_index) = match rval.layout.variants { layout::Variants::Single { index } => { - let discr_val = rval.layout.ty.discriminant_for_variant(*self.tcx, index).map_or( - index.as_u32() as u128, - |discr| discr.val); + let discr_val = rval + .layout + .ty + .discriminant_for_variant(*self.tcx, index) + .map_or(index.as_u32() as u128, |discr| discr.val); return Ok((discr_val, index)); } layout::Variants::Multiple { @@ -667,8 +636,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ref discr_kind, discr_index, .. - } => - (discr_layout, discr_kind, discr_index), + } => (discr_layout, discr_kind, discr_index), }; // read raw discriminant value @@ -688,8 +656,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // requires first sign extending with the discriminant layout let sexted = sign_extend(bits_discr, discr_val.layout.size) as i128; // and then zeroing with the typeck discriminant type - let discr_ty = rval.layout.ty - .ty_adt_def().expect("tagged layout corresponds to adt") + let discr_ty = rval + .layout + .ty + .ty_adt_def() + .expect("tagged layout corresponds to adt") .repr .discr_type(); let size = layout::Integer::from_attr(self, discr_ty).size(); @@ -700,9 +671,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; // Make sure we catch invalid discriminants let index = match rval.layout.ty.kind { - ty::Adt(adt, _) => adt - .discriminants(self.tcx.tcx) - .find(|(_, var)| var.val == real_discr), + ty::Adt(adt, _) => { + adt.discriminants(self.tcx.tcx).find(|(_, var)| var.val == real_discr) + } ty::Generator(def_id, substs, _) => { let substs = substs.as_generator(); substs @@ -710,12 +681,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .find(|(_, var)| var.val == real_discr) } _ => bug!("tagged layout for non-adt non-generator"), - - }.ok_or_else( - || err_ub!(InvalidDiscriminant(raw_discr.erase_tag())) - )?; + } + .ok_or_else(|| err_ub!(InvalidDiscriminant(raw_discr.erase_tag())))?; (real_discr, index.0) - }, + } layout::DiscriminantKind::Niche { dataful_variant, ref niche_variants, @@ -723,30 +692,29 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } => { let variants_start = niche_variants.start().as_u32(); let variants_end = niche_variants.end().as_u32(); - let raw_discr = raw_discr.not_undef().map_err(|_| { - err_ub!(InvalidDiscriminant(ScalarMaybeUndef::Undef)) - })?; + let raw_discr = raw_discr + .not_undef() + .map_err(|_| err_ub!(InvalidDiscriminant(ScalarMaybeUndef::Undef)))?; match raw_discr.to_bits_or_ptr(discr_val.layout.size, self) { Err(ptr) => { // The niche must be just 0 (which an inbounds pointer value never is) - let ptr_valid = niche_start == 0 && variants_start == variants_end && - !self.memory.ptr_may_be_null(ptr); + let ptr_valid = niche_start == 0 + && variants_start == variants_end + && !self.memory.ptr_may_be_null(ptr); if !ptr_valid { throw_ub!(InvalidDiscriminant(raw_discr.erase_tag().into())) } (dataful_variant.as_u32() as u128, dataful_variant) - }, + } Ok(raw_discr) => { // We need to use machine arithmetic to get the relative variant idx: // variant_index_relative = discr_val - niche_start_val - let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?; + let discr_layout = + self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?; let discr_val = ImmTy::from_uint(raw_discr, discr_layout); let niche_start_val = ImmTy::from_uint(niche_start, discr_layout); - let variant_index_relative_val = self.binary_op( - mir::BinOp::Sub, - discr_val, - niche_start_val, - )?; + let variant_index_relative_val = + self.binary_op(mir::BinOp::Sub, discr_val, niche_start_val)?; let variant_index_relative = variant_index_relative_val .to_scalar()? .assert_bits(discr_val.layout.size); @@ -758,15 +726,21 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let variant_index = variants_start .checked_add(variant_index_relative) .expect("oveflow computing absolute variant idx"); - assert!((variant_index as usize) < rval.layout.ty - .ty_adt_def() - .expect("tagged layout for non adt") - .variants.len()); + assert!( + (variant_index as usize) + < rval + .layout + .ty + .ty_adt_def() + .expect("tagged layout for non adt") + .variants + .len() + ); (u128::from(variant_index), VariantIdx::from_u32(variant_index)) } else { (u128::from(dataful_variant.as_u32()), dataful_variant) } - }, + } } } }) diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index 68004294c5dc9..5050fe4906474 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -1,11 +1,14 @@ use rustc::mir; -use rustc::ty::{self, Ty, layout::{TyLayout, LayoutOf}}; -use syntax::ast::FloatTy; -use rustc_apfloat::Float; use rustc::mir::interpret::{InterpResult, Scalar}; +use rustc::ty::{ + self, + layout::{LayoutOf, TyLayout}, + Ty, +}; +use rustc_apfloat::Float; +use syntax::ast::FloatTy; -use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy}; - +use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy}; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Applies the binary operation `op` to the two operands and writes a tuple of the result @@ -21,7 +24,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { debug_assert_eq!( self.tcx.intern_tup(&[ty, self.tcx.types.bool]), dest.layout.ty, - "type mismatch for result of {:?}", op, + "type mismatch for result of {:?}", + op, ); let val = Immediate::ScalarPair(val.into(), Scalar::from_bool(overflowed).into()); self.write_immediate(val, dest) @@ -157,8 +161,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { bug!( "invalid asymmetric binary op {:?}: {:?} ({:?}), {:?} ({:?})", bin_op, - l, left_layout.ty, - r, right_layout.ty, + l, + left_layout.ty, + r, + right_layout.ty, ) } @@ -196,8 +202,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if r == -1 && l == (1 << (size.bits() - 1)) { return Ok((Scalar::from_uint(l, size), true, left_layout.ty)); } - }, - _ => {}, + } + _ => {} } trace!("{}, {}, {}", l, l128, r); let (result, mut oflo) = op(l128, r); @@ -249,15 +255,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { )); } - _ => { - bug!( - "invalid binary op {:?}: {:?}, {:?} (both {:?})", - bin_op, - l, - r, - right_layout.ty, - ) - } + _ => bug!( + "invalid binary op {:?}: {:?}, {:?} (both {:?})", + bin_op, + l, + r, + right_layout.ty, + ), }; Ok((val, false, ty)) @@ -271,8 +275,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { left: ImmTy<'tcx, M::PointerTag>, right: ImmTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> { - trace!("Running binary op {:?}: {:?} ({:?}), {:?} ({:?})", - bin_op, *left, left.layout.ty, *right, right.layout.ty); + trace!( + "Running binary op {:?}: {:?} ({:?}), {:?} ({:?})", + bin_op, + *left, + left.layout.ty, + *right, + right.layout.ty + ); match left.layout.ty.kind { ty::Char => { @@ -293,10 +303,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let left = left.to_scalar()?; let right = right.to_scalar()?; Ok(match fty { - FloatTy::F32 => - self.binary_float_op(bin_op, ty, left.to_f32()?, right.to_f32()?), - FloatTy::F64 => - self.binary_float_op(bin_op, ty, left.to_f64()?, right.to_f64()?), + FloatTy::F32 => { + self.binary_float_op(bin_op, ty, left.to_f32()?, right.to_f32()?) + } + FloatTy::F64 => { + self.binary_float_op(bin_op, ty, left.to_f64()?, right.to_f64()?) + } }) } _ if left.layout.ty.is_integral() => { @@ -304,7 +316,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert!( right.layout.ty.is_integral(), "Unexpected types for BinOp: {:?} {:?} {:?}", - left.layout.ty, bin_op, right.layout.ty + left.layout.ty, + bin_op, + right.layout.ty ); let l = self.force_bits(left.to_scalar()?, left.layout.size)?; @@ -316,7 +330,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert!( right.layout.ty == left.layout.ty || right.layout.ty.is_integral(), "Unexpected types for BinOp: {:?} {:?} {:?}", - left.layout.ty, bin_op, right.layout.ty + left.layout.ty, + bin_op, + right.layout.ty ); M::binary_ptr_op(self, bin_op, left, right) @@ -353,7 +369,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val = val.to_bool()?; let res = match un_op { Not => !val, - _ => bug!("Invalid bool op {:?}", un_op) + _ => bug!("Invalid bool op {:?}", un_op), }; Ok(ImmTy::from_scalar(Scalar::from_bool(res), self.layout_of(self.tcx.types.bool)?)) } @@ -361,7 +377,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let res = match (un_op, fty) { (Neg, FloatTy::F32) => Scalar::from_f32(-val.to_f32()?), (Neg, FloatTy::F64) => Scalar::from_f64(-val.to_f64()?), - _ => bug!("Invalid float op {:?}", un_op) + _ => bug!("Invalid float op {:?}", un_op), }; Ok(ImmTy::from_scalar(res, layout)) } diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index 3ea00d6922186..1500b5fef2bdf 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -10,21 +10,20 @@ use std::hash::{Hash, Hasher}; use rustc::ich::StableHashingContextProvider; use rustc::mir; use rustc::mir::interpret::{ - AllocId, Pointer, Scalar, - Relocations, Allocation, UndefMask, InterpResult, + AllocId, Allocation, InterpResult, Pointer, Relocations, Scalar, UndefMask, }; -use rustc::ty::{self, TyCtxt}; use rustc::ty::layout::{Align, Size}; +use rustc::ty::{self, TyCtxt}; use rustc_data_structures::fx::FxHashSet; -use rustc_index::vec::IndexVec; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_index::vec::IndexVec; use rustc_macros::HashStable; use syntax::ast::Mutability; use syntax::source_map::Span; use super::eval_context::{LocalState, StackPopCleanup}; -use super::{Frame, Memory, Operand, MemPlace, Place, Immediate, ScalarMaybeUndef, LocalValue}; +use super::{Frame, Immediate, LocalValue, MemPlace, Memory, Operand, Place, ScalarMaybeUndef}; use crate::const_eval::CompileTimeInterpreter; #[derive(Default)] @@ -60,12 +59,14 @@ impl<'mir, 'tcx> InfiniteLoopDetector<'mir, 'tcx> { // Check if we know that hash already if self.hashes.is_empty() { // FIXME(#49980): make this warning a lint - tcx.sess.span_warn(span, - "Constant evaluating a complex constant, this might take some time"); + tcx.sess.span_warn( + span, + "Constant evaluating a complex constant, this might take some time", + ); } if self.hashes.insert(hash) { // No collision - return Ok(()) + return Ok(()); } // We need to make a full copy. NOW things that to get really expensive. @@ -73,7 +74,7 @@ impl<'mir, 'tcx> InfiniteLoopDetector<'mir, 'tcx> { if self.snapshots.insert(InterpSnapshot::new(memory, stack)) { // Spurious collision or first cycle - return Ok(()) + return Ok(()); } // Second cycle @@ -93,8 +94,12 @@ trait Snapshot<'a, Ctx: SnapshotContext<'a>> { } macro_rules! __impl_snapshot_field { - ($field:ident, $ctx:expr) => ($field.snapshot($ctx)); - ($field:ident, $ctx:expr, $delegate:expr) => ($delegate); + ($field:ident, $ctx:expr) => { + $field.snapshot($ctx) + }; + ($field:ident, $ctx:expr, $delegate:expr) => { + $delegate + }; } // This assumes the type has two type parameters, first for the tag (set to `()`), @@ -145,8 +150,9 @@ macro_rules! impl_snapshot_for { } impl<'a, Ctx, T> Snapshot<'a, Ctx> for Option - where Ctx: SnapshotContext<'a>, - T: Snapshot<'a, Ctx> +where + Ctx: SnapshotContext<'a>, + T: Snapshot<'a, Ctx>, { type Item = Option<>::Item>; @@ -162,7 +168,8 @@ impl<'a, Ctx, T> Snapshot<'a, Ctx> for Option struct AllocIdSnapshot<'a>(Option>); impl<'a, Ctx> Snapshot<'a, Ctx> for AllocId - where Ctx: SnapshotContext<'a>, +where + Ctx: SnapshotContext<'a>, { type Item = AllocIdSnapshot<'a>; @@ -178,25 +185,25 @@ impl_snapshot_for!(struct Pointer { }); impl<'a, Ctx> Snapshot<'a, Ctx> for Scalar - where Ctx: SnapshotContext<'a>, +where + Ctx: SnapshotContext<'a>, { type Item = Scalar<(), AllocIdSnapshot<'a>>; fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { match self { Scalar::Ptr(p) => Scalar::Ptr(p.snapshot(ctx)), - Scalar::Raw{ size, data } => Scalar::Raw { - data: *data, - size: *size, - }, + Scalar::Raw { size, data } => Scalar::Raw { data: *data, size: *size }, } } } -impl_snapshot_for!(enum ScalarMaybeUndef { - Scalar(s), - Undef, -}); +impl_snapshot_for!( + enum ScalarMaybeUndef { + Scalar(s), + Undef, + } +); impl_snapshot_for!(struct MemPlace { ptr, @@ -205,7 +212,8 @@ impl_snapshot_for!(struct MemPlace { }); impl<'a, Ctx> Snapshot<'a, Ctx> for Place - where Ctx: SnapshotContext<'a>, +where + Ctx: SnapshotContext<'a>, { type Item = Place<(), AllocIdSnapshot<'a>>; @@ -213,39 +221,43 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for Place match self { Place::Ptr(p) => Place::Ptr(p.snapshot(ctx)), - Place::Local{ frame, local } => Place::Local{ - frame: *frame, - local: *local, - }, + Place::Local { frame, local } => Place::Local { frame: *frame, local: *local }, } } } -impl_snapshot_for!(enum Immediate { - Scalar(s), - ScalarPair(s, t), -}); +impl_snapshot_for!( + enum Immediate { + Scalar(s), + ScalarPair(s, t), + } +); -impl_snapshot_for!(enum Operand { - Immediate(v), - Indirect(m), -}); +impl_snapshot_for!( + enum Operand { + Immediate(v), + Indirect(m), + } +); -impl_snapshot_for!(enum LocalValue { - Dead, - Uninitialized, - Live(v), -}); +impl_snapshot_for!( + enum LocalValue { + Dead, + Uninitialized, + Live(v), + } +); impl<'a, Ctx> Snapshot<'a, Ctx> for Relocations - where Ctx: SnapshotContext<'a>, +where + Ctx: SnapshotContext<'a>, { type Item = Relocations<(), AllocIdSnapshot<'a>>; fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { - Relocations::from_presorted(self.iter() - .map(|(size, ((), id))| (*size, ((), id.snapshot(ctx)))) - .collect()) + Relocations::from_presorted( + self.iter().map(|(size, ((), id))| (*size, ((), id.snapshot(ctx)))).collect(), + ) } } @@ -260,18 +272,13 @@ struct AllocationSnapshot<'a> { } impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation - where Ctx: SnapshotContext<'a>, +where + Ctx: SnapshotContext<'a>, { type Item = AllocationSnapshot<'a>; fn snapshot(&self, ctx: &'a Ctx) -> Self::Item { - let Allocation { - size, - align, - mutability, - extra: (), - .. - } = self; + let Allocation { size, align, mutability, extra: (), .. } = self; let all_bytes = 0..self.len(); // This 'inspect' is okay since following access respects undef and relocations. This does @@ -305,7 +312,8 @@ struct FrameSnapshot<'a, 'tcx> { } impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx> - where Ctx: SnapshotContext<'a>, +where + Ctx: SnapshotContext<'a>, { type Item = FrameSnapshot<'a, 'tcx>; @@ -335,7 +343,8 @@ impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx> } impl<'a, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a LocalState<'tcx> - where Ctx: SnapshotContext<'a>, +where + Ctx: SnapshotContext<'a>, { type Item = LocalValue<(), AllocIdSnapshot<'a>>; @@ -369,16 +378,11 @@ impl InterpSnapshot<'mir, 'tcx> { memory: &Memory<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, stack: &[Frame<'mir, 'tcx>], ) -> Self { - InterpSnapshot { - memory: memory.clone(), - stack: stack.into(), - } + InterpSnapshot { memory: memory.clone(), stack: stack.into() } } // Used to compare two snapshots - fn snapshot(&'b self) - -> Vec> - { + fn snapshot(&'b self) -> Vec> { // Start with the stack, iterate and recursively snapshot self.stack.iter().map(|frame| frame.snapshot(&self.memory)).collect() } diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 33cdf1b27f8db..a99abc4cbf428 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -3,8 +3,8 @@ //! The main entry point is the `step` method. use rustc::mir; +use rustc::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc::ty::layout::LayoutOf; -use rustc::mir::interpret::{InterpResult, Scalar, PointerArithmetic}; use super::{InterpCx, Machine}; @@ -14,11 +14,8 @@ use super::{InterpCx, Machine}; fn binop_left_homogeneous(op: mir::BinOp) -> bool { use rustc::mir::BinOp::*; match op { - Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | - Offset | Shl | Shr => - true, - Eq | Ne | Lt | Le | Gt | Ge => - false, + Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Offset | Shl | Shr => true, + Eq | Ne | Lt | Le | Gt | Ge => false, } } /// Classify whether an operator is "right-homogeneous", i.e., the RHS has the @@ -27,11 +24,8 @@ fn binop_left_homogeneous(op: mir::BinOp) -> bool { fn binop_right_homogeneous(op: mir::BinOp) -> bool { use rustc::mir::BinOp::*; match op { - Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | - Eq | Ne | Lt | Le | Gt | Ge => - true, - Offset | Shl | Shr => - false, + Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Eq | Ne | Lt | Le | Gt | Ge => true, + Offset | Shl | Shr => false, } } @@ -56,7 +50,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Just go on unwinding. trace!("unwinding: skipping frame"); self.pop_stack_frame(/* unwinding */ true)?; - return Ok(true) + return Ok(true); } }; let stmt_id = self.frame().stmt; @@ -91,12 +85,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.memory.tcx.span = stmt.source_info.span; match stmt.kind { - Assign(box(ref place, ref rvalue)) => self.eval_rvalue_into_place(rvalue, place)?, + Assign(box (ref place, ref rvalue)) => self.eval_rvalue_into_place(rvalue, place)?, - SetDiscriminant { - ref place, - variant_index, - } => { + SetDiscriminant { ref place, variant_index } => { let dest = self.eval_place(place)?; self.write_discriminant_index(variant_index, dest)?; } @@ -161,12 +152,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let left = self.read_immediate(self.eval_operand(left, layout)?)?; let layout = binop_right_homogeneous(bin_op).then_some(left.layout); let right = self.read_immediate(self.eval_operand(right, layout)?)?; - self.binop_ignore_overflow( - bin_op, - left, - right, - dest, - )?; + self.binop_ignore_overflow(bin_op, left, right, dest)?; } CheckedBinaryOp(bin_op, ref left, ref right) => { @@ -174,12 +160,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let left = self.read_immediate(self.eval_operand(left, None)?)?; let layout = binop_right_homogeneous(bin_op).then_some(left.layout); let right = self.read_immediate(self.eval_operand(right, layout)?)?; - self.binop_with_overflow( - bin_op, - left, - right, - dest, - )?; + self.binop_with_overflow(bin_op, left, right, dest)?; } UnaryOp(un_op, ref operand) => { @@ -200,7 +181,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (dest, active_field_index) } } - _ => (dest, None) + _ => (dest, None), }; for (i, operand) in operands.iter().enumerate() { @@ -230,7 +211,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // for big static/const arrays! let rest_ptr = first_ptr.offset(elem_size, self)?; self.memory.copy_repeatedly( - first_ptr, rest_ptr, elem_size, length - 1, /*nonoverlapping:*/true + first_ptr, + rest_ptr, + elem_size, + length - 1, + /*nonoverlapping:*/ true, )?; } } @@ -242,10 +227,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let mplace = self.force_allocation(src)?; let len = mplace.len(self)?; let size = self.pointer_size(); - self.write_scalar( - Scalar::from_uint(len, size), - dest, - )?; + self.write_scalar(Scalar::from_uint(len, size), dest)?; } AddressOf(_, ref place) | Ref(_, _, ref place) => { @@ -265,13 +247,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { NullaryOp(mir::NullOp::SizeOf, ty) => { let ty = self.subst_from_frame_and_normalize_erasing_regions(ty); let layout = self.layout_of(ty)?; - assert!(!layout.is_unsized(), - "SizeOf nullary MIR operator called for unsized type"); + assert!( + !layout.is_unsized(), + "SizeOf nullary MIR operator called for unsized type" + ); let size = self.pointer_size(); - self.write_scalar( - Scalar::from_uint(layout.size.bytes(), size), - dest, - )?; + self.write_scalar(Scalar::from_uint(layout.size.bytes(), size), dest)?; } Cast(kind, ref operand, _) => { diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index b8dc15f451da4..9bd288171b851 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -1,14 +1,14 @@ use std::borrow::Cow; -use rustc::{mir, ty}; +use rustc::ty::layout::{self, LayoutOf, TyLayout}; use rustc::ty::Instance; -use rustc::ty::layout::{self, TyLayout, LayoutOf}; -use syntax::source_map::Span; +use rustc::{mir, ty}; use rustc_target::spec::abi::Abi; +use syntax::source_map::Span; use super::{ - GlobalId, InterpResult, InterpCx, Machine, - OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal, + FnVal, GlobalId, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, PlaceTy, + StackPopCleanup, }; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { @@ -25,12 +25,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Goto { target } => self.go_to_block(target), - SwitchInt { - ref discr, - ref values, - ref targets, - .. - } => { + SwitchInt { ref discr, ref values, ref targets, .. } => { let discr = self.read_immediate(self.eval_operand(discr, None)?)?; trace!("SwitchInt({:?})", *discr); @@ -39,10 +34,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { for (index, &const_int) in values.iter().enumerate() { // Compare using binary_op, to also support pointer values - let res = self.overflowing_binary_op(mir::BinOp::Eq, - discr, - ImmTy::from_uint(const_int, discr.layout), - )?.0; + let res = self + .overflowing_binary_op( + mir::BinOp::Eq, + discr, + ImmTy::from_uint(const_int, discr.layout), + )? + .0; if res.to_bool()? { target_block = targets[index]; break; @@ -52,13 +50,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.go_to_block(target_block); } - Call { - ref func, - ref args, - ref destination, - ref cleanup, - .. - } => { + Call { ref func, ref args, ref destination, ref cleanup, .. } => { let func = self.eval_operand(func, None)?; let (fn_val, abi) = match func.layout.ty.kind { ty::FnPtr(sig) => { @@ -70,10 +62,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::FnDef(def_id, substs) => { let sig = func.layout.ty.fn_sig(*self.tcx); (FnVal::Instance(self.resolve(def_id, substs)?), sig.abi()) - }, - _ => { - bug!("invalid callee of type {:?}", func.layout.ty) } + _ => bug!("invalid callee of type {:?}", func.layout.ty), }; let args = self.eval_operands(args)?; let ret = match destination { @@ -86,39 +76,23 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { abi, &args[..], ret, - *cleanup + *cleanup, )?; } - Drop { - ref location, - target, - unwind, - } => { + Drop { ref location, target, unwind } => { // FIXME(CTFE): forbid drop in const eval let place = self.eval_place(location)?; let ty = place.layout.ty; trace!("TerminatorKind::drop: {:?}, type {}", location, ty); let instance = Instance::resolve_drop_in_place(*self.tcx, ty); - self.drop_in_place( - place, - instance, - terminator.source_info.span, - target, - unwind - )?; + self.drop_in_place(place, instance, terminator.source_info.span, target, unwind)?; } - Assert { - ref cond, - expected, - ref msg, - target, - cleanup, - } => { - let cond_val = self.read_immediate(self.eval_operand(cond, None)?)? - .to_scalar()?.to_bool()?; + Assert { ref cond, expected, ref msg, target, cleanup } => { + let cond_val = + self.read_immediate(self.eval_operand(cond, None)?)?.to_scalar()?.to_bool()?; if expected == cond_val { self.go_to_block(target); } else { @@ -126,7 +100,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - // When we encounter Resume, we've finished unwinding // cleanup for the current stack frame. We pop it in order // to continue unwinding the next frame @@ -135,24 +108,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // By definition, a Resume terminator means // that we're unwinding self.pop_stack_frame(/* unwinding */ true)?; - return Ok(()) - }, + return Ok(()); + } // It is UB to ever encounter this. Unreachable => throw_ub!(Unreachable), // These should never occur for MIR we actually run. - DropAndReplace { .. } | - FalseEdges { .. } | - FalseUnwind { .. } => - bug!("{:#?} should have been eliminated by MIR pass", terminator.kind), + DropAndReplace { .. } | FalseEdges { .. } | FalseUnwind { .. } => { + bug!("{:#?} should have been eliminated by MIR pass", terminator.kind) + } // These are not (yet) supported. It is unclear if they even can occur in // MIR that we actually run. - Yield { .. } | - GeneratorDrop | - Abort => - throw_unsup_format!("Unsupported terminator kind: {:#?}", terminator.kind), + Yield { .. } | GeneratorDrop | Abort => { + throw_unsup_format!("Unsupported terminator kind: {:#?}", terminator.kind) + } } Ok(()) @@ -176,13 +147,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Different valid ranges are okay (once we enforce validity, // that will take care to make it UB to leave the range, just // like for transmute). - (layout::Abi::Scalar(ref caller), layout::Abi::Scalar(ref callee)) => - caller.value == callee.value, - (layout::Abi::ScalarPair(ref caller1, ref caller2), - layout::Abi::ScalarPair(ref callee1, ref callee2)) => - caller1.value == callee1.value && caller2.value == callee2.value, + (layout::Abi::Scalar(ref caller), layout::Abi::Scalar(ref callee)) => { + caller.value == callee.value + } + ( + layout::Abi::ScalarPair(ref caller1, ref caller2), + layout::Abi::ScalarPair(ref callee1, ref callee2), + ) => caller1.value == callee1.value && caller2.value == callee2.value, // Be conservative - _ => false + _ => false, } } @@ -190,7 +163,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { fn pass_argument( &mut self, rust_abi: bool, - caller_arg: &mut impl Iterator>, + caller_arg: &mut impl Iterator>, callee_arg: PlaceTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx> { if rust_abi && callee_arg.layout.is_zst() { @@ -198,8 +171,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { trace!("Skipping callee ZST"); return Ok(()); } - let caller_arg = caller_arg.next() - .ok_or_else(|| err_unsup!(FunctionArgCountMismatch)) ?; + let caller_arg = caller_arg.next().ok_or_else(|| err_unsup!(FunctionArgCountMismatch))?; if rust_abi { debug_assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out"); } @@ -219,7 +191,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { caller_abi: Abi, args: &[OpTy<'tcx, M::PointerTag>], ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>, - unwind: Option + unwind: Option, ) -> InterpResult<'tcx> { trace!("eval_fn_call: {:#?}", fn_val); @@ -235,8 +207,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let callee_abi = { let instance_ty = instance.ty(*self.tcx); match instance_ty.kind { - ty::FnDef(..) => - instance_ty.fn_sig(*self.tcx).abi(), + ty::FnDef(..) => instance_ty.fn_sig(*self.tcx).abi(), ty::Closure(..) => Abi::RustCall, ty::Generator(..) => Abi::Rust, _ => bug!("unexpected callee ty: {:?}", instance_ty), @@ -244,10 +215,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; let normalize_abi = |abi| match abi { Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic => - // These are all the same ABI, really. - Abi::Rust, - abi => - abi, + // These are all the same ABI, really. + { + Abi::Rust + } + abi => abi, }; if normalize_abi(caller_abi) != normalize_abi(callee_abi) { throw_unsup!(FunctionAbiMismatch(caller_abi, callee_abi)) @@ -259,13 +231,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic); return M::call_intrinsic(self, span, instance, args, ret, unwind); } - ty::InstanceDef::VtableShim(..) | - ty::InstanceDef::ReifyShim(..) | - ty::InstanceDef::ClosureOnceShim { .. } | - ty::InstanceDef::FnPtrShim(..) | - ty::InstanceDef::DropGlue(..) | - ty::InstanceDef::CloneShim(..) | - ty::InstanceDef::Item(_) => { + ty::InstanceDef::VtableShim(..) + | ty::InstanceDef::ReifyShim(..) + | ty::InstanceDef::ClosureOnceShim { .. } + | ty::InstanceDef::FnPtrShim(..) + | ty::InstanceDef::DropGlue(..) + | ty::InstanceDef::CloneShim(..) + | ty::InstanceDef::Item(_) => { // We need MIR for this fn let body = match M::find_mir_or_eval_fn(self, instance, args, ret, unwind)? { Some(body) => body, @@ -277,119 +249,120 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { span, body, ret.map(|p| p.0), - StackPopCleanup::Goto { ret: ret.map(|p| p.1), unwind } + StackPopCleanup::Goto { ret: ret.map(|p| p.1), unwind }, )?; // We want to pop this frame again in case there was an error, to put // the blame in the right location. Until the 2018 edition is used in // the compiler, we have to do this with an immediately invoked function. - let res = (||{ - trace!( - "caller ABI: {:?}, args: {:#?}", - caller_abi, - args.iter() - .map(|arg| (arg.layout.ty, format!("{:?}", **arg))) - .collect::>() - ); - trace!( - "spread_arg: {:?}, locals: {:#?}", - body.spread_arg, - body.args_iter() - .map(|local| - (local, self.layout_of_local(self.frame(), local, None).unwrap().ty) - ) - .collect::>() - ); - - // Figure out how to pass which arguments. - // The Rust ABI is special: ZST get skipped. - let rust_abi = match caller_abi { - Abi::Rust | Abi::RustCall => true, - _ => false - }; - // We have two iterators: Where the arguments come from, - // and where they go to. - - // For where they come from: If the ABI is RustCall, we untuple the - // last incoming argument. These two iterators do not have the same type, - // so to keep the code paths uniform we accept an allocation - // (for RustCall ABI only). - let caller_args : Cow<'_, [OpTy<'tcx, M::PointerTag>]> = - if caller_abi == Abi::RustCall && !args.is_empty() { - // Untuple - let (&untuple_arg, args) = args.split_last().unwrap(); - trace!("eval_fn_call: Will pass last argument by untupling"); - Cow::from(args.iter().map(|&a| Ok(a)) + let res = + (|| { + trace!( + "caller ABI: {:?}, args: {:#?}", + caller_abi, + args.iter() + .map(|arg| (arg.layout.ty, format!("{:?}", **arg))) + .collect::>() + ); + trace!( + "spread_arg: {:?}, locals: {:#?}", + body.spread_arg, + body.args_iter() + .map(|local| ( + local, + self.layout_of_local(self.frame(), local, None).unwrap().ty + )) + .collect::>() + ); + + // Figure out how to pass which arguments. + // The Rust ABI is special: ZST get skipped. + let rust_abi = match caller_abi { + Abi::Rust | Abi::RustCall => true, + _ => false, + }; + // We have two iterators: Where the arguments come from, + // and where they go to. + + // For where they come from: If the ABI is RustCall, we untuple the + // last incoming argument. These two iterators do not have the same type, + // so to keep the code paths uniform we accept an allocation + // (for RustCall ABI only). + let caller_args: Cow<'_, [OpTy<'tcx, M::PointerTag>]> = + if caller_abi == Abi::RustCall && !args.is_empty() { + // Untuple + let (&untuple_arg, args) = args.split_last().unwrap(); + trace!("eval_fn_call: Will pass last argument by untupling"); + Cow::from(args.iter().map(|&a| Ok(a)) .chain((0..untuple_arg.layout.fields.count()).into_iter() .map(|i| self.operand_field(untuple_arg, i as u64)) ) .collect::>>>()?) - } else { - // Plain arg passing - Cow::from(args) - }; - // Skip ZSTs - let mut caller_iter = caller_args.iter() - .filter(|op| !rust_abi || !op.layout.is_zst()) - .map(|op| *op); - - // Now we have to spread them out across the callee's locals, - // taking into account the `spread_arg`. If we could write - // this is a single iterator (that handles `spread_arg`), then - // `pass_argument` would be the loop body. It takes care to - // not advance `caller_iter` for ZSTs. - let mut locals_iter = body.args_iter(); - while let Some(local) = locals_iter.next() { - let dest = self.eval_place( - &mir::Place::from(local) - )?; - if Some(local) == body.spread_arg { - // Must be a tuple - for i in 0..dest.layout.fields.count() { - let dest = self.place_field(dest, i as u64)?; + } else { + // Plain arg passing + Cow::from(args) + }; + // Skip ZSTs + let mut caller_iter = caller_args + .iter() + .filter(|op| !rust_abi || !op.layout.is_zst()) + .map(|op| *op); + + // Now we have to spread them out across the callee's locals, + // taking into account the `spread_arg`. If we could write + // this is a single iterator (that handles `spread_arg`), then + // `pass_argument` would be the loop body. It takes care to + // not advance `caller_iter` for ZSTs. + let mut locals_iter = body.args_iter(); + while let Some(local) = locals_iter.next() { + let dest = self.eval_place(&mir::Place::from(local))?; + if Some(local) == body.spread_arg { + // Must be a tuple + for i in 0..dest.layout.fields.count() { + let dest = self.place_field(dest, i as u64)?; + self.pass_argument(rust_abi, &mut caller_iter, dest)?; + } + } else { + // Normal argument self.pass_argument(rust_abi, &mut caller_iter, dest)?; } - } else { - // Normal argument - self.pass_argument(rust_abi, &mut caller_iter, dest)?; } - } - // Now we should have no more caller args - if caller_iter.next().is_some() { - trace!("Caller has passed too many args"); - throw_unsup!(FunctionArgCountMismatch) - } - // Don't forget to check the return type! - if let Some((caller_ret, _)) = ret { - let callee_ret = self.eval_place( - &mir::Place::return_place() - )?; - if !Self::check_argument_compat( - rust_abi, - caller_ret.layout, - callee_ret.layout, - ) { - throw_unsup!( - FunctionRetMismatch(caller_ret.layout.ty, callee_ret.layout.ty) - ) + // Now we should have no more caller args + if caller_iter.next().is_some() { + trace!("Caller has passed too many args"); + throw_unsup!(FunctionArgCountMismatch) } - } else { - let local = mir::RETURN_PLACE; - let callee_layout = self.layout_of_local(self.frame(), local, None)?; - if !callee_layout.abi.is_uninhabited() { - throw_unsup!(FunctionRetMismatch( - self.tcx.types.never, callee_layout.ty - )) + // Don't forget to check the return type! + if let Some((caller_ret, _)) = ret { + let callee_ret = self.eval_place(&mir::Place::return_place())?; + if !Self::check_argument_compat( + rust_abi, + caller_ret.layout, + callee_ret.layout, + ) { + throw_unsup!(FunctionRetMismatch( + caller_ret.layout.ty, + callee_ret.layout.ty + )) + } + } else { + let local = mir::RETURN_PLACE; + let callee_layout = self.layout_of_local(self.frame(), local, None)?; + if !callee_layout.abi.is_uninhabited() { + throw_unsup!(FunctionRetMismatch( + self.tcx.types.never, + callee_layout.ty + )) + } } - } - Ok(()) - })(); + Ok(()) + })(); match res { Err(err) => { self.stack.pop(); Err(err) } - Ok(v) => Ok(v) + Ok(v) => Ok(v), } } // cannot use the shim here, because that will only result in infinite recursion @@ -420,10 +393,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let receiver_ptr_ty = self.tcx.mk_mut_ptr(receiver_place.layout.ty); let this_receiver_ptr = self.layout_of(receiver_ptr_ty)?.field(self, 0)?; // Adjust receiver argument. - args[0] = OpTy::from(ImmTy { - layout: this_receiver_ptr, - imm: receiver_place.ptr.into() - }); + args[0] = + OpTy::from(ImmTy { layout: this_receiver_ptr, imm: receiver_place.ptr.into() }); trace!("Patched self operand to {:#?}", args[0]); // recurse with concrete function self.eval_fn_call(drop_fn, span, caller_abi, &args, ret, unwind) @@ -434,7 +405,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Evaluate a const function where all arguments (if any) are zero-sized types. /// The evaluation is memoized thanks to the query system. // FIXME: Consider moving this to `const_eval.rs`. - pub (crate) fn eval_const_fn_call( + pub(crate) fn eval_const_fn_call( &mut self, gid: GlobalId<'tcx>, ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>, @@ -448,7 +419,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.return_to_block(ret.map(|r| r.1))?; self.dump_place(*dest); - return Ok(()) + return Ok(()); } fn drop_in_place( @@ -457,7 +428,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { instance: ty::Instance<'tcx>, span: Span, target: mir::BasicBlock, - unwind: Option + unwind: Option, ) -> InterpResult<'tcx> { trace!("drop_in_place: {:?},\n {:?}, {:?}", *place, place.layout.ty, instance); // We take the address of the object. This may well be unaligned, which is fine @@ -487,7 +458,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Abi::Rust, &[arg.into()], Some((dest.into(), target)), - unwind + unwind, ) } } diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 916ea3dc393e9..d6fd48cc89fa0 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -1,8 +1,8 @@ -use super::{InterpCx, Machine, MemoryKind, FnVal}; +use super::{FnVal, InterpCx, Machine, MemoryKind}; -use rustc::ty::{self, Ty, Instance, TypeFoldable}; -use rustc::ty::layout::{Size, Align, LayoutOf, HasDataLayout}; -use rustc::mir::interpret::{Scalar, Pointer, InterpResult, PointerArithmetic,}; +use rustc::mir::interpret::{InterpResult, Pointer, PointerArithmetic, Scalar}; +use rustc::ty::layout::{Align, HasDataLayout, LayoutOf, Size}; +use rustc::ty::{self, Instance, Ty, TypeFoldable}; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Creates a dynamic vtable for the given type and vtable origin. This is used only for @@ -77,17 +77,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { for (i, method) in methods.iter().enumerate() { if let Some((def_id, substs)) = *method { // resolve for vtable: insert shims where needed - let instance = ty::Instance::resolve_for_vtable( - *tcx, - self.param_env, - def_id, - substs, - ).ok_or_else(|| err_inval!(TooGeneric))?; + let instance = + ty::Instance::resolve_for_vtable(*tcx, self.param_env, def_id, substs) + .ok_or_else(|| err_inval!(TooGeneric))?; let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); // We cannot use `vtable_allic` as we are creating fn ptrs in this loop. let method_ptr = vtable.offset(ptr_size * (3 + i as u64), tcx)?; - self.memory.get_raw_mut(vtable.alloc_id)? - .write_ptr_sized(tcx, method_ptr, fn_ptr.into())?; + self.memory.get_raw_mut(vtable.alloc_id)?.write_ptr_sized( + tcx, + method_ptr, + fn_ptr.into(), + )?; } } @@ -103,18 +103,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn get_vtable_slot( &self, vtable: Scalar, - idx: usize + idx: usize, ) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> { let ptr_size = self.pointer_size(); // Skip over the 'drop_ptr', 'size', and 'align' fields. let vtable_slot = vtable.ptr_offset(ptr_size * (idx as u64 + 3), self)?; - let vtable_slot = self.memory.check_ptr_access( - vtable_slot, - ptr_size, - self.tcx.data_layout.pointer_align.abi, - )?.expect("cannot be a ZST"); - let fn_ptr = self.memory.get_raw(vtable_slot.alloc_id)? - .read_ptr_sized(self, vtable_slot)?.not_undef()?; + let vtable_slot = self + .memory + .check_ptr_access(vtable_slot, ptr_size, self.tcx.data_layout.pointer_align.abi)? + .expect("cannot be a ZST"); + let fn_ptr = self + .memory + .get_raw(vtable_slot.alloc_id)? + .read_ptr_sized(self, vtable_slot)? + .not_undef()?; Ok(self.memory.get_fn(fn_ptr)?) } @@ -124,15 +126,16 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { vtable: Scalar, ) -> InterpResult<'tcx, (ty::Instance<'tcx>, Ty<'tcx>)> { // We don't care about the pointee type; we just want a pointer. - let vtable = self.memory.check_ptr_access( - vtable, - self.tcx.data_layout.pointer_size, - self.tcx.data_layout.pointer_align.abi, - )?.expect("cannot be a ZST"); - let drop_fn = self.memory - .get_raw(vtable.alloc_id)? - .read_ptr_sized(self, vtable)? - .not_undef()?; + let vtable = self + .memory + .check_ptr_access( + vtable, + self.tcx.data_layout.pointer_size, + self.tcx.data_layout.pointer_align.abi, + )? + .expect("cannot be a ZST"); + let drop_fn = + self.memory.get_raw(vtable.alloc_id)?.read_ptr_sized(self, vtable)?.not_undef()?; // We *need* an instance here, no other kind of function value, to be able // to determine the type. let drop_instance = self.memory.get_fn(drop_fn)?.as_instance()?; @@ -142,15 +145,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // The drop function takes `*mut T` where `T` is the type being dropped, so get that. let args = fn_sig.inputs(); if args.len() != 1 { - throw_ub_format!( - "drop fn should have 1 argument, but signature is {:?}", fn_sig - ); + throw_ub_format!("drop fn should have 1 argument, but signature is {:?}", fn_sig); } - let ty = args[0].builtin_deref(true) - .ok_or_else(|| err_ub_format!( - "drop fn argument type {} is not a pointer type", - args[0] - ))? + let ty = args[0] + .builtin_deref(true) + .ok_or_else(|| { + err_ub_format!("drop fn argument type {} is not a pointer type", args[0]) + })? .ty; Ok((drop_instance, ty)) } @@ -162,26 +163,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let pointer_size = self.pointer_size(); // We check for `size = 3 * ptr_size`, which covers the drop fn (unused here), // the size, and the align (which we read below). - let vtable = self.memory.check_ptr_access( - vtable, - 3*pointer_size, - self.tcx.data_layout.pointer_align.abi, - )?.expect("cannot be a ZST"); + let vtable = self + .memory + .check_ptr_access(vtable, 3 * pointer_size, self.tcx.data_layout.pointer_align.abi)? + .expect("cannot be a ZST"); let alloc = self.memory.get_raw(vtable.alloc_id)?; - let size = alloc.read_ptr_sized( - self, - vtable.offset(pointer_size, self)? - )?.not_undef()?; + let size = alloc.read_ptr_sized(self, vtable.offset(pointer_size, self)?)?.not_undef()?; let size = self.force_bits(size, pointer_size)? as u64; - let align = alloc.read_ptr_sized( - self, - vtable.offset(pointer_size * 2, self)?, - )?.not_undef()?; + let align = + alloc.read_ptr_sized(self, vtable.offset(pointer_size * 2, self)?)?.not_undef()?; let align = self.force_bits(align, pointer_size)? as u64; if size >= self.tcx.data_layout().obj_size_bound() { - throw_ub_format!("invalid vtable: \ - size is bigger than largest supported object"); + throw_ub_format!( + "invalid vtable: \ + size is bigger than largest supported object" + ); } Ok((Size::from_bytes(size), Align::from_bytes(align).unwrap())) } diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 1dbcfe5588e48..df8cb5d692b15 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -7,17 +7,17 @@ use std::fmt::Write; use std::ops::RangeInclusive; -use syntax_pos::symbol::{sym, Symbol}; use rustc::hir; -use rustc::ty::layout::{self, TyLayout, LayoutOf, VariantIdx}; use rustc::ty; +use rustc::ty::layout::{self, LayoutOf, TyLayout, VariantIdx}; use rustc_data_structures::fx::FxHashSet; +use syntax_pos::symbol::{sym, Symbol}; use std::hash::Hash; use super::{ - GlobalAlloc, InterpResult, CheckInAllocMsg, - Scalar, OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy, + CheckInAllocMsg, GlobalAlloc, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, Scalar, + ValueVisitor, }; macro_rules! throw_validation_failure { @@ -83,16 +83,11 @@ pub struct RefTracking { impl RefTracking { pub fn empty() -> Self { - RefTracking { - seen: FxHashSet::default(), - todo: vec![], - } + RefTracking { seen: FxHashSet::default(), todo: vec![] } } pub fn new(op: T) -> Self { - let mut ref_tracking_for_consts = RefTracking { - seen: FxHashSet::default(), - todo: vec![(op, PATH::default())], - }; + let mut ref_tracking_for_consts = + RefTracking { seen: FxHashSet::default(), todo: vec![(op, PATH::default())] }; ref_tracking_for_consts.seen.insert(op); ref_tracking_for_consts } @@ -120,14 +115,17 @@ fn write_path(out: &mut String, path: &Vec) { TupleElem(idx) => write!(out, ".{}", idx), ArrayElem(idx) => write!(out, "[{}]", idx), Deref => - // This does not match Rust syntax, but it is more readable for long paths -- and - // some of the other items here also are not Rust syntax. Actually we can't - // even use the usual syntax because we are just showing the projections, - // not the root. - write!(out, "."), + // This does not match Rust syntax, but it is more readable for long paths -- and + // some of the other items here also are not Rust syntax. Actually we can't + // even use the usual syntax because we are just showing the projections, + // not the root. + { + write!(out, ".") + } Tag => write!(out, "."), DynDowncast => write!(out, "."), - }.unwrap() + } + .unwrap() } } @@ -168,19 +166,13 @@ struct ValidityVisitor<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> { /// starts must not be changed! `visit_fields` and `visit_array` rely on /// this stack discipline. path: Vec, - ref_tracking_for_consts: Option<&'rt mut RefTracking< - MPlaceTy<'tcx, M::PointerTag>, - Vec, - >>, + ref_tracking_for_consts: + Option<&'rt mut RefTracking, Vec>>, ecx: &'rt InterpCx<'mir, 'tcx, M>, } impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M> { - fn aggregate_field_path_elem( - &mut self, - layout: TyLayout<'tcx>, - field: usize, - ) -> PathElem { + fn aggregate_field_path_elem(&mut self, layout: TyLayout<'tcx>, field: usize) -> PathElem { match layout.ty.kind { // generators and closures. ty::Closure(def_id, _) | ty::Generator(def_id, _, _) => { @@ -215,8 +207,10 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M // we might be projecting *to* a variant, or to a field *in*a variant. match layout.variants { layout::Variants::Single { index } => - // Inside a variant - PathElem::Field(def.variants[index].fields[field].ident.name), + // Inside a variant + { + PathElem::Field(def.variants[index].fields[field].ident.name) + } _ => bug!(), } } @@ -262,21 +256,30 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M try_validation!( self.ecx.memory.check_ptr_access( vtable, - 3*self.ecx.tcx.data_layout.pointer_size, // drop, size, align + 3 * self.ecx.tcx.data_layout.pointer_size, // drop, size, align self.ecx.tcx.data_layout.pointer_align.abi, ), "dangling or unaligned vtable pointer in wide pointer or too small vtable", self.path ); - try_validation!(self.ecx.read_drop_type_from_vtable(vtable), - "invalid drop fn in vtable", self.path); - try_validation!(self.ecx.read_size_and_align_from_vtable(vtable), - "invalid size or align in vtable", self.path); + try_validation!( + self.ecx.read_drop_type_from_vtable(vtable), + "invalid drop fn in vtable", + self.path + ); + try_validation!( + self.ecx.read_size_and_align_from_vtable(vtable), + "invalid size or align in vtable", + self.path + ); // FIXME: More checks for the vtable. } ty::Slice(..) | ty::Str => { - let _len = try_validation!(meta.unwrap().to_machine_usize(self.ecx), - "non-integer slice length in wide pointer", self.path); + let _len = try_validation!( + meta.unwrap().to_machine_usize(self.ecx), + "non-integer slice length in wide pointer", + self.path + ); // We do not check that `len * elem_size <= isize::MAX`: // that is only required for references, and there it falls out of the // "dereferenceable" check performed by Stacked Borrows. @@ -284,8 +287,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M ty::Foreign(..) => { // Unsized, but not wide. } - _ => - bug!("Unexpected unsized type tail: {:?}", tail), + _ => bug!("Unexpected unsized type tail: {:?}", tail), } Ok(()) @@ -307,7 +309,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> &mut self, old_op: OpTy<'tcx, M::PointerTag>, field: usize, - new_op: OpTy<'tcx, M::PointerTag> + new_op: OpTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx> { let elem = self.aggregate_field_path_elem(old_op.layout, field); self.visit_elem(new_op, elem) @@ -318,7 +320,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> &mut self, old_op: OpTy<'tcx, M::PointerTag>, variant_id: VariantIdx, - new_op: OpTy<'tcx, M::PointerTag> + new_op: OpTy<'tcx, M::PointerTag>, ) -> InterpResult<'tcx> { let name = match old_op.layout.ty.kind { ty::Adt(adt, _) => PathElem::Variant(adt.variants[variant_id].ident.name), @@ -330,42 +332,36 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } #[inline] - fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> - { + fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> { trace!("visit_value: {:?}, {:?}", *op, op.layout); // Translate some possible errors to something nicer. match self.walk_value(op) { Ok(()) => Ok(()), Err(err) => match err.kind { - err_ub!(InvalidDiscriminant(val)) => - throw_validation_failure!( - val, self.path, "a valid enum discriminant" - ), - err_unsup!(ReadPointerAsBytes) => - throw_validation_failure!( - "a pointer", self.path, "plain (non-pointer) bytes" - ), + err_ub!(InvalidDiscriminant(val)) => { + throw_validation_failure!(val, self.path, "a valid enum discriminant") + } + err_unsup!(ReadPointerAsBytes) => { + throw_validation_failure!("a pointer", self.path, "plain (non-pointer) bytes") + } _ => Err(err), - } + }, } } - fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> - { + fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> { let value = self.ecx.read_immediate(value)?; // Go over all the primitive types let ty = value.layout.ty; match ty.kind { ty::Bool => { let value = value.to_scalar_or_undef(); - try_validation!(value.to_bool(), - value, self.path, "a boolean"); - }, + try_validation!(value.to_bool(), value, self.path, "a boolean"); + } ty::Char => { let value = value.to_scalar_or_undef(); - try_validation!(value.to_char(), - value, self.path, "a valid unicode codepoint"); - }, + try_validation!(value.to_char(), value, self.path, "a valid unicode codepoint"); + } ty::Float(_) | ty::Int(_) | ty::Uint(_) => { // NOTE: Keep this in sync with the array optimization for int/float // types below! @@ -373,8 +369,12 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> let value = value.to_scalar_or_undef(); if self.ref_tracking_for_consts.is_some() { // Integers/floats in CTFE: Must be scalar bits, pointers are dangerous - try_validation!(value.to_bits(size), - value, self.path, "initialized plain (non-pointer) bytes"); + try_validation!( + value.to_bits(size), + value, + self.path, + "initialized plain (non-pointer) bytes" + ); } else { // At run-time, for now, we accept *anything* for these types, including // undef. We should fix that, but let's start low. @@ -383,8 +383,8 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> ty::RawPtr(..) => { // We are conservative with undef for integers, but try to // actually enforce our current rules for raw pointers. - let place = try_validation!(self.ecx.ref_to_mplace(value), - "undefined pointer", self.path); + let place = + try_validation!(self.ecx.ref_to_mplace(value), "undefined pointer", self.path); if place.layout.is_unsized() { self.check_wide_ptr_meta(place.meta, place.layout)?; } @@ -392,25 +392,25 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> _ if ty.is_box() || ty.is_region_ptr() => { // Handle wide pointers. // Check metadata early, for better diagnostics - let place = try_validation!(self.ecx.ref_to_mplace(value), - "undefined pointer", self.path); + let place = + try_validation!(self.ecx.ref_to_mplace(value), "undefined pointer", self.path); if place.layout.is_unsized() { self.check_wide_ptr_meta(place.meta, place.layout)?; } // Make sure this is dereferenceable and all. - let (size, align) = self.ecx.size_and_align_of(place.meta, place.layout)? + let (size, align) = self + .ecx + .size_and_align_of(place.meta, place.layout)? // for the purpose of validity, consider foreign types to have // alignment and size determined by the layout (size will be 0, // alignment should take attributes into account). .unwrap_or_else(|| (place.layout.size, place.layout.align.abi)); - let ptr: Option<_> = match - self.ecx.memory.check_ptr_access_align( - place.ptr, - size, - Some(align), - CheckInAllocMsg::InboundsTest, - ) - { + let ptr: Option<_> = match self.ecx.memory.check_ptr_access_align( + place.ptr, + size, + Some(align), + CheckInAllocMsg::InboundsTest, + ) { Ok(ptr) => ptr, Err(err) => { info!( @@ -418,28 +418,35 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> place.ptr, size, align ); match err.kind { - err_unsup!(InvalidNullPointerUsage) => - throw_validation_failure!("NULL reference", self.path), - err_unsup!(AlignmentCheckFailed { required, has }) => - throw_validation_failure!(format_args!("unaligned reference \ - (required {} byte alignment but found {})", - required.bytes(), has.bytes()), self.path), - err_unsup!(ReadBytesAsPointer) => - throw_validation_failure!( - "dangling reference (created from integer)", - self.path - ), - _ => + err_unsup!(InvalidNullPointerUsage) => { + throw_validation_failure!("NULL reference", self.path) + } + err_unsup!(AlignmentCheckFailed { required, has }) => { throw_validation_failure!( - "dangling reference (not entirely in bounds)", + format_args!( + "unaligned reference \ + (required {} byte alignment but found {})", + required.bytes(), + has.bytes() + ), self.path - ), + ) + } + err_unsup!(ReadBytesAsPointer) => throw_validation_failure!( + "dangling reference (created from integer)", + self.path + ), + _ => throw_validation_failure!( + "dangling reference (not entirely in bounds)", + self.path + ), } } }; // Recursive checking if let Some(ref mut ref_tracking) = self.ref_tracking_for_consts { - if let Some(ptr) = ptr { // not a ZST + if let Some(ptr) = ptr { + // not a ZST // Skip validation entirely for some external statics let alloc_kind = self.ecx.tcx.alloc_map.lock().get(ptr.alloc_id); if let Some(GlobalAlloc::Static(did)) = alloc_kind { @@ -457,8 +464,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> // Normalize before handing `place` to tracking because that will // check for duplicates. let place = if size.bytes() > 0 { - self.ecx.force_mplace_ptr(place) - .expect("we already bounds-checked") + self.ecx.force_mplace_ptr(place).expect("we already bounds-checked") } else { place }; @@ -477,18 +483,19 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> let value = value.to_scalar_or_undef(); let _fn = try_validation!( value.not_undef().and_then(|ptr| self.ecx.memory.get_fn(ptr)), - value, self.path, "a function pointer" + value, + self.path, + "a function pointer" ); // FIXME: Check if the signature matches } // This should be all the primitive types - _ => bug!("Unexpected primitive type {}", value.layout.ty) + _ => bug!("Unexpected primitive type {}", value.layout.ty), } Ok(()) } - fn visit_uninhabited(&mut self) -> InterpResult<'tcx> - { + fn visit_uninhabited(&mut self) -> InterpResult<'tcx> { throw_validation_failure!("a value of an uninhabited type", self.path) } @@ -509,13 +516,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> return Ok(()); } // At least one value is excluded. Get the bits. - let value = try_validation!(value.not_undef(), + let value = try_validation!( + value.not_undef(), value, self.path, - format_args!( - "something {}", - wrapping_range_format(&layout.valid_range, max_hi), - ) + format_args!("something {}", wrapping_range_format(&layout.valid_range, max_hi),) ); let bits = match value.to_bits_or_ptr(op.layout.size, self.ecx) { Err(ptr) => { @@ -545,8 +550,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> ) } } - Ok(data) => - data + Ok(data) => data, }; // Now compare. This is slightly subtle because this is a special "wrap-around" range. if wrapping_range_contains(&layout.valid_range, bits) { @@ -563,22 +567,27 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> fn visit_aggregate( &mut self, op: OpTy<'tcx, M::PointerTag>, - fields: impl Iterator>, + fields: impl Iterator>, ) -> InterpResult<'tcx> { match op.layout.ty.kind { ty::Str => { let mplace = op.assert_mem_place(); // strings are never immediate - try_validation!(self.ecx.read_str(mplace), - "uninitialized or non-UTF-8 data in str", self.path); + try_validation!( + self.ecx.read_str(mplace), + "uninitialized or non-UTF-8 data in str", + self.path + ); } - ty::Array(tys, ..) | ty::Slice(tys) if { - // This optimization applies only for integer and floating point types - // (i.e., types that can hold arbitrary bytes). - match tys.kind { - ty::Int(..) | ty::Uint(..) | ty::Float(..) => true, - _ => false, - } - } => { + ty::Array(tys, ..) | ty::Slice(tys) + if { + // This optimization applies only for integer and floating point types + // (i.e., types that can hold arbitrary bytes). + match tys.kind { + ty::Int(..) | ty::Uint(..) | ty::Float(..) => true, + _ => false, + } + } => + { // Optimized handling for arrays of integer/float type. // bailing out for zsts is ok, since the array element type can only be int/float @@ -617,7 +626,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> /*allow_ptr_and_undef*/ self.ref_tracking_for_consts.is_none(), ) { // In the happy case, we needn't check anything else. - Ok(()) => {}, + Ok(()) => {} // Some error happened, try to provide a more detailed description. Err(err) => { // For some errors we might be able to provide extra information @@ -630,7 +639,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> self.path.push(PathElem::ArrayElem(i)); throw_validation_failure!("undefined bytes", self.path) - }, + } // Other errors shouldn't be possible _ => return Err(err), } @@ -658,19 +667,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &self, op: OpTy<'tcx, M::PointerTag>, path: Vec, - ref_tracking_for_consts: Option<&mut RefTracking< - MPlaceTy<'tcx, M::PointerTag>, - Vec, - >>, + ref_tracking_for_consts: Option< + &mut RefTracking, Vec>, + >, ) -> InterpResult<'tcx> { trace!("validate_operand: {:?}, {:?}", *op, op.layout.ty); // Construct a visitor - let mut visitor = ValidityVisitor { - path, - ref_tracking_for_consts, - ecx: self, - }; + let mut visitor = ValidityVisitor { path, ref_tracking_for_consts, ecx: self }; // Try to cast to ptr *once* instead of all the time. let op = self.force_op_ptr(op).unwrap_or(op); diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs index 427f94f4fbb02..2cfcf0ff06d0f 100644 --- a/src/librustc_mir/interpret/visitor.rs +++ b/src/librustc_mir/interpret/visitor.rs @@ -1,15 +1,11 @@ //! Visitor for a run-time value with a given layout: Traverse enums, structs and other compound //! types until we arrive at the leaves, with custom handling for primitive types. -use rustc::ty::layout::{self, TyLayout, VariantIdx}; +use rustc::mir::interpret::InterpResult; use rustc::ty; -use rustc::mir::interpret::{ - InterpResult, -}; +use rustc::ty::layout::{self, TyLayout, VariantIdx}; -use super::{ - Machine, InterpCx, MPlaceTy, OpTy, -}; +use super::{InterpCx, MPlaceTy, Machine, OpTy}; // A thing that we can project into, and that has a layout. // This wouldn't have to depend on `Machine` but with the current type inference, @@ -19,10 +15,7 @@ pub trait Value<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Copy { fn layout(&self) -> TyLayout<'tcx>; /// Makes this into an `OpTy`. - fn to_op( - self, - ecx: &InterpCx<'mir, 'tcx, M>, - ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>>; + fn to_op(self, ecx: &InterpCx<'mir, 'tcx, M>) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>>; /// Creates this from an `MPlaceTy`. fn from_mem_place(mplace: MPlaceTy<'tcx, M::PointerTag>) -> Self; @@ -35,11 +28,7 @@ pub trait Value<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Copy { ) -> InterpResult<'tcx, Self>; /// Projects to the n-th field. - fn project_field( - self, - ecx: &InterpCx<'mir, 'tcx, M>, - field: u64, - ) -> InterpResult<'tcx, Self>; + fn project_field(self, ecx: &InterpCx<'mir, 'tcx, M>, field: u64) -> InterpResult<'tcx, Self>; } // Operands and memory-places are both values. @@ -73,11 +62,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for OpTy<'tcx, M:: } #[inline(always)] - fn project_field( - self, - ecx: &InterpCx<'mir, 'tcx, M>, - field: u64, - ) -> InterpResult<'tcx, Self> { + fn project_field(self, ecx: &InterpCx<'mir, 'tcx, M>, field: u64) -> InterpResult<'tcx, Self> { ecx.operand_field(self, field) } } @@ -111,11 +96,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for MPlaceTy<'tcx, } #[inline(always)] - fn project_field( - self, - ecx: &InterpCx<'mir, 'tcx, M>, - field: u64, - ) -> InterpResult<'tcx, Self> { + fn project_field(self, ecx: &InterpCx<'mir, 'tcx, M>, field: u64) -> InterpResult<'tcx, Self> { ecx.mplace_field(self, field) } } @@ -332,4 +313,4 @@ macro_rules! make_value_visitor { } make_value_visitor!(ValueVisitor,); -make_value_visitor!(MutValueVisitor,mut); +make_value_visitor!(MutValueVisitor, mut); diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index cf54530317c43..30db1ce345ab3 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -30,24 +30,26 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(stmt_expr_attributes)] #![feature(trait_alias)] #![feature(matches_macro)] +#![recursion_limit = "256"] -#![recursion_limit="256"] - -#[macro_use] extern crate log; -#[macro_use] extern crate rustc; -#[macro_use] extern crate syntax; +#[macro_use] +extern crate log; +#[macro_use] +extern crate rustc; +#[macro_use] +extern crate syntax; mod borrow_check; mod build; +pub mod const_eval; pub mod dataflow; mod hair; +pub mod interpret; mod lints; +pub mod monomorphize; mod shim; pub mod transform; pub mod util; -pub mod interpret; -pub mod monomorphize; -pub mod const_eval; use rustc::ty::query::Providers; diff --git a/src/librustc_mir/lints.rs b/src/librustc_mir/lints.rs index 158b730b9bd43..910286f55740f 100644 --- a/src/librustc_mir/lints.rs +++ b/src/librustc_mir/lints.rs @@ -1,11 +1,11 @@ -use rustc_index::bit_set::BitSet; use rustc::hir::def_id::DefId; use rustc::hir::intravisit::FnKind; use rustc::hir::map::blocks::FnLikeNode; use rustc::lint::builtin::UNCONDITIONAL_RECURSION; use rustc::mir::{self, Body, TerminatorKind}; -use rustc::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt}; use rustc::ty::subst::InternalSubsts; +use rustc::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt}; +use rustc_index::bit_set::BitSet; pub fn check(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId) { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); @@ -61,14 +61,12 @@ fn check_fn_for_unconditional_recursion( let mut visited = BitSet::new_empty(basic_blocks.len()); let param_env = tcx.param_env(def_id); - let trait_substs_count = - match tcx.opt_associated_item(def_id) { - Some(AssocItem { - container: AssocItemContainer::TraitContainer(trait_def_id), - .. - }) => tcx.generics_of(trait_def_id).count(), - _ => 0 - }; + let trait_substs_count = match tcx.opt_associated_item(def_id) { + Some(AssocItem { container: AssocItemContainer::TraitContainer(trait_def_id), .. }) => { + tcx.generics_of(trait_def_id).count() + } + _ => 0, + }; let caller_substs = &InternalSubsts::identity_for_item(tcx, def_id)[..trait_substs_count]; while let Some(bb) = reachable_without_self_call_queue.pop() { @@ -85,19 +83,16 @@ fn check_fn_for_unconditional_recursion( let func_ty = func.ty(body, tcx); if let ty::FnDef(fn_def_id, substs) = func_ty.kind { - let (call_fn_id, call_substs) = - if let Some(instance) = Instance::resolve(tcx, - param_env, - fn_def_id, - substs) { - (instance.def_id(), instance.substs) - } else { - (fn_def_id, substs) - }; - - let is_self_call = - call_fn_id == def_id && - &call_substs[..caller_substs.len()] == caller_substs; + let (call_fn_id, call_substs) = if let Some(instance) = + Instance::resolve(tcx, param_env, fn_def_id, substs) + { + (instance.def_id(), instance.substs) + } else { + (fn_def_id, substs) + }; + + let is_self_call = call_fn_id == def_id + && &call_substs[..caller_substs.len()] == caller_substs; if is_self_call { self_call_locations.push(terminator.source_info); @@ -107,7 +102,7 @@ fn check_fn_for_unconditional_recursion( continue; } } - }, + } TerminatorKind::Abort | TerminatorKind::Return => { //found a path! reached_exit_without_self_call = true; @@ -129,10 +124,12 @@ fn check_fn_for_unconditional_recursion( if !reached_exit_without_self_call && !self_call_locations.is_empty() { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); let sp = tcx.sess.source_map().def_span(tcx.hir().span(hir_id)); - let mut db = tcx.struct_span_lint_hir(UNCONDITIONAL_RECURSION, - hir_id, - sp, - "function cannot return without recursing"); + let mut db = tcx.struct_span_lint_hir( + UNCONDITIONAL_RECURSION, + hir_id, + sp, + "function cannot return without recursing", + ); db.span_label(sp, "cannot return without recursing"); // offer some help to the programmer. for location in &self_call_locations { diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index db8caed629c17..8bc63bfcfcbe3 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -14,10 +14,10 @@ pub fn custom_coerce_unsize_info<'tcx>( let trait_ref = ty::Binder::bind(ty::TraitRef { def_id: def_id, - substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]) + substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]), }); - match tcx.codegen_fulfill_obligation( (ty::ParamEnv::reveal_all(), trait_ref)) { + match tcx.codegen_fulfill_obligation((ty::ParamEnv::reveal_all(), trait_ref)) { traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => { tcx.coerce_unsized_info(impl_def_id).custom_kind.unwrap() } diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 591f220549dea..ebacae95b810b 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -92,22 +92,22 @@ //! source-level module, functions from the same module will be available for //! inlining, even when they are not marked `#[inline]`. -use std::collections::hash_map::Entry; use std::cmp; +use std::collections::hash_map::Entry; use std::sync::Arc; -use syntax::symbol::Symbol; -use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def::DefKind; -use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX}; -use rustc::mir::mono::{Linkage, Visibility, CodegenUnitNameBuilder, CodegenUnit}; +use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc::hir::CodegenFnAttrFlags; use rustc::middle::exported_symbols::SymbolExportLevel; -use rustc::ty::{self, DefIdTree, TyCtxt, InstanceDef}; +use rustc::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, Linkage, Visibility}; +use rustc::mir::mono::{InstantiationMode, MonoItem}; use rustc::ty::print::characteristic_def_id_of_type; use rustc::ty::query::Providers; +use rustc::ty::{self, DefIdTree, InstanceDef, TyCtxt}; use rustc::util::common::time; use rustc::util::nodemap::{DefIdSet, FxHashMap, FxHashSet}; -use rustc::mir::mono::{MonoItem, InstantiationMode}; +use syntax::symbol::Symbol; use crate::monomorphize::collector::InliningMap; use crate::monomorphize::collector::{self, MonoItemCollectionMode}; @@ -117,7 +117,7 @@ pub enum PartitioningStrategy { PerModule, /// Partition the whole crate into a fixed number of codegen units. - FixedUnitCount(usize) + FixedUnitCount(usize), } // Anything we can't find a proper codegen unit for goes into this. @@ -161,8 +161,7 @@ where // monomorphizations can be drop-glue, functions from external crates, and // local functions the definition of which is marked with `#[inline]`. let mut post_inlining = { - let _prof_timer = - tcx.prof.generic_activity("cgu_partitioning_place_inline_items"); + let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_inline_items"); place_inlined_mono_items(initial_partitioning, inlining_map) }; @@ -173,8 +172,7 @@ where // 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 { - let _prof_timer = - tcx.prof.generic_activity("cgu_partitioning_internalize_symbols"); + let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols"); internalize_symbols(tcx, &mut post_inlining, inlining_map); } @@ -224,8 +222,7 @@ where // available to downstream crates. This depends on whether we are in // share-generics mode and whether the current crate can even have // downstream crates. - let export_generics = tcx.sess.opts.share_generics() && - tcx.local_crate_exports_generics(); + let export_generics = tcx.sess.opts.share_generics() && tcx.local_crate_exports_generics(); let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx); let cgu_name_cache = &mut FxHashMap::default(); @@ -237,19 +234,21 @@ where } let characteristic_def_id = characteristic_def_id_of_mono_item(tcx, mono_item); - let is_volatile = is_incremental_build && - mono_item.is_generic_fn(); + let is_volatile = is_incremental_build && mono_item.is_generic_fn(); let codegen_unit_name = match characteristic_def_id { - Some(def_id) => compute_codegen_unit_name(tcx, - cgu_name_builder, - def_id, - is_volatile, - cgu_name_cache), + Some(def_id) => compute_codegen_unit_name( + tcx, + cgu_name_builder, + def_id, + is_volatile, + cgu_name_cache, + ), None => fallback_cgu_name(cgu_name_builder), }; - let codegen_unit = codegen_units.entry(codegen_unit_name) + let codegen_unit = codegen_units + .entry(codegen_unit_name) .or_insert_with(|| CodegenUnit::new(codegen_unit_name)); let mut can_be_internalized = true; @@ -275,9 +274,7 @@ where } PreInliningPartitioning { - codegen_units: codegen_units.into_iter() - .map(|(_, codegen_unit)| codegen_unit) - .collect(), + codegen_units: codegen_units.into_iter().map(|(_, codegen_unit)| codegen_unit).collect(), roots, internalization_candidates, } @@ -290,14 +287,9 @@ fn mono_item_linkage_and_visibility( export_generics: bool, ) -> (Linkage, Visibility) { if let Some(explicit_linkage) = mono_item.explicit_linkage(tcx) { - return (explicit_linkage, Visibility::Default) + return (explicit_linkage, Visibility::Default); } - let vis = mono_item_visibility( - tcx, - mono_item, - can_be_internalized, - export_generics, - ); + let vis = mono_item_visibility(tcx, mono_item, can_be_internalized, export_generics); (Linkage::External, vis) } @@ -335,16 +327,14 @@ fn mono_item_visibility( InstanceDef::Item(def_id) => def_id, // These are all compiler glue and such, never exported, always hidden. - InstanceDef::VtableShim(..) | - InstanceDef::ReifyShim(..) | - InstanceDef::FnPtrShim(..) | - InstanceDef::Virtual(..) | - InstanceDef::Intrinsic(..) | - InstanceDef::ClosureOnceShim { .. } | - InstanceDef::DropGlue(..) | - InstanceDef::CloneShim(..) => { - return Visibility::Hidden - } + InstanceDef::VtableShim(..) + | InstanceDef::ReifyShim(..) + | InstanceDef::FnPtrShim(..) + | InstanceDef::Virtual(..) + | InstanceDef::Intrinsic(..) + | InstanceDef::ClosureOnceShim { .. } + | InstanceDef::DropGlue(..) + | InstanceDef::CloneShim(..) => return Visibility::Hidden, }; // The `start_fn` lang item is actually a monomorphized instance of a @@ -362,7 +352,7 @@ fn mono_item_visibility( // This may be fixable with a new `InstanceDef` perhaps? Unsure! if tcx.lang_items().start_fn() == Some(def_id) { *can_be_internalized = false; - return Visibility::Hidden + return Visibility::Hidden; } let is_generic = instance.substs.non_erasable_generics().next().is_some(); @@ -376,7 +366,7 @@ fn mono_item_visibility( default_visibility(tcx, def_id, true) } else { Visibility::Hidden - } + }; } if is_generic { @@ -395,14 +385,13 @@ fn mono_item_visibility( Visibility::Hidden } } else { - // If this isn't a generic function then we mark this a `Default` if // this is a reachable item, meaning that it's a symbol other crates may // access when they link to us. if tcx.is_reachable_non_generic(def_id) { *can_be_internalized = false; debug_assert!(!is_generic); - return default_visibility(tcx, def_id, false) + return default_visibility(tcx, def_id, false); } // If this isn't reachable then we're gonna tag this with `Hidden` @@ -450,18 +439,18 @@ fn mono_item_visibility( fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibility { if !tcx.sess.target.target.options.default_hidden_visibility { - return Visibility::Default + return Visibility::Default; } // Generic functions never have export-level C. if is_generic { - return Visibility::Hidden + return Visibility::Hidden; } // Things with export level C don't get instantiated in // downstream crates. if !id.is_local() { - return Visibility::Hidden + return Visibility::Hidden; } // C-export level items remain at `Default`, all other internal @@ -502,9 +491,11 @@ fn merge_codegen_units<'tcx>( for (k, v) in smallest.items_mut().drain() { second_smallest.items_mut().insert(k, v); } - debug!("CodegenUnit {} merged in to CodegenUnit {}", - smallest.name(), - second_smallest.name()); + debug!( + "CodegenUnit {} merged in to CodegenUnit {}", + smallest.name(), + second_smallest.name() + ); } let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx); @@ -513,17 +504,15 @@ fn merge_codegen_units<'tcx>( } } -fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning<'tcx>, - inlining_map: &InliningMap<'tcx>) - -> PostInliningPartitioning<'tcx> { +fn place_inlined_mono_items<'tcx>( + initial_partitioning: PreInliningPartitioning<'tcx>, + inlining_map: &InliningMap<'tcx>, +) -> PostInliningPartitioning<'tcx> { let mut new_partitioning = Vec::new(); let mut mono_item_placements = FxHashMap::default(); - let PreInliningPartitioning { - codegen_units: initial_cgus, - roots, - internalization_candidates, - } = initial_partitioning; + let PreInliningPartitioning { codegen_units: initial_cgus, roots, internalization_candidates } = + initial_partitioning; let single_codegen_unit = initial_cgus.len() == 1; @@ -543,15 +532,17 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning< new_codegen_unit.items_mut().insert(mono_item, *linkage); } else { if roots.contains(&mono_item) { - bug!("GloballyShared mono-item inlined into other CGU: \ - {:?}", mono_item); + bug!( + "GloballyShared mono-item inlined into other CGU: \ + {:?}", + mono_item + ); } // This is a CGU-private copy. - new_codegen_unit.items_mut().insert( - mono_item, - (Linkage::Internal, Visibility::Default), - ); + new_codegen_unit + .items_mut() + .insert(mono_item, (Linkage::Internal, Visibility::Default)); } if !single_codegen_unit { @@ -570,7 +561,7 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning< } Entry::Vacant(e) => { e.insert(MonoItemPlacement::SingleCgu { - cgu_name: new_codegen_unit.name() + cgu_name: new_codegen_unit.name(), }); } } @@ -586,9 +577,11 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning< internalization_candidates, }; - fn follow_inlining<'tcx>(mono_item: MonoItem<'tcx>, - inlining_map: &InliningMap<'tcx>, - visited: &mut FxHashSet>) { + fn follow_inlining<'tcx>( + mono_item: MonoItem<'tcx>, + inlining_map: &InliningMap<'tcx>, + visited: &mut FxHashSet>, + ) { if !visited.insert(mono_item) { return; } @@ -610,8 +603,7 @@ fn internalize_symbols<'tcx>( // could be accessed from. for cgu in &mut partitioning.codegen_units { for candidate in &partitioning.internalization_candidates { - cgu.items_mut().insert(*candidate, - (Linkage::Internal, Visibility::Default)); + cgu.items_mut().insert(*candidate, (Linkage::Internal, Visibility::Default)); } } @@ -623,9 +615,7 @@ fn internalize_symbols<'tcx>( let mut accessor_map: FxHashMap, Vec>> = Default::default(); inlining_map.iter_accesses(|accessor, accessees| { for accessee in accessees { - accessor_map.entry(*accessee) - .or_default() - .push(accessor); + accessor_map.entry(*accessee).or_default().push(accessor); } }); @@ -634,28 +624,28 @@ fn internalize_symbols<'tcx>( // For each internalization candidates in each codegen unit, check if it is // accessed from outside its defining codegen unit. for cgu in &mut partitioning.codegen_units { - let home_cgu = MonoItemPlacement::SingleCgu { - cgu_name: cgu.name() - }; + let home_cgu = MonoItemPlacement::SingleCgu { cgu_name: cgu.name() }; for (accessee, linkage_and_visibility) in cgu.items_mut() { if !partitioning.internalization_candidates.contains(accessee) { // This item is no candidate for internalizing, so skip it. - continue + continue; } debug_assert_eq!(mono_item_placements[accessee], home_cgu); if let Some(accessors) = accessor_map.get(accessee) { - if accessors.iter() - .filter_map(|accessor| { - // Some accessors might not have been - // instantiated. We can safely ignore those. - mono_item_placements.get(accessor) - }) - .any(|placement| *placement != home_cgu) { + if accessors + .iter() + .filter_map(|accessor| { + // Some accessors might not have been + // instantiated. We can safely ignore those. + mono_item_placements.get(accessor) + }) + .any(|placement| *placement != home_cgu) + { // Found an accessor from another CGU, so skip to the next // item without marking this one as internal. - continue + continue; } } @@ -674,14 +664,14 @@ fn characteristic_def_id_of_mono_item<'tcx>( MonoItem::Fn(instance) => { let def_id = match instance.def { ty::InstanceDef::Item(def_id) => def_id, - ty::InstanceDef::VtableShim(..) | - ty::InstanceDef::ReifyShim(..) | - ty::InstanceDef::FnPtrShim(..) | - ty::InstanceDef::ClosureOnceShim { .. } | - ty::InstanceDef::Intrinsic(..) | - ty::InstanceDef::DropGlue(..) | - ty::InstanceDef::Virtual(..) | - ty::InstanceDef::CloneShim(..) => return None + ty::InstanceDef::VtableShim(..) + | ty::InstanceDef::ReifyShim(..) + | ty::InstanceDef::FnPtrShim(..) + | ty::InstanceDef::ClosureOnceShim { .. } + | ty::InstanceDef::Intrinsic(..) + | ty::InstanceDef::DropGlue(..) + | ty::InstanceDef::Virtual(..) + | ty::InstanceDef::CloneShim(..) => return None, }; // If this is a method, we want to put it into the same module as @@ -731,12 +721,9 @@ fn compute_codegen_unit_name( if current_def_id.index == CRATE_DEF_INDEX { if cgu_def_id.is_none() { // If we have not found a module yet, take the crate root. - cgu_def_id = Some(DefId { - krate: def_id.krate, - index: CRATE_DEF_INDEX, - }); + cgu_def_id = Some(DefId { krate: def_id.krate, index: CRATE_DEF_INDEX }); } - break + break; } else if tcx.def_kind(current_def_id) == Some(DefKind::Mod) { if cgu_def_id.is_none() { cgu_def_id = Some(current_def_id); @@ -753,18 +740,18 @@ fn compute_codegen_unit_name( let cgu_def_id = cgu_def_id.unwrap(); - cache.entry((cgu_def_id, volatile)).or_insert_with(|| { - let def_path = tcx.def_path(cgu_def_id); + cache + .entry((cgu_def_id, volatile)) + .or_insert_with(|| { + let def_path = tcx.def_path(cgu_def_id); - let components = def_path - .data - .iter() - .map(|part| part.data.as_symbol()); + let components = def_path.data.iter().map(|part| part.data.as_symbol()); - let volatile_suffix = volatile.then_some("volatile"); + let volatile_suffix = volatile.then_some("volatile"); - name_builder.build_cgu_name(def_path.krate, components, volatile_suffix) - }).clone() + name_builder.build_cgu_name(def_path.krate, components, volatile_suffix) + }) + .clone() } fn numbered_codegen_unit_name( @@ -787,14 +774,16 @@ where for (mono_item, linkage) in cgu.items() { let symbol_name = mono_item.symbol_name(tcx).name.as_str(); let symbol_hash_start = symbol_name.rfind('h'); - let symbol_hash = symbol_hash_start.map(|i| &symbol_name[i ..]) - .unwrap_or(""); - - debug!(" - {} [{:?}] [{}] estimated size {}", - mono_item.to_string(tcx, true), - linkage, - symbol_hash, - mono_item.size_estimate(tcx)); + let symbol_hash = + symbol_hash_start.map(|i| &symbol_name[i..]).unwrap_or(""); + + debug!( + " - {} [{:?}] [{}] estimated size {}", + mono_item.to_string(tcx, true), + linkage, + symbol_hash, + mono_item.size_estimate(tcx) + ); } debug!(""); @@ -808,9 +797,8 @@ where I: Iterator>, 'tcx: 'a, { - let mut symbols: Vec<_> = mono_items.map(|mono_item| { - (mono_item, mono_item.symbol_name(tcx)) - }).collect(); + let mut symbols: Vec<_> = + mono_items.map(|mono_item| (mono_item, mono_item.symbol_name(tcx))).collect(); symbols.sort_by_key(|sym| sym.1); @@ -828,11 +816,7 @@ where // Deterministically select one of the spans for error reporting let span = match (span1, span2) { (Some(span1), Some(span2)) => { - Some(if span1.lo().0 > span2.lo().0 { - span1 - } else { - span2 - }) + Some(if span1.lo().0 > span2.lo().0 { span1 } else { span2 }) } (span1, span2) => span1.or(span2), }; @@ -862,9 +846,11 @@ fn collect_and_partition_mono_items( MonoItemCollectionMode::Eager } else { if mode_string != "lazy" { - let message = format!("Unknown codegen-item collection mode '{}'. \ + let message = format!( + "Unknown codegen-item collection mode '{}'. \ Falling back to 'lazy' mode.", - mode_string); + mode_string + ); tcx.sess.warn(&message); } @@ -880,9 +866,8 @@ fn collect_and_partition_mono_items( } }; - let (items, inlining_map) = - time(tcx.sess, "monomorphization collection", || { - collector::collect_crate_mono_items(tcx, collection_mode) + let (items, inlining_map) = time(tcx.sess, "monomorphization collection", || { + collector::collect_crate_mono_items(tcx, collection_mode) }); tcx.sess.abort_if_errors(); @@ -896,33 +881,27 @@ fn collect_and_partition_mono_items( }; let codegen_units = time(tcx.sess, "codegen unit partitioning", || { - partition( - tcx, - items.iter().cloned(), - strategy, - &inlining_map - ) + partition(tcx, items.iter().cloned(), strategy, &inlining_map) .into_iter() .map(Arc::new) .collect::>() }); - let mono_items: DefIdSet = items.iter().filter_map(|mono_item| { - match *mono_item { + let mono_items: DefIdSet = items + .iter() + .filter_map(|mono_item| match *mono_item { MonoItem::Fn(ref instance) => Some(instance.def_id()), MonoItem::Static(def_id) => Some(def_id), _ => None, - } - }).collect(); + }) + .collect(); if tcx.sess.opts.debugging_opts.print_mono_items.is_some() { let mut item_to_cgus: FxHashMap<_, Vec<_>> = Default::default(); for cgu in &codegen_units { for (&mono_item, &linkage) in cgu.items() { - item_to_cgus.entry(mono_item) - .or_default() - .push((cgu.name(), linkage)); + item_to_cgus.entry(mono_item).or_default().push((cgu.name(), linkage)); } } @@ -972,12 +951,10 @@ fn collect_and_partition_mono_items( } pub fn provide(providers: &mut Providers<'_>) { - providers.collect_and_partition_mono_items = - collect_and_partition_mono_items; + providers.collect_and_partition_mono_items = collect_and_partition_mono_items; providers.is_codegened_item = |tcx, def_id| { - let (all_mono_items, _) = - tcx.collect_and_partition_mono_items(LOCAL_CRATE); + let (all_mono_items, _) = tcx.collect_and_partition_mono_items(LOCAL_CRATE); all_mono_items.contains(&def_id) }; diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index a29748962181e..923fa3a20b72f 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -1,26 +1,26 @@ use rustc::hir; use rustc::hir::def_id::DefId; use rustc::mir::*; -use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::layout::VariantIdx; -use rustc::ty::subst::{Subst, InternalSubsts}; use rustc::ty::query::Providers; +use rustc::ty::subst::{InternalSubsts, Subst}; +use rustc::ty::{self, Ty, TyCtxt}; -use rustc_index::vec::{IndexVec, Idx}; +use rustc_index::vec::{Idx, IndexVec}; use rustc_target::spec::abi::Abi; -use syntax_pos::{Span, sym}; +use syntax_pos::{sym, Span}; use std::fmt; use std::iter; use crate::transform::{ - add_moves_for_packed_drops, add_call_guards, - remove_noop_landing_pads, no_landing_pads, simplify, run_passes + add_call_guards, add_moves_for_packed_drops, no_landing_pads, remove_noop_landing_pads, + run_passes, simplify, }; -use crate::util::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode}; -use crate::util::patch::MirPatch; +use crate::util::elaborate_drops::{self, DropElaborator, DropFlagMode, DropStyle}; use crate::util::expand_aggregate; +use crate::util::patch::MirPatch; pub fn provide(providers: &mut Providers<'_>) { providers.mir_shims = make_shim; @@ -30,24 +30,16 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx debug!("make_shim({:?})", instance); let mut result = match instance { - ty::InstanceDef::Item(..) => - bug!("item {:?} passed to make_shim", instance), + ty::InstanceDef::Item(..) => bug!("item {:?} passed to make_shim", instance), ty::InstanceDef::VtableShim(def_id) => { - build_call_shim( - tcx, - instance, - Adjustment::DerefMove, - CallKind::Direct(def_id), - None, - ) + build_call_shim(tcx, instance, Adjustment::DerefMove, CallKind::Direct(def_id), None) } ty::InstanceDef::FnPtrShim(def_id, ty) => { let trait_ = tcx.trait_of_item(def_id).unwrap(); let adjustment = match tcx.lang_items().fn_trait_kind(trait_) { Some(ty::ClosureKind::FnOnce) => Adjustment::Identity, - Some(ty::ClosureKind::FnMut) | - Some(ty::ClosureKind::Fn) => Adjustment::Deref, - None => bug!("fn pointer {:?} is not an fn", ty) + Some(ty::ClosureKind::FnMut) | Some(ty::ClosureKind::Fn) => Adjustment::Deref, + None => bug!("fn pointer {:?} is not an fn", ty), }; // HACK: we need the "real" argument types for the MIR, // but because our substs are (Self, Args), where Args @@ -58,13 +50,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx let sig = tcx.erase_late_bound_regions(&ty.fn_sig(tcx)); let arg_tys = sig.inputs(); - build_call_shim( - tcx, - instance, - adjustment, - CallKind::Indirect, - Some(arg_tys) - ) + build_call_shim(tcx, instance, adjustment, CallKind::Indirect, Some(arg_tys)) } // We are generating a call back to our def-id, which the // codegen backend knows to turn to an actual call, be it @@ -72,32 +58,19 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx // indirect calls must be codegen'd differently than direct ones // (such as `#[track_caller]`). ty::InstanceDef::ReifyShim(def_id) => { - build_call_shim( - tcx, - instance, - Adjustment::Identity, - CallKind::Direct(def_id), - None - ) + build_call_shim(tcx, instance, Adjustment::Identity, CallKind::Direct(def_id), None) } ty::InstanceDef::ClosureOnceShim { call_once: _ } => { let fn_mut = tcx.lang_items().fn_mut_trait().unwrap(); let call_mut = tcx .associated_items(fn_mut) .find(|it| it.kind == ty::AssocKind::Method) - .unwrap().def_id; + .unwrap() + .def_id; - build_call_shim( - tcx, - instance, - Adjustment::RefMut, - CallKind::Direct(call_mut), - None - ) - } - ty::InstanceDef::DropGlue(def_id, ty) => { - build_drop_shim(tcx, def_id, ty) + build_call_shim(tcx, instance, Adjustment::RefMut, CallKind::Direct(call_mut), None) } + ty::InstanceDef::DropGlue(def_id, ty) => build_drop_shim(tcx, def_id, ty), ty::InstanceDef::CloneShim(def_id, ty) => { let name = tcx.item_name(def_id); if name == sym::clone { @@ -118,13 +91,20 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx }; debug!("make_shim({:?}) = untransformed {:?}", instance, result); - run_passes(tcx, &mut result, instance, None, MirPhase::Const, &[ - &add_moves_for_packed_drops::AddMovesForPackedDrops, - &no_landing_pads::NoLandingPads::new(tcx), - &remove_noop_landing_pads::RemoveNoopLandingPads, - &simplify::SimplifyCfg::new("make_shim"), - &add_call_guards::CriticalCallEdges, - ]); + run_passes( + tcx, + &mut result, + instance, + None, + MirPhase::Const, + &[ + &add_moves_for_packed_drops::AddMovesForPackedDrops, + &no_landing_pads::NoLandingPads::new(tcx), + &remove_noop_landing_pads::RemoveNoopLandingPads, + &simplify::SimplifyCfg::new("make_shim"), + &add_call_guards::CriticalCallEdges, + ], + ); debug!("make_shim({:?}) = {:?}", instance, result); @@ -159,17 +139,19 @@ fn temp_decl(mutability: Mutability, ty: Ty<'_>, span: Span) -> LocalDecl<'_> { } } -fn local_decls_for_sig<'tcx>(sig: &ty::FnSig<'tcx>, span: Span) - -> IndexVec> -{ +fn local_decls_for_sig<'tcx>( + sig: &ty::FnSig<'tcx>, + span: Span, +) -> IndexVec> { iter::once(temp_decl(Mutability::Mut, sig.output(), span)) - .chain(sig.inputs().iter().map( - |ity| temp_decl(Mutability::Not, ity, span))) + .chain(sig.inputs().iter().map(|ity| temp_decl(Mutability::Not, ity, span))) .collect() } fn build_drop_shim<'tcx>( - tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option> + tcx: TyCtxt<'tcx>, + def_id: DefId, + ty: Option>, ) -> BodyAndCache<'tcx> { debug!("build_drop_shim(def_id={:?}, ty={:?})", def_id, ty); @@ -196,38 +178,33 @@ fn build_drop_shim<'tcx>( blocks.push(BasicBlockData { statements: vec![], terminator: Some(Terminator { source_info, kind }), - is_cleanup: false + is_cleanup: false, }) }; block(&mut blocks, TerminatorKind::Goto { target: return_block }); block(&mut blocks, TerminatorKind::Return); - let body = new_body( - blocks, - local_decls_for_sig(&sig, span), - sig.inputs().len(), - span); + let body = new_body(blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span); let mut body = BodyAndCache::new(body); if let Some(..) = ty { // The first argument (index 0), but add 1 for the return value. - let dropee_ptr = Place::from(Local::new(1+0)); + let dropee_ptr = Place::from(Local::new(1 + 0)); if tcx.sess.opts.debugging_opts.mir_emit_retag { // Function arguments should be retagged, and we make this one raw. - body.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement { - source_info, - kind: StatementKind::Retag(RetagKind::Raw, box(dropee_ptr.clone())), - }); + body.basic_blocks_mut()[START_BLOCK].statements.insert( + 0, + Statement { + source_info, + kind: StatementKind::Retag(RetagKind::Raw, box (dropee_ptr.clone())), + }, + ); } let patch = { let param_env = tcx.param_env(def_id).with_reveal_all(); - let mut elaborator = DropShimElaborator { - body: &body, - patch: MirPatch::new(&body), - tcx, - param_env - }; + let mut elaborator = + DropShimElaborator { body: &body, patch: MirPatch::new(&body), tcx, param_env }; let dropee = tcx.mk_place_deref(dropee_ptr); let resume_block = elaborator.patch.resume_block(); elaborate_drops::elaborate_drop( @@ -237,7 +214,7 @@ fn build_drop_shim<'tcx>( (), return_block, elaborate_drops::Unwind::To(resume_block), - START_BLOCK + START_BLOCK, ); elaborator.patch }; @@ -285,27 +262,28 @@ impl<'a, 'tcx> fmt::Debug for DropShimElaborator<'a, 'tcx> { impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { type Path = (); - fn patch(&mut self) -> &mut MirPatch<'tcx> { &mut self.patch } - fn body(&self) -> &'a Body<'tcx> { self.body } + fn patch(&mut self) -> &mut MirPatch<'tcx> { + &mut self.patch + } + fn body(&self) -> &'a Body<'tcx> { + self.body + } fn tcx(&self) -> TyCtxt<'tcx> { self.tcx - } - fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { + self.param_env + } fn drop_style(&self, _path: Self::Path, mode: DropFlagMode) -> DropStyle { - if let DropFlagMode::Shallow = mode { - DropStyle::Static - } else { - DropStyle::Open - } + if let DropFlagMode::Shallow = mode { DropStyle::Static } else { DropStyle::Open } } fn get_drop_flag(&mut self, _path: Self::Path) -> Option> { None } - fn clear_drop_flag(&mut self, _location: Location, _path: Self::Path, _mode: DropFlagMode) { - } + fn clear_drop_flag(&mut self, _location: Location, _path: Self::Path, _mode: DropFlagMode) {} fn field_subpath(&self, _path: Self::Path, _field: Field) -> Option { None @@ -335,7 +313,7 @@ fn build_clone_shim<'tcx>( let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env, builder.span); let dest = Place::return_place(); - let src = tcx.mk_place_deref(Place::from(Local::new(1+0))); + let src = tcx.mk_place_deref(Place::from(Local::new(1 + 0))); match self_ty.kind { _ if is_copy => builder.copy_shim(), @@ -344,15 +322,10 @@ fn build_clone_shim<'tcx>( builder.array_shim(dest, src, ty, len) } ty::Closure(def_id, substs) => { - builder.tuple_like_shim( - dest, src, - substs.as_closure().upvar_tys(def_id, tcx) - ) + builder.tuple_like_shim(dest, src, substs.as_closure().upvar_tys(def_id, tcx)) } ty::Tuple(..) => builder.tuple_like_shim(dest, src, self_ty.tuple_fields()), - _ => { - bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty) - } + _ => bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty), }; BodyAndCache::new(builder.into_mir()) @@ -388,12 +361,7 @@ impl CloneShimBuilder<'tcx> { } fn into_mir(self) -> Body<'tcx> { - new_body( - self.blocks, - self.local_decls, - self.sig.inputs().len(), - self.span, - ) + new_body(self.blocks, self.local_decls, self.sig.inputs().len(), self.span) } fn source_info(&self) -> SourceInfo { @@ -404,7 +372,7 @@ impl CloneShimBuilder<'tcx> { &mut self, statements: Vec>, kind: TerminatorKind<'tcx>, - is_cleanup: bool + is_cleanup: bool, ) -> BasicBlock { let source_info = self.source_info(); self.blocks.push(BasicBlockData { @@ -423,22 +391,15 @@ impl CloneShimBuilder<'tcx> { } fn make_statement(&self, kind: StatementKind<'tcx>) -> Statement<'tcx> { - Statement { - source_info: self.source_info(), - kind, - } + Statement { source_info: self.source_info(), kind } } fn copy_shim(&mut self) { - let rcvr = self.tcx.mk_place_deref(Place::from(Local::new(1+0))); - let ret_statement = self.make_statement( - StatementKind::Assign( - box( - Place::return_place(), - Rvalue::Use(Operand::Copy(rcvr)) - ) - ) - ); + let rcvr = self.tcx.mk_place_deref(Place::from(Local::new(1 + 0))); + let ret_statement = self.make_statement(StatementKind::Assign(box ( + Place::return_place(), + Rvalue::Use(Operand::Copy(rcvr)), + ))); self.block(vec![ret_statement], TerminatorKind::Return, false); } @@ -453,7 +414,7 @@ impl CloneShimBuilder<'tcx> { src: Place<'tcx>, ty: Ty<'tcx>, next: BasicBlock, - cleanup: BasicBlock + cleanup: BasicBlock, ) { let tcx = self.tcx; @@ -469,30 +430,27 @@ impl CloneShimBuilder<'tcx> { let ref_loc = self.make_place( Mutability::Not, - tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut { - ty, - mutbl: hir::Mutability::Not, - }) + tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut { ty, mutbl: hir::Mutability::Not }), ); // `let ref_loc: &ty = &src;` - let statement = self.make_statement( - StatementKind::Assign( - box( - ref_loc.clone(), - Rvalue::Ref(tcx.lifetimes.re_erased, BorrowKind::Shared, src) - ) - ) - ); + let statement = self.make_statement(StatementKind::Assign(box ( + ref_loc.clone(), + Rvalue::Ref(tcx.lifetimes.re_erased, BorrowKind::Shared, src), + ))); // `let loc = Clone::clone(ref_loc);` - self.block(vec![statement], TerminatorKind::Call { - func, - args: vec![Operand::Move(ref_loc)], - destination: Some((dest, next)), - cleanup: Some(cleanup), - from_hir_call: true, - }, false); + self.block( + vec![statement], + TerminatorKind::Call { + func, + args: vec![Operand::Move(ref_loc)], + destination: Some((dest, next)), + cleanup: Some(cleanup), + from_hir_call: true, + }, + false, + ); } fn loop_header( @@ -501,25 +459,21 @@ impl CloneShimBuilder<'tcx> { end: Place<'tcx>, loop_body: BasicBlock, loop_end: BasicBlock, - is_cleanup: bool + is_cleanup: bool, ) { let tcx = self.tcx; let cond = self.make_place(Mutability::Mut, tcx.types.bool); - let compute_cond = self.make_statement( - StatementKind::Assign( - box( - cond.clone(), - Rvalue::BinaryOp(BinOp::Ne, Operand::Copy(end), Operand::Copy(beg)) - ) - ) - ); + let compute_cond = self.make_statement(StatementKind::Assign(box ( + cond.clone(), + Rvalue::BinaryOp(BinOp::Ne, Operand::Copy(end), Operand::Copy(beg)), + ))); // `if end != beg { goto loop_body; } else { goto loop_end; }` self.block( vec![compute_cond], TerminatorKind::if_(tcx, Operand::Move(cond), loop_body, loop_end), - is_cleanup + is_cleanup, ); } @@ -543,22 +497,14 @@ impl CloneShimBuilder<'tcx> { // `let end = len;` // `goto #1;` let inits = vec![ - self.make_statement( - StatementKind::Assign( - box( - Place::from(beg), - Rvalue::Use(Operand::Constant(self.make_usize(0))) - ) - ) - ), - self.make_statement( - StatementKind::Assign( - box( - end.clone(), - Rvalue::Use(Operand::Constant(self.make_usize(len))) - ) - ) - ) + self.make_statement(StatementKind::Assign(box ( + Place::from(beg), + Rvalue::Use(Operand::Constant(self.make_usize(0))), + ))), + self.make_statement(StatementKind::Assign(box ( + end.clone(), + Rvalue::Use(Operand::Constant(self.make_usize(len))), + ))), ]; self.block(inits, TerminatorKind::Goto { target: BasicBlock::new(1) }, false); @@ -567,37 +513,26 @@ impl CloneShimBuilder<'tcx> { // BB #3; // } // BB #4; - self.loop_header(Place::from(beg), - end, - BasicBlock::new(2), - BasicBlock::new(4), - false); + self.loop_header(Place::from(beg), end, BasicBlock::new(2), BasicBlock::new(4), false); // BB #2 // `dest[i] = Clone::clone(src[beg])`; // Goto #3 if ok, #5 if unwinding happens. let dest_field = self.tcx.mk_place_index(dest.clone(), beg); let src_field = self.tcx.mk_place_index(src, beg); - self.make_clone_call(dest_field, src_field, ty, BasicBlock::new(3), - BasicBlock::new(5)); + self.make_clone_call(dest_field, src_field, ty, BasicBlock::new(3), BasicBlock::new(5)); // BB #3 // `beg = beg + 1;` // `goto #1`; - let statements = vec![ - self.make_statement( - StatementKind::Assign( - box( - Place::from(beg), - Rvalue::BinaryOp( - BinOp::Add, - Operand::Copy(Place::from(beg)), - Operand::Constant(self.make_usize(1)) - ) - ) - ) - ) - ]; + let statements = vec![self.make_statement(StatementKind::Assign(box ( + Place::from(beg), + Rvalue::BinaryOp( + BinOp::Add, + Operand::Copy(Place::from(beg)), + Operand::Constant(self.make_usize(1)), + ), + )))]; self.block(statements, TerminatorKind::Goto { target: BasicBlock::new(1) }, false); // BB #4 @@ -610,14 +545,10 @@ impl CloneShimBuilder<'tcx> { // goto #6; let end = beg; let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span)); - let init = self.make_statement( - StatementKind::Assign( - box( - Place::from(beg), - Rvalue::Use(Operand::Constant(self.make_usize(0))) - ) - ) - ); + let init = self.make_statement(StatementKind::Assign(box ( + Place::from(beg), + Rvalue::Use(Operand::Constant(self.make_usize(0))), + ))); self.block(vec![init], TerminatorKind::Goto { target: BasicBlock::new(6) }, true); // BB #6 (cleanup): loop { @@ -625,41 +556,47 @@ impl CloneShimBuilder<'tcx> { // BB #8; // } // BB #9; - self.loop_header(Place::from(beg), Place::from(end), - BasicBlock::new(7), BasicBlock::new(9), true); + self.loop_header( + Place::from(beg), + Place::from(end), + BasicBlock::new(7), + BasicBlock::new(9), + true, + ); // BB #7 (cleanup) // `drop(dest[beg])`; - self.block(vec![], TerminatorKind::Drop { - location: self.tcx.mk_place_index(dest, beg), - target: BasicBlock::new(8), - unwind: None, - }, true); + self.block( + vec![], + TerminatorKind::Drop { + location: self.tcx.mk_place_index(dest, beg), + target: BasicBlock::new(8), + unwind: None, + }, + true, + ); // BB #8 (cleanup) // `beg = beg + 1;` // `goto #6;` - let statement = self.make_statement( - StatementKind::Assign( - box( - Place::from(beg), - Rvalue::BinaryOp( - BinOp::Add, - Operand::Copy(Place::from(beg)), - Operand::Constant(self.make_usize(1)) - ) - ) - ) - ); + let statement = self.make_statement(StatementKind::Assign(box ( + Place::from(beg), + Rvalue::BinaryOp( + BinOp::Add, + Operand::Copy(Place::from(beg)), + Operand::Constant(self.make_usize(1)), + ), + ))); self.block(vec![statement], TerminatorKind::Goto { target: BasicBlock::new(6) }, true); // BB #9 (resume) self.block(vec![], TerminatorKind::Resume, true); } - fn tuple_like_shim(&mut self, dest: Place<'tcx>, - src: Place<'tcx>, tys: I) - where I: Iterator> { + fn tuple_like_shim(&mut self, dest: Place<'tcx>, src: Place<'tcx>, tys: I) + where + I: Iterator>, + { let mut previous_field = None; for (i, ity) in tys.enumerate() { let field = Field::new(i); @@ -676,22 +613,20 @@ impl CloneShimBuilder<'tcx> { // BB #(2i) // `dest.i = Clone::clone(&src.i);` // Goto #(2i + 2) if ok, #(2i + 1) if unwinding happens. - self.make_clone_call( - dest_field.clone(), - src_field, - ity, - next_block, - cleanup_block, - ); + self.make_clone_call(dest_field.clone(), src_field, ity, next_block, cleanup_block); // BB #(2i + 1) (cleanup) if let Some((previous_field, previous_cleanup)) = previous_field.take() { // Drop previous field and goto previous cleanup block. - self.block(vec![], TerminatorKind::Drop { - location: previous_field, - target: previous_cleanup, - unwind: None, - }, true); + self.block( + vec![], + TerminatorKind::Drop { + location: previous_field, + target: previous_cleanup, + unwind: None, + }, + true, + ); } else { // Nothing to drop, just resume. self.block(vec![], TerminatorKind::Resume, true); @@ -717,9 +652,11 @@ fn build_call_shim<'tcx>( call_kind: CallKind, untuple_args: Option<&[Ty<'tcx>]>, ) -> BodyAndCache<'tcx> { - debug!("build_call_shim(instance={:?}, rcvr_adjustment={:?}, \ + debug!( + "build_call_shim(instance={:?}, rcvr_adjustment={:?}, \ call_kind={:?}, untuple_args={:?})", - instance, rcvr_adjustment, call_kind, untuple_args); + instance, rcvr_adjustment, call_kind, untuple_args + ); let def_id = instance.def_id(); let sig = tcx.fn_sig(def_id); @@ -743,7 +680,7 @@ fn build_call_shim<'tcx>( let mut local_decls = local_decls_for_sig(&sig, span); let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }; - let rcvr_arg = Local::new(1+0); + let rcvr_arg = Local::new(1 + 0); let rcvr_l = Place::from(rcvr_arg); let mut statements = vec![]; @@ -755,23 +692,19 @@ fn build_call_shim<'tcx>( // let rcvr = &mut rcvr; let ref_rcvr = local_decls.push(temp_decl( Mutability::Not, - tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut { - ty: sig.inputs()[0], - mutbl: hir::Mutability::Mut - }), - span + tcx.mk_ref( + tcx.lifetimes.re_erased, + ty::TypeAndMut { ty: sig.inputs()[0], mutbl: hir::Mutability::Mut }, + ), + span, )); - let borrow_kind = BorrowKind::Mut { - allow_two_phase_borrow: false, - }; + let borrow_kind = BorrowKind::Mut { allow_two_phase_borrow: false }; statements.push(Statement { source_info, - kind: StatementKind::Assign( - box( - Place::from(ref_rcvr), - Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_l) - ) - ) + kind: StatementKind::Assign(box ( + Place::from(ref_rcvr), + Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_l), + )), }); Operand::Move(Place::from(ref_rcvr)) } @@ -781,24 +714,24 @@ fn build_call_shim<'tcx>( CallKind::Indirect => (rcvr, vec![]), CallKind::Direct(def_id) => { let ty = tcx.type_of(def_id); - (Operand::Constant(box Constant { - span, - user_ty: None, - literal: ty::Const::zero_sized(tcx, ty), - }), - vec![rcvr]) + ( + Operand::Constant(box Constant { + span, + user_ty: None, + literal: ty::Const::zero_sized(tcx, ty), + }), + vec![rcvr], + ) } }; if let Some(untuple_args) = untuple_args { args.extend(untuple_args.iter().enumerate().map(|(i, ity)| { - let arg_place = Place::from(Local::new(1+1)); + let arg_place = Place::from(Local::new(1 + 1)); Operand::Move(tcx.mk_place_field(arg_place, Field::new(i), *ity)) })); } else { - args.extend((1..sig.inputs().len()).map(|i| { - Operand::Move(Place::from(Local::new(1+i))) - })); + args.extend((1..sig.inputs().len()).map(|i| Operand::Move(Place::from(Local::new(1 + i))))); } let n_blocks = if let Adjustment::RefMut = rcvr_adjustment { 5 } else { 2 }; @@ -807,52 +740,61 @@ fn build_call_shim<'tcx>( blocks.push(BasicBlockData { statements, terminator: Some(Terminator { source_info, kind }), - is_cleanup + is_cleanup, }) }; // BB #0 - block(&mut blocks, statements, TerminatorKind::Call { - func: callee, - args, - destination: Some((Place::return_place(), - BasicBlock::new(1))), - cleanup: if let Adjustment::RefMut = rcvr_adjustment { - Some(BasicBlock::new(3)) - } else { - None + block( + &mut blocks, + statements, + TerminatorKind::Call { + func: callee, + args, + destination: Some((Place::return_place(), BasicBlock::new(1))), + cleanup: if let Adjustment::RefMut = rcvr_adjustment { + Some(BasicBlock::new(3)) + } else { + None + }, + from_hir_call: true, }, - from_hir_call: true, - }, false); + false, + ); if let Adjustment::RefMut = rcvr_adjustment { // BB #1 - drop for Self - block(&mut blocks, vec![], TerminatorKind::Drop { - location: Place::from(rcvr_arg), - target: BasicBlock::new(2), - unwind: None - }, false); + block( + &mut blocks, + vec![], + TerminatorKind::Drop { + location: Place::from(rcvr_arg), + target: BasicBlock::new(2), + unwind: None, + }, + false, + ); } // BB #1/#2 - return block(&mut blocks, vec![], TerminatorKind::Return, false); if let Adjustment::RefMut = rcvr_adjustment { // BB #3 - drop if closure panics - block(&mut blocks, vec![], TerminatorKind::Drop { - location: Place::from(rcvr_arg), - target: BasicBlock::new(4), - unwind: None - }, true); + block( + &mut blocks, + vec![], + TerminatorKind::Drop { + location: Place::from(rcvr_arg), + target: BasicBlock::new(4), + unwind: None, + }, + true, + ); // BB #4 - resume block(&mut blocks, vec![], TerminatorKind::Resume, true); } - let mut body = new_body( - blocks, - local_decls, - sig.inputs().len(), - span, - ); + let mut body = new_body(blocks, local_decls, sig.inputs().len(), span); if let Abi::RustCall = sig.abi { body.spread_arg = Some(Local::new(sig.inputs().len())); @@ -863,30 +805,25 @@ fn build_call_shim<'tcx>( pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &BodyAndCache<'_> { debug_assert!(tcx.is_constructor(ctor_id)); - let span = tcx.hir().span_if_local(ctor_id) - .unwrap_or_else(|| bug!("no span for ctor {:?}", ctor_id)); + let span = + tcx.hir().span_if_local(ctor_id).unwrap_or_else(|| bug!("no span for ctor {:?}", ctor_id)); let param_env = tcx.param_env(ctor_id); // Normalize the sig. - let sig = tcx.fn_sig(ctor_id) - .no_bound_vars() - .expect("LBR in ADT constructor signature"); + let sig = tcx.fn_sig(ctor_id).no_bound_vars().expect("LBR in ADT constructor signature"); let sig = tcx.normalize_erasing_regions(param_env, sig); let (adt_def, substs) = match sig.output().kind { ty::Adt(adt_def, substs) => (adt_def, substs), - _ => bug!("unexpected type for ADT ctor {:?}", sig.output()) + _ => bug!("unexpected type for ADT ctor {:?}", sig.output()), }; debug!("build_ctor: ctor_id={:?} sig={:?}", ctor_id, sig); let local_decls = local_decls_for_sig(&sig, span); - let source_info = SourceInfo { - span, - scope: OUTERMOST_SOURCE_SCOPE - }; + let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }; let variant_index = if adt_def.is_enum() { adt_def.variant_index_with_ctor_id(ctor_id) @@ -904,35 +841,23 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &BodyAndCache<'_> { let statements = expand_aggregate( Place::return_place(), - adt_def - .variants[variant_index] - .fields - .iter() - .enumerate() - .map(|(idx, field_def)| ( - Operand::Move(Place::from(Local::new(idx + 1))), - field_def.ty(tcx, substs), - )), + adt_def.variants[variant_index].fields.iter().enumerate().map(|(idx, field_def)| { + (Operand::Move(Place::from(Local::new(idx + 1))), field_def.ty(tcx, substs)) + }), AggregateKind::Adt(adt_def, variant_index, substs, None, None), source_info, tcx, - ).collect(); + ) + .collect(); let start_block = BasicBlockData { statements, - terminator: Some(Terminator { - source_info, - kind: TerminatorKind::Return, - }), - is_cleanup: false + terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }), + is_cleanup: false, }; - let body = new_body( - IndexVec::from_elem_n(start_block, 1), - local_decls, - sig.inputs().len(), - span, - ); + let body = + new_body(IndexVec::from_elem_n(start_block, 1), local_decls, sig.inputs().len(), span); crate::util::dump_mir( tcx, diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs index d1832ebf962a4..c979b569ec5c7 100644 --- a/src/librustc_mir/transform/add_call_guards.rs +++ b/src/librustc_mir/transform/add_call_guards.rs @@ -1,7 +1,7 @@ -use rustc::ty::TyCtxt; +use crate::transform::{MirPass, MirSource}; use rustc::mir::*; +use rustc::ty::TyCtxt; use rustc_index::vec::{Idx, IndexVec}; -use crate::transform::{MirPass, MirSource}; #[derive(PartialEq)] pub enum AddCallGuards { @@ -31,9 +31,7 @@ pub use self::AddCallGuards::*; */ impl<'tcx> MirPass<'tcx> for AddCallGuards { - fn run_pass( - &self, _tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut BodyAndCache<'tcx> - ) { + fn run_pass(&self, _tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { self.add_call_guards(body); } } @@ -50,13 +48,15 @@ impl AddCallGuards { for block in body.basic_blocks_mut() { match block.terminator { Some(Terminator { - kind: TerminatorKind::Call { - destination: Some((_, ref mut destination)), - cleanup, - .. - }, source_info - }) if pred_count[*destination] > 1 && - (cleanup.is_some() || self == &AllCallEdges) => + kind: + TerminatorKind::Call { + destination: Some((_, ref mut destination)), + cleanup, + .. + }, + source_info, + }) if pred_count[*destination] > 1 + && (cleanup.is_some() || self == &AllCallEdges) => { // It's a critical edge, break it let call_guard = BasicBlockData { @@ -64,8 +64,8 @@ impl AddCallGuards { is_cleanup: block.is_cleanup, terminator: Some(Terminator { source_info, - kind: TerminatorKind::Goto { target: *destination } - }) + kind: TerminatorKind::Goto { target: *destination }, + }), }; // Get the index it will be when inserted into the MIR diff --git a/src/librustc_mir/transform/add_moves_for_packed_drops.rs b/src/librustc_mir/transform/add_moves_for_packed_drops.rs index 861e7fea4f903..dbbbbeff51338 100644 --- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs +++ b/src/librustc_mir/transform/add_moves_for_packed_drops.rs @@ -3,8 +3,8 @@ use rustc::mir::*; use rustc::ty::TyCtxt; use crate::transform::{MirPass, MirSource}; -use crate::util::patch::MirPatch; use crate::util; +use crate::util::patch::MirPatch; // This pass moves values being dropped that are within a packed // struct to a separate local before dropping them, to ensure that @@ -47,7 +47,9 @@ impl<'tcx> MirPass<'tcx> for AddMovesForPackedDrops { } pub fn add_moves_for_packed_drops<'tcx>( - tcx: TyCtxt<'tcx>, body: &mut BodyAndCache<'tcx>, def_id: DefId + tcx: TyCtxt<'tcx>, + body: &mut BodyAndCache<'tcx>, + def_id: DefId, ) { let patch = add_moves_for_packed_drops_patch(tcx, body, def_id); patch.apply(body); @@ -69,12 +71,10 @@ fn add_moves_for_packed_drops_patch<'tcx>( TerminatorKind::Drop { ref location, .. } if util::is_disaligned(tcx, body, param_env, location) => { - add_move_for_packed_drop(tcx, body, &mut patch, terminator, - loc, data.is_cleanup); + add_move_for_packed_drop(tcx, body, &mut patch, terminator, loc, data.is_cleanup); } TerminatorKind::DropAndReplace { .. } => { - span_bug!(terminator.source_info.span, - "replace in AddMovesForPackedDrops"); + span_bug!(terminator.source_info.span, "replace in AddMovesForPackedDrops"); } _ => {} } @@ -93,9 +93,8 @@ fn add_move_for_packed_drop<'tcx>( ) { debug!("add_move_for_packed_drop({:?} @ {:?})", terminator, loc); let (location, target, unwind) = match terminator.kind { - TerminatorKind::Drop { ref location, target, unwind } => - (location, target, unwind), - _ => unreachable!() + TerminatorKind::Drop { ref location, target, unwind } => (location, target, unwind), + _ => unreachable!(), }; let source_info = terminator.source_info; @@ -103,22 +102,15 @@ fn add_move_for_packed_drop<'tcx>( let temp = patch.new_temp(ty, terminator.source_info.span); let storage_dead_block = patch.new_block(BasicBlockData { - statements: vec![Statement { - source_info, kind: StatementKind::StorageDead(temp) - }], - terminator: Some(Terminator { - source_info, kind: TerminatorKind::Goto { target } - }), - is_cleanup + statements: vec![Statement { source_info, kind: StatementKind::StorageDead(temp) }], + terminator: Some(Terminator { source_info, kind: TerminatorKind::Goto { target } }), + is_cleanup, }); - patch.add_statement( - loc, StatementKind::StorageLive(temp)); - patch.add_assign(loc, Place::from(temp), - Rvalue::Use(Operand::Move(location.clone()))); - patch.patch_terminator(loc.block, TerminatorKind::Drop { - location: Place::from(temp), - target: storage_dead_block, - unwind - }); + patch.add_statement(loc, StatementKind::StorageLive(temp)); + patch.add_assign(loc, Place::from(temp), Rvalue::Use(Operand::Move(location.clone()))); + patch.patch_terminator( + loc.block, + TerminatorKind::Drop { location: Place::from(temp), target: storage_dead_block, unwind }, + ); } diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs index 0e4fe3f7f4015..d7ab3ea517b5f 100644 --- a/src/librustc_mir/transform/add_retag.rs +++ b/src/librustc_mir/transform/add_retag.rs @@ -4,9 +4,9 @@ //! of MIR building, and only after this pass we think of the program has having the //! normal MIR semantics. -use rustc::ty::{self, Ty, TyCtxt}; -use rustc::mir::*; use crate::transform::{MirPass, MirSource}; +use rustc::mir::*; +use rustc::ty::{self, Ty, TyCtxt}; pub struct AddRetag; @@ -14,9 +14,7 @@ pub struct AddRetag; /// after the assignment, we can be sure to obtain the same place value. /// (Concurrent accesses by other threads are no problem as these are anyway non-atomic /// copies. Data races are UB.) -fn is_stable( - place: PlaceRef<'_, '_>, -) -> bool { +fn is_stable(place: PlaceRef<'_, '_>) -> bool { place.projection.iter().all(|elem| { match elem { // Which place this evaluates to can change with any memory write, @@ -39,20 +37,21 @@ fn is_stable( fn may_be_reference<'tcx>(ty: Ty<'tcx>) -> bool { match ty.kind { // Primitive types that are not references - ty::Bool | ty::Char | - ty::Float(_) | ty::Int(_) | ty::Uint(_) | - ty::RawPtr(..) | ty::FnPtr(..) | - ty::Str | ty::FnDef(..) | ty::Never => - false, + ty::Bool + | ty::Char + | ty::Float(_) + | ty::Int(_) + | ty::Uint(_) + | ty::RawPtr(..) + | ty::FnPtr(..) + | ty::Str + | ty::FnDef(..) + | ty::Never => false, // References ty::Ref(..) => true, ty::Adt(..) if ty.is_box() => true, // Compound types are not references - ty::Array(..) | - ty::Slice(..) | - ty::Tuple(..) | - ty::Adt(..) => - false, + ty::Array(..) | ty::Slice(..) | ty::Tuple(..) | ty::Adt(..) => false, // Conservative fallback _ => true, } @@ -68,8 +67,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag { let needs_retag = |place: &Place<'tcx>| { // FIXME: Instead of giving up for unstable places, we should introduce // a temporary and retag on that. - is_stable(place.as_ref()) - && may_be_reference(place.ty(&*local_decls, tcx).ty) + is_stable(place.as_ref()) && may_be_reference(place.ty(&*local_decls, tcx).ty) }; // PART 1 @@ -81,16 +79,20 @@ impl<'tcx> MirPass<'tcx> for AddRetag { // argument declaration. }; // Gather all arguments, skip return value. - let places = local_decls.iter_enumerated().skip(1).take(arg_count) - .map(|(local, _)| Place::from(local)) - .filter(needs_retag) - .collect::>(); + let places = local_decls + .iter_enumerated() + .skip(1) + .take(arg_count) + .map(|(local, _)| Place::from(local)) + .filter(needs_retag) + .collect::>(); // Emit their retags. - basic_blocks[START_BLOCK].statements.splice(0..0, + basic_blocks[START_BLOCK].statements.splice( + 0..0, places.into_iter().map(|place| Statement { source_info, - kind: StatementKind::Retag(RetagKind::FnEntry, box(place)), - }) + kind: StatementKind::Retag(RetagKind::FnEntry, box (place)), + }), ); } @@ -112,8 +114,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag { } } } - TerminatorKind::Drop { .. } | - TerminatorKind::DropAndReplace { .. } => { + TerminatorKind::Drop { .. } | TerminatorKind::DropAndReplace { .. } => { // `Drop` is also a call, but it doesn't return anything so we are good. } _ => { @@ -123,10 +124,13 @@ impl<'tcx> MirPass<'tcx> for AddRetag { } // Now we go over the returns we collected to retag the return values. for (source_info, dest_place, dest_block) in returns { - basic_blocks[dest_block].statements.insert(0, Statement { - source_info, - kind: StatementKind::Retag(RetagKind::Default, box(dest_place)), - }); + basic_blocks[dest_block].statements.insert( + 0, + Statement { + source_info, + kind: StatementKind::Retag(RetagKind::Default, box (dest_place)), + }, + ); } // PART 3 @@ -143,14 +147,14 @@ impl<'tcx> MirPass<'tcx> for AddRetag { // Assignments of reference or ptr type are the ones where we may have // to update tags. This includes `x = &[mut] ...` and hence // we also retag after taking a reference! - StatementKind::Assign(box(ref place, ref rvalue)) if needs_retag(place) => { + StatementKind::Assign(box (ref place, ref rvalue)) if needs_retag(place) => { let kind = match rvalue { Rvalue::Ref(_, borrow_kind, _) - if borrow_kind.allows_two_phase_borrow() - => - RetagKind::TwoPhase, - _ => - RetagKind::Default, + if borrow_kind.allows_two_phase_borrow() => + { + RetagKind::TwoPhase + } + _ => RetagKind::Default, }; (kind, place.clone()) } @@ -159,10 +163,10 @@ impl<'tcx> MirPass<'tcx> for AddRetag { }; // Insert a retag after the statement. let source_info = block_data.statements[i].source_info; - block_data.statements.insert(i+1, Statement { - source_info, - kind: StatementKind::Retag(retag_kind, box(place)), - }); + block_data.statements.insert( + i + 1, + Statement { source_info, kind: StatementKind::Retag(retag_kind, box (place)) }, + ); } } } diff --git a/src/librustc_mir/transform/check_consts/mod.rs b/src/librustc_mir/transform/check_consts/mod.rs index e8365a9ee1c13..b50ce0a0e003e 100644 --- a/src/librustc_mir/transform/check_consts/mod.rs +++ b/src/librustc_mir/transform/check_consts/mod.rs @@ -36,13 +36,7 @@ impl Item<'mir, 'tcx> { let param_env = tcx.param_env(def_id); let const_kind = ConstKind::for_item(tcx, def_id); - Item { - body, - tcx, - def_id, - param_env, - const_kind, - } + Item { body, tcx, def_id, param_env, const_kind } } /// Returns the kind of const context this `Item` represents (`const`, `static`, etc.). @@ -114,6 +108,5 @@ impl fmt::Display for ConstKind { /// Returns `true` if this `DefId` points to one of the official `panic` lang items. pub fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { - Some(def_id) == tcx.lang_items().panic_fn() || - Some(def_id) == tcx.lang_items().begin_panic_fn() + Some(def_id) == tcx.lang_items().panic_fn() || Some(def_id) == tcx.lang_items().begin_panic_fn() } diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/src/librustc_mir/transform/check_consts/ops.rs index e5f3003cd7110..dccb8ad06ec8f 100644 --- a/src/librustc_mir/transform/check_consts/ops.rs +++ b/src/librustc_mir/transform/check_consts/ops.rs @@ -39,10 +39,14 @@ pub trait NonConstOp: std::fmt::Debug { item.const_kind() ); if item.tcx.sess.teach(&err.get_code().unwrap()) { - err.note("A function call isn't allowed in the const's initialization expression \ - because the expression's value must be known at compile-time."); - err.note("Remember: you can't use a function call inside a const's initialization \ - expression! However, you can use it anywhere else."); + err.note( + "A function call isn't allowed in the const's initialization expression \ + because the expression's value must be known at compile-time.", + ); + err.note( + "Remember: you can't use a function call inside a const's initialization \ + expression! However, you can use it anywhere else.", + ); } err.emit(); } @@ -62,9 +66,10 @@ impl NonConstOp for Downcast { pub struct FnCallIndirect; impl NonConstOp for FnCallIndirect { fn emit_error(&self, item: &Item<'_, '_>, span: Span) { - let mut err = item.tcx.sess.struct_span_err( - span, - &format!("function pointers are not allowed in const fn")); + let mut err = item + .tcx + .sess + .struct_span_err(span, &format!("function pointers are not allowed in const fn")); err.emit(); } } @@ -105,14 +110,17 @@ impl NonConstOp for FnCallUnstable { fn emit_error(&self, item: &Item<'_, '_>, span: Span) { let FnCallUnstable(def_id, feature) = *self; - let mut err = item.tcx.sess.struct_span_err(span, - &format!("`{}` is not yet stable as a const fn", - item.tcx.def_path_str(def_id))); + let mut err = item.tcx.sess.struct_span_err( + span, + &format!("`{}` is not yet stable as a const fn", item.tcx.def_path_str(def_id)), + ); if nightly_options::is_nightly_build() { - help!(&mut err, - "add `#![feature({})]` to the \ + help!( + &mut err, + "add `#![feature({})]` to the \ crate attributes to enable", - feature); + feature + ); } err.emit(); } @@ -124,15 +132,20 @@ impl NonConstOp for HeapAllocation { const IS_SUPPORTED_IN_MIRI: bool = false; fn emit_error(&self, item: &Item<'_, '_>, span: Span) { - let mut err = struct_span_err!(item.tcx.sess, span, E0010, - "allocations are not allowed in {}s", item.const_kind()); + let mut err = struct_span_err!( + item.tcx.sess, + span, + E0010, + "allocations are not allowed in {}s", + item.const_kind() + ); err.span_label(span, format!("allocation not allowed in {}s", item.const_kind())); if item.tcx.sess.teach(&err.get_code().unwrap()) { err.note( "The value of statics and constants must be known at compile time, \ and they live for the entire lifetime of a program. Creating a boxed \ value allocates memory on the heap at runtime, and therefore cannot \ - be done at compile time." + be done at compile time.", ); } err.emit(); @@ -148,10 +161,7 @@ impl NonConstOp for IfOrMatch { fn emit_error(&self, item: &Item<'_, '_>, span: Span) { // This should be caught by the HIR const-checker. - item.tcx.sess.delay_span_bug( - span, - "complex control flow is forbidden in a const context", - ); + item.tcx.sess.delay_span_bug(span, "complex control flow is forbidden in a const context"); } } @@ -159,11 +169,14 @@ impl NonConstOp for IfOrMatch { pub struct LiveDrop; impl NonConstOp for LiveDrop { fn emit_error(&self, item: &Item<'_, '_>, span: Span) { - struct_span_err!(item.tcx.sess, span, E0493, - "destructors cannot be evaluated at compile-time") - .span_label(span, format!("{}s cannot evaluate destructors", - item.const_kind())) - .emit(); + struct_span_err!( + item.tcx.sess, + span, + E0493, + "destructors cannot be evaluated at compile-time" + ) + .span_label(span, format!("{}s cannot evaluate destructors", item.const_kind())) + .emit(); } } @@ -176,10 +189,7 @@ impl NonConstOp for Loop { fn emit_error(&self, item: &Item<'_, '_>, span: Span) { // This should be caught by the HIR const-checker. - item.tcx.sess.delay_span_bug( - span, - "complex control flow is forbidden in a const context", - ); + item.tcx.sess.delay_span_bug(span, "complex control flow is forbidden in a const context"); } } @@ -187,9 +197,13 @@ impl NonConstOp for Loop { pub struct CellBorrow; impl NonConstOp for CellBorrow { fn emit_error(&self, item: &Item<'_, '_>, span: Span) { - span_err!(item.tcx.sess, span, E0492, + span_err!( + item.tcx.sess, + span, + E0492, "cannot borrow a constant which may contain \ - interior mutability, create a static instead"); + interior mutability, create a static instead" + ); } } @@ -205,20 +219,24 @@ impl NonConstOp for MutBorrow { &item.tcx.sess.parse_sess, sym::const_mut_refs, span, - &format!("references in {}s may only refer \ - to immutable values", item.const_kind()) + &format!( + "references in {}s may only refer \ + to immutable values", + item.const_kind() + ), ); - err.span_label(span, format!("{}s require immutable values", - item.const_kind())); + err.span_label(span, format!("{}s require immutable values", item.const_kind())); if item.tcx.sess.teach(&err.get_code().unwrap()) { - err.note("References in statics and constants may only refer \ + err.note( + "References in statics and constants may only refer \ to immutable values.\n\n\ Statics are shared everywhere, and if they refer to \ mutable data one might violate memory safety since \ holding multiple mutable references to shared data \ is not allowed.\n\n\ If you really want global mutable state, try using \ - static mut or a global UnsafeCell."); + static mut or a global UnsafeCell.", + ); } err.emit(); } @@ -236,8 +254,9 @@ impl NonConstOp for MutAddressOf { &item.tcx.sess.parse_sess, sym::const_mut_refs, span, - &format!("`&raw mut` is not allowed in {}s", item.const_kind()) - ).emit(); + &format!("`&raw mut` is not allowed in {}s", item.const_kind()), + ) + .emit(); } } @@ -294,11 +313,10 @@ impl NonConstOp for RawPtrDeref { fn emit_error(&self, item: &Item<'_, '_>, span: Span) { feature_err( - &item.tcx.sess.parse_sess, sym::const_raw_ptr_deref, span, - &format!( - "dereferencing raw pointers in {}s is unstable", - item.const_kind(), - ), + &item.tcx.sess.parse_sess, + sym::const_raw_ptr_deref, + span, + &format!("dereferencing raw pointers in {}s is unstable", item.const_kind(),), ) .emit(); } @@ -313,11 +331,10 @@ impl NonConstOp for RawPtrToIntCast { fn emit_error(&self, item: &Item<'_, '_>, span: Span) { feature_err( - &item.tcx.sess.parse_sess, sym::const_raw_ptr_to_usize_cast, span, - &format!( - "casting pointers to integers in {}s is unstable", - item.const_kind(), - ), + &item.tcx.sess.parse_sess, + sym::const_raw_ptr_to_usize_cast, + span, + &format!("casting pointers to integers in {}s is unstable", item.const_kind(),), ) .emit(); } @@ -332,17 +349,20 @@ impl NonConstOp for StaticAccess { } fn emit_error(&self, item: &Item<'_, '_>, span: Span) { - let mut err = struct_span_err!(item.tcx.sess, span, E0013, - "{}s cannot refer to statics, use \ - a constant instead", item.const_kind()); + let mut err = struct_span_err!( + item.tcx.sess, + span, + E0013, + "{}s cannot refer to statics, use \ + a constant instead", + item.const_kind() + ); if item.tcx.sess.teach(&err.get_code().unwrap()) { err.note( "Static and const variables can refer to other const variables. \ - But a const variable cannot refer to a static variable." - ); - err.help( - "To fix this, the value can be extracted as a const and then used." + But a const variable cannot refer to a static variable.", ); + err.help("To fix this, the value can be extracted as a const and then used."); } err.emit(); } @@ -355,9 +375,13 @@ impl NonConstOp for ThreadLocalAccess { const IS_SUPPORTED_IN_MIRI: bool = false; fn emit_error(&self, item: &Item<'_, '_>, span: Span) { - span_err!(item.tcx.sess, span, E0625, + span_err!( + item.tcx.sess, + span, + E0625, "thread-local statics cannot be \ - accessed at compile-time"); + accessed at compile-time" + ); } } @@ -375,7 +399,9 @@ impl NonConstOp for UnionAccess { fn emit_error(&self, item: &Item<'_, '_>, span: Span) { feature_err( - &item.tcx.sess.parse_sess, sym::const_fn_union, span, + &item.tcx.sess.parse_sess, + sym::const_fn_union, + span, "unions in const fn are unstable", ) .emit(); diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index 28243bd71a228..746d83b05c6b3 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -1,8 +1,8 @@ //! A copy of the `Qualif` trait in `qualify_consts.rs` that is suitable for the new validator. +use rustc::hir::def_id::DefId; use rustc::mir::*; use rustc::ty::{self, Ty}; -use rustc::hir::def_id::DefId; use syntax_pos::DUMMY_SP; use super::Item as ConstCx; @@ -45,22 +45,21 @@ pub trait Qualif { place: PlaceRef<'_, 'tcx>, ) -> bool { if let [proj_base @ .., elem] = place.projection { - let base_qualif = Self::in_place(cx, per_local, PlaceRef { - base: place.base, - projection: proj_base, - }); - let qualif = base_qualif && Self::in_any_value_of_ty( - cx, - Place::ty_from(place.base, proj_base, *cx.body, cx.tcx) - .projection_ty(cx.tcx, elem) - .ty, - ); + let base_qualif = + Self::in_place(cx, per_local, PlaceRef { base: place.base, projection: proj_base }); + let qualif = base_qualif + && Self::in_any_value_of_ty( + cx, + Place::ty_from(place.base, proj_base, *cx.body, cx.tcx) + .projection_ty(cx.tcx, elem) + .ty, + ); match elem { - ProjectionElem::Deref | - ProjectionElem::Subslice { .. } | - ProjectionElem::Field(..) | - ProjectionElem::ConstantIndex { .. } | - ProjectionElem::Downcast(..) => qualif, + ProjectionElem::Deref + | ProjectionElem::Subslice { .. } + | ProjectionElem::Field(..) + | ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Downcast(..) => qualif, ProjectionElem::Index(local) => qualif || per_local(*local), } @@ -83,18 +82,11 @@ pub trait Qualif { place: PlaceRef<'_, 'tcx>, ) -> bool { match place { - PlaceRef { - base: PlaceBase::Local(local), - projection: [], - } => per_local(*local), - PlaceRef { - base: PlaceBase::Static(_), - projection: [], - } => bug!("qualifying already promoted MIR"), - PlaceRef { - base: _, - projection: [.., _], - } => Self::in_projection(cx, per_local, place), + PlaceRef { base: PlaceBase::Local(local), projection: [] } => per_local(*local), + PlaceRef { base: PlaceBase::Static(_), projection: [] } => { + bug!("qualifying already promoted MIR") + } + PlaceRef { base: _, projection: [.., _] } => Self::in_projection(cx, per_local, place), } } @@ -104,8 +96,9 @@ pub trait Qualif { operand: &Operand<'tcx>, ) -> bool { match *operand { - Operand::Copy(ref place) | - Operand::Move(ref place) => Self::in_place(cx, per_local, place.as_ref()), + Operand::Copy(ref place) | Operand::Move(ref place) => { + Self::in_place(cx, per_local, place.as_ref()) + } Operand::Constant(ref constant) => { if let Some(static_) = constant.check_static_ptr(cx.tcx) { @@ -138,16 +131,17 @@ pub trait Qualif { match *rvalue { Rvalue::NullaryOp(..) => false, - Rvalue::Discriminant(ref place) | - Rvalue::Len(ref place) => Self::in_place(cx, per_local, place.as_ref()), + Rvalue::Discriminant(ref place) | Rvalue::Len(ref place) => { + Self::in_place(cx, per_local, place.as_ref()) + } - Rvalue::Use(ref operand) | - Rvalue::Repeat(ref operand, _) | - Rvalue::UnaryOp(_, ref operand) | - Rvalue::Cast(_, ref operand, _) => Self::in_operand(cx, per_local, operand), + Rvalue::Use(ref operand) + | Rvalue::Repeat(ref operand, _) + | Rvalue::UnaryOp(_, ref operand) + | Rvalue::Cast(_, ref operand, _) => Self::in_operand(cx, per_local, operand), - Rvalue::BinaryOp(_, ref lhs, ref rhs) | - Rvalue::CheckedBinaryOp(_, ref lhs, ref rhs) => { + Rvalue::BinaryOp(_, ref lhs, ref rhs) + | Rvalue::CheckedBinaryOp(_, ref lhs, ref rhs) => { Self::in_operand(cx, per_local, lhs) || Self::in_operand(cx, per_local, rhs) } @@ -156,10 +150,11 @@ pub trait Qualif { if let [proj_base @ .., ProjectionElem::Deref] = place.projection.as_ref() { let base_ty = Place::ty_from(&place.base, proj_base, *cx.body, cx.tcx).ty; if let ty::Ref(..) = base_ty.kind { - return Self::in_place(cx, per_local, PlaceRef { - base: &place.base, - projection: proj_base, - }); + return Self::in_place( + cx, + per_local, + PlaceRef { base: &place.base, projection: proj_base }, + ); } } diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/src/librustc_mir/transform/check_consts/resolver.rs index cb542484be633..207683054f925 100644 --- a/src/librustc_mir/transform/check_consts/resolver.rs +++ b/src/librustc_mir/transform/check_consts/resolver.rs @@ -8,8 +8,8 @@ use rustc_index::bit_set::BitSet; use std::marker::PhantomData; -use crate::dataflow::{self as old_dataflow, generic as dataflow}; use super::{Item, Qualif}; +use crate::dataflow::{self as old_dataflow, generic as dataflow}; /// A `Visitor` that propagates qualifs between locals. This defines the transfer function of /// `FlowSensitiveAnalysis`. @@ -28,15 +28,8 @@ impl TransferFunction<'a, 'mir, 'tcx, Q> where Q: Qualif, { - fn new( - item: &'a Item<'mir, 'tcx>, - qualifs_per_local: &'a mut BitSet, - ) -> Self { - TransferFunction { - item, - qualifs_per_local, - _qualif: PhantomData, - } + fn new(item: &'a Item<'mir, 'tcx>, qualifs_per_local: &'a mut BitSet) -> Self { + TransferFunction { item, qualifs_per_local, _qualif: PhantomData } } fn initialize_state(&mut self) { @@ -78,13 +71,8 @@ where return_place: &mir::Place<'tcx>, ) { let return_ty = return_place.ty(*self.item.body, self.item.tcx).ty; - let qualif = Q::in_call( - self.item, - &|l| self.qualifs_per_local.contains(l), - func, - args, - return_ty, - ); + let qualif = + Q::in_call(self.item, &|l| self.qualifs_per_local.contains(l), func, args, return_ty); if !return_place.is_indirect() { self.assign_qualif_direct(return_place, qualif); } @@ -155,10 +143,7 @@ where Q: Qualif, { pub(super) fn new(_: Q, item: &'a Item<'mir, 'tcx>) -> Self { - FlowSensitiveAnalysis { - item, - _qualif: PhantomData, - } + FlowSensitiveAnalysis { item, _qualif: PhantomData } } fn transfer_function( diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 0904264586c7c..afe119725b7b5 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -1,26 +1,26 @@ //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations. -use rustc::hir::{HirId, def_id::DefId}; +use rustc::hir::{def_id::DefId, HirId}; use rustc::middle::lang_items; -use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext}; +use rustc::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc::mir::*; use rustc::traits::{self, TraitEngine}; use rustc::ty::cast::CastTy; use rustc::ty::{self, TyCtxt}; -use rustc_index::bit_set::BitSet; use rustc_error_codes::*; +use rustc_index::bit_set::BitSet; use syntax::symbol::sym; use syntax_pos::Span; use std::borrow::Cow; use std::ops::Deref; -use crate::dataflow::{self as old_dataflow, generic as dataflow}; use self::old_dataflow::IndirectlyMutableLocals; use super::ops::{self, NonConstOp}; use super::qualifs::{self, HasMutInterior, NeedsDrop}; use super::resolver::FlowSensitiveAnalysis; -use super::{ConstKind, Item, Qualif, is_lang_panic_fn}; +use super::{is_lang_panic_fn, ConstKind, Item, Qualif}; +use crate::dataflow::{self as old_dataflow, generic as dataflow}; pub type IndirectlyMutableResults<'mir, 'tcx> = old_dataflow::DataflowResultsCursor<'mir, 'tcx, IndirectlyMutableLocals<'mir, 'tcx>>; @@ -31,11 +31,7 @@ struct QualifCursor<'a, 'mir, 'tcx, Q: Qualif> { } impl QualifCursor<'a, 'mir, 'tcx, Q> { - pub fn new( - q: Q, - item: &'a Item<'mir, 'tcx>, - dead_unwinds: &BitSet, - ) -> Self { + pub fn new(q: Q, item: &'a Item<'mir, 'tcx>, dead_unwinds: &BitSet) -> Self { let analysis = FlowSensitiveAnalysis::new(q, item); let results = dataflow::Engine::new(item.tcx, &item.body, item.def_id, dead_unwinds, analysis) @@ -49,10 +45,7 @@ impl QualifCursor<'a, 'mir, 'tcx, Q> { } } - QualifCursor { - cursor, - in_any_value_of_ty, - } + QualifCursor { cursor, in_any_value_of_ty } } } @@ -77,8 +70,7 @@ impl Qualifs<'a, 'mir, 'tcx> { } self.needs_drop.cursor.seek_before(location); - self.needs_drop.cursor.get().contains(local) - || self.indirectly_mutable(local, location) + self.needs_drop.cursor.get().contains(local) || self.indirectly_mutable(local, location) } /// Returns `true` if `local` is `HasMutInterior` at the given `Location`. @@ -110,14 +102,13 @@ impl Qualifs<'a, 'mir, 'tcx> { // // If no `Return` terminator exists, this MIR is divergent. Just return the conservative // qualifs for the return type. - let return_block = item.body + let return_block = item + .body .basic_blocks() .iter_enumerated() - .find(|(_, block)| { - match block.terminator().kind { - TerminatorKind::Return => true, - _ => false, - } + .find(|(_, block)| match block.terminator().kind { + TerminatorKind::Return => true, + _ => false, }) .map(|(bb, _)| bb); @@ -152,22 +143,12 @@ impl Deref for Validator<'_, 'mir, 'tcx> { } impl Validator<'a, 'mir, 'tcx> { - pub fn new( - item: &'a Item<'mir, 'tcx>, - ) -> Self { + pub fn new(item: &'a Item<'mir, 'tcx>) -> Self { let dead_unwinds = BitSet::new_empty(item.body.basic_blocks().len()); - let needs_drop = QualifCursor::new( - NeedsDrop, - item, - &dead_unwinds, - ); + let needs_drop = QualifCursor::new(NeedsDrop, item, &dead_unwinds); - let has_mut_interior = QualifCursor::new( - HasMutInterior, - item, - &dead_unwinds, - ); + let has_mut_interior = QualifCursor::new(HasMutInterior, item, &dead_unwinds); let indirectly_mutable = old_dataflow::do_dataflow( item.tcx, @@ -179,29 +160,19 @@ impl Validator<'a, 'mir, 'tcx> { |_, local| old_dataflow::DebugFormatted::new(&local), ); - let indirectly_mutable = old_dataflow::DataflowResultsCursor::new( - indirectly_mutable, - *item.body, - ); + let indirectly_mutable = + old_dataflow::DataflowResultsCursor::new(indirectly_mutable, *item.body); - let qualifs = Qualifs { - needs_drop, - has_mut_interior, - indirectly_mutable, - }; + let qualifs = Qualifs { needs_drop, has_mut_interior, indirectly_mutable }; - Validator { - span: item.body.span, - item, - qualifs, - } + Validator { span: item.body.span, item, qualifs } } pub fn check_body(&mut self) { - let Item { tcx, body, def_id, const_kind, .. } = *self.item; + let Item { tcx, body, def_id, const_kind, .. } = *self.item; - let use_min_const_fn_checks = - (const_kind == Some(ConstKind::ConstFn) && tcx.is_min_const_fn(def_id)) + let use_min_const_fn_checks = (const_kind == Some(ConstKind::ConstFn) + && tcx.is_min_const_fn(def_id)) && !tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you; if use_min_const_fn_checks { @@ -224,8 +195,8 @@ impl Validator<'a, 'mir, 'tcx> { self.visit_body(body); // Ensure that the end result is `Sync` in a non-thread local `static`. - let should_check_for_sync = const_kind == Some(ConstKind::Static) - && !tcx.has_attr(def_id, sym::thread_local); + let should_check_for_sync = + const_kind == Some(ConstKind::Static) && !tcx.has_attr(def_id, sym::thread_local); if should_check_for_sync { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); @@ -241,7 +212,7 @@ impl Validator<'a, 'mir, 'tcx> { /// context. pub fn check_op_spanned(&mut self, op: O, span: Span) where - O: NonConstOp + O: NonConstOp, { trace!("check_op: op={:?}", op); @@ -251,8 +222,7 @@ impl Validator<'a, 'mir, 'tcx> { // If an operation is supported in miri (and is not already controlled by a feature gate) it // can be turned on with `-Zunleash-the-miri-inside-of-you`. - let is_unleashable = O::IS_SUPPORTED_IN_MIRI - && O::feature_gate(self.tcx).is_none(); + let is_unleashable = O::IS_SUPPORTED_IN_MIRI && O::feature_gate(self.tcx).is_none(); if is_unleashable && self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you { self.tcx.sess.span_warn(span, "skipping const checks"); @@ -277,11 +247,7 @@ impl Validator<'a, 'mir, 'tcx> { } } - fn check_immutable_borrow_like( - &mut self, - location: Location, - place: &Place<'tcx>, - ) { + fn check_immutable_borrow_like(&mut self, location: Location, place: &Place<'tcx>) { // FIXME: Change the `in_*` methods to take a `FnMut` so we don't have to manually // seek the cursors beforehand. self.qualifs.has_mut_interior.cursor.seek_before(location); @@ -300,11 +266,7 @@ impl Validator<'a, 'mir, 'tcx> { } impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { - fn visit_basic_block_data( - &mut self, - bb: BasicBlock, - block: &BasicBlockData<'tcx>, - ) { + fn visit_basic_block_data(&mut self, bb: BasicBlock, block: &BasicBlockData<'tcx>) { trace!("visit_basic_block_data: bb={:?} is_cleanup={:?}", bb, block.is_cleanup); // Just as the old checker did, we skip const-checking basic blocks on the unwind path. @@ -327,18 +289,18 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { Rvalue::Ref(_, kind, ref place) => { if let Some(reborrowed_proj) = place_as_reborrow(self.tcx, *self.body, place) { let ctx = match kind { - BorrowKind::Shared => PlaceContext::NonMutatingUse( - NonMutatingUseContext::SharedBorrow, - ), - BorrowKind::Shallow => PlaceContext::NonMutatingUse( - NonMutatingUseContext::ShallowBorrow, - ), - BorrowKind::Unique => PlaceContext::NonMutatingUse( - NonMutatingUseContext::UniqueBorrow, - ), - BorrowKind::Mut { .. } => PlaceContext::MutatingUse( - MutatingUseContext::Borrow, - ), + BorrowKind::Shared => { + PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) + } + BorrowKind::Shallow => { + PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) + } + BorrowKind::Unique => { + PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) + } + BorrowKind::Mut { .. } => { + PlaceContext::MutatingUse(MutatingUseContext::Borrow) + } }; self.visit_place_base(&place.base, ctx, location); self.visit_projection(&place.base, reborrowed_proj, ctx, location); @@ -348,12 +310,10 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { Rvalue::AddressOf(mutbl, ref place) => { if let Some(reborrowed_proj) = place_as_reborrow(self.tcx, *self.body, place) { let ctx = match mutbl { - Mutability::Not => PlaceContext::NonMutatingUse( - NonMutatingUseContext::AddressOf, - ), - Mutability::Mut => PlaceContext::MutatingUse( - MutatingUseContext::AddressOf, - ), + Mutability::Not => { + PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) + } + Mutability::Mut => PlaceContext::MutatingUse(MutatingUseContext::AddressOf), }; self.visit_place_base(&place.base, ctx, location); self.visit_projection(&place.base, reborrowed_proj, ctx, location); @@ -366,25 +326,25 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { self.super_rvalue(rvalue, location); match *rvalue { - Rvalue::Use(_) | - Rvalue::Repeat(..) | - Rvalue::UnaryOp(UnOp::Neg, _) | - Rvalue::UnaryOp(UnOp::Not, _) | - Rvalue::NullaryOp(NullOp::SizeOf, _) | - Rvalue::CheckedBinaryOp(..) | - Rvalue::Cast(CastKind::Pointer(_), ..) | - Rvalue::Discriminant(..) | - Rvalue::Len(_) | - Rvalue::Aggregate(..) => {} - - | Rvalue::Ref(_, kind @ BorrowKind::Mut { .. }, ref place) - | Rvalue::Ref(_, kind @ BorrowKind::Unique, ref place) - => { + Rvalue::Use(_) + | Rvalue::Repeat(..) + | Rvalue::UnaryOp(UnOp::Neg, _) + | Rvalue::UnaryOp(UnOp::Not, _) + | Rvalue::NullaryOp(NullOp::SizeOf, _) + | Rvalue::CheckedBinaryOp(..) + | Rvalue::Cast(CastKind::Pointer(_), ..) + | Rvalue::Discriminant(..) + | Rvalue::Len(_) + | Rvalue::Aggregate(..) => {} + + Rvalue::Ref(_, kind @ BorrowKind::Mut { .. }, ref place) + | Rvalue::Ref(_, kind @ BorrowKind::Unique, ref place) => { let ty = place.ty(*self.body, self.tcx).ty; let is_allowed = match ty.kind { // Inside a `static mut`, `&mut [...]` is allowed. - ty::Array(..) | ty::Slice(_) if self.const_kind() == ConstKind::StaticMut - => true, + ty::Array(..) | ty::Slice(_) if self.const_kind() == ConstKind::StaticMut => { + true + } // FIXME(ecstaticmorse): We could allow `&mut []` inside a const context given // that this is merely a ZST and it is already eligible for promotion. @@ -393,12 +353,11 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { ty::Array(_, len) if len.try_eval_usize(cx.tcx, cx.param_env) == Some(0) => true, */ - _ => false, }; if !is_allowed { - if let BorrowKind::Mut{ .. } = kind { + if let BorrowKind::Mut { .. } = kind { self.check_op(ops::MutBorrow); } else { self.check_op(ops::CellBorrow); @@ -406,44 +365,49 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } } - Rvalue::AddressOf(Mutability::Mut, _) => { - self.check_op(ops::MutAddressOf) - } + Rvalue::AddressOf(Mutability::Mut, _) => self.check_op(ops::MutAddressOf), // At the moment, `PlaceBase::Static` is only used for promoted MIR. - | Rvalue::Ref(_, BorrowKind::Shared, ref place) + Rvalue::Ref(_, BorrowKind::Shared, ref place) | Rvalue::Ref(_, BorrowKind::Shallow, ref place) | Rvalue::AddressOf(Mutability::Not, ref place) - if matches!(place.base, PlaceBase::Static(_)) - => bug!("Saw a promoted during const-checking, which must run before promotion"), + if matches!(place.base, PlaceBase::Static(_)) => + { + bug!("Saw a promoted during const-checking, which must run before promotion") + } - | Rvalue::Ref(_, BorrowKind::Shared, ref place) + Rvalue::Ref(_, BorrowKind::Shared, ref place) | Rvalue::Ref(_, BorrowKind::Shallow, ref place) => { self.check_immutable_borrow_like(location, place) - }, + } Rvalue::AddressOf(Mutability::Not, ref place) => { self.check_immutable_borrow_like(location, place) - }, + } Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) => { let operand_ty = operand.ty(*self.body, self.tcx); let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast"); let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast"); - if let (CastTy::Ptr(_), CastTy::Int(_)) - | (CastTy::FnPtr, CastTy::Int(_)) = (cast_in, cast_out) { + if let (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) = + (cast_in, cast_out) + { self.check_op(ops::RawPtrToIntCast); } } Rvalue::BinaryOp(op, ref lhs, _) => { if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(*self.body, self.tcx).kind { - assert!(op == BinOp::Eq || op == BinOp::Ne || - op == BinOp::Le || op == BinOp::Lt || - op == BinOp::Ge || op == BinOp::Gt || - op == BinOp::Offset); - + assert!( + op == BinOp::Eq + || op == BinOp::Ne + || op == BinOp::Le + || op == BinOp::Lt + || op == BinOp::Ge + || op == BinOp::Gt + || op == BinOp::Offset + ); self.check_op(ops::RawPtrComparison); } @@ -477,11 +441,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } } - fn visit_operand( - &mut self, - op: &Operand<'tcx>, - location: Location, - ) { + fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) { self.super_operand(op, location); if let Operand::Constant(c) = op { if let Some(def_id) = c.check_static_ptr(self.tcx) { @@ -531,10 +491,10 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } } - ProjectionElem::ConstantIndex {..} | - ProjectionElem::Subslice {..} | - ProjectionElem::Field(..) | - ProjectionElem::Index(_) => { + ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Subslice { .. } + | ProjectionElem::Field(..) + | ProjectionElem::Index(_) => { let base_ty = Place::ty_from(place_base, proj_base, *self.body, self.tcx).ty; match base_ty.ty_adt_def() { Some(def) if def.is_union() => { @@ -551,7 +511,6 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } } - fn visit_source_info(&mut self, source_info: &SourceInfo) { trace!("visit_source_info: source_info={:?}", source_info); self.span = source_info.span; @@ -568,13 +527,13 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { self.check_op(ops::IfOrMatch); } // FIXME(eddyb) should these really do nothing? - StatementKind::FakeRead(..) | - StatementKind::StorageLive(_) | - StatementKind::StorageDead(_) | - StatementKind::InlineAsm {..} | - StatementKind::Retag { .. } | - StatementKind::AscribeUserType(..) | - StatementKind::Nop => {} + StatementKind::FakeRead(..) + | StatementKind::StorageLive(_) + | StatementKind::StorageDead(_) + | StatementKind::InlineAsm { .. } + | StatementKind::Retag { .. } + | StatementKind::AscribeUserType(..) + | StatementKind::Nop => {} } } @@ -615,22 +574,18 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } else { self.check_op(ops::FnCallNonConst(def_id)); } - } // Forbid all `Drop` terminators unless the place being dropped is a local with no // projections that cannot be `NeedsDrop`. - | TerminatorKind::Drop { location: dropped_place, .. } - | TerminatorKind::DropAndReplace { location: dropped_place, .. } - => { + TerminatorKind::Drop { location: dropped_place, .. } + | TerminatorKind::DropAndReplace { location: dropped_place, .. } => { let mut err_span = self.span; // Check to see if the type of this place can ever have a drop impl. If not, this // `Drop` terminator is frivolous. - let ty_needs_drop = dropped_place - .ty(*self.body, self.tcx) - .ty - .needs_drop(self.tcx, self.param_env); + let ty_needs_drop = + dropped_place.ty(*self.body, self.tcx).ty.needs_drop(self.tcx, self.param_env); if !ty_needs_drop { return; @@ -682,10 +637,13 @@ fn check_short_circuiting_in_const_local(item: &Item<'_, 'tcx>) { for (span, kind) in body.control_flow_destroyed.iter() { error.span_note( *span, - &format!("use of {} here does not actually short circuit due to \ + &format!( + "use of {} here does not actually short circuit due to \ the const evaluator presently not being able to do control flow. \ See https://github.com/rust-lang/rust/issues/49146 for more \ - information.", kind), + information.", + kind + ), ); } for local in locals { @@ -714,30 +672,27 @@ fn place_as_reborrow( body: &Body<'tcx>, place: &'a Place<'tcx>, ) -> Option<&'a [PlaceElem<'tcx>]> { - place - .projection - .split_last() - .and_then(|(outermost, inner)| { - if outermost != &ProjectionElem::Deref { - return None; - } + place.projection.split_last().and_then(|(outermost, inner)| { + if outermost != &ProjectionElem::Deref { + return None; + } - // A borrow of a `static` also looks like `&(*_1)` in the MIR, but `_1` is a `const` - // that points to the allocation for the static. Don't treat these as reborrows. - if let PlaceBase::Local(local) = place.base { - if body.local_decls[local].is_ref_to_static() { - return None; - } + // A borrow of a `static` also looks like `&(*_1)` in the MIR, but `_1` is a `const` + // that points to the allocation for the static. Don't treat these as reborrows. + if let PlaceBase::Local(local) = place.base { + if body.local_decls[local].is_ref_to_static() { + return None; } + } - // Ensure the type being derefed is a reference and not a raw pointer. - // - // This is sufficient to prevent an access to a `static mut` from being marked as a - // reborrow, even if the check above were to disappear. - let inner_ty = Place::ty_from(&place.base, inner, body, tcx).ty; - match inner_ty.kind { - ty::Ref(..) => Some(inner), - _ => None, - } - }) + // Ensure the type being derefed is a reference and not a raw pointer. + // + // This is sufficient to prevent an access to a `static mut` from being marked as a + // reborrow, even if the check above were to disappear. + let inner_ty = Place::ty_from(&place.base, inner, body, tcx).ty; + match inner_ty.kind { + ty::Ref(..) => Some(inner), + _ => None, + } + }) } diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 284285c327c34..715ae1ce01ef9 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -1,16 +1,16 @@ use rustc_data_structures::fx::FxHashSet; -use rustc::ty::query::Providers; -use rustc::ty::{self, TyCtxt}; -use rustc::ty::cast::CastTy; use rustc::hir; -use rustc::hir::Node; use rustc::hir::def_id::DefId; +use rustc::hir::Node; use rustc::lint::builtin::{SAFE_PACKED_BORROWS, UNUSED_UNSAFE}; +use rustc::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; use rustc::mir::*; -use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext}; +use rustc::ty::cast::CastTy; +use rustc::ty::query::Providers; +use rustc::ty::{self, TyCtxt}; -use syntax::symbol::{Symbol, sym}; +use syntax::symbol::{sym, Symbol}; use std::ops::Bound; @@ -48,10 +48,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { const_context, min_const_fn, violations: vec![], - source_info: SourceInfo { - span: body.span, - scope: OUTERMOST_SOURCE_SCOPE - }, + source_info: SourceInfo { span: body.span, scope: OUTERMOST_SOURCE_SCOPE }, tcx, param_env, used_unsafe: Default::default(), @@ -61,25 +58,22 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { } impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { - fn visit_terminator(&mut self, - terminator: &Terminator<'tcx>, - location: Location) - { + fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { self.source_info = terminator.source_info; match terminator.kind { - TerminatorKind::Goto { .. } | - TerminatorKind::SwitchInt { .. } | - TerminatorKind::Drop { .. } | - TerminatorKind::Yield { .. } | - TerminatorKind::Assert { .. } | - TerminatorKind::DropAndReplace { .. } | - TerminatorKind::GeneratorDrop | - TerminatorKind::Resume | - TerminatorKind::Abort | - TerminatorKind::Return | - TerminatorKind::Unreachable | - TerminatorKind::FalseEdges { .. } | - TerminatorKind::FalseUnwind { .. } => { + TerminatorKind::Goto { .. } + | TerminatorKind::SwitchInt { .. } + | TerminatorKind::Drop { .. } + | TerminatorKind::Yield { .. } + | TerminatorKind::Assert { .. } + | TerminatorKind::DropAndReplace { .. } + | TerminatorKind::GeneratorDrop + | TerminatorKind::Resume + | TerminatorKind::Abort + | TerminatorKind::Return + | TerminatorKind::Unreachable + | TerminatorKind::FalseEdges { .. } + | TerminatorKind::FalseUnwind { .. } => { // safe (at least as emitted during MIR construction) } @@ -87,89 +81,86 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { let func_ty = func.ty(self.body, self.tcx); let sig = func_ty.fn_sig(self.tcx); if let hir::Unsafety::Unsafe = sig.unsafety() { - self.require_unsafe("call to unsafe function", + self.require_unsafe( + "call to unsafe function", "consult the function's documentation for information on how to avoid \ - undefined behavior", UnsafetyViolationKind::GeneralAndConstFn) + undefined behavior", + UnsafetyViolationKind::GeneralAndConstFn, + ) } } } self.super_terminator(terminator, location); } - fn visit_statement(&mut self, - statement: &Statement<'tcx>, - location: Location) - { + fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { self.source_info = statement.source_info; match statement.kind { - StatementKind::Assign(..) | - StatementKind::FakeRead(..) | - StatementKind::SetDiscriminant { .. } | - StatementKind::StorageLive(..) | - StatementKind::StorageDead(..) | - StatementKind::Retag { .. } | - StatementKind::AscribeUserType(..) | - StatementKind::Nop => { + StatementKind::Assign(..) + | StatementKind::FakeRead(..) + | StatementKind::SetDiscriminant { .. } + | StatementKind::StorageLive(..) + | StatementKind::StorageDead(..) + | StatementKind::Retag { .. } + | StatementKind::AscribeUserType(..) + | StatementKind::Nop => { // safe (at least as emitted during MIR construction) } - StatementKind::InlineAsm { .. } => { - self.require_unsafe("use of inline assembly", - "inline assembly is entirely unchecked and can cause undefined behavior", - UnsafetyViolationKind::General) - }, + StatementKind::InlineAsm { .. } => self.require_unsafe( + "use of inline assembly", + "inline assembly is entirely unchecked and can cause undefined behavior", + UnsafetyViolationKind::General, + ), } self.super_statement(statement, location); } - fn visit_rvalue(&mut self, - rvalue: &Rvalue<'tcx>, - location: Location) - { + fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { match rvalue { - Rvalue::Aggregate(box ref aggregate, _) => { - match aggregate { - &AggregateKind::Array(..) | - &AggregateKind::Tuple => {} - &AggregateKind::Adt(ref def, ..) => { - match self.tcx.layout_scalar_valid_range(def.did) { - (Bound::Unbounded, Bound::Unbounded) => {}, - _ => self.require_unsafe( - "initializing type with `rustc_layout_scalar_valid_range` attr", - "initializing a layout restricted type's field with a value \ + Rvalue::Aggregate(box ref aggregate, _) => match aggregate { + &AggregateKind::Array(..) | &AggregateKind::Tuple => {} + &AggregateKind::Adt(ref def, ..) => { + match self.tcx.layout_scalar_valid_range(def.did) { + (Bound::Unbounded, Bound::Unbounded) => {} + _ => self.require_unsafe( + "initializing type with `rustc_layout_scalar_valid_range` attr", + "initializing a layout restricted type's field with a value \ outside the valid range is undefined behavior", - UnsafetyViolationKind::GeneralAndConstFn, - ), - } - } - &AggregateKind::Closure(def_id, _) | - &AggregateKind::Generator(def_id, _, _) => { - let UnsafetyCheckResult { - violations, unsafe_blocks - } = self.tcx.unsafety_check_result(def_id); - self.register_violations(&violations, &unsafe_blocks); + UnsafetyViolationKind::GeneralAndConstFn, + ), } } + &AggregateKind::Closure(def_id, _) | &AggregateKind::Generator(def_id, _, _) => { + let UnsafetyCheckResult { violations, unsafe_blocks } = + self.tcx.unsafety_check_result(def_id); + self.register_violations(&violations, &unsafe_blocks); + } }, // casting pointers to ints is unsafe in const fn because the const evaluator cannot // possibly know what the result of various operations like `address / 2` would be // pointers during const evaluation have no integral address, only an abstract one Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) - if self.const_context && self.tcx.features().const_raw_ptr_to_usize_cast => { + if self.const_context && self.tcx.features().const_raw_ptr_to_usize_cast => + { let operand_ty = operand.ty(self.body, self.tcx); let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast"); let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast"); match (cast_in, cast_out) { - (CastTy::Ptr(_), CastTy::Int(_)) | - (CastTy::FnPtr, CastTy::Int(_)) => { - self.register_violations(&[UnsafetyViolation { - source_info: self.source_info, - description: Symbol::intern("cast of pointer to int"), - details: Symbol::intern("casting pointers to integers in constants"), - kind: UnsafetyViolationKind::General, - }], &[]); - }, - _ => {}, + (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => { + self.register_violations( + &[UnsafetyViolation { + source_info: self.source_info, + description: Symbol::intern("cast of pointer to int"), + details: Symbol::intern( + "casting pointers to integers in constants", + ), + kind: UnsafetyViolationKind::General, + }], + &[], + ); + } + _ => {} } } // raw pointer and fn pointer operations are unsafe as it is not clear whether one @@ -177,25 +168,26 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { // or the linker will place various statics in memory. Without this information the // result of a comparison of addresses would differ between runtime and compile-time. Rvalue::BinaryOp(_, ref lhs, _) - if self.const_context && self.tcx.features().const_compare_raw_pointers => { + if self.const_context && self.tcx.features().const_compare_raw_pointers => + { if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body, self.tcx).kind { - self.register_violations(&[UnsafetyViolation { - source_info: self.source_info, - description: Symbol::intern("pointer operation"), - details: Symbol::intern("operations on pointers in constants"), - kind: UnsafetyViolationKind::General, - }], &[]); + self.register_violations( + &[UnsafetyViolation { + source_info: self.source_info, + description: Symbol::intern("pointer operation"), + details: Symbol::intern("operations on pointers in constants"), + kind: UnsafetyViolationKind::General, + }], + &[], + ); } } - _ => {}, + _ => {} } self.super_rvalue(rvalue, location); } - fn visit_place(&mut self, - place: &Place<'tcx>, - context: PlaceContext, - _location: Location) { + fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { match place.base { PlaceBase::Local(..) => { // Locals are safe. @@ -219,21 +211,27 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { .as_ref() .assert_crate_local() .lint_root; - self.register_violations(&[UnsafetyViolation { - source_info, - description: Symbol::intern("borrow of packed field"), - details: Symbol::intern( - "fields of packed structs might be misaligned: dereferencing a \ + self.register_violations( + &[UnsafetyViolation { + source_info, + description: Symbol::intern("borrow of packed field"), + details: Symbol::intern( + "fields of packed structs might be misaligned: dereferencing a \ misaligned pointer or even just creating a misaligned reference \ - is undefined behavior"), - kind: UnsafetyViolationKind::BorrowPacked(lint_root) - }], &[]); + is undefined behavior", + ), + kind: UnsafetyViolationKind::BorrowPacked(lint_root), + }], + &[], + ); } } - let is_borrow_of_interior_mut = context.is_borrow() && - !Place::ty_from(&place.base, proj_base, self.body, self.tcx) - .ty - .is_freeze(self.tcx, self.param_env, self.source_info.span); + let is_borrow_of_interior_mut = context.is_borrow() + && !Place::ty_from(&place.base, proj_base, self.body, self.tcx).ty.is_freeze( + self.tcx, + self.param_env, + self.source_info.span, + ); // prevent // * `&mut x.field` // * `x.field = y;` @@ -241,9 +239,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { // because either of these would allow modifying the layout constrained field and // insert values that violate the layout constraints. if context.is_mutating_use() || is_borrow_of_interior_mut { - self.check_mut_borrowing_layout_constrained_field( - place, context.is_mutating_use(), - ); + self.check_mut_borrowing_layout_constrained_field(place, context.is_mutating_use()); } let old_source_info = self.source_info; if let (PlaceBase::Local(local), []) = (&place.base, proj_base) { @@ -276,26 +272,26 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { } let base_ty = Place::ty_from(&place.base, proj_base, self.body, self.tcx).ty; match base_ty.kind { - ty::RawPtr(..) => { - self.require_unsafe("dereference of raw pointer", - "raw pointers may be NULL, dangling or unaligned; they can violate \ + ty::RawPtr(..) => self.require_unsafe( + "dereference of raw pointer", + "raw pointers may be NULL, dangling or unaligned; they can violate \ aliasing rules and cause data races: all of these are undefined \ - behavior", UnsafetyViolationKind::General) - } + behavior", + UnsafetyViolationKind::General, + ), ty::Adt(adt, _) => { if adt.is_union() { - if context == PlaceContext::MutatingUse(MutatingUseContext::Store) || - context == PlaceContext::MutatingUse(MutatingUseContext::Drop) || - context == PlaceContext::MutatingUse( - MutatingUseContext::AsmOutput - ) + if context == PlaceContext::MutatingUse(MutatingUseContext::Store) + || context == PlaceContext::MutatingUse(MutatingUseContext::Drop) + || context == PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) { let elem_ty = match elem { ProjectionElem::Field(_, ty) => ty, _ => span_bug!( self.source_info.span, "non-field projection {:?} from union?", - place) + place + ), }; if !elem_ty.is_copy_modulo_regions( self.tcx, @@ -306,15 +302,19 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { "assignment to non-`Copy` union field", "the previous content of the field will be dropped, which \ causes undefined behavior if the field was not properly \ - initialized", UnsafetyViolationKind::GeneralAndConstFn) + initialized", + UnsafetyViolationKind::GeneralAndConstFn, + ) } else { // write to non-move union, safe } } else { - self.require_unsafe("access to union field", + self.require_unsafe( + "access to union field", "the field may not be properly initialized: using \ uninitialized data will cause undefined behavior", - UnsafetyViolationKind::GeneralAndConstFn) + UnsafetyViolationKind::GeneralAndConstFn, + ) } } } @@ -333,17 +333,22 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { kind: UnsafetyViolationKind, ) { let source_info = self.source_info; - self.register_violations(&[UnsafetyViolation { - source_info, - description: Symbol::intern(description), - details: Symbol::intern(details), - kind, - }], &[]); + self.register_violations( + &[UnsafetyViolation { + source_info, + description: Symbol::intern(description), + details: Symbol::intern(details), + kind, + }], + &[], + ); } - fn register_violations(&mut self, - violations: &[UnsafetyViolation], - unsafe_blocks: &[(hir::HirId, bool)]) { + fn register_violations( + &mut self, + violations: &[UnsafetyViolation], + unsafe_blocks: &[(hir::HirId, bool)], + ) { let safety = self.body.source_scopes[self.source_info.scope] .local_data .as_ref() @@ -355,14 +360,16 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { for violation in violations { let mut violation = violation.clone(); match violation.kind { - UnsafetyViolationKind::GeneralAndConstFn | - UnsafetyViolationKind::General => {}, - UnsafetyViolationKind::BorrowPacked(_) => if self.min_const_fn { - // const fns don't need to be backwards compatible and can - // emit these violations as a hard error instead of a backwards - // compat lint - violation.kind = UnsafetyViolationKind::General; - }, + UnsafetyViolationKind::GeneralAndConstFn + | UnsafetyViolationKind::General => {} + UnsafetyViolationKind::BorrowPacked(_) => { + if self.min_const_fn { + // const fns don't need to be backwards compatible and can + // emit these violations as a hard error instead of a backwards + // compat lint + violation.kind = UnsafetyViolationKind::General; + } + } } if !self.violations.contains(&violation) { self.violations.push(violation) @@ -382,10 +389,10 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { for violation in violations { match violation.kind { // these unsafe things are stable in const fn - UnsafetyViolationKind::GeneralAndConstFn => {}, + UnsafetyViolationKind::GeneralAndConstFn => {} // these things are forbidden in const fns - UnsafetyViolationKind::General | - UnsafetyViolationKind::BorrowPacked(_) => { + UnsafetyViolationKind::General + | UnsafetyViolationKind::BorrowPacked(_) => { let mut violation = violation.clone(); // const fns don't need to be backwards compatible and can // emit these violations as a hard error instead of a backwards @@ -394,16 +401,16 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { if !self.violations.contains(&violation) { self.violations.push(violation) } - }, + } } } } true } }; - self.inherited_blocks.extend(unsafe_blocks.iter().map(|&(hir_id, is_used)| { - (hir_id, is_used && !within_unsafe) - })); + self.inherited_blocks.extend( + unsafe_blocks.iter().map(|&(hir_id, is_used)| (hir_id, is_used && !within_unsafe)), + ); } fn check_mut_borrowing_layout_constrained_field( &mut self, @@ -417,11 +424,10 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { match elem { ProjectionElem::Field(..) => { let ty = - Place::ty_from(&place.base, proj_base, &self.body.local_decls, self.tcx) - .ty; + Place::ty_from(&place.base, proj_base, &self.body.local_decls, self.tcx).ty; match ty.kind { ty::Adt(def, _) => match self.tcx.layout_scalar_valid_range(def.did) { - (Bound::Unbounded, Bound::Unbounded) => {}, + (Bound::Unbounded, Bound::Unbounded) => {} _ => { let (description, details) = if is_mut_use { ( @@ -439,12 +445,15 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { ) }; let source_info = self.source_info; - self.register_violations(&[UnsafetyViolation { - source_info, - description: Symbol::intern(description), - details: Symbol::intern(details), - kind: UnsafetyViolationKind::GeneralAndConstFn, - }], &[]); + self.register_violations( + &[UnsafetyViolation { + source_info, + description: Symbol::intern(description), + details: Symbol::intern(details), + kind: UnsafetyViolationKind::GeneralAndConstFn, + }], + &[], + ); } }, _ => {} @@ -457,11 +466,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { } pub(crate) fn provide(providers: &mut Providers<'_>) { - *providers = Providers { - unsafety_check_result, - unsafe_derive_on_repr_packed, - ..*providers - }; + *providers = Providers { unsafety_check_result, unsafe_derive_on_repr_packed, ..*providers }; } struct UnusedUnsafeVisitor<'a> { @@ -470,9 +475,7 @@ struct UnusedUnsafeVisitor<'a> { } impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'a> { - fn nested_visit_map<'this>(&'this mut self) -> - hir::intravisit::NestedVisitorMap<'this, 'tcx> - { + fn nested_visit_map<'this>(&'this mut self) -> hir::intravisit::NestedVisitorMap<'this, 'tcx> { hir::intravisit::NestedVisitorMap::None } @@ -492,22 +495,19 @@ fn check_unused_unsafe( unsafe_blocks: &mut Vec<(hir::HirId, bool)>, ) { let body_id = - tcx.hir().as_local_hir_id(def_id).and_then(|hir_id| { - tcx.hir().maybe_body_owned_by(hir_id) - }); + tcx.hir().as_local_hir_id(def_id).and_then(|hir_id| tcx.hir().maybe_body_owned_by(hir_id)); let body_id = match body_id { Some(body) => body, None => { debug!("check_unused_unsafe({:?}) - no body found", def_id); - return + return; } }; let body = tcx.hir().body(body_id); - debug!("check_unused_unsafe({:?}, body={:?}, used_unsafe={:?})", - def_id, body, used_unsafe); + debug!("check_unused_unsafe({:?}, body={:?}, used_unsafe={:?})", def_id, body, used_unsafe); - let mut visitor = UnusedUnsafeVisitor { used_unsafe, unsafe_blocks }; + let mut visitor = UnusedUnsafeVisitor { used_unsafe, unsafe_blocks }; hir::intravisit::Visitor::visit_body(&mut visitor, body); } @@ -524,8 +524,7 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult let (const_context, min_const_fn) = match tcx.hir().body_owner_kind(id) { hir::BodyOwnerKind::Closure => (false, false), hir::BodyOwnerKind::Fn => (tcx.is_const_fn(def_id), tcx.is_min_const_fn(def_id)), - hir::BodyOwnerKind::Const | - hir::BodyOwnerKind::Static(_) => (true, false), + hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => (true, false), }; let mut checker = UnsafetyChecker::new(const_context, min_const_fn, body, tcx, param_env); // mir_built ensures that body has a computed cache, so we don't (and can't) attempt to @@ -536,27 +535,28 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult check_unused_unsafe(tcx, def_id, &checker.used_unsafe, &mut checker.inherited_blocks); UnsafetyCheckResult { violations: checker.violations.into(), - unsafe_blocks: checker.inherited_blocks.into() + unsafe_blocks: checker.inherited_blocks.into(), } } fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: DefId) { - let lint_hir_id = tcx.hir().as_local_hir_id(def_id).unwrap_or_else(|| - bug!("checking unsafety for non-local def id {:?}", def_id)); + let lint_hir_id = tcx + .hir() + .as_local_hir_id(def_id) + .unwrap_or_else(|| bug!("checking unsafety for non-local def id {:?}", def_id)); // FIXME: when we make this a hard error, this should have its // own error code. let message = if tcx.generics_of(def_id).own_requires_monomorphization() { "`#[derive]` can't be used on a `#[repr(packed)]` struct with \ - type or const parameters (error E0133)".to_string() + type or const parameters (error E0133)" + .to_string() } else { "`#[derive]` can't be used on a `#[repr(packed)]` struct that \ - does not derive Copy (error E0133)".to_string() + does not derive Copy (error E0133)" + .to_string() }; - tcx.lint_hir(SAFE_PACKED_BORROWS, - lint_hir_id, - tcx.def_span(def_id), - &message); + tcx.lint_hir(SAFE_PACKED_BORROWS, lint_hir_id, tcx.def_span(def_id), &message); } /// Returns the `HirId` for an enclosing scope that is also `unsafe`. @@ -570,9 +570,9 @@ fn is_enclosed( if used_unsafe.contains(&parent_id) { Some(("block".to_string(), parent_id)) } else if let Some(Node::Item(&hir::Item { - kind: hir::ItemKind::Fn(ref sig, _, _), - .. - })) = tcx.hir().find(parent_id) { + kind: hir::ItemKind::Fn(ref sig, _, _), .. + })) = tcx.hir().find(parent_id) + { match sig.header.unsafety { hir::Unsafety::Unsafe => Some(("fn".to_string(), parent_id)), hir::Unsafety::Normal => None, @@ -591,8 +591,10 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, used_unsafe: &FxHashSet, id let mut db = tcx.struct_span_lint_hir(UNUSED_UNSAFE, id, span, msg); db.span_label(span, msg); if let Some((kind, id)) = is_enclosed(tcx, used_unsafe, id) { - db.span_label(tcx.sess.source_map().def_span(tcx.hir().span(id)), - format!("because it's nested under this `unsafe` {}", kind)); + db.span_label( + tcx.sess.source_map().def_span(tcx.hir().span(id)), + format!("because it's nested under this `unsafe` {}", kind), + ); } db.emit(); } @@ -621,35 +623,38 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) { return; } - let UnsafetyCheckResult { - violations, - unsafe_blocks - } = tcx.unsafety_check_result(def_id); + let UnsafetyCheckResult { violations, unsafe_blocks } = tcx.unsafety_check_result(def_id); - for &UnsafetyViolation { - source_info, description, details, kind - } in violations.iter() { + for &UnsafetyViolation { source_info, description, details, kind } in violations.iter() { // Report an error. match kind { - UnsafetyViolationKind::GeneralAndConstFn | - UnsafetyViolationKind::General => { + UnsafetyViolationKind::GeneralAndConstFn | UnsafetyViolationKind::General => { struct_span_err!( - tcx.sess, source_info.span, E0133, - "{} is unsafe and requires unsafe function or block", description) - .span_label(source_info.span, &*description.as_str()) - .note(&details.as_str()) - .emit(); + tcx.sess, + source_info.span, + E0133, + "{} is unsafe and requires unsafe function or block", + description + ) + .span_label(source_info.span, &*description.as_str()) + .note(&details.as_str()) + .emit(); } UnsafetyViolationKind::BorrowPacked(lint_hir_id) => { if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) { tcx.unsafe_derive_on_repr_packed(impl_def_id); } else { - tcx.lint_node_note(SAFE_PACKED_BORROWS, - lint_hir_id, - source_info.span, - &format!("{} is unsafe and requires unsafe function or block \ - (error E0133)", description), - &details.as_str()); + tcx.lint_node_note( + SAFE_PACKED_BORROWS, + lint_hir_id, + source_info.span, + &format!( + "{} is unsafe and requires unsafe function or block \ + (error E0133)", + description + ), + &details.as_str(), + ); } } } @@ -657,9 +662,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) { let mut unsafe_blocks: Vec<_> = unsafe_blocks.into_iter().collect(); unsafe_blocks.sort_by_cached_key(|(hir_id, _)| tcx.hir().hir_to_node_id(*hir_id)); - let used_unsafe: FxHashSet<_> = unsafe_blocks.iter() - .flat_map(|&&(id, used)| used.then_some(id)) - .collect(); + let used_unsafe: FxHashSet<_> = + unsafe_blocks.iter().flat_map(|&&(id, used)| used.then_some(id)).collect(); for &(block_id, is_used) in unsafe_blocks { if !is_used { report_unused_unsafe(tcx, &used_unsafe, block_id); diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs index 34519bc9fa627..5288b6b370ddb 100644 --- a/src/librustc_mir/transform/cleanup_post_borrowck.rs +++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs @@ -16,11 +16,11 @@ //! [`FakeRead`]: rustc::mir::StatementKind::FakeRead //! [`Nop`]: rustc::mir::StatementKind::Nop -use rustc::mir::{BodyAndCache, BorrowKind, Rvalue, Location}; -use rustc::mir::{Statement, StatementKind}; +use crate::transform::{MirPass, MirSource}; use rustc::mir::visit::MutVisitor; +use rustc::mir::{BodyAndCache, BorrowKind, Location, Rvalue}; +use rustc::mir::{Statement, StatementKind}; use rustc::ty::TyCtxt; -use crate::transform::{MirPass, MirSource}; pub struct CleanupNonCodegenStatements; @@ -29,9 +29,7 @@ pub struct DeleteNonCodegenStatements<'tcx> { } impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements { - fn run_pass( - &self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx> - ) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { let mut delete = DeleteNonCodegenStatements { tcx }; delete.visit_body(body); } @@ -42,12 +40,10 @@ impl<'tcx> MutVisitor<'tcx> for DeleteNonCodegenStatements<'tcx> { self.tcx } - fn visit_statement(&mut self, - statement: &mut Statement<'tcx>, - location: Location) { + fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { match statement.kind { StatementKind::AscribeUserType(..) - | StatementKind::Assign(box(_, Rvalue::Ref(_, BorrowKind::Shallow, _))) + | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _))) | StatementKind::FakeRead(..) => statement.make_nop(), _ => (), } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 1a24a8b371d76..c36cdc9832391 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -6,34 +6,33 @@ use std::cell::Cell; use rustc::hir::def::DefKind; use rustc::hir::def_id::DefId; +use rustc::mir::interpret::{InterpResult, PanicInfo, Scalar}; +use rustc::mir::visit::{ + MutVisitor, MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor, +}; use rustc::mir::{ - AggregateKind, Constant, Location, Place, PlaceBase, Body, BodyAndCache, Operand, Local, UnOp, - Rvalue, StatementKind, Statement, LocalKind, TerminatorKind, Terminator, ClearCrossCrate, - SourceInfo, BinOp, SourceScope, SourceScopeData, LocalDecl, BasicBlock, ReadOnlyBodyAndCache, - read_only, RETURN_PLACE + read_only, AggregateKind, BasicBlock, BinOp, Body, BodyAndCache, ClearCrossCrate, Constant, + Local, LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, ReadOnlyBodyAndCache, Rvalue, + SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind, + UnOp, RETURN_PLACE, }; -use rustc::mir::visit::{ - Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext, +use rustc::ty::layout::{ + HasDataLayout, HasTyCtxt, LayoutError, LayoutOf, Size, TargetDataLayout, TyLayout, }; -use rustc::mir::interpret::{Scalar, InterpResult, PanicInfo}; -use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; -use syntax::ast::Mutability; -use syntax_pos::{Span, DUMMY_SP}; use rustc::ty::subst::InternalSubsts; +use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; use rustc_index::vec::IndexVec; -use rustc::ty::layout::{ - LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout, Size, -}; +use syntax::ast::Mutability; +use syntax_pos::{Span, DUMMY_SP}; -use crate::rustc::ty::subst::Subst; +use crate::const_eval::error_to_const_error; use crate::interpret::{ - self, InterpCx, ScalarMaybeUndef, Immediate, OpTy, - StackPopCleanup, LocalValue, LocalState, AllocId, Frame, - Allocation, MemoryKind, ImmTy, Pointer, Memory, PlaceTy, - Operand as InterpOperand, intern_const_alloc_recursive, + self, intern_const_alloc_recursive, AllocId, Allocation, Frame, ImmTy, Immediate, InterpCx, + LocalState, LocalValue, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy, Pointer, + ScalarMaybeUndef, StackPopCleanup, }; -use crate::const_eval::error_to_const_error; +use crate::rustc::ty::subst::Subst; use crate::transform::{MirPass, MirSource}; /// The maximum number of bytes that we'll allocate space for a return value. @@ -42,17 +41,17 @@ const MAX_ALLOC_LIMIT: u64 = 1024; pub struct ConstProp; impl<'tcx> MirPass<'tcx> for ConstProp { - fn run_pass( - &self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx> - ) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { // will be evaluated by miri and produce its errors there if source.promoted.is_some() { return; } use rustc::hir::map::blocks::FnLikeNode; - let hir_id = tcx.hir().as_local_hir_id(source.def_id()) - .expect("Non-local call to local provider is_const_fn"); + let hir_id = tcx + .hir() + .as_local_hir_id(source.def_id()) + .expect("Non-local call to local provider is_const_fn"); let is_fn_like = FnLikeNode::from_node(tcx.hir().get(hir_id)).is_some(); let is_assoc_const = match tcx.def_kind(source.def_id()) { @@ -61,10 +60,10 @@ impl<'tcx> MirPass<'tcx> for ConstProp { }; // Only run const prop on functions, methods, closures and associated constants - if !is_fn_like && !is_assoc_const { + if !is_fn_like && !is_assoc_const { // skip anon_const/statics/consts because they'll be evaluated by miri anyway trace!("ConstProp skipped for {:?}", source.def_id()); - return + return; } let is_generator = tcx.type_of(source.def_id()).is_generator(); @@ -72,34 +71,29 @@ impl<'tcx> MirPass<'tcx> for ConstProp { // computing their layout. if is_generator { trace!("ConstProp skipped for generator {:?}", source.def_id()); - return + return; } trace!("ConstProp starting for {:?}", source.def_id()); - let dummy_body = - &Body::new( - body.basic_blocks().clone(), - body.source_scopes.clone(), - body.local_decls.clone(), - Default::default(), - body.arg_count, - Default::default(), - tcx.def_span(source.def_id()), - Default::default(), - body.generator_kind, - ); + let dummy_body = &Body::new( + body.basic_blocks().clone(), + body.source_scopes.clone(), + body.local_decls.clone(), + Default::default(), + body.arg_count, + Default::default(), + tcx.def_span(source.def_id()), + Default::default(), + body.generator_kind, + ); // FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold // constants, instead of just checking for const-folding succeeding. // That would require an uniform one-def no-mutation analysis // and RPO (or recursing when needing the value of a local). - let mut optimization_finder = ConstPropagator::new( - read_only!(body), - dummy_body, - tcx, - source - ); + let mut optimization_finder = + ConstPropagator::new(read_only!(body), dummy_body, tcx, source); optimization_finder.visit_body(body); trace!("ConstProp done for {:?}", source.def_id()); @@ -143,7 +137,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine { fn_val: !, _args: &[OpTy<'tcx>], _ret: Option<(PlaceTy<'tcx>, BasicBlock)>, - _unwind: Option + _unwind: Option, ) -> InterpResult<'tcx> { match fn_val {} } @@ -154,7 +148,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine { _instance: ty::Instance<'tcx>, _args: &[OpTy<'tcx>], _ret: Option<(PlaceTy<'tcx>, BasicBlock)>, - _unwind: Option + _unwind: Option, ) -> InterpResult<'tcx> { throw_unsup!(ConstPropUnsupported("calling intrinsics isn't supported in ConstProp")); } @@ -168,10 +162,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine { bug!("panics terminators are not evaluated in ConstProp"); } - fn ptr_to_int( - _mem: &Memory<'mir, 'tcx, Self>, - _ptr: Pointer, - ) -> InterpResult<'tcx, u64> { + fn ptr_to_int(_mem: &Memory<'mir, 'tcx, Self>, _ptr: Pointer) -> InterpResult<'tcx, u64> { throw_unsup!(ConstPropUnsupported("ptr-to-int casts aren't supported in ConstProp")); } @@ -182,8 +173,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine { _right: ImmTy<'tcx>, ) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> { // We can't do this because aliasing of memory can differ between const eval and llvm - throw_unsup!(ConstPropUnsupported("pointer arithmetic or comparisons aren't supported \ - in ConstProp")); + throw_unsup!(ConstPropUnsupported( + "pointer arithmetic or comparisons aren't supported \ + in ConstProp" + )); } fn find_foreign_static( @@ -205,10 +198,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine { } #[inline(always)] - fn tag_static_base_pointer( - _memory_extra: &(), - _id: AllocId, - ) -> Self::PointerTag { + fn tag_static_base_pointer(_memory_extra: &(), _id: AllocId) -> Self::PointerTag { () } @@ -309,25 +299,24 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let substs = &InternalSubsts::identity_for_item(tcx, def_id); - let ret = - ecx - .layout_of(body.return_ty().subst(tcx, substs)) - .ok() - // Don't bother allocating memory for ZST types which have no values - // or for large values. - .filter(|ret_layout| !ret_layout.is_zst() && - ret_layout.size < Size::from_bytes(MAX_ALLOC_LIMIT)) - .map(|ret_layout| ecx.allocate(ret_layout, MemoryKind::Stack)); + let ret = ecx + .layout_of(body.return_ty().subst(tcx, substs)) + .ok() + // Don't bother allocating memory for ZST types which have no values + // or for large values. + .filter(|ret_layout| { + !ret_layout.is_zst() && ret_layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) + }) + .map(|ret_layout| ecx.allocate(ret_layout, MemoryKind::Stack)); ecx.push_stack_frame( Instance::new(def_id, substs), span, dummy_body, ret.map(Into::into), - StackPopCleanup::None { - cleanup: false, - }, - ).expect("failed to push initial stack frame"); + StackPopCleanup::None { cleanup: false }, + ) + .expect("failed to push initial stack frame"); ConstPropagator { ecx, @@ -358,17 +347,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } fn remove_const(&mut self, local: Local) { - self.ecx.frame_mut().locals[local] = LocalState { - value: LocalValue::Uninitialized, - layout: Cell::new(None), - }; + self.ecx.frame_mut().locals[local] = + LocalState { value: LocalValue::Uninitialized, layout: Cell::new(None) }; } - fn use_ecx( - &mut self, - source_info: SourceInfo, - f: F - ) -> Option + fn use_ecx(&mut self, source_info: SourceInfo, f: F) -> Option where F: FnOnce(&mut Self) -> InterpResult<'tcx, T>, { @@ -384,9 +367,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Ok(val) => Some(val), Err(error) => { use rustc::mir::interpret::{ - UnsupportedOpInfo, - UndefinedBehaviorInfo, - InterpError::* + InterpError::*, UndefinedBehaviorInfo, UnsupportedOpInfo, }; match error.kind { MachineStop(_) => bug!("ConstProp does not stop"), @@ -399,7 +380,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { | Unsupported(UnsupportedOpInfo::ValidationFailure(_)) | UndefinedBehavior(UndefinedBehaviorInfo::Ub(_)) | UndefinedBehavior(UndefinedBehaviorInfo::UbExperimental(_)) - if cfg!(debug_assertions) => { + if cfg!(debug_assertions) => + { bug!("const-prop encountered allocating error: {:?}", error.kind); } @@ -420,41 +402,35 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } } None - }, + } }; self.ecx.tcx.span = DUMMY_SP; r } - fn eval_constant( - &mut self, - c: &Constant<'tcx>, - ) -> Option> { + fn eval_constant(&mut self, c: &Constant<'tcx>) -> Option> { self.ecx.tcx.span = c.span; match self.ecx.eval_const_to_op(c.literal, None) { - Ok(op) => { - Some(op) - }, + Ok(op) => Some(op), Err(error) => { let err = error_to_const_error(&self.ecx, error); err.report_as_error(self.ecx.tcx, "erroneous constant used"); None - }, + } } } fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option> { trace!("eval_place(place={:?})", place); - self.use_ecx(source_info, |this| { - this.ecx.eval_place_to_op(place, None) - }) + self.use_ecx(source_info, |this| this.ecx.eval_place_to_op(place, None)) } fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option> { match *op { Operand::Constant(ref c) => self.eval_constant(c), - | Operand::Move(ref place) - | Operand::Copy(ref place) => self.eval_place(place, source_info), + Operand::Move(ref place) | Operand::Copy(ref place) => { + self.eval_place(place, source_info) + } } } @@ -522,16 +498,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ClearCrossCrate::Set(data) => data.lint_root, ClearCrossCrate::Clear => return None, }; - let dir = if *op == BinOp::Shr { - "right" - } else { - "left" - }; + let dir = if *op == BinOp::Shr { "right" } else { "left" }; self.tcx.lint_hir( ::rustc::lint::builtin::EXCEEDING_BITSHIFTS, lint_root, span, - &format!("attempt to shift {} with overflow", dir)); + &format!("attempt to shift {} with overflow", dir), + ); return None; } } @@ -566,12 +539,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { trace!("checking Ref({:?})", place_ref); if let Some(local) = place_ref.as_local() { - let alive = - if let LocalValue::Live(_) = self.ecx.frame().locals[local].value { - true - } else { - false - }; + let alive = if let LocalValue::Live(_) = self.ecx.frame().locals[local].value { + true + } else { + false + }; if !alive { trace!("skipping Ref({:?}) to uninitialized local", place); @@ -580,7 +552,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } } - _ => { } + _ => {} } self.use_ecx(source_info, |this| { @@ -591,17 +563,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } fn operand_from_scalar(&self, scalar: Scalar, ty: Ty<'tcx>, span: Span) -> Operand<'tcx> { - Operand::Constant(Box::new( - Constant { - span, - user_ty: None, - literal: self.tcx.mk_const(*ty::Const::from_scalar( - self.tcx, - scalar, - ty, - )) - } - )) + Operand::Constant(Box::new(Constant { + span, + user_ty: None, + literal: self.tcx.mk_const(*ty::Const::from_scalar(self.tcx, scalar, ty)), + })) } fn replace_with_const( @@ -622,19 +588,20 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } // FIXME> figure out what tho do when try_read_immediate fails - let imm = self.use_ecx(source_info, |this| { - this.ecx.try_read_immediate(value) - }); + let imm = self.use_ecx(source_info, |this| this.ecx.try_read_immediate(value)); if let Some(Ok(imm)) = imm { match *imm { interpret::Immediate::Scalar(ScalarMaybeUndef::Scalar(scalar)) => { - *rval = Rvalue::Use( - self.operand_from_scalar(scalar, value.layout.ty, source_info.span)); - }, + *rval = Rvalue::Use(self.operand_from_scalar( + scalar, + value.layout.ty, + source_info.span, + )); + } Immediate::ScalarPair( ScalarMaybeUndef::Scalar(one), - ScalarMaybeUndef::Scalar(two) + ScalarMaybeUndef::Scalar(two), ) => { // Found a value represented as a pair. For now only do cont-prop if type of // Rvalue is also a pair with two scalars. The more general case is more @@ -648,10 +615,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let ty1 = substs[0].expect_ty(); let ty2 = substs[1].expect_ty(); let ty_is_scalar = |ty| { - this.ecx - .layout_of(ty) - .ok() - .map(|ty| ty.details.abi.is_scalar()) + this.ecx.layout_of(ty).ok().map(|ty| ty.details.abi.is_scalar()) == Some(true) }; if ty_is_scalar(ty1) && ty_is_scalar(ty2) { @@ -665,19 +629,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { *rval = Rvalue::Aggregate( Box::new(AggregateKind::Tuple), vec![ - self.operand_from_scalar( - one, ty1, source_info.span - ), - self.operand_from_scalar( - two, ty2, source_info.span - ), + self.operand_from_scalar(one, ty1, source_info.span), + self.operand_from_scalar(two, ty2, source_info.span), ], ); } } } - }, - _ => { } + } + _ => {} } } } @@ -690,20 +650,19 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } match *op { - interpret::Operand::Immediate(Immediate::Scalar(ScalarMaybeUndef::Scalar(s))) => - s.is_bits(), - interpret::Operand::Immediate(Immediate::ScalarPair(ScalarMaybeUndef::Scalar(l), - ScalarMaybeUndef::Scalar(r))) => - l.is_bits() && r.is_bits(), + interpret::Operand::Immediate(Immediate::Scalar(ScalarMaybeUndef::Scalar(s))) => { + s.is_bits() + } + interpret::Operand::Immediate(Immediate::ScalarPair( + ScalarMaybeUndef::Scalar(l), + ScalarMaybeUndef::Scalar(r), + )) => l.is_bits() && r.is_bits(), interpret::Operand::Indirect(_) if mir_opt_level >= 2 => { - intern_const_alloc_recursive( - &mut self.ecx, - None, - op.assert_mem_place() - ).expect("failed to intern alloc"); + intern_const_alloc_recursive(&mut self.ecx, None, op.assert_mem_place()) + .expect("failed to intern alloc"); true - }, - _ => false + } + _ => false, } } } @@ -751,34 +710,31 @@ impl CanConstProp { } impl<'tcx> Visitor<'tcx> for CanConstProp { - fn visit_local( - &mut self, - &local: &Local, - context: PlaceContext, - _: Location, - ) { + fn visit_local(&mut self, &local: &Local, context: PlaceContext, _: Location) { use rustc::mir::visit::PlaceContext::*; match context { // Constants must have at most one write // FIXME(oli-obk): we could be more powerful here, if the multiple writes // only occur in independent execution paths - MutatingUse(MutatingUseContext::Store) => if self.found_assignment[local] { - trace!("local {:?} can't be propagated because of multiple assignments", local); - self.can_const_prop[local] = ConstPropMode::NoPropagation; - } else { - self.found_assignment[local] = true - }, + MutatingUse(MutatingUseContext::Store) => { + if self.found_assignment[local] { + trace!("local {:?} can't be propagated because of multiple assignments", local); + self.can_const_prop[local] = ConstPropMode::NoPropagation; + } else { + self.found_assignment[local] = true + } + } // Reading constants is allowed an arbitrary number of times - NonMutatingUse(NonMutatingUseContext::Copy) | - NonMutatingUse(NonMutatingUseContext::Move) | - NonMutatingUse(NonMutatingUseContext::Inspect) | - NonMutatingUse(NonMutatingUseContext::Projection) | - MutatingUse(MutatingUseContext::Projection) | - NonUse(_) => {}, + NonMutatingUse(NonMutatingUseContext::Copy) + | NonMutatingUse(NonMutatingUseContext::Move) + | NonMutatingUse(NonMutatingUseContext::Inspect) + | NonMutatingUse(NonMutatingUseContext::Projection) + | MutatingUse(MutatingUseContext::Projection) + | NonUse(_) => {} _ => { trace!("local {:?} can't be propagaged because it's used: {:?}", local, context); self.can_const_prop[local] = ConstPropMode::NoPropagation; - }, + } } } } @@ -788,41 +744,28 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { self.tcx } - fn visit_constant( - &mut self, - constant: &mut Constant<'tcx>, - location: Location, - ) { + fn visit_constant(&mut self, constant: &mut Constant<'tcx>, location: Location) { trace!("visit_constant: {:?}", constant); self.super_constant(constant, location); self.eval_constant(constant); } - fn visit_statement( - &mut self, - statement: &mut Statement<'tcx>, - location: Location, - ) { + fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { trace!("visit_statement: {:?}", statement); - if let StatementKind::Assign(box(ref place, ref mut rval)) = statement.kind { - let place_ty: Ty<'tcx> = place - .ty(&self.local_decls, self.tcx) - .ty; + if let StatementKind::Assign(box (ref place, ref mut rval)) = statement.kind { + let place_ty: Ty<'tcx> = place.ty(&self.local_decls, self.tcx).ty; if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) { if let Some(local) = place.as_local() { let source = statement.source_info; let can_const_prop = self.can_const_prop[local]; if let Some(()) = self.const_prop(rval, place_layout, source, place) { - if can_const_prop == ConstPropMode::FullConstProp || - can_const_prop == ConstPropMode::OnlyPropagateInto { + if can_const_prop == ConstPropMode::FullConstProp + || can_const_prop == ConstPropMode::OnlyPropagateInto + { if let Some(value) = self.get_const(local) { if self.should_const_prop(value) { trace!("replacing {:?} with {:?}", rval, value); - self.replace_with_const( - rval, - value, - statement.source_info, - ); + self.replace_with_const(rval, value, statement.source_info); if can_const_prop == ConstPropMode::FullConstProp { trace!("propagated into {:?}", local); @@ -841,8 +784,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { } } else { match statement.kind { - StatementKind::StorageLive(local) | - StatementKind::StorageDead(local) => { + StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => { let frame = self.ecx.frame_mut(); frame.locals[local].value = if let StatementKind::StorageLive(_) = statement.kind { @@ -858,11 +800,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { self.super_statement(statement, location); } - fn visit_terminator( - &mut self, - terminator: &mut Terminator<'tcx>, - location: Location, - ) { + fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) { self.super_terminator(terminator, location); let source_info = terminator.source_info; match &mut terminator.kind { @@ -879,7 +817,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { if let PlaceBase::Local(local) = place.base { self.remove_const(local); } - }, + } Operand::Constant(_) => {} } let span = terminator.source_info.span; @@ -889,46 +827,34 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { .as_local_hir_id(self.source.def_id()) .expect("some part of a failing const eval must be local"); let msg = match msg { - PanicInfo::Overflow(_) | - PanicInfo::OverflowNeg | - PanicInfo::DivisionByZero | - PanicInfo::RemainderByZero => - msg.description().to_owned(), + PanicInfo::Overflow(_) + | PanicInfo::OverflowNeg + | PanicInfo::DivisionByZero + | PanicInfo::RemainderByZero => msg.description().to_owned(), PanicInfo::BoundsCheck { ref len, ref index } => { - let len = self - .eval_operand(len, source_info) - .expect("len must be const"); + let len = + self.eval_operand(len, source_info).expect("len must be const"); let len = match self.ecx.read_scalar(len) { - Ok(ScalarMaybeUndef::Scalar(Scalar::Raw { - data, .. - })) => data, + Ok(ScalarMaybeUndef::Scalar(Scalar::Raw { data, .. })) => data, other => bug!("const len not primitive: {:?}", other), }; let index = self .eval_operand(index, source_info) .expect("index must be const"); let index = match self.ecx.read_scalar(index) { - Ok(ScalarMaybeUndef::Scalar(Scalar::Raw { - data, .. - })) => data, + Ok(ScalarMaybeUndef::Scalar(Scalar::Raw { data, .. })) => data, other => bug!("const index not primitive: {:?}", other), }; format!( "index out of bounds: \ the len is {} but the index is {}", - len, - index, + len, index, ) - }, + } // Need proper const propagator for these _ => return, }; - self.tcx.lint_hir( - ::rustc::lint::builtin::CONST_ERR, - hir_id, - span, - &msg, - ); + self.tcx.lint_hir(::rustc::lint::builtin::CONST_ERR, hir_id, span, &msg); } else { if self.should_const_prop(value) { if let ScalarMaybeUndef::Scalar(scalar) = value_const { @@ -941,31 +867,32 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { } } } - }, + } TerminatorKind::SwitchInt { ref mut discr, switch_ty, .. } => { if let Some(value) = self.eval_operand(&discr, source_info) { if self.should_const_prop(value) { if let ScalarMaybeUndef::Scalar(scalar) = - self.ecx.read_scalar(value).unwrap() { + self.ecx.read_scalar(value).unwrap() + { *discr = self.operand_from_scalar(scalar, switch_ty, source_info.span); } } } - }, + } //none of these have Operands to const-propagate - TerminatorKind::Goto { .. } | - TerminatorKind::Resume | - TerminatorKind::Abort | - TerminatorKind::Return | - TerminatorKind::Unreachable | - TerminatorKind::Drop { .. } | - TerminatorKind::DropAndReplace { .. } | - TerminatorKind::Yield { .. } | - TerminatorKind::GeneratorDrop | - TerminatorKind::FalseEdges { .. } | - TerminatorKind::FalseUnwind { .. } => { } + TerminatorKind::Goto { .. } + | TerminatorKind::Resume + | TerminatorKind::Abort + | TerminatorKind::Return + | TerminatorKind::Unreachable + | TerminatorKind::Drop { .. } + | TerminatorKind::DropAndReplace { .. } + | TerminatorKind::Yield { .. } + | TerminatorKind::GeneratorDrop + | TerminatorKind::FalseEdges { .. } + | TerminatorKind::FalseUnwind { .. } => {} //FIXME(wesleywiser) Call does have Operands that could be const-propagated - TerminatorKind::Call { .. } => { } + TerminatorKind::Call { .. } => {} } } } diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index 272f6e9ce1937..b8ca823a985ba 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -19,21 +19,19 @@ //! (non-mutating) use of `SRC`. These restrictions are conservative and may be relaxed in the //! future. +use crate::transform::{MirPass, MirSource}; +use crate::util::def_use::DefUseAnalysis; +use rustc::mir::visit::MutVisitor; use rustc::mir::{ - Constant, Local, LocalKind, Location, Place, Body, BodyAndCache, Operand, Rvalue, - StatementKind, read_only + read_only, Body, BodyAndCache, Constant, Local, LocalKind, Location, Operand, Place, Rvalue, + StatementKind, }; -use rustc::mir::visit::MutVisitor; use rustc::ty::TyCtxt; -use crate::transform::{MirPass, MirSource}; -use crate::util::def_use::DefUseAnalysis; pub struct CopyPropagation; impl<'tcx> MirPass<'tcx> for CopyPropagation { - fn run_pass( - &self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx> - ) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { // We only run when the MIR optimization level is > 1. // This avoids a slow pass, and messing up debug info. if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 { @@ -59,26 +57,25 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation { let dest_use_info = def_use_analysis.local_info(dest_local); let dest_def_count = dest_use_info.def_count_not_including_drop(); if dest_def_count == 0 { - debug!(" Can't copy-propagate local: dest {:?} undefined", - dest_local); - continue + debug!(" Can't copy-propagate local: dest {:?} undefined", dest_local); + continue; } if dest_def_count > 1 { - debug!(" Can't copy-propagate local: dest {:?} defined {} times", - dest_local, - dest_use_info.def_count()); - continue + debug!( + " Can't copy-propagate local: dest {:?} defined {} times", + dest_local, + dest_use_info.def_count() + ); + continue; } if dest_use_info.use_count() == 0 { - debug!(" Can't copy-propagate local: dest {:?} unused", - dest_local); - continue + debug!(" Can't copy-propagate local: dest {:?} unused", dest_local); + continue; } // Conservatively gives up if the dest is an argument, // because there may be uses of the original argument value. if body.local_kind(dest_local) == LocalKind::Arg { - debug!(" Can't copy-propagate local: dest {:?} (argument)", - dest_local); + debug!(" Can't copy-propagate local: dest {:?} (argument)", dest_local); continue; } let dest_place_def = dest_use_info.defs_not_including_drop().next().unwrap(); @@ -90,22 +87,19 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation { Some(statement) => statement, None => { debug!(" Can't copy-propagate local: used in terminator"); - continue + continue; } }; // That use of the source must be an assignment. match &statement.kind { - StatementKind::Assign(box(place, Rvalue::Use(operand))) => { + StatementKind::Assign(box (place, Rvalue::Use(operand))) => { if let Some(local) = place.as_local() { if local == dest_local { let maybe_action = match operand { - Operand::Copy(ref src_place) | - Operand::Move(ref src_place) => { - Action::local_copy( - &body, - &def_use_analysis, - src_place) + Operand::Copy(ref src_place) + | Operand::Move(ref src_place) => { + Action::local_copy(&body, &def_use_analysis, src_place) } Operand::Constant(ref src_constant) => { Action::constant(src_constant) @@ -116,41 +110,44 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation { None => continue, } } else { - debug!(" Can't copy-propagate local: source use is not an \ - assignment"); - continue + debug!( + " Can't copy-propagate local: source use is not an \ + assignment" + ); + continue; } } else { - debug!(" Can't copy-propagate local: source use is not an \ - assignment"); - continue + debug!( + " Can't copy-propagate local: source use is not an \ + assignment" + ); + continue; } } _ => { - debug!(" Can't copy-propagate local: source use is not an \ - assignment"); - continue + debug!( + " Can't copy-propagate local: source use is not an \ + assignment" + ); + continue; } } } - changed = action.perform(body, &def_use_analysis, dest_local, location, tcx) - || changed; + changed = + action.perform(body, &def_use_analysis, dest_local, location, tcx) || changed; // FIXME(pcwalton): Update the use-def chains to delete the instructions instead of // regenerating the chains. - break + break; } if !changed { - break + break; } } } } -fn eliminate_self_assignments( - body: &mut Body<'_>, - def_use_analysis: &DefUseAnalysis, -) -> bool { +fn eliminate_self_assignments(body: &mut Body<'_>, def_use_analysis: &DefUseAnalysis) -> bool { let mut changed = false; for dest_local in body.local_decls.indices() { @@ -195,8 +192,11 @@ enum Action<'tcx> { } impl<'tcx> Action<'tcx> { - fn local_copy(body: &Body<'tcx>, def_use_analysis: &DefUseAnalysis, src_place: &Place<'tcx>) - -> Option> { + fn local_copy( + body: &Body<'tcx>, + def_use_analysis: &DefUseAnalysis, + src_place: &Place<'tcx>, + ) -> Option> { // The source must be a local. let src_local = if let Some(local) = src_place.as_local() { local @@ -211,11 +211,11 @@ impl<'tcx> Action<'tcx> { let src_use_count = src_use_info.use_count(); if src_use_count == 0 { debug!(" Can't copy-propagate local: no uses"); - return None + return None; } if src_use_count != 1 { debug!(" Can't copy-propagate local: {} uses", src_use_info.use_count()); - return None + return None; } // Verify that the source doesn't change in between. This is done conservatively for now, @@ -239,7 +239,7 @@ impl<'tcx> Action<'tcx> { src_def_count, if is_arg { " (argument)" } else { "" }, ); - return None + return None; } Some(Action::PropagateLocalCopy(src_local)) @@ -249,13 +249,14 @@ impl<'tcx> Action<'tcx> { Some(Action::PropagateConstant((*src_constant).clone())) } - fn perform(self, - body: &mut BodyAndCache<'tcx>, - def_use_analysis: &DefUseAnalysis, - dest_local: Local, - location: Location, - tcx: TyCtxt<'tcx>) - -> bool { + fn perform( + self, + body: &mut BodyAndCache<'tcx>, + def_use_analysis: &DefUseAnalysis, + dest_local: Local, + location: Location, + tcx: TyCtxt<'tcx>, + ) -> bool { match self { Action::PropagateLocalCopy(src_local) => { // Eliminate the destination and the assignment. @@ -263,9 +264,7 @@ impl<'tcx> Action<'tcx> { // First, remove all markers. // // FIXME(pcwalton): Don't do this. Merge live ranges instead. - debug!(" Replacing all uses of {:?} with {:?} (local)", - dest_local, - src_local); + debug!(" Replacing all uses of {:?} with {:?} (local)", dest_local, src_local); for place_use in &def_use_analysis.local_info(dest_local).defs_and_uses { if place_use.context.is_storage_marker() { body.make_statement_nop(place_use.location) @@ -278,8 +277,7 @@ impl<'tcx> Action<'tcx> { } // Replace all uses of the destination local with the source local. - def_use_analysis - .replace_all_defs_and_uses_with(dest_local, body, src_local, tcx); + def_use_analysis.replace_all_defs_and_uses_with(dest_local, body, src_local, tcx); // Finally, zap the now-useless assignment instruction. debug!(" Deleting assignment"); @@ -291,9 +289,10 @@ impl<'tcx> Action<'tcx> { // First, remove all markers. // // FIXME(pcwalton): Don't do this. Merge live ranges instead. - debug!(" Replacing all uses of {:?} with {:?} (constant)", - dest_local, - src_constant); + debug!( + " Replacing all uses of {:?} with {:?} (constant)", + dest_local, src_constant + ); let dest_local_info = def_use_analysis.local_info(dest_local); for place_use in &dest_local_info.defs_and_uses { if place_use.context.is_storage_marker() { @@ -302,9 +301,7 @@ impl<'tcx> Action<'tcx> { } // Replace all uses of the destination local with the constant. - let mut visitor = ConstantPropagationVisitor::new(dest_local, - src_constant, - tcx); + let mut visitor = ConstantPropagationVisitor::new(dest_local, src_constant, tcx); for dest_place_use in &dest_local_info.defs_and_uses { visitor.visit_location(body, dest_place_use.location) } @@ -314,18 +311,20 @@ impl<'tcx> Action<'tcx> { // must have places on their LHS. let use_count = dest_local_info.use_count(); if visitor.uses_replaced == use_count { - debug!(" {} of {} use(s) replaced; deleting assignment", - visitor.uses_replaced, - use_count); + debug!( + " {} of {} use(s) replaced; deleting assignment", + visitor.uses_replaced, use_count + ); body.make_statement_nop(location); true } else if visitor.uses_replaced == 0 { debug!(" No uses replaced; not deleting assignment"); false } else { - debug!(" {} of {} use(s) replaced; not deleting assignment", - visitor.uses_replaced, - use_count); + debug!( + " {} of {} use(s) replaced; not deleting assignment", + visitor.uses_replaced, use_count + ); true } } @@ -341,14 +340,12 @@ struct ConstantPropagationVisitor<'tcx> { } impl<'tcx> ConstantPropagationVisitor<'tcx> { - fn new(dest_local: Local, constant: Constant<'tcx>, tcx: TyCtxt<'tcx>) - -> ConstantPropagationVisitor<'tcx> { - ConstantPropagationVisitor { - dest_local, - constant, - tcx, - uses_replaced: 0, - } + fn new( + dest_local: Local, + constant: Constant<'tcx>, + tcx: TyCtxt<'tcx>, + ) -> ConstantPropagationVisitor<'tcx> { + ConstantPropagationVisitor { dest_local, constant, tcx, uses_replaced: 0 } } } @@ -361,8 +358,7 @@ impl<'tcx> MutVisitor<'tcx> for ConstantPropagationVisitor<'tcx> { self.super_operand(operand, location); match operand { - Operand::Copy(place) | - Operand::Move(place) => { + Operand::Copy(place) | Operand::Move(place) => { if let Some(local) = place.as_local() { if local == self.dest_local { } else { diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs index cd77c9c60fa5a..9f8964ee5a0c4 100644 --- a/src/librustc_mir/transform/deaggregator.rs +++ b/src/librustc_mir/transform/deaggregator.rs @@ -1,20 +1,18 @@ -use rustc::mir::*; -use rustc::ty::TyCtxt; use crate::transform::{MirPass, MirSource}; use crate::util::expand_aggregate; +use rustc::mir::*; +use rustc::ty::TyCtxt; pub struct Deaggregator; impl<'tcx> MirPass<'tcx> for Deaggregator { - fn run_pass( - &self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx> - ) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut(); let local_decls = &*local_decls; for bb in basic_blocks { bb.expand_statements(|stmt| { // FIXME(eddyb) don't match twice on `stmt.kind` (post-NLL). - if let StatementKind::Assign(box(_, ref rhs)) = stmt.kind { + if let StatementKind::Assign(box (_, ref rhs)) = stmt.kind { if let Rvalue::Aggregate(ref kind, _) = *rhs { // FIXME(#48193) Deaggregate arrays when it's cheaper to do so. if let AggregateKind::Array(_) = **kind { @@ -30,13 +28,11 @@ impl<'tcx> MirPass<'tcx> for Deaggregator { let stmt = stmt.replace_nop(); let source_info = stmt.source_info; let (lhs, kind, operands) = match stmt.kind { - StatementKind::Assign(box(lhs, rvalue)) => { - match rvalue { - Rvalue::Aggregate(kind, operands) => (lhs, kind, operands), - _ => bug!() - } - } - _ => bug!() + StatementKind::Assign(box (lhs, rvalue)) => match rvalue { + Rvalue::Aggregate(kind, operands) => (lhs, kind, operands), + _ => bug!(), + }, + _ => bug!(), }; Some(expand_aggregate( diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index 221ced3a71c4b..2cbda33ad2db1 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -5,11 +5,11 @@ use std::fmt; use std::fs::File; use std::io; +use crate::transform::{MirPass, MirSource}; +use crate::util as mir_util; use rustc::mir::{Body, BodyAndCache}; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::ty::TyCtxt; -use crate::transform::{MirPass, MirSource}; -use crate::util as mir_util; pub struct Marker(pub &'static str); @@ -19,12 +19,16 @@ impl<'tcx> MirPass<'tcx> for Marker { } fn run_pass( - &self, _tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, _body: &mut BodyAndCache<'tcx> - ) {} + &self, + _tcx: TyCtxt<'tcx>, + _source: MirSource<'tcx>, + _body: &mut BodyAndCache<'tcx>, + ) { + } } pub struct Disambiguator { - is_after: bool + is_after: bool, } impl fmt::Display for Disambiguator { @@ -43,13 +47,15 @@ pub fn on_mir_pass<'tcx>( is_after: bool, ) { if mir_util::dump_enabled(tcx, pass_name, source) { - mir_util::dump_mir(tcx, - Some(pass_num), - pass_name, - &Disambiguator { is_after }, - source, - body, - |_, _| Ok(()) ); + mir_util::dump_mir( + tcx, + Some(pass_num), + pass_name, + &Disambiguator { is_after }, + source, + body, + |_, _| Ok(()), + ); } } diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index 1cacf1f3b0a57..43c8628a161c7 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -1,18 +1,18 @@ -use crate::dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex, LookupResult}; -use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; -use crate::dataflow::{DataflowResults}; -use crate::dataflow::{on_all_children_bits, on_all_drop_children_bits}; -use crate::dataflow::{drop_flag_effects_for_location, on_lookup_result_bits}; +use crate::dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex}; +use crate::dataflow::DataflowResults; use crate::dataflow::MoveDataParamEnv; use crate::dataflow::{self, do_dataflow, DebugFormatted}; +use crate::dataflow::{drop_flag_effects_for_location, on_lookup_result_bits}; +use crate::dataflow::{on_all_children_bits, on_all_drop_children_bits}; +use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use crate::transform::{MirPass, MirSource}; +use crate::util::elaborate_drops::{elaborate_drop, DropFlagState, Unwind}; +use crate::util::elaborate_drops::{DropElaborator, DropFlagMode, DropStyle}; use crate::util::patch::MirPatch; -use crate::util::elaborate_drops::{DropFlagState, Unwind, elaborate_drop}; -use crate::util::elaborate_drops::{DropElaborator, DropStyle, DropFlagMode}; -use rustc::ty::{self, TyCtxt}; -use rustc::ty::layout::VariantIdx; use rustc::hir; use rustc::mir::*; +use rustc::ty::layout::VariantIdx; +use rustc::ty::{self, TyCtxt}; use rustc::util::nodemap::FxHashMap; use rustc_index::bit_set::BitSet; use std::fmt; @@ -32,19 +32,26 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { }; let elaborate_patch = { let body = &*body; - let env = MoveDataParamEnv { - move_data, - param_env, - }; + let env = MoveDataParamEnv { move_data, param_env }; let dead_unwinds = find_dead_unwinds(tcx, body, def_id, &env); - let flow_inits = - do_dataflow(tcx, body, def_id, &[], &dead_unwinds, - MaybeInitializedPlaces::new(tcx, body, &env), - |bd, p| DebugFormatted::new(&bd.move_data().move_paths[p])); - let flow_uninits = - do_dataflow(tcx, body, def_id, &[], &dead_unwinds, - MaybeUninitializedPlaces::new(tcx, body, &env), - |bd, p| DebugFormatted::new(&bd.move_data().move_paths[p])); + let flow_inits = do_dataflow( + tcx, + body, + def_id, + &[], + &dead_unwinds, + MaybeInitializedPlaces::new(tcx, body, &env), + |bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]), + ); + let flow_uninits = do_dataflow( + tcx, + body, + def_id, + &[], + &dead_unwinds, + MaybeUninitializedPlaces::new(tcx, body, &env), + |bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]), + ); ElaborateDropsCtxt { tcx, @@ -54,7 +61,8 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { flow_uninits, drop_flags: Default::default(), patch: MirPatch::new(body), - }.elaborate() + } + .elaborate() }; elaborate_patch.apply(body); } @@ -73,14 +81,19 @@ fn find_dead_unwinds<'tcx>( // We only need to do this pass once, because unwind edges can only // reach cleanup blocks, which can't have unwind edges themselves. let mut dead_unwinds = BitSet::new_empty(body.basic_blocks().len()); - let flow_inits = - do_dataflow(tcx, body, def_id, &[], &dead_unwinds, - MaybeInitializedPlaces::new(tcx, body, &env), - |bd, p| DebugFormatted::new(&bd.move_data().move_paths[p])); + let flow_inits = do_dataflow( + tcx, + body, + def_id, + &[], + &dead_unwinds, + MaybeInitializedPlaces::new(tcx, body, &env), + |bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]), + ); for (bb, bb_data) in body.basic_blocks().iter_enumerated() { let location = match bb_data.terminator().kind { - TerminatorKind::Drop { ref location, unwind: Some(_), .. } | - TerminatorKind::DropAndReplace { ref location, unwind: Some(_), .. } => location, + TerminatorKind::Drop { ref location, unwind: Some(_), .. } + | TerminatorKind::DropAndReplace { ref location, unwind: Some(_), .. } => location, _ => continue, }; @@ -88,8 +101,7 @@ fn find_dead_unwinds<'tcx>( live: flow_inits.sets().entry_set_for(bb.index()).to_owned(), dead: BitSet::new_empty(env.move_data.move_paths.len()), }; - debug!("find_dead_unwinds @ {:?}: {:?}; init_data={:?}", - bb, bb_data, init_data.live); + debug!("find_dead_unwinds @ {:?}: {:?}; init_data={:?}", bb, bb_data, init_data.live); for stmt in 0..bb_data.statements.len() { let loc = Location { block: bb, statement_index: stmt }; init_data.apply_location(tcx, body, env, loc); @@ -99,7 +111,7 @@ fn find_dead_unwinds<'tcx>( LookupResult::Exact(e) => e, LookupResult::Parent(..) => { debug!("find_dead_unwinds: has parent; skipping"); - continue + continue; } }; @@ -122,7 +134,7 @@ fn find_dead_unwinds<'tcx>( struct InitializationData { live: BitSet, - dead: BitSet + dead: BitSet, } impl InitializationData { @@ -134,8 +146,7 @@ impl InitializationData { loc: Location, ) { drop_flag_effects_for_location(tcx, body, env, loc, |path, df| { - debug!("at location {:?}: setting {:?} to {:?}", - loc, path, df); + debug!("at location {:?}: setting {:?} to {:?}", loc, path, df); match df { DropFlagState::Present => { self.live.insert(path); @@ -191,15 +202,13 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> { let mut some_live = false; let mut some_dead = false; let mut children_count = 0; - on_all_drop_children_bits( - self.tcx(), self.body(), self.ctxt.env, path, |child| { - let (live, dead) = self.init_data.state(child); - debug!("elaborate_drop: state({:?}) = {:?}", - child, (live, dead)); - some_live |= live; - some_dead |= dead; - children_count += 1; - }); + on_all_drop_children_bits(self.tcx(), self.body(), self.ctxt.env, path, |child| { + let (live, dead) = self.init_data.state(child); + debug!("elaborate_drop: state({:?}) = {:?}", child, (live, dead)); + some_live |= live; + some_dead |= dead; + children_count += 1; + }); ((some_live, some_dead), children_count != 1) } }; @@ -218,9 +227,12 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> { } DropFlagMode::Deep => { on_all_children_bits( - self.tcx(), self.body(), self.ctxt.move_data(), path, - |child| self.ctxt.set_drop_flag(loc, child, DropFlagState::Absent) - ); + self.tcx(), + self.body(), + self.ctxt.move_data(), + path, + |child| self.ctxt.set_drop_flag(loc, child, DropFlagState::Absent), + ); } } } @@ -252,7 +264,7 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> { fn downcast_subpath(&self, path: Self::Path, variant: VariantIdx) -> Option { dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e { ProjectionElem::Downcast(_, idx) => *idx == variant, - _ => false + _ => false, }) } @@ -272,7 +284,9 @@ struct ElaborateDropsCtxt<'a, 'tcx> { } impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { - fn move_data(&self) -> &'b MoveData<'tcx> { &self.env.move_data } + fn move_data(&self) -> &'b MoveData<'tcx> { + &self.env.move_data + } fn param_env(&self) -> ty::ParamEnv<'tcx> { self.env.param_env @@ -280,14 +294,16 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { fn initialization_data_at(&self, loc: Location) -> InitializationData { let mut data = InitializationData { - live: self.flow_inits.sets().entry_set_for(loc.block.index()) - .to_owned(), - dead: self.flow_uninits.sets().entry_set_for(loc.block.index()) - .to_owned(), + live: self.flow_inits.sets().entry_set_for(loc.block.index()).to_owned(), + dead: self.flow_uninits.sets().entry_set_for(loc.block.index()).to_owned(), }; for stmt in 0..loc.statement_index { - data.apply_location(self.tcx, self.body, self.env, - Location { block: loc.block, statement_index: stmt }); + data.apply_location( + self.tcx, + self.body, + self.env, + Location { block: loc.block, statement_index: stmt }, + ); } data } @@ -296,9 +312,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { let tcx = self.tcx; let patch = &mut self.patch; debug!("create_drop_flag({:?})", self.body.span); - self.drop_flags.entry(index).or_insert_with(|| { - patch.new_internal(tcx.types.bool, span) - }); + self.drop_flags.entry(index).or_insert_with(|| patch.new_internal(tcx.types.bool, span)); } fn drop_flag(&mut self, index: MovePathIndex) -> Option> { @@ -307,8 +321,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { /// create a patch that elaborates all drops in the input /// MIR. - fn elaborate(mut self) -> MirPatch<'tcx> - { + fn elaborate(mut self) -> MirPatch<'tcx> { self.collect_drop_flags(); self.elaborate_drops(); @@ -321,24 +334,22 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { self.patch } - fn collect_drop_flags(&mut self) - { + fn collect_drop_flags(&mut self) { for (bb, data) in self.body.basic_blocks().iter_enumerated() { let terminator = data.terminator(); let location = match terminator.kind { - TerminatorKind::Drop { ref location, .. } | - TerminatorKind::DropAndReplace { ref location, .. } => location, - _ => continue + TerminatorKind::Drop { ref location, .. } + | TerminatorKind::DropAndReplace { ref location, .. } => location, + _ => continue, }; let init_data = self.initialization_data_at(Location { block: bb, - statement_index: data.statements.len() + statement_index: data.statements.len(), }); let path = self.move_data().rev_lookup.find(location.as_ref()); - debug!("collect_drop_flags: {:?}, place {:?} ({:?})", - bb, location, path); + debug!("collect_drop_flags: {:?}, place {:?} ({:?})", bb, location, path); let path = match path { LookupResult::Exact(e) => e, @@ -346,18 +357,27 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { LookupResult::Parent(Some(parent)) => { let (_maybe_live, maybe_dead) = init_data.state(parent); if maybe_dead { - span_bug!(terminator.source_info.span, - "drop of untracked, uninitialized value {:?}, place {:?} ({:?})", - bb, location, path); + span_bug!( + terminator.source_info.span, + "drop of untracked, uninitialized value {:?}, place {:?} ({:?})", + bb, + location, + path + ); } - continue + continue; } }; on_all_drop_children_bits(self.tcx, self.body, self.env, path, |child| { let (maybe_live, maybe_dead) = init_data.state(child); - debug!("collect_drop_flags: collecting {:?} from {:?}@{:?} - {:?}", - child, location, path, (maybe_live, maybe_dead)); + debug!( + "collect_drop_flags: collecting {:?} from {:?}@{:?} - {:?}", + child, + location, + path, + (maybe_live, maybe_dead) + ); if maybe_live && maybe_dead { self.create_drop_flag(child, terminator.source_info.span) } @@ -365,8 +385,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } } - fn elaborate_drops(&mut self) - { + fn elaborate_drops(&mut self) { for (bb, data) in self.body.basic_blocks().iter_enumerated() { let loc = Location { block: bb, statement_index: data.statements.len() }; let terminator = data.terminator(); @@ -376,41 +395,34 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { TerminatorKind::Drop { ref location, target, unwind } => { let init_data = self.initialization_data_at(loc); match self.move_data().rev_lookup.find(location.as_ref()) { - LookupResult::Exact(path) => { - elaborate_drop( - &mut Elaborator { - init_data: &init_data, - ctxt: self - }, - terminator.source_info, - location, - path, - target, - if data.is_cleanup { - Unwind::InCleanup - } else { - Unwind::To(Option::unwrap_or(unwind, resume_block)) - }, - bb) - } + LookupResult::Exact(path) => elaborate_drop( + &mut Elaborator { init_data: &init_data, ctxt: self }, + terminator.source_info, + location, + path, + target, + if data.is_cleanup { + Unwind::InCleanup + } else { + Unwind::To(Option::unwrap_or(unwind, resume_block)) + }, + bb, + ), LookupResult::Parent(..) => { - span_bug!(terminator.source_info.span, - "drop of untracked value {:?}", bb); + span_bug!( + terminator.source_info.span, + "drop of untracked value {:?}", + bb + ); } } } - TerminatorKind::DropAndReplace { ref location, ref value, - target, unwind } => - { + TerminatorKind::DropAndReplace { ref location, ref value, target, unwind } => { assert!(!data.is_cleanup); - self.elaborate_replace( - loc, - location, value, - target, unwind - ); + self.elaborate_replace(loc, location, value, target, unwind); } - _ => continue + _ => continue, } } } @@ -433,16 +445,16 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { location: &Place<'tcx>, value: &Operand<'tcx>, target: BasicBlock, - unwind: Option) - { + unwind: Option, + ) { let bb = loc.block; let data = &self.body[bb]; let terminator = data.terminator(); assert!(!data.is_cleanup, "DropAndReplace in unwind path not supported"); let assign = Statement { - kind: StatementKind::Assign(box(location.clone(), Rvalue::Use(value.clone()))), - source_info: terminator.source_info + kind: StatementKind::Assign(box (location.clone(), Rvalue::Use(value.clone()))), + source_info: terminator.source_info, }; let unwind = unwind.unwrap_or_else(|| self.patch.resume_block()); @@ -452,15 +464,12 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { kind: TerminatorKind::Goto { target: unwind }, ..*terminator }), - is_cleanup: true + is_cleanup: true, }); let target = self.patch.new_block(BasicBlockData { statements: vec![assign], - terminator: Some(Terminator { - kind: TerminatorKind::Goto { target }, - ..*terminator - }), + terminator: Some(Terminator { kind: TerminatorKind::Goto { target }, ..*terminator }), is_cleanup: false, }); @@ -470,32 +479,39 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { let init_data = self.initialization_data_at(loc); elaborate_drop( - &mut Elaborator { - init_data: &init_data, - ctxt: self - }, + &mut Elaborator { init_data: &init_data, ctxt: self }, terminator.source_info, location, path, target, Unwind::To(unwind), - bb); + bb, + ); on_all_children_bits(self.tcx, self.body, self.move_data(), path, |child| { - self.set_drop_flag(Location { block: target, statement_index: 0 }, - child, DropFlagState::Present); - self.set_drop_flag(Location { block: unwind, statement_index: 0 }, - child, DropFlagState::Present); + self.set_drop_flag( + Location { block: target, statement_index: 0 }, + child, + DropFlagState::Present, + ); + self.set_drop_flag( + Location { block: unwind, statement_index: 0 }, + child, + DropFlagState::Present, + ); }); } LookupResult::Parent(parent) => { // drop and replace behind a pointer/array/whatever. The location // must be initialized. debug!("elaborate_drop_and_replace({:?}) - untracked {:?}", terminator, parent); - self.patch.patch_terminator(bb, TerminatorKind::Drop { - location: location.clone(), - target, - unwind: Some(unwind) - }); + self.patch.patch_terminator( + bb, + TerminatorKind::Drop { + location: location.clone(), + target, + unwind: Some(unwind), + }, + ); } } } @@ -528,27 +544,27 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { fn drop_flags_for_fn_rets(&mut self) { for (bb, data) in self.body.basic_blocks().iter_enumerated() { if let TerminatorKind::Call { - destination: Some((ref place, tgt)), cleanup: Some(_), .. - } = data.terminator().kind { + destination: Some((ref place, tgt)), + cleanup: Some(_), + .. + } = data.terminator().kind + { assert!(!self.patch.is_patched(bb)); let loc = Location { block: tgt, statement_index: 0 }; let path = self.move_data().rev_lookup.find(place.as_ref()); - on_lookup_result_bits( - self.tcx, self.body, self.move_data(), path, - |child| self.set_drop_flag(loc, child, DropFlagState::Present) - ); + on_lookup_result_bits(self.tcx, self.body, self.move_data(), path, |child| { + self.set_drop_flag(loc, child, DropFlagState::Present) + }); } } } fn drop_flags_for_args(&mut self) { let loc = Location::START; - dataflow::drop_flag_effects_for_function_entry( - self.tcx, self.body, self.env, |path, ds| { - self.set_drop_flag(loc, path, ds); - } - ) + dataflow::drop_flag_effects_for_function_entry(self.tcx, self.body, self.env, |path, ds| { + self.set_drop_flag(loc, path, ds); + }) } fn drop_flags_for_locs(&mut self) { @@ -560,14 +576,14 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { for (bb, data) in self.body.basic_blocks().iter_enumerated() { debug!("drop_flags_for_locs({:?})", data); - for i in 0..(data.statements.len()+1) { + for i in 0..(data.statements.len() + 1) { debug!("drop_flag_for_locs: stmt {}", i); let mut allow_initializations = true; if i == data.statements.len() { match data.terminator().kind { TerminatorKind::Drop { .. } => { // drop elaboration should handle that by itself - continue + continue; } TerminatorKind::DropAndReplace { .. } => { // this contains the move of the source and @@ -590,11 +606,15 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } let loc = Location { block: bb, statement_index: i }; dataflow::drop_flag_effects_for_location( - self.tcx, self.body, self.env, loc, |path, ds| { + self.tcx, + self.body, + self.env, + loc, + |path, ds| { if ds == DropFlagState::Absent || allow_initializations { self.set_drop_flag(loc, path, ds) } - } + }, ) } @@ -603,15 +623,15 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { // call. if let TerminatorKind::Call { destination: Some((ref place, _)), cleanup: None, .. - } = data.terminator().kind { + } = data.terminator().kind + { assert!(!self.patch.is_patched(bb)); let loc = Location { block: bb, statement_index: data.statements.len() }; let path = self.move_data().rev_lookup.find(place.as_ref()); - on_lookup_result_bits( - self.tcx, self.body, self.move_data(), path, - |child| self.set_drop_flag(loc, child, DropFlagState::Present) - ); + on_lookup_result_bits(self.tcx, self.body, self.move_data(), path, |child| { + self.set_drop_flag(loc, child, DropFlagState::Present) + }); } } } diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index 1eef3f254f053..996b97c03b14e 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -4,11 +4,11 @@ //! N.B., we do _not_ erase regions of statements that are relevant for //! "types-as-contracts"-validation, namely, `AcquireValid` and `ReleaseValid`. +use crate::transform::{MirPass, MirSource}; +use rustc::mir::visit::{MutVisitor, TyContext}; +use rustc::mir::*; use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::mir::*; -use rustc::mir::visit::{MutVisitor, TyContext}; -use crate::transform::{MirPass, MirSource}; struct EraseRegionsVisitor<'tcx> { tcx: TyCtxt<'tcx>, @@ -16,9 +16,7 @@ struct EraseRegionsVisitor<'tcx> { impl EraseRegionsVisitor<'tcx> { pub fn new(tcx: TyCtxt<'tcx>) -> Self { - EraseRegionsVisitor { - tcx, - } + EraseRegionsVisitor { tcx } } } @@ -43,10 +41,7 @@ impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> { *substs = self.tcx.erase_regions(substs); } - fn process_projection_elem( - &mut self, - elem: &PlaceElem<'tcx>, - ) -> Option> { + fn process_projection_elem(&mut self, elem: &PlaceElem<'tcx>) -> Option> { if let PlaceElem::Field(field, ty) = elem { let new_ty = self.tcx.erase_regions(ty); diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index b314ff83abe6a..fc4f8031960b7 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -49,27 +49,27 @@ //! For generators with state 1 (returned) and state 2 (poisoned) it does nothing. //! Otherwise it drops all the values in scope at the last suspension point. +use crate::dataflow::{do_dataflow, DataflowResultsCursor, DebugFormatted}; +use crate::dataflow::{DataflowResults, DataflowResultsConsumer, FlowAtLocation}; +use crate::dataflow::{HaveBeenBorrowedLocals, MaybeStorageLive, RequiresStorage}; +use crate::transform::no_landing_pads::no_landing_pads; +use crate::transform::simplify; +use crate::transform::{MirPass, MirSource}; +use crate::util::dump_mir; +use crate::util::liveness; use rustc::hir; use rustc::hir::def_id::DefId; +use rustc::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc::mir::*; -use rustc::mir::visit::{PlaceContext, Visitor, MutVisitor}; -use rustc::ty::{self, TyCtxt, AdtDef, Ty}; -use rustc::ty::GeneratorSubsts; use rustc::ty::layout::VariantIdx; use rustc::ty::subst::SubstsRef; +use rustc::ty::GeneratorSubsts; +use rustc::ty::{self, AdtDef, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; +use rustc_index::bit_set::{BitMatrix, BitSet}; use rustc_index::vec::{Idx, IndexVec}; -use rustc_index::bit_set::{BitSet, BitMatrix}; use std::borrow::Cow; use std::iter; -use crate::transform::{MirPass, MirSource}; -use crate::transform::simplify; -use crate::transform::no_landing_pads::no_landing_pads; -use crate::dataflow::{DataflowResults, DataflowResultsConsumer, FlowAtLocation}; -use crate::dataflow::{do_dataflow, DebugFormatted, DataflowResultsCursor}; -use crate::dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals, RequiresStorage}; -use crate::util::dump_mir; -use crate::util::liveness; pub struct StateTransform; @@ -84,23 +84,15 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor<'tcx> { self.tcx } - fn visit_local(&mut self, - local: &mut Local, - _: PlaceContext, - _: Location) { + fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) { if *local == self.from { *local = self.to; } } - fn process_projection_elem( - &mut self, - elem: &PlaceElem<'tcx>, - ) -> Option> { + fn process_projection_elem(&mut self, elem: &PlaceElem<'tcx>) -> Option> { match elem { - PlaceElem::Index(local) if *local == self.from => { - Some(PlaceElem::Index(self.to)) - } + PlaceElem::Index(local) if *local == self.from => Some(PlaceElem::Index(self.to)), _ => None, } } @@ -115,22 +107,20 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> { self.tcx } - fn visit_local(&mut self, - local: &mut Local, - _: PlaceContext, - _: Location) { + fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) { assert_ne!(*local, self_arg()); } - fn visit_place(&mut self, - place: &mut Place<'tcx>, - context: PlaceContext, - location: Location) { + fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { if place.base == PlaceBase::Local(self_arg()) { - replace_base(place, Place { - base: PlaceBase::Local(self_arg()), - projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Deref]), - }, self.tcx); + replace_base( + place, + Place { + base: PlaceBase::Local(self_arg()), + projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Deref]), + }, + self.tcx, + ); } else { self.visit_place_base(&mut place.base, context, location); @@ -153,10 +143,7 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { self.tcx } - fn visit_local(&mut self, - local: &mut Local, - _: PlaceContext, - _: Location) { + fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) { assert_ne!(*local, self_arg()); } @@ -167,8 +154,8 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { Place { base: PlaceBase::Local(self_arg()), projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Field( - Field::new(0), - self.ref_gen_ty, + Field::new(0), + self.ref_gen_ty, )]), }, self.tcx, @@ -249,10 +236,7 @@ impl TransformVisitor<'tcx> { let mut projection = base.projection.to_vec(); projection.push(ProjectionElem::Field(Field::new(idx), ty)); - Place { - base: base.base, - projection: self.tcx.intern_place_elems(&projection), - } + Place { base: base.base, projection: self.tcx.intern_place_elems(&projection) } } // Create a statement which changes the discriminant @@ -276,7 +260,7 @@ impl TransformVisitor<'tcx> { let self_place = Place::from(self_arg()); let assign = Statement { source_info: source_info(body), - kind: StatementKind::Assign(box(temp.clone(), Rvalue::Discriminant(self_place))), + kind: StatementKind::Assign(box (temp.clone(), Rvalue::Discriminant(self_place))), }; (assign, temp) } @@ -287,19 +271,11 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> { self.tcx } - fn visit_local(&mut self, - local: &mut Local, - _: PlaceContext, - _: Location) { + fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) { assert_eq!(self.remap.get(local), None); } - fn visit_place( - &mut self, - place: &mut Place<'tcx>, - context: PlaceContext, - location: Location, - ) { + fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { if let PlaceBase::Local(l) = place.base { // Replace an Local in the remap with a generator struct access if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) { @@ -316,29 +292,26 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> { } } - fn visit_basic_block_data(&mut self, - block: BasicBlock, - data: &mut BasicBlockData<'tcx>) { + fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) { // Remove StorageLive and StorageDead statements for remapped locals - data.retain_statements(|s| { - match s.kind { - StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => { - !self.remap.contains_key(&l) - } - _ => true + data.retain_statements(|s| match s.kind { + StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => { + !self.remap.contains_key(&l) } + _ => true, }); let ret_val = match data.terminator().kind { - TerminatorKind::Return => Some((VariantIdx::new(1), + TerminatorKind::Return => Some(( + VariantIdx::new(1), None, Operand::Move(Place::from(self.new_ret_local)), - None)), - TerminatorKind::Yield { ref value, resume, drop } => Some((VariantIdx::new(0), - Some(resume), - value.clone(), - drop)), - _ => None + None, + )), + TerminatorKind::Yield { ref value, resume, drop } => { + Some((VariantIdx::new(0), Some(resume), value.clone(), drop)) + } + _ => None, }; if let Some((state_idx, resume, v, drop)) = ret_val { @@ -346,14 +319,13 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> { // We must assign the value first in case it gets declared dead below data.statements.push(Statement { source_info, - kind: StatementKind::Assign( - box( - Place::return_place(), - self.make_state(state_idx, v) - ) - ), + kind: StatementKind::Assign(box ( + Place::return_place(), + self.make_state(state_idx, v), + )), }); - let state = if let Some(resume) = resume { // Yield + let state = if let Some(resume) = resume { + // Yield let state = 3 + self.suspension_points.len(); self.suspension_points.push(SuspensionPoint { @@ -364,7 +336,8 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> { }); VariantIdx::new(state) - } else { // Return + } else { + // Return VariantIdx::new(RETURNED) // state for returned }; data.statements.push(self.set_discr(state, source_info)); @@ -382,17 +355,11 @@ fn make_generator_state_argument_indirect<'tcx>( ) { let gen_ty = body.local_decls.raw[1].ty; - let region = ty::ReFree(ty::FreeRegion { - scope: def_id, - bound_region: ty::BoundRegion::BrEnv, - }); + let region = ty::ReFree(ty::FreeRegion { scope: def_id, bound_region: ty::BoundRegion::BrEnv }); let region = tcx.mk_region(region); - let ref_gen_ty = tcx.mk_ref(region, ty::TypeAndMut { - ty: gen_ty, - mutbl: hir::Mutability::Mut - }); + let ref_gen_ty = tcx.mk_ref(region, ty::TypeAndMut { ty: gen_ty, mutbl: hir::Mutability::Mut }); // Replace the by value generator argument body.local_decls.raw[1].ty = ref_gen_ty; @@ -429,17 +396,13 @@ fn replace_result_variable<'tcx>( source_info, internal: false, is_block_tail: None, - local_info: LocalInfo::Other + local_info: LocalInfo::Other, }; let new_ret_local = Local::new(body.local_decls.len()); body.local_decls.push(new_ret); body.local_decls.swap(RETURN_PLACE, new_ret_local); - RenameLocalVisitor { - from: RETURN_PLACE, - to: new_ret_local, - tcx, - }.visit_body(body); + RenameLocalVisitor { from: RETURN_PLACE, to: new_ret_local, tcx }.visit_body(body); new_ret_local } @@ -447,12 +410,11 @@ fn replace_result_variable<'tcx>( struct StorageIgnored(liveness::LiveVarSet); impl<'tcx> Visitor<'tcx> for StorageIgnored { - fn visit_statement(&mut self, - statement: &Statement<'tcx>, - _location: Location) { + fn visit_statement(&mut self, statement: &Statement<'tcx>, _location: Location) { match statement.kind { - StatementKind::StorageLive(l) | - StatementKind::StorageDead(l) => { self.0.remove(l); } + StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => { + self.0.remove(l); + } _ => (), } } @@ -493,8 +455,9 @@ fn locals_live_across_suspend_points( // lifetimes. let storage_live_analysis = MaybeStorageLive::new(body_ref); let storage_live_results = - do_dataflow(tcx, body_ref, def_id, &[], &dead_unwinds, storage_live_analysis, - |bd, p| DebugFormatted::new(&bd.body().local_decls[p])); + do_dataflow(tcx, body_ref, def_id, &[], &dead_unwinds, storage_live_analysis, |bd, p| { + DebugFormatted::new(&bd.body().local_decls[p]) + }); let mut storage_live_cursor = DataflowResultsCursor::new(&storage_live_results, body_ref); // Find the MIR locals which do not use StorageLive/StorageDead statements. @@ -505,42 +468,43 @@ fn locals_live_across_suspend_points( // Calculate the MIR locals which have been previously // borrowed (even if they are still active). let borrowed_locals_analysis = HaveBeenBorrowedLocals::new(body_ref); - let borrowed_locals_results = - do_dataflow(tcx, body_ref, def_id, &[], &dead_unwinds, borrowed_locals_analysis, - |bd, p| DebugFormatted::new(&bd.body().local_decls[p])); + let borrowed_locals_results = do_dataflow( + tcx, + body_ref, + def_id, + &[], + &dead_unwinds, + borrowed_locals_analysis, + |bd, p| DebugFormatted::new(&bd.body().local_decls[p]), + ); let mut borrowed_locals_cursor = DataflowResultsCursor::new(&borrowed_locals_results, body_ref); // Calculate the MIR locals that we actually need to keep storage around // for. let requires_storage_analysis = RequiresStorage::new(body, &borrowed_locals_results); - let requires_storage_results = - do_dataflow(tcx, body_ref, def_id, &[], &dead_unwinds, requires_storage_analysis, - |bd, p| DebugFormatted::new(&bd.body().local_decls[p])); - let mut requires_storage_cursor - = DataflowResultsCursor::new(&requires_storage_results, body_ref); - - // Calculate the liveness of MIR locals ignoring borrows. - let mut live_locals = liveness::LiveVarSet::new_empty(body.local_decls.len()); - let mut liveness = liveness::liveness_of_locals( - body, - ); - liveness::dump_mir( + let requires_storage_results = do_dataflow( tcx, - "generator_liveness", - source, body_ref, - &liveness, + def_id, + &[], + &dead_unwinds, + requires_storage_analysis, + |bd, p| DebugFormatted::new(&bd.body().local_decls[p]), ); + let mut requires_storage_cursor = + DataflowResultsCursor::new(&requires_storage_results, body_ref); + + // Calculate the liveness of MIR locals ignoring borrows. + let mut live_locals = liveness::LiveVarSet::new_empty(body.local_decls.len()); + let mut liveness = liveness::liveness_of_locals(body); + liveness::dump_mir(tcx, "generator_liveness", source, body_ref, &liveness); let mut storage_liveness_map = FxHashMap::default(); let mut live_locals_at_suspension_points = Vec::new(); for (block, data) in body.basic_blocks().iter_enumerated() { if let TerminatorKind::Yield { .. } = data.terminator().kind { - let loc = Location { - block: block, - statement_index: data.statements.len(), - }; + let loc = Location { block: block, statement_index: data.statements.len() }; if !movable { // The `liveness` variable contains the liveness of MIR locals ignoring borrows. @@ -594,11 +558,8 @@ fn locals_live_across_suspend_points( .map(|live_here| renumber_bitset(&live_here, &live_locals)) .collect(); - let storage_conflicts = compute_storage_conflicts( - body_ref, - &live_locals, - &ignored, - requires_storage_results); + let storage_conflicts = + compute_storage_conflicts(body_ref, &live_locals, &ignored, requires_storage_results); LivenessInfo { live_locals, @@ -613,8 +574,10 @@ fn locals_live_across_suspend_points( /// /// For example, if `stored_locals = [1, 3, 5]`, this would be renumbered to /// `[0, 1, 2]`. Thus, if `input = [3, 5]` we would return `[1, 2]`. -fn renumber_bitset(input: &BitSet, stored_locals: &liveness::LiveVarSet) --> BitSet { +fn renumber_bitset( + input: &BitSet, + stored_locals: &liveness::LiveVarSet, +) -> BitSet { assert!(stored_locals.superset(&input), "{:?} not a superset of {:?}", stored_locals, input); let mut out = BitSet::new_empty(stored_locals.count()); for (idx, local) in stored_locals.iter().enumerate() { @@ -700,32 +663,36 @@ impl<'body, 'tcx, 's> DataflowResultsConsumer<'body, 'tcx> self.body } - fn visit_block_entry(&mut self, - block: BasicBlock, - flow_state: &Self::FlowState) { + fn visit_block_entry(&mut self, block: BasicBlock, flow_state: &Self::FlowState) { // statement_index is only used for logging, so this is fine. self.apply_state(flow_state, Location { block, statement_index: 0 }); } - fn visit_statement_entry(&mut self, - loc: Location, - _stmt: &Statement<'tcx>, - flow_state: &Self::FlowState) { + fn visit_statement_entry( + &mut self, + loc: Location, + _stmt: &Statement<'tcx>, + flow_state: &Self::FlowState, + ) { self.apply_state(flow_state, loc); } - fn visit_terminator_entry(&mut self, - loc: Location, - _term: &Terminator<'tcx>, - flow_state: &Self::FlowState) { + fn visit_terminator_entry( + &mut self, + loc: Location, + _term: &Terminator<'tcx>, + flow_state: &Self::FlowState, + ) { self.apply_state(flow_state, loc); } } impl<'body, 'tcx, 's> StorageConflictVisitor<'body, 'tcx, 's> { - fn apply_state(&mut self, - flow_state: &FlowAtLocation<'tcx, RequiresStorage<'body, 'tcx>>, - loc: Location) { + fn apply_state( + &mut self, + flow_state: &FlowAtLocation<'tcx, RequiresStorage<'body, 'tcx>>, + loc: Location, + ) { // Ignore unreachable blocks. match self.body.basic_blocks()[loc.block].terminator().kind { TerminatorKind::Unreachable => return, @@ -759,7 +726,10 @@ fn compute_layout<'tcx>( ) { // Use a liveness analysis to compute locals which are live across a suspension point let LivenessInfo { - live_locals, live_locals_at_suspension_points, storage_conflicts, storage_liveness + live_locals, + live_locals_at_suspension_points, + storage_conflicts, + storage_liveness, } = locals_live_across_suspend_points(tcx, read_only!(body), source, movable); // Erase regions from the types passed in from typeck so we can compare them with @@ -779,11 +749,13 @@ fn compute_layout<'tcx>( // Sanity check that typeck knows about the type of locals which are // live across a suspension point if !allowed.contains(&decl.ty) && !allowed_upvars.contains(&decl.ty) { - span_bug!(body.span, - "Broken MIR: generator contains type {} in MIR, \ + span_bug!( + body.span, + "Broken MIR: generator contains type {} in MIR, \ but typeck only knows about {}", - decl.ty, - interior); + decl.ty, + interior + ); } } @@ -820,11 +792,7 @@ fn compute_layout<'tcx>( debug!("generator variant_fields = {:?}", variant_fields); debug!("generator storage_conflicts = {:#?}", storage_conflicts); - let layout = GeneratorLayout { - field_tys: tys, - variant_fields, - storage_conflicts, - }; + let layout = GeneratorLayout { field_tys: tys, variant_fields, storage_conflicts }; (remap, layout, storage_liveness) } @@ -845,14 +813,14 @@ fn insert_switch<'tcx>( }; let source_info = source_info(body); - body.basic_blocks_mut().raw.insert(0, BasicBlockData { - statements: vec![assign], - terminator: Some(Terminator { - source_info, - kind: switch, - }), - is_cleanup: false, - }); + body.basic_blocks_mut().raw.insert( + 0, + BasicBlockData { + statements: vec![assign], + terminator: Some(Terminator { source_info, kind: switch }), + is_cleanup: false, + }, + ); let blocks = body.basic_blocks_mut().iter_mut(); @@ -862,11 +830,13 @@ fn insert_switch<'tcx>( } fn elaborate_generator_drops<'tcx>( - tcx: TyCtxt<'tcx>, def_id: DefId, body: &mut BodyAndCache<'tcx> + tcx: TyCtxt<'tcx>, + def_id: DefId, + body: &mut BodyAndCache<'tcx>, ) { + use crate::shim::DropShimElaborator; use crate::util::elaborate_drops::{elaborate_drop, Unwind}; use crate::util::patch::MirPatch; - use crate::shim::DropShimElaborator; // Note that `elaborate_drops` only drops the upvars of a generator, and // this is ok because `open_drop` can only be reached within that own @@ -875,23 +845,11 @@ fn elaborate_generator_drops<'tcx>( let param_env = tcx.param_env(def_id); let gen = self_arg(); - let mut elaborator = DropShimElaborator { - body, - patch: MirPatch::new(body), - tcx, - param_env - }; + let mut elaborator = DropShimElaborator { body, patch: MirPatch::new(body), tcx, param_env }; for (block, block_data) in body.basic_blocks().iter_enumerated() { let (target, unwind, source_info) = match block_data.terminator() { - Terminator { - source_info, - kind: TerminatorKind::Drop { - location, - target, - unwind - } - } => { + Terminator { source_info, kind: TerminatorKind::Drop { location, target, unwind } } => { if let Some(local) = location.as_local() { if local == gen { (target, unwind, source_info) @@ -959,7 +917,7 @@ fn create_generator_drop_shim<'tcx>( source_info, internal: false, is_block_tail: None, - local_info: LocalInfo::Other + local_info: LocalInfo::Other, }; make_generator_state_argument_indirect(tcx, def_id, &mut body); @@ -967,22 +925,22 @@ fn create_generator_drop_shim<'tcx>( // Change the generator argument from &mut to *mut body.local_decls[self_arg()] = LocalDecl { mutability: Mutability::Mut, - ty: tcx.mk_ptr(ty::TypeAndMut { - ty: gen_ty, - mutbl: hir::Mutability::Mut, - }), + ty: tcx.mk_ptr(ty::TypeAndMut { ty: gen_ty, mutbl: hir::Mutability::Mut }), user_ty: UserTypeProjections::none(), source_info, internal: false, is_block_tail: None, - local_info: LocalInfo::Other + local_info: LocalInfo::Other, }; if tcx.sess.opts.debugging_opts.mir_emit_retag { // Alias tracking must know we changed the type - body.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement { - source_info, - kind: StatementKind::Retag(RetagKind::Raw, box Place::from(self_arg())), - }) + body.basic_blocks_mut()[START_BLOCK].statements.insert( + 0, + Statement { + source_info, + kind: StatementKind::Retag(RetagKind::Raw, box Place::from(self_arg())), + }, + ) } no_landing_pads(tcx, &mut body); @@ -991,22 +949,20 @@ fn create_generator_drop_shim<'tcx>( // unrelated code from the resume part of the function simplify::remove_dead_blocks(&mut body); - dump_mir(tcx, None, "generator_drop", &0, source, &mut body, |_, _| Ok(()) ); + dump_mir(tcx, None, "generator_drop", &0, source, &mut body, |_, _| Ok(())); body } fn insert_term_block<'tcx>( - body: &mut BodyAndCache<'tcx>, kind: TerminatorKind<'tcx> + body: &mut BodyAndCache<'tcx>, + kind: TerminatorKind<'tcx>, ) -> BasicBlock { let term_block = BasicBlock::new(body.basic_blocks().len()); let source_info = source_info(body); body.basic_blocks_mut().push(BasicBlockData { statements: Vec::new(), - terminator: Some(Terminator { - source_info, - kind, - }), + terminator: Some(Terminator { source_info, kind }), is_cleanup: false, }); term_block @@ -1033,10 +989,7 @@ fn insert_panic_block<'tcx>( let source_info = source_info(body); body.basic_blocks_mut().push(BasicBlockData { statements: Vec::new(), - terminator: Some(Terminator { - source_info, - kind: term, - }), + terminator: Some(Terminator { source_info, kind: term }), is_cleanup: false, }); @@ -1054,31 +1007,21 @@ fn create_generator_resume_function<'tcx>( for block in body.basic_blocks_mut() { let source_info = block.terminator().source_info; if let &TerminatorKind::Resume = &block.terminator().kind { - block.statements.push( - transform.set_discr(VariantIdx::new(POISONED), source_info)); + block.statements.push(transform.set_discr(VariantIdx::new(POISONED), source_info)); } } let mut cases = create_cases(body, &transform, |point| Some(point.resume)); - use rustc::mir::interpret::PanicInfo::{ - ResumedAfterPanic, - ResumedAfterReturn, - }; + use rustc::mir::interpret::PanicInfo::{ResumedAfterPanic, ResumedAfterReturn}; // Jump to the entry point on the unresumed cases.insert(0, (UNRESUMED, BasicBlock::new(0))); // Panic when resumed on the returned or poisoned state let generator_kind = body.generator_kind.unwrap(); - cases.insert(1, (RETURNED, insert_panic_block( - tcx, - body, - ResumedAfterReturn(generator_kind)))); - cases.insert(2, (POISONED, insert_panic_block( - tcx, - body, - ResumedAfterPanic(generator_kind)))); + cases.insert(1, (RETURNED, insert_panic_block(tcx, body, ResumedAfterReturn(generator_kind)))); + cases.insert(2, (POISONED, insert_panic_block(tcx, body, ResumedAfterPanic(generator_kind)))); insert_switch(body, cases, &transform, TerminatorKind::Unreachable); @@ -1091,14 +1034,11 @@ fn create_generator_resume_function<'tcx>( // unrelated code from the drop part of the function simplify::remove_dead_blocks(body); - dump_mir(tcx, None, "generator_resume", &0, source, body, |_, _| Ok(()) ); + dump_mir(tcx, None, "generator_resume", &0, source, body, |_, _| Ok(())); } fn source_info(body: &Body<'_>) -> SourceInfo { - SourceInfo { - span: body.span, - scope: OUTERMOST_SOURCE_SCOPE, - } + SourceInfo { span: body.span, scope: OUTERMOST_SOURCE_SCOPE } } fn insert_clean_drop(body: &mut BodyAndCache<'_>) -> BasicBlock { @@ -1114,10 +1054,7 @@ fn insert_clean_drop(body: &mut BodyAndCache<'_>) -> BasicBlock { let source_info = source_info(body); body.basic_blocks_mut().push(BasicBlockData { statements: Vec::new(), - terminator: Some(Terminator { - source_info, - kind: term, - }), + terminator: Some(Terminator { source_info, kind: term }), is_cleanup: false, }); @@ -1134,49 +1071,47 @@ where { let source_info = source_info(body); - transform.suspension_points.iter().filter_map(|point| { - // Find the target for this suspension point, if applicable - target(point).map(|target| { - let block = BasicBlock::new(body.basic_blocks().len()); - let mut statements = Vec::new(); - - // Create StorageLive instructions for locals with live storage - for i in 0..(body.local_decls.len()) { - let l = Local::new(i); - if point.storage_liveness.contains(l) && !transform.remap.contains_key(&l) { - statements.push(Statement { - source_info, - kind: StatementKind::StorageLive(l), - }); + transform + .suspension_points + .iter() + .filter_map(|point| { + // Find the target for this suspension point, if applicable + target(point).map(|target| { + let block = BasicBlock::new(body.basic_blocks().len()); + let mut statements = Vec::new(); + + // Create StorageLive instructions for locals with live storage + for i in 0..(body.local_decls.len()) { + let l = Local::new(i); + if point.storage_liveness.contains(l) && !transform.remap.contains_key(&l) { + statements + .push(Statement { source_info, kind: StatementKind::StorageLive(l) }); + } } - } - // Then jump to the real target - body.basic_blocks_mut().push(BasicBlockData { - statements, - terminator: Some(Terminator { - source_info, - kind: TerminatorKind::Goto { - target, - }, - }), - is_cleanup: false, - }); + // Then jump to the real target + body.basic_blocks_mut().push(BasicBlockData { + statements, + terminator: Some(Terminator { + source_info, + kind: TerminatorKind::Goto { target }, + }), + is_cleanup: false, + }); - (point.state, block) + (point.state, block) + }) }) - }).collect() + .collect() } impl<'tcx> MirPass<'tcx> for StateTransform { - fn run_pass( - &self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx> - ) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { let yield_ty = if let Some(yield_ty) = body.yield_ty { yield_ty } else { // This only applies to generators - return + return; }; assert!(body.generator_drop.is_none()); @@ -1190,10 +1125,12 @@ impl<'tcx> MirPass<'tcx> for StateTransform { let (upvars, interior, discr_ty, movable) = match gen_ty.kind { ty::Generator(_, substs, movability) => { let substs = substs.as_generator(); - (substs.upvar_tys(def_id, tcx).collect(), - substs.witness(def_id, tcx), - substs.discr_ty(tcx), - movability == hir::Movability::Movable) + ( + substs.upvar_tys(def_id, tcx).collect(), + substs.witness(def_id, tcx), + substs.discr_ty(tcx), + movability == hir::Movability::Movable, + ) } _ => bug!(), }; @@ -1201,10 +1138,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform { // Compute GeneratorState let state_did = tcx.lang_items().gen_state().unwrap(); let state_adt_ref = tcx.adt_def(state_did); - let state_substs = tcx.intern_substs(&[ - yield_ty.into(), - body.return_ty().into(), - ]); + let state_substs = tcx.intern_substs(&[yield_ty.into(), body.return_ty().into()]); let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); // We rename RETURN_PLACE which has type mir.return_ty to new_ret_local @@ -1214,13 +1148,8 @@ impl<'tcx> MirPass<'tcx> for StateTransform { // Extract locals which are live across suspension point into `layout` // `remap` gives a mapping from local indices onto generator struct indices // `storage_liveness` tells us which locals have live storage at suspension points - let (remap, layout, storage_liveness) = compute_layout( - tcx, - source, - &upvars, - interior, - movable, - body); + let (remap, layout, storage_liveness) = + compute_layout(tcx, source, &upvars, interior, movable, body); // Run the transformation which converts Places from Local to generator struct // accesses for locals in `remap`. @@ -1249,23 +1178,18 @@ impl<'tcx> MirPass<'tcx> for StateTransform { // This is expanded to a drop ladder in `elaborate_generator_drops`. let drop_clean = insert_clean_drop(body); - dump_mir(tcx, None, "generator_pre-elab", &0, source, body, |_, _| Ok(()) ); + dump_mir(tcx, None, "generator_pre-elab", &0, source, body, |_, _| Ok(())); // Expand `drop(generator_struct)` to a drop ladder which destroys upvars. // If any upvars are moved out of, drop elaboration will handle upvar destruction. // However we need to also elaborate the code generated by `insert_clean_drop`. elaborate_generator_drops(tcx, def_id, body); - dump_mir(tcx, None, "generator_post-transform", &0, source, body, |_, _| Ok(()) ); + dump_mir(tcx, None, "generator_post-transform", &0, source, body, |_, _| Ok(())); // Create a copy of our MIR and use it to create the drop shim for the generator - let drop_shim = create_generator_drop_shim(tcx, - &transform, - def_id, - source, - gen_ty, - body, - drop_clean); + let drop_shim = + create_generator_drop_shim(tcx, &transform, def_id, source, gen_ty, body, drop_clean); body.generator_drop = Some(box drop_shim); diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index dca142279463c..aa0c71ff0f176 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -1,23 +1,23 @@ //! Inlining pass for MIR functions -use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def_id::DefId; +use rustc::hir::CodegenFnAttrFlags; use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; -use rustc::mir::*; use rustc::mir::visit::*; -use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; +use rustc::mir::*; use rustc::ty::subst::{Subst, SubstsRef}; +use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; +use super::simplify::{remove_dead_blocks, CfgSimplifier}; +use crate::transform::{MirPass, MirSource}; use std::collections::VecDeque; use std::iter; -use crate::transform::{MirPass, MirSource}; -use super::simplify::{remove_dead_blocks, CfgSimplifier}; -use syntax::attr; use rustc_target::spec::abi::Abi; +use syntax::attr; const DEFAULT_THRESHOLD: usize = 50; const HINT_THRESHOLD: usize = 100; @@ -38,9 +38,7 @@ struct CallSite<'tcx> { } impl<'tcx> MirPass<'tcx> for Inline { - fn run_pass( - &self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx> - ) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 { Inliner { tcx, source }.run_pass(body); } @@ -72,14 +70,11 @@ impl Inliner<'tcx> { // Only do inlining into fn bodies. let id = self.tcx.hir().as_local_hir_id(self.source.def_id()).unwrap(); - if self.tcx.hir().body_owner_kind(id).is_fn_or_closure() - && self.source.promoted.is_none() - { + if self.tcx.hir().body_owner_kind(id).is_fn_or_closure() && self.source.promoted.is_none() { for (bb, bb_data) in caller_body.basic_blocks().iter_enumerated() { - if let Some(callsite) = self.get_valid_function_call(bb, - bb_data, - caller_body, - param_env) { + if let Some(callsite) = + self.get_valid_function_call(bb, bb_data, caller_body, param_env) + { callsites.push_back(callsite); } } @@ -108,7 +103,8 @@ impl Inliner<'tcx> { // 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_node_id.as_u32() < callee_node_id.as_u32() { + && self_node_id.as_u32() < callee_node_id.as_u32() + { self.tcx.optimized_mir(callsite.callee) } else { continue; @@ -138,12 +134,10 @@ impl Inliner<'tcx> { debug!("attempting to inline callsite {:?} - success", callsite); // Add callsites from inlined function - for (bb, bb_data) in caller_body.basic_blocks().iter_enumerated().skip(start) - { - if let Some(new_callsite) = self.get_valid_function_call(bb, - bb_data, - caller_body, - param_env) { + for (bb, bb_data) in caller_body.basic_blocks().iter_enumerated().skip(start) { + if let Some(new_callsite) = + self.get_valid_function_call(bb, bb_data, caller_body, param_env) + { // Don't inline the same function multiple times. if callsite.callee != new_callsite.callee { callsites.push_back(new_callsite); @@ -168,23 +162,23 @@ impl Inliner<'tcx> { } } - fn get_valid_function_call(&self, - bb: BasicBlock, - bb_data: &BasicBlockData<'tcx>, - caller_body: &Body<'tcx>, - param_env: ParamEnv<'tcx>, + fn get_valid_function_call( + &self, + bb: BasicBlock, + bb_data: &BasicBlockData<'tcx>, + caller_body: &Body<'tcx>, + param_env: ParamEnv<'tcx>, ) -> Option> { // Don't inline calls that are in cleanup blocks. - if bb_data.is_cleanup { return None; } + if bb_data.is_cleanup { + return None; + } // Only consider direct calls to functions let terminator = bb_data.terminator(); if let TerminatorKind::Call { func: ref op, .. } = terminator.kind { if let ty::FnDef(callee_def_id, substs) = op.ty(caller_body, self.tcx).kind { - let instance = Instance::resolve(self.tcx, - param_env, - callee_def_id, - substs)?; + let instance = Instance::resolve(self.tcx, param_env, callee_def_id, substs)?; if let InstanceDef::Virtual(..) = instance.def { return None; @@ -194,7 +188,7 @@ impl Inliner<'tcx> { callee: instance.def_id(), substs: instance.substs, bb, - location: terminator.source_info + location: terminator.source_info, }); } } @@ -202,23 +196,15 @@ impl Inliner<'tcx> { None } - fn consider_optimizing(&self, - callsite: CallSite<'tcx>, - callee_body: &Body<'tcx>) - -> bool - { + fn consider_optimizing(&self, callsite: CallSite<'tcx>, callee_body: &Body<'tcx>) -> bool { debug!("consider_optimizing({:?})", callsite); self.should_inline(callsite, callee_body) - && self.tcx.consider_optimizing(|| format!("Inline {:?} into {:?}", - callee_body.span, - callsite)) + && self.tcx.consider_optimizing(|| { + format!("Inline {:?} into {:?}", callee_body.span, callsite) + }) } - fn should_inline(&self, - callsite: CallSite<'tcx>, - callee_body: &Body<'tcx>) - -> bool - { + fn should_inline(&self, callsite: CallSite<'tcx>, callee_body: &Body<'tcx>) -> bool { debug!("should_inline({:?})", callsite); let tcx = self.tcx; @@ -242,7 +228,7 @@ impl Inliner<'tcx> { attr::InlineAttr::Always => true, attr::InlineAttr::Never => { debug!("`#[inline(never)]` present - not inlining"); - return false + return false; } attr::InlineAttr::Hint => true, attr::InlineAttr::None => false, @@ -258,11 +244,7 @@ impl Inliner<'tcx> { } } - let mut threshold = if hinted { - HINT_THRESHOLD - } else { - DEFAULT_THRESHOLD - }; + let mut threshold = if hinted { HINT_THRESHOLD } else { DEFAULT_THRESHOLD }; // Significantly lower the threshold for inlining cold functions if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::COLD) { @@ -289,23 +271,25 @@ impl Inliner<'tcx> { let mut work_list = vec![START_BLOCK]; let mut visited = BitSet::new_empty(callee_body.basic_blocks().len()); while let Some(bb) = work_list.pop() { - if !visited.insert(bb.index()) { continue; } + if !visited.insert(bb.index()) { + continue; + } let blk = &callee_body.basic_blocks()[bb]; for stmt in &blk.statements { // Don't count StorageLive/StorageDead in the inlining cost. match stmt.kind { - StatementKind::StorageLive(_) | - StatementKind::StorageDead(_) | - StatementKind::Nop => {} - _ => cost += INSTR_COST + StatementKind::StorageLive(_) + | StatementKind::StorageDead(_) + | StatementKind::Nop => {} + _ => cost += INSTR_COST, } } let term = blk.terminator(); let mut is_drop = false; match term.kind { - TerminatorKind::Drop { ref location, target, unwind } | - TerminatorKind::DropAndReplace { ref location, target, unwind, .. } => { + TerminatorKind::Drop { ref location, target, unwind } + | TerminatorKind::DropAndReplace { ref location, target, unwind, .. } => { is_drop = true; work_list.push(target); // If the location doesn't actually need dropping, treat it like @@ -321,14 +305,15 @@ impl Inliner<'tcx> { } } - TerminatorKind::Unreachable | - TerminatorKind::Call { destination: None, .. } if first_block => { + TerminatorKind::Unreachable | TerminatorKind::Call { destination: None, .. } + if first_block => + { // If the function always diverges, don't inline // unless the cost is zero threshold = 0; } - TerminatorKind::Call {func: Operand::Constant(ref f), .. } => { + TerminatorKind::Call { func: Operand::Constant(ref f), .. } => { if let ty::FnDef(def_id, _) = f.literal.ty.kind { // Don't give intrinsics the extra penalty for calls let f = tcx.fn_sig(def_id); @@ -340,7 +325,7 @@ impl Inliner<'tcx> { } } TerminatorKind::Assert { .. } => cost += CALL_PENALTY, - _ => cost += INSTR_COST + _ => cost += INSTR_COST, } if !is_drop { @@ -383,10 +368,12 @@ impl Inliner<'tcx> { } } - fn inline_call(&self, - callsite: CallSite<'tcx>, - caller_body: &mut BodyAndCache<'tcx>, - mut callee_body: BodyAndCache<'tcx>) -> bool { + fn inline_call( + &self, + callsite: CallSite<'tcx>, + caller_body: &mut BodyAndCache<'tcx>, + mut callee_body: BodyAndCache<'tcx>, + ) -> bool { let terminator = caller_body[callsite.bb].terminator.take().unwrap(); match terminator.kind { // FIXME: Handle inlining of diverging calls @@ -416,8 +403,7 @@ impl Inliner<'tcx> { for loc in callee_body.vars_and_temps_iter() { let mut local = callee_body.local_decls[loc].clone(); - local.source_info.scope = - scope_map[local.source_info.scope]; + local.source_info.scope = scope_map[local.source_info.scope]; local.source_info.span = callsite.location.span; let idx = caller_body.local_decls.push(local); @@ -432,8 +418,7 @@ impl Inliner<'tcx> { fn dest_needs_borrow(place: &Place<'_>) -> bool { for elem in place.projection.iter() { match elem { - ProjectionElem::Deref | - ProjectionElem::Index(_) => return true, + ProjectionElem::Deref | ProjectionElem::Index(_) => return true, _ => {} } } @@ -442,7 +427,7 @@ impl Inliner<'tcx> { // Static variables need a borrow because the callee // might modify the same static. PlaceBase::Static(_) => true, - _ => false + _ => false, } } @@ -451,7 +436,8 @@ impl Inliner<'tcx> { let dest = Rvalue::Ref( self.tcx.lifetimes.re_erased, BorrowKind::Mut { allow_two_phase_borrow: false }, - destination.0); + destination.0, + ); let ty = dest.ty(&**caller_body, self.tcx); @@ -462,10 +448,9 @@ impl Inliner<'tcx> { let stmt = Statement { source_info: callsite.location, - kind: StatementKind::Assign(box(tmp.clone(), dest)) + kind: StatementKind::Assign(box (tmp.clone(), dest)), }; - caller_body[callsite.bb] - .statements.push(stmt); + caller_body[callsite.bb].statements.push(stmt); self.tcx.mk_place_deref(tmp) } else { destination.0 @@ -501,7 +486,7 @@ impl Inliner<'tcx> { let terminator = Terminator { source_info: callsite.location, - kind: TerminatorKind::Goto { target: BasicBlock::new(bb_len) } + kind: TerminatorKind::Goto { target: BasicBlock::new(bb_len) }, }; caller_body[callsite.bb].terminator = Some(terminator); @@ -509,10 +494,8 @@ impl Inliner<'tcx> { true } kind => { - caller_body[callsite.bb].terminator = Some(Terminator { - source_info: terminator.source_info, - kind, - }); + caller_body[callsite.bb].terminator = + Some(Terminator { source_info: terminator.source_info, kind }); false } } @@ -551,10 +534,8 @@ impl Inliner<'tcx> { // and the vector is `[closure_ref, tmp0, tmp1, tmp2]`. if tcx.is_closure(callsite.callee) { let mut args = args.into_iter(); - let self_ - = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body); - let tuple - = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body); + let self_ = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body); + let tuple = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body); assert!(args.next().is_none()); let tuple = Place::from(tuple); @@ -568,18 +549,14 @@ impl Inliner<'tcx> { let closure_ref_arg = iter::once(self_); // The `tmp0`, `tmp1`, and `tmp2` in our example abonve. - let tuple_tmp_args = - tuple_tys.iter().enumerate().map(|(i, ty)| { - // This is e.g., `tuple_tmp.0` in our example above. - let tuple_field = Operand::Move(tcx.mk_place_field( - tuple.clone(), - Field::new(i), - ty.expect_ty(), - )); - - // Spill to a local to make e.g., `tmp0`. - self.create_temp_if_necessary(tuple_field, callsite, caller_body) - }); + let tuple_tmp_args = tuple_tys.iter().enumerate().map(|(i, ty)| { + // This is e.g., `tuple_tmp.0` in our example above. + let tuple_field = + Operand::Move(tcx.mk_place_field(tuple.clone(), Field::new(i), ty.expect_ty())); + + // Spill to a local to make e.g., `tmp0`. + self.create_temp_if_necessary(tuple_field, callsite, caller_body) + }); closure_ref_arg.chain(tuple_tmp_args).collect() } else { @@ -620,7 +597,7 @@ impl Inliner<'tcx> { let stmt = Statement { source_info: callsite.location, - kind: StatementKind::Assign(box(Place::from(arg_tmp), arg)), + kind: StatementKind::Assign(box (Place::from(arg_tmp), arg)), }; caller_body[callsite.bb].statements.push(stmt); arg_tmp @@ -683,12 +660,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { self.tcx } - fn visit_local( - &mut self, - local: &mut Local, - _ctxt: PlaceContext, - _location: Location, - ) { + fn visit_local(&mut self, local: &mut Local, _ctxt: PlaceContext, _location: Location) { *local = self.make_integrate_local(local); } @@ -699,7 +671,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { _location: Location, ) { match &mut place.base { - PlaceBase::Static(_) => {}, + PlaceBase::Static(_) => {} PlaceBase::Local(l) => { // If this is the `RETURN_PLACE`, we need to rebase any projections onto it. let dest_proj_len = self.destination.projection.len(); @@ -716,15 +688,12 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { } } - fn process_projection_elem( - &mut self, - elem: &PlaceElem<'tcx>, - ) -> Option> { + fn process_projection_elem(&mut self, elem: &PlaceElem<'tcx>) -> Option> { if let PlaceElem::Index(local) = elem { let new_local = self.make_integrate_local(local); if new_local != *local { - return Some(PlaceElem::Index(new_local)) + return Some(PlaceElem::Index(new_local)); } } @@ -737,12 +706,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { self.in_cleanup_block = false; } - fn visit_retag( - &mut self, - kind: &mut RetagKind, - place: &mut Place<'tcx>, - loc: Location, - ) { + fn visit_retag(&mut self, kind: &mut RetagKind, place: &mut Place<'tcx>, loc: Location) { self.super_retag(kind, place, loc); // We have to patch all inlined retags to be aware that they are no longer @@ -752,14 +716,12 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { } } - fn visit_terminator_kind(&mut self, - kind: &mut TerminatorKind<'tcx>, loc: Location) { + fn visit_terminator_kind(&mut self, kind: &mut TerminatorKind<'tcx>, loc: Location) { self.super_terminator_kind(kind, loc); match *kind { - TerminatorKind::GeneratorDrop | - TerminatorKind::Yield { .. } => bug!(), - TerminatorKind::Goto { ref mut target} => { + TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => bug!(), + TerminatorKind::Goto { ref mut target } => { *target = self.update_target(*target); } TerminatorKind::SwitchInt { ref mut targets, .. } => { @@ -767,8 +729,8 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { *tgt = self.update_target(*tgt); } } - TerminatorKind::Drop { ref mut target, ref mut unwind, .. } | - TerminatorKind::DropAndReplace { ref mut target, ref mut unwind, .. } => { + TerminatorKind::Drop { ref mut target, ref mut unwind, .. } + | TerminatorKind::DropAndReplace { ref mut target, ref mut unwind, .. } => { *target = self.update_target(*target); if let Some(tgt) = *unwind { *unwind = Some(self.update_target(tgt)); @@ -808,15 +770,17 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { *kind = TerminatorKind::Goto { target: tgt } } } - TerminatorKind::Abort => { } - TerminatorKind::Unreachable => { } + TerminatorKind::Abort => {} + TerminatorKind::Unreachable => {} TerminatorKind::FalseEdges { ref mut real_target, ref mut imaginary_target } => { *real_target = self.update_target(*real_target); *imaginary_target = self.update_target(*imaginary_target); } - TerminatorKind::FalseUnwind { real_target: _ , unwind: _ } => - // see the ordering of passes in the optimized_mir query. + TerminatorKind::FalseUnwind { real_target: _, unwind: _ } => + // see the ordering of passes in the optimized_mir query. + { bug!("False unwinds should have been removed before inlining") + } } } diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index eca1b596a4846..02022b7bbf1d1 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -1,15 +1,15 @@ //! Performs various peephole optimizations. +use crate::transform::{MirPass, MirSource}; +use rustc::mir::visit::{MutVisitor, Visitor}; use rustc::mir::{ - Constant, Location, Place, PlaceBase, PlaceRef, Body, BodyAndCache, Operand, ProjectionElem, - Rvalue, Local, read_only + read_only, Body, BodyAndCache, Constant, Local, Location, Operand, Place, PlaceBase, PlaceRef, + ProjectionElem, Rvalue, }; -use rustc::mir::visit::{MutVisitor, Visitor}; use rustc::ty::{self, TyCtxt}; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_index::vec::Idx; use std::mem; -use crate::transform::{MirPass, MirSource}; pub struct InstCombine; @@ -17,7 +17,7 @@ impl<'tcx> MirPass<'tcx> for InstCombine { fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { // We only run when optimizing MIR (at any level). if tcx.sess.opts.debugging_opts.mir_opt_level == 0 { - return + return; } // First, find optimization opportunities. This is done in a pre-pass to keep the MIR @@ -85,21 +85,16 @@ struct OptimizationFinder<'b, 'tcx> { impl OptimizationFinder<'b, 'tcx> { fn new(body: &'b Body<'tcx>, tcx: TyCtxt<'tcx>) -> OptimizationFinder<'b, 'tcx> { - OptimizationFinder { - body, - tcx, - optimizations: OptimizationList::default(), - } + OptimizationFinder { body, tcx, optimizations: OptimizationList::default() } } } impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> { fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { if let Rvalue::Ref(_, _, place) = rvalue { - if let PlaceRef { - base, - projection: &[ref proj_base @ .., ProjectionElem::Deref], - } = place.as_ref() { + if let PlaceRef { base, projection: &[ref proj_base @ .., ProjectionElem::Deref] } = + place.as_ref() + { if Place::ty_from(base, proj_base, self.body, self.tcx).ty.is_region_ptr() { self.optimizations.and_stars.insert(location); } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 350df5750470f..06d0b8c72927a 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -1,40 +1,40 @@ use crate::{build, shim}; -use rustc_index::vec::IndexVec; +use rustc::hir; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; -use rustc::mir::{BodyAndCache, MirPhase, Promoted, ConstQualifs}; -use rustc::ty::{TyCtxt, InstanceDef, TypeFoldable}; +use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; +use rustc::mir::{BodyAndCache, ConstQualifs, MirPhase, Promoted}; use rustc::ty::query::Providers; use rustc::ty::steal::Steal; -use rustc::hir; -use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; +use rustc::ty::{InstanceDef, TyCtxt, TypeFoldable}; use rustc::util::nodemap::DefIdSet; +use rustc_index::vec::IndexVec; use std::borrow::Cow; use syntax::ast; use syntax_pos::Span; -pub mod add_retag; +pub mod add_call_guards; pub mod add_moves_for_packed_drops; -pub mod cleanup_post_borrowck; +pub mod add_retag; pub mod check_consts; pub mod check_unsafety; -pub mod simplify_branches; -pub mod simplify_try; -pub mod simplify; +pub mod cleanup_post_borrowck; +pub mod const_prop; +pub mod copy_prop; +pub mod deaggregator; +pub mod dump_mir; +pub mod elaborate_drops; pub mod erase_regions; +pub mod generator; +pub mod inline; +pub mod instcombine; pub mod no_landing_pads; -pub mod rustc_peek; -pub mod elaborate_drops; -pub mod add_call_guards; pub mod promote_consts; pub mod qualify_min_const_fn; pub mod remove_noop_landing_pads; -pub mod dump_mir; -pub mod deaggregator; -pub mod instcombine; -pub mod copy_prop; -pub mod const_prop; -pub mod generator; -pub mod inline; +pub mod rustc_peek; +pub mod simplify; +pub mod simplify_branches; +pub mod simplify_try; pub mod uninhabited_enum_branching; pub(crate) fn provide(providers: &mut Providers<'_>) { @@ -73,12 +73,14 @@ fn mir_keys(tcx: TyCtxt<'_>, krate: CrateNum) -> &DefIdSet { set: &'a mut DefIdSet, } impl<'a, 'tcx> Visitor<'tcx> for GatherCtors<'a, 'tcx> { - fn visit_variant_data(&mut self, - v: &'tcx hir::VariantData<'tcx>, - _: ast::Name, - _: &'tcx hir::Generics, - _: hir::HirId, - _: Span) { + fn visit_variant_data( + &mut self, + v: &'tcx hir::VariantData<'tcx>, + _: ast::Name, + _: &'tcx hir::Generics, + _: hir::HirId, + _: Span, + ) { if let hir::VariantData::Tuple(_, hir_id) = *v { self.set.insert(self.tcx.hir().local_def_id(hir_id)); } @@ -88,10 +90,9 @@ fn mir_keys(tcx: TyCtxt<'_>, krate: CrateNum) -> &DefIdSet { NestedVisitorMap::None } } - tcx.hir().krate().visit_all_item_likes(&mut GatherCtors { - tcx, - set: &mut set, - }.as_deep_visitor()); + tcx.hir() + .krate() + .visit_all_item_likes(&mut GatherCtors { tcx, set: &mut set }.as_deep_visitor()); tcx.arena.alloc(set) } @@ -112,10 +113,7 @@ pub struct MirSource<'tcx> { impl<'tcx> MirSource<'tcx> { pub fn item(def_id: DefId) -> Self { - MirSource { - instance: InstanceDef::Item(def_id), - promoted: None - } + MirSource { instance: InstanceDef::Item(def_id), promoted: None } } #[inline] @@ -128,11 +126,7 @@ impl<'tcx> MirSource<'tcx> { /// type `T`. pub fn default_name() -> Cow<'static, str> { let name = ::std::any::type_name::(); - if let Some(tail) = name.rfind(":") { - Cow::from(&name[tail+1..]) - } else { - Cow::from(name) - } + if let Some(tail) = name.rfind(":") { Cow::from(&name[tail + 1..]) } else { Cow::from(name) } } /// A streamlined trait that you can implement to create a pass; the @@ -160,15 +154,18 @@ pub fn run_passes( return; } - let source = MirSource { - instance, - promoted, - }; + let source = MirSource { instance, promoted }; let mut index = 0; let mut run_pass = |pass: &dyn MirPass<'tcx>| { let run_hooks = |body: &_, index, is_after| { - dump_mir::on_mir_pass(tcx, &format_args!("{:03}-{:03}", phase_index, index), - &pass.name(), source, body, is_after); + dump_mir::on_mir_pass( + tcx, + &format_args!("{:03}-{:03}", phase_index, index), + &pass.name(), + source, + body, + is_after, + ); }; run_hooks(body, index, false); pass.run_pass(tcx, source, body); @@ -224,11 +221,18 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal> { let _ = tcx.unsafety_check_result(def_id); let mut body = tcx.mir_built(def_id).steal(); - run_passes(tcx, &mut body, InstanceDef::Item(def_id), None, MirPhase::Const, &[ - // What we need to do constant evaluation. - &simplify::SimplifyCfg::new("initial"), - &rustc_peek::SanityCheck, - ]); + run_passes( + tcx, + &mut body, + InstanceDef::Item(def_id), + None, + MirPhase::Const, + &[ + // What we need to do constant evaluation. + &simplify::SimplifyCfg::new("initial"), + &rustc_peek::SanityCheck, + ], + ); body.ensure_predecessors(); tcx.alloc_steal_mir(body) } @@ -243,11 +247,18 @@ fn mir_validated( let mut body = tcx.mir_const(def_id).steal(); let promote_pass = promote_consts::PromoteTemps::default(); - run_passes(tcx, &mut body, InstanceDef::Item(def_id), None, MirPhase::Validated, &[ - // What we need to run borrowck etc. - &promote_pass, - &simplify::SimplifyCfg::new("qualify-consts"), - ]); + run_passes( + tcx, + &mut body, + InstanceDef::Item(def_id), + None, + MirPhase::Validated, + &[ + // What we need to run borrowck etc. + &promote_pass, + &simplify::SimplifyCfg::new("qualify-consts"), + ], + ); let promoted = promote_pass.promoted_fragments.into_inner(); (tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted)) @@ -259,61 +270,59 @@ fn run_optimization_passes<'tcx>( def_id: DefId, promoted: Option, ) { - run_passes(tcx, body, InstanceDef::Item(def_id), promoted, MirPhase::Optimized, &[ - // Remove all things only needed by analysis - &no_landing_pads::NoLandingPads::new(tcx), - &simplify_branches::SimplifyBranches::new("initial"), - &remove_noop_landing_pads::RemoveNoopLandingPads, - &cleanup_post_borrowck::CleanupNonCodegenStatements, - - &simplify::SimplifyCfg::new("early-opt"), - - // These next passes must be executed together - &add_call_guards::CriticalCallEdges, - &elaborate_drops::ElaborateDrops, - &no_landing_pads::NoLandingPads::new(tcx), - // AddMovesForPackedDrops needs to run after drop - // elaboration. - &add_moves_for_packed_drops::AddMovesForPackedDrops, - // AddRetag needs to run after ElaborateDrops, and it needs - // an AllCallEdges pass right before it. Otherwise it should - // run fairly late, but before optimizations begin. - &add_call_guards::AllCallEdges, - &add_retag::AddRetag, - - &simplify::SimplifyCfg::new("elaborate-drops"), - - // No lifetime analysis based on borrowing can be done from here on out. - - // From here on out, regions are gone. - &erase_regions::EraseRegions, - - - // Optimizations begin. - &uninhabited_enum_branching::UninhabitedEnumBranching, - &simplify::SimplifyCfg::new("after-uninhabited-enum-branching"), - &inline::Inline, - - // Lowering generator control-flow and variables - // has to happen before we do anything else to them. - &generator::StateTransform, - - &instcombine::InstCombine, - &const_prop::ConstProp, - &simplify_branches::SimplifyBranches::new("after-const-prop"), - &deaggregator::Deaggregator, - ©_prop::CopyPropagation, - &simplify_branches::SimplifyBranches::new("after-copy-prop"), - &remove_noop_landing_pads::RemoveNoopLandingPads, - &simplify::SimplifyCfg::new("after-remove-noop-landing-pads"), - &simplify_try::SimplifyArmIdentity, - &simplify_try::SimplifyBranchSame, - &simplify::SimplifyCfg::new("final"), - &simplify::SimplifyLocals, - - &add_call_guards::CriticalCallEdges, - &dump_mir::Marker("PreCodegen"), - ]); + run_passes( + tcx, + body, + InstanceDef::Item(def_id), + promoted, + MirPhase::Optimized, + &[ + // Remove all things only needed by analysis + &no_landing_pads::NoLandingPads::new(tcx), + &simplify_branches::SimplifyBranches::new("initial"), + &remove_noop_landing_pads::RemoveNoopLandingPads, + &cleanup_post_borrowck::CleanupNonCodegenStatements, + &simplify::SimplifyCfg::new("early-opt"), + // These next passes must be executed together + &add_call_guards::CriticalCallEdges, + &elaborate_drops::ElaborateDrops, + &no_landing_pads::NoLandingPads::new(tcx), + // AddMovesForPackedDrops needs to run after drop + // elaboration. + &add_moves_for_packed_drops::AddMovesForPackedDrops, + // AddRetag needs to run after ElaborateDrops, and it needs + // an AllCallEdges pass right before it. Otherwise it should + // run fairly late, but before optimizations begin. + &add_call_guards::AllCallEdges, + &add_retag::AddRetag, + &simplify::SimplifyCfg::new("elaborate-drops"), + // No lifetime analysis based on borrowing can be done from here on out. + + // From here on out, regions are gone. + &erase_regions::EraseRegions, + // Optimizations begin. + &uninhabited_enum_branching::UninhabitedEnumBranching, + &simplify::SimplifyCfg::new("after-uninhabited-enum-branching"), + &inline::Inline, + // Lowering generator control-flow and variables + // has to happen before we do anything else to them. + &generator::StateTransform, + &instcombine::InstCombine, + &const_prop::ConstProp, + &simplify_branches::SimplifyBranches::new("after-const-prop"), + &deaggregator::Deaggregator, + ©_prop::CopyPropagation, + &simplify_branches::SimplifyBranches::new("after-copy-prop"), + &remove_noop_landing_pads::RemoveNoopLandingPads, + &simplify::SimplifyCfg::new("after-remove-noop-landing-pads"), + &simplify_try::SimplifyArmIdentity, + &simplify_try::SimplifyBranchSame, + &simplify::SimplifyCfg::new("final"), + &simplify::SimplifyLocals, + &add_call_guards::CriticalCallEdges, + &dump_mir::Marker("PreCodegen"), + ], + ); } fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &BodyAndCache<'_> { diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs index d4fe72f6ed7c8..e17c733e8bb5f 100644 --- a/src/librustc_mir/transform/no_landing_pads.rs +++ b/src/librustc_mir/transform/no_landing_pads.rs @@ -1,10 +1,10 @@ //! This pass removes the unwind branch of all the terminators when the no-landing-pads option is //! specified. -use rustc::ty::TyCtxt; -use rustc::mir::*; -use rustc::mir::visit::MutVisitor; use crate::transform::{MirPass, MirSource}; +use rustc::mir::visit::MutVisitor; +use rustc::mir::*; +use rustc::ty::TyCtxt; pub struct NoLandingPads<'tcx> { tcx: TyCtxt<'tcx>, @@ -33,9 +33,7 @@ impl<'tcx> MutVisitor<'tcx> for NoLandingPads<'tcx> { self.tcx } - fn visit_terminator_kind(&mut self, - kind: &mut TerminatorKind<'tcx>, - location: Location) { + fn visit_terminator_kind(&mut self, kind: &mut TerminatorKind<'tcx>, location: Location) { if let Some(unwind) = kind.unwind_mut() { unwind.take(); } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 4e5d8ae08fe5b..b52231e55f9a0 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -13,24 +13,24 @@ //! move analysis runs after promotion on broken MIR. use rustc::hir::def_id::DefId; -use rustc::mir::*; -use rustc::mir::visit::{PlaceContext, MutatingUseContext, MutVisitor, Visitor}; use rustc::mir::traversal::ReversePostorder; -use rustc::ty::{self, List, TyCtxt, TypeFoldable}; -use rustc::ty::subst::InternalSubsts; +use rustc::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; +use rustc::mir::*; use rustc::ty::cast::CastTy; +use rustc::ty::subst::InternalSubsts; +use rustc::ty::{self, List, TyCtxt, TypeFoldable}; use syntax::ast::LitKind; use syntax::symbol::sym; use syntax_pos::{Span, DUMMY_SP}; -use rustc_index::vec::{IndexVec, Idx}; +use rustc_index::vec::{Idx, IndexVec}; use rustc_target::spec::abi::Abi; use std::cell::Cell; use std::{iter, mem, usize}; +use crate::transform::check_consts::{is_lang_panic_fn, qualifs, ConstKind, Item}; use crate::transform::{MirPass, MirSource}; -use crate::transform::check_consts::{qualifs, Item, ConstKind, is_lang_panic_fn}; /// A `MirPass` for promotion. /// @@ -63,8 +63,8 @@ impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> { let mut rpo = traversal::reverse_postorder(body); let (temps, all_candidates) = collect_temps_and_candidates(tcx, body, &mut rpo); - let promotable_candidates - = validate_candidates(tcx, read_only!(body), def_id, &temps, &all_candidates); + let promotable_candidates = + validate_candidates(tcx, read_only!(body), def_id, &temps, &all_candidates); let promoted = promote_candidates(def_id, body, tcx, temps, promotable_candidates); self.promoted_fragments.set(promoted); @@ -79,25 +79,18 @@ pub enum TempState { /// One direct assignment and any number of direct uses. /// A borrow of this temp is promotable if the assigned /// value is qualified as constant. - Defined { - location: Location, - uses: usize - }, + Defined { location: Location, uses: usize }, /// Any other combination of assignments/uses. Unpromotable, /// This temp was part of an rvalue which got extracted /// during promotion and needs cleanup. - PromotedOut + PromotedOut, } impl TempState { pub fn is_promotable(&self) -> bool { debug!("is_promotable: self={:?}", self); - if let TempState::Defined { .. } = *self { - true - } else { - false - } + if let TempState::Defined { .. } = *self { true } else { false } } } @@ -124,8 +117,7 @@ impl Candidate { /// Returns `true` if we should use the "explicit" rules for promotability for this `Candidate`. fn forces_explicit_promotion(&self) -> bool { match self { - Candidate::Ref(_) | - Candidate::Repeat(_) => false, + Candidate::Ref(_) | Candidate::Repeat(_) => false, Candidate::Argument { .. } => true, } } @@ -137,7 +129,9 @@ fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { let mut ret = vec![]; for meta in attr.meta_item_list()? { match meta.literal()?.kind { - LitKind::Int(a, _) => { ret.push(a as usize); } + LitKind::Int(a, _) => { + ret.push(a as usize); + } _ => return None, } } @@ -153,19 +147,12 @@ struct Collector<'a, 'tcx> { } impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> { - fn visit_local(&mut self, - &index: &Local, - context: PlaceContext, - location: Location) { + fn visit_local(&mut self, &index: &Local, context: PlaceContext, location: Location) { debug!("visit_local: index={:?} context={:?} location={:?}", index, context, location); // We're only interested in temporaries and the return place match self.body.local_kind(index) { - | LocalKind::Temp - | LocalKind::ReturnPointer - => {}, - | LocalKind::Arg - | LocalKind::Var - => return, + LocalKind::Temp | LocalKind::ReturnPointer => {} + LocalKind::Arg | LocalKind::Var => return, } // Ignore drops, if the temp gets promoted, @@ -174,7 +161,8 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> { if context.is_drop() || !context.is_use() { debug!( "visit_local: context.is_drop={:?} context.is_use={:?}", - context.is_drop(), context.is_use(), + context.is_drop(), + context.is_use(), ); return; } @@ -183,12 +171,9 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> { debug!("visit_local: temp={:?}", temp); if *temp == TempState::Undefined { match context { - PlaceContext::MutatingUse(MutatingUseContext::Store) | - PlaceContext::MutatingUse(MutatingUseContext::Call) => { - *temp = TempState::Defined { - location, - uses: 0 - }; + PlaceContext::MutatingUse(MutatingUseContext::Store) + | PlaceContext::MutatingUse(MutatingUseContext::Call) => { + *temp = TempState::Defined { location, uses: 0 }; return; } _ => { /* mark as unpromotable below */ } @@ -199,8 +184,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> { let allowed_use = match context { PlaceContext::MutatingUse(MutatingUseContext::Borrow) | PlaceContext::NonMutatingUse(_) => true, - PlaceContext::MutatingUse(_) - | PlaceContext::NonUse(_) => false, + PlaceContext::MutatingUse(_) | PlaceContext::NonUse(_) => false, }; debug!("visit_local: allowed_use={:?}", allowed_use); if allowed_use { @@ -228,9 +212,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> { } } - fn visit_terminator_kind(&mut self, - kind: &TerminatorKind<'tcx>, - location: Location) { + fn visit_terminator_kind(&mut self, kind: &TerminatorKind<'tcx>, location: Location) { self.super_terminator_kind(kind, location); if let TerminatorKind::Call { ref func, .. } = *kind { @@ -240,10 +222,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> { let name = self.tcx.item_name(def_id); // FIXME(eddyb) use `#[rustc_args_required_const(2)]` for shuffles. if name.as_str().starts_with("simd_shuffle") { - self.candidates.push(Candidate::Argument { - bb: location.block, - index: 2, - }); + self.candidates.push(Candidate::Argument { bb: location.block, index: 2 }); return; // Don't double count `simd_shuffle` candidates } @@ -315,7 +294,7 @@ impl<'tcx> Validator<'_, 'tcx> { let statement = &self.body[loc.block].statements[loc.statement_index]; match &statement.kind { - StatementKind::Assign(box(_, Rvalue::Ref(_, kind, place))) => { + StatementKind::Assign(box (_, Rvalue::Ref(_, kind, place))) => { match kind { BorrowKind::Shared | BorrowKind::Mut { .. } => {} @@ -352,14 +331,10 @@ impl<'tcx> Validator<'_, 'tcx> { while let [proj_base @ .., elem] = place_projection { // FIXME(eddyb) this is probably excessive, with // the exception of `union` member accesses. - let ty = Place::ty_from( - &place.base, - proj_base, - *self.body, - self.tcx - ) - .projection_ty(self.tcx, elem) - .ty; + let ty = + Place::ty_from(&place.base, proj_base, *self.body, self.tcx) + .projection_ty(self.tcx, elem) + .ty; if ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) { has_mut_interior = false; break; @@ -393,7 +368,7 @@ impl<'tcx> Validator<'_, 'tcx> { // FIXME(eddyb) the `self.is_non_const_fn` condition // seems unnecessary, given that this is merely a ZST. match len.try_eval_usize(self.tcx, self.param_env) { - Some(0) if self.const_kind.is_none() => {}, + Some(0) if self.const_kind.is_none() => {} _ => return Err(Unpromotable), } } else { @@ -403,7 +378,7 @@ impl<'tcx> Validator<'_, 'tcx> { Ok(()) } - _ => bug!() + _ => bug!(), } } Candidate::Repeat(loc) => { @@ -411,25 +386,23 @@ impl<'tcx> Validator<'_, 'tcx> { let statement = &self.body[loc.block].statements[loc.statement_index]; match &statement.kind { - StatementKind::Assign(box(_, Rvalue::Repeat(ref operand, _))) => { + StatementKind::Assign(box (_, Rvalue::Repeat(ref operand, _))) => { if !self.tcx.features().const_in_array_repeat_expressions { return Err(Unpromotable); } self.validate_operand(operand) } - _ => bug!() + _ => bug!(), } - }, + } Candidate::Argument { bb, index } => { assert!(self.explicit); let terminator = self.body[bb].terminator(); match &terminator.kind { - TerminatorKind::Call { args, .. } => { - self.validate_operand(&args[index]) - } - _ => bug!() + TerminatorKind::Call { args, .. } => self.validate_operand(&args[index]), + _ => bug!(), } } } @@ -445,12 +418,13 @@ impl<'tcx> Validator<'_, 'tcx> { if loc.statement_index < num_stmts { let statement = &self.body[loc.block].statements[loc.statement_index]; match &statement.kind { - StatementKind::Assign(box(_, rhs)) => { - Q::in_rvalue(&self.item, per_local, rhs) - } + StatementKind::Assign(box (_, rhs)) => Q::in_rvalue(&self.item, per_local, rhs), _ => { - span_bug!(statement.source_info.span, "{:?} is not an assignment", - statement); + span_bug!( + statement.source_info.span, + "{:?} is not an assignment", + statement + ); } } } else { @@ -479,10 +453,13 @@ impl<'tcx> Validator<'_, 'tcx> { if loc.statement_index < num_stmts { let statement = &self.body[loc.block].statements[loc.statement_index]; match &statement.kind { - StatementKind::Assign(box(_, rhs)) => self.validate_rvalue(rhs), + StatementKind::Assign(box (_, rhs)) => self.validate_rvalue(rhs), _ => { - span_bug!(statement.source_info.span, "{:?} is not an assignment", - statement); + span_bug!( + statement.source_info.span, + "{:?} is not an assignment", + statement + ); } } } else { @@ -501,24 +478,19 @@ impl<'tcx> Validator<'_, 'tcx> { fn validate_place(&self, place: PlaceRef<'_, 'tcx>) -> Result<(), Unpromotable> { match place { - PlaceRef { - base: PlaceBase::Local(local), - projection: [], - } => self.validate_local(*local), - PlaceRef { - base: PlaceBase::Static(_), - projection: [], - } => bug!("qualifying already promoted MIR"), - PlaceRef { - base: _, - projection: [proj_base @ .., elem], - } => { + PlaceRef { base: PlaceBase::Local(local), projection: [] } => { + self.validate_local(*local) + } + PlaceRef { base: PlaceBase::Static(_), projection: [] } => { + bug!("qualifying already promoted MIR") + } + PlaceRef { base: _, projection: [proj_base @ .., elem] } => { match *elem { - ProjectionElem::Deref | - ProjectionElem::Downcast(..) => return Err(Unpromotable), + ProjectionElem::Deref | ProjectionElem::Downcast(..) => { + return Err(Unpromotable); + } - ProjectionElem::ConstantIndex {..} | - ProjectionElem::Subslice {..} => {} + ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {} ProjectionElem::Index(local) => { self.validate_local(local)?; @@ -538,18 +510,14 @@ impl<'tcx> Validator<'_, 'tcx> { } } - self.validate_place(PlaceRef { - base: place.base, - projection: proj_base, - }) + self.validate_place(PlaceRef { base: place.base, projection: proj_base }) } } } fn validate_operand(&self, operand: &Operand<'tcx>) -> Result<(), Unpromotable> { match operand { - Operand::Copy(place) | - Operand::Move(place) => self.validate_place(place.as_ref()), + Operand::Copy(place) | Operand::Move(place) => self.validate_place(place.as_ref()), // The qualifs for a constant (e.g. `HasMutInterior`) are checked in // `validate_rvalue` upon access. @@ -569,7 +537,7 @@ impl<'tcx> Validator<'_, 'tcx> { } Ok(()) - }, + } } } @@ -580,8 +548,7 @@ impl<'tcx> Validator<'_, 'tcx> { let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast"); let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast"); match (cast_in, cast_out) { - (CastTy::Ptr(_), CastTy::Int(_)) | - (CastTy::FnPtr, CastTy::Int(_)) => { + (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => { // in normal functions, mark such casts as not promotable return Err(Unpromotable); } @@ -591,10 +558,15 @@ impl<'tcx> Validator<'_, 'tcx> { Rvalue::BinaryOp(op, ref lhs, _) if self.const_kind.is_none() => { if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(*self.body, self.tcx).kind { - assert!(op == BinOp::Eq || op == BinOp::Ne || - op == BinOp::Le || op == BinOp::Lt || - op == BinOp::Ge || op == BinOp::Gt || - op == BinOp::Offset); + assert!( + op == BinOp::Eq + || op == BinOp::Ne + || op == BinOp::Le + || op == BinOp::Lt + || op == BinOp::Ge + || op == BinOp::Gt + || op == BinOp::Offset + ); // raw pointer operations are not allowed inside promoteds return Err(Unpromotable); @@ -609,16 +581,14 @@ impl<'tcx> Validator<'_, 'tcx> { match rvalue { Rvalue::NullaryOp(..) => Ok(()), - Rvalue::Discriminant(place) | - Rvalue::Len(place) => self.validate_place(place.as_ref()), + Rvalue::Discriminant(place) | Rvalue::Len(place) => self.validate_place(place.as_ref()), - Rvalue::Use(operand) | - Rvalue::Repeat(operand, _) | - Rvalue::UnaryOp(_, operand) | - Rvalue::Cast(_, operand, _) => self.validate_operand(operand), + Rvalue::Use(operand) + | Rvalue::Repeat(operand, _) + | Rvalue::UnaryOp(_, operand) + | Rvalue::Cast(_, operand, _) => self.validate_operand(operand), - Rvalue::BinaryOp(_, lhs, rhs) | - Rvalue::CheckedBinaryOp(_, lhs, rhs) => { + Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => { self.validate_operand(lhs)?; self.validate_operand(rhs) } @@ -629,10 +599,8 @@ impl<'tcx> Validator<'_, 'tcx> { if let [proj_base @ .., ProjectionElem::Deref] = place.projection.as_ref() { let base_ty = Place::ty_from(&place.base, proj_base, *self.body, self.tcx).ty; if let ty::Ref(..) = base_ty.kind { - return self.validate_place(PlaceRef { - base: &place.base, - projection: proj_base, - }); + return self + .validate_place(PlaceRef { base: &place.base, projection: proj_base }); } } Err(Unpromotable) @@ -655,7 +623,7 @@ impl<'tcx> Validator<'_, 'tcx> { // FIXME(eddyb): We only return `Unpromotable` for `&mut []` inside a // const context which seems unnecessary given that this is merely a ZST. match len.try_eval_usize(self.tcx, self.param_env) { - Some(0) if self.const_kind.is_none() => {}, + Some(0) if self.const_kind.is_none() => {} _ => return Err(Unpromotable), } } else { @@ -666,13 +634,9 @@ impl<'tcx> Validator<'_, 'tcx> { // Special-case reborrows to be more like a copy of the reference. let mut place = place.as_ref(); if let [proj_base @ .., ProjectionElem::Deref] = &place.projection { - let base_ty = - Place::ty_from(&place.base, proj_base, *self.body, self.tcx).ty; + let base_ty = Place::ty_from(&place.base, proj_base, *self.body, self.tcx).ty; if let ty::Ref(..) = base_ty.kind { - place = PlaceRef { - base: &place.base, - projection: proj_base, - }; + place = PlaceRef { base: &place.base, projection: proj_base }; } } @@ -682,9 +646,7 @@ impl<'tcx> Validator<'_, 'tcx> { // `::in_projection` from // `check_consts::qualifs` but without recursion. let mut has_mut_interior = match place.base { - PlaceBase::Local(local) => { - self.qualif_local::(*local) - } + PlaceBase::Local(local) => self.qualif_local::(*local), PlaceBase::Static(_) => false, }; if has_mut_interior { @@ -740,9 +702,9 @@ impl<'tcx> Validator<'_, 'tcx> { let is_const_fn = match fn_ty.kind { ty::FnDef(def_id, _) => { - self.tcx.is_const_fn(def_id) || - self.tcx.is_unstable_const_fn(def_id).is_some() || - is_lang_panic_fn(self.tcx, self.def_id) + self.tcx.is_const_fn(def_id) + || self.tcx.is_unstable_const_fn(def_id).is_some() + || is_lang_panic_fn(self.tcx, self.def_id) } _ => false, }; @@ -767,30 +729,30 @@ pub fn validate_candidates( temps: &IndexVec, candidates: &[Candidate], ) -> Vec { - let mut validator = Validator { - item: Item::new(tcx, def_id, body), - temps, - explicit: false, - }; + let mut validator = Validator { item: Item::new(tcx, def_id, body), temps, explicit: false }; - candidates.iter().copied().filter(|&candidate| { - validator.explicit = candidate.forces_explicit_promotion(); + candidates + .iter() + .copied() + .filter(|&candidate| { + validator.explicit = candidate.forces_explicit_promotion(); - // FIXME(eddyb) also emit the errors for shuffle indices - // and `#[rustc_args_required_const]` arguments here. + // FIXME(eddyb) also emit the errors for shuffle indices + // and `#[rustc_args_required_const]` arguments here. - let is_promotable = validator.validate_candidate(candidate).is_ok(); - match candidate { - Candidate::Argument { bb, index } if !is_promotable => { - let span = body[bb].terminator().source_info.span; - let msg = format!("argument {} is required to be a constant", index + 1); - tcx.sess.span_err(span, &msg); + let is_promotable = validator.validate_candidate(candidate).is_ok(); + match candidate { + Candidate::Argument { bb, index } if !is_promotable => { + let span = body[bb].terminator().source_info.span; + let msg = format!("argument {} is required to be a constant", index + 1); + tcx.sess.span_err(span, &msg); + } + _ => (), } - _ => () - } - is_promotable - }).collect() + is_promotable + }) + .collect() } struct Promoter<'a, 'tcx> { @@ -810,13 +772,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { self.promoted.basic_blocks_mut().push(BasicBlockData { statements: vec![], terminator: Some(Terminator { - source_info: SourceInfo { - span, - scope: OUTERMOST_SOURCE_SCOPE - }, - kind: TerminatorKind::Return + source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }, + kind: TerminatorKind::Return, }), - is_cleanup: false + is_cleanup: false, }) } @@ -824,11 +783,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let last = self.promoted.basic_blocks().last().unwrap(); let data = &mut self.promoted[last]; data.statements.push(Statement { - source_info: SourceInfo { - span, - scope: OUTERMOST_SOURCE_SCOPE - }, - kind: StatementKind::Assign(box(Place::from(dest), rvalue)) + source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }, + kind: StatementKind::Assign(box (Place::from(dest), rvalue)), }); } @@ -847,9 +803,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } location } - state => { - span_bug!(self.promoted.span, "{:?} not promotable: {:?}", - temp, state); + state => { + span_bug!(self.promoted.span, "{:?} not promotable: {:?}", temp, state); } }; if !self.keep_original { @@ -857,12 +812,12 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } let num_stmts = self.source[loc.block].statements.len(); - let new_temp = self.promoted.local_decls.push( - LocalDecl::new_temp(self.source.local_decls[temp].ty, - self.source.local_decls[temp].source_info.span)); + let new_temp = self.promoted.local_decls.push(LocalDecl::new_temp( + self.source.local_decls[temp].ty, + self.source.local_decls[temp].source_info.span, + )); - debug!("promote({:?} @ {:?}/{:?}, {:?})", - temp, loc, num_stmts, self.keep_original); + debug!("promote({:?} @ {:?}/{:?}, {:?})", temp, loc, num_stmts, self.keep_original); // First, take the Rvalue or Call out of the source MIR, // or duplicate it, depending on keep_original. @@ -870,19 +825,25 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let (mut rvalue, source_info) = { let statement = &mut self.source[loc.block].statements[loc.statement_index]; let rhs = match statement.kind { - StatementKind::Assign(box(_, ref mut rhs)) => rhs, + StatementKind::Assign(box (_, ref mut rhs)) => rhs, _ => { - span_bug!(statement.source_info.span, "{:?} is not an assignment", - statement); + span_bug!( + statement.source_info.span, + "{:?} is not an assignment", + statement + ); } }; - (if self.keep_original { - rhs.clone() - } else { - let unit = Rvalue::Aggregate(box AggregateKind::Tuple, vec![]); - mem::replace(rhs, unit) - }, statement.source_info) + ( + if self.keep_original { + rhs.clone() + } else { + let unit = Rvalue::Aggregate(box AggregateKind::Tuple, vec![]); + mem::replace(rhs, unit) + }, + statement.source_info, + ) }; self.visit_rvalue(&mut rvalue, loc); @@ -900,9 +861,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { }; Terminator { source_info: terminator.source_info, - kind: mem::replace(&mut terminator.kind, TerminatorKind::Goto { - target, - }) + kind: mem::replace(&mut terminator.kind, TerminatorKind::Goto { target }), } }; @@ -921,9 +880,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { func, args, cleanup: None, - destination: Some( - (Place::from(new_temp), new_target) - ), + destination: Some((Place::from(new_temp), new_target)), from_hir_call, }, ..terminator @@ -954,11 +911,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span); Place { base: PlaceBase::Static(box Static { - kind: - StaticKind::Promoted( - promoted_id, - InternalSubsts::identity_for_item(tcx, def_id), - ), + kind: StaticKind::Promoted( + promoted_id, + InternalSubsts::identity_for_item(tcx, def_id), + ), ty, def_id, }), @@ -976,30 +932,24 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let span = statement.source_info.span; Operand::Move(Place { - base: mem::replace( - &mut place.base, - promoted_place(ty, span).base, - ), + base: mem::replace(&mut place.base, promoted_place(ty, span).base), projection: List::empty(), }) } - _ => bug!() + _ => bug!(), } } Candidate::Repeat(loc) => { let ref mut statement = blocks[loc.block].statements[loc.statement_index]; match statement.kind { - StatementKind::Assign(box(_, Rvalue::Repeat(ref mut operand, _))) => { + StatementKind::Assign(box (_, Rvalue::Repeat(ref mut operand, _))) => { let ty = operand.ty(local_decls, self.tcx); let span = statement.source_info.span; - mem::replace( - operand, - Operand::Copy(promoted_place(ty, span)) - ) + mem::replace(operand, Operand::Copy(promoted_place(ty, span))) } - _ => bug!() + _ => bug!(), } - }, + } Candidate::Argument { bb, index } => { let terminator = blocks[bb].terminator_mut(); match terminator.kind { @@ -1017,17 +967,17 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { // providing a value whose computation contains another call to a function // requiring a constant argument. TerminatorKind::Goto { .. } => return None, - _ => bug!() + _ => bug!(), } } } }; assert_eq!(self.new_block(), START_BLOCK); - self.visit_operand(&mut operand, Location { - block: BasicBlock::new(0), - statement_index: usize::MAX - }); + self.visit_operand( + &mut operand, + Location { block: BasicBlock::new(0), statement_index: usize::MAX }, + ); let span = self.promoted.span; self.assign(RETURN_PLACE, Rvalue::Use(operand), span); @@ -1041,19 +991,13 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> { self.tcx } - fn visit_local(&mut self, - local: &mut Local, - _: PlaceContext, - _: Location) { + fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) { if self.is_temp_kind(*local) { *local = self.promote_temp(*local); } } - fn process_projection_elem( - &mut self, - elem: &PlaceElem<'tcx>, - ) -> Option> { + fn process_projection_elem(&mut self, elem: &PlaceElem<'tcx>) -> Option> { match elem { PlaceElem::Index(local) if self.is_temp_kind(*local) => { Some(PlaceElem::Index(self.promote_temp(*local))) @@ -1077,10 +1021,10 @@ pub fn promote_candidates<'tcx>( for candidate in candidates.into_iter().rev() { match candidate { - Candidate::Repeat(Location { block, statement_index }) | - Candidate::Ref(Location { block, statement_index }) => { + Candidate::Repeat(Location { block, statement_index }) + | Candidate::Ref(Location { block, statement_index }) => { match &body[block].statements[statement_index].kind { - StatementKind::Assign(box(place, _)) => { + StatementKind::Assign(box (place, _)) => { if let Some(local) = place.as_local() { if temps[local] == TempState::PromotedOut { // Already promoted. @@ -1094,11 +1038,9 @@ pub fn promote_candidates<'tcx>( Candidate::Argument { .. } => {} } - // Declare return place local so that `mir::Body::new` doesn't complain. - let initial_locals = iter::once( - LocalDecl::new_return_place(tcx.types.never, body.span) - ).collect(); + let initial_locals = + iter::once(LocalDecl::new_return_place(tcx.types.never, body.span)).collect(); let promoter = Promoter { promoted: BodyAndCache::new(Body::new( @@ -1117,7 +1059,7 @@ pub fn promote_candidates<'tcx>( tcx, source: body, temps: &mut temps, - keep_original: false + keep_original: false, }; //FIXME(oli-obk): having a `maybe_push()` method on `IndexVec` might be nice @@ -1129,30 +1071,25 @@ pub fn promote_candidates<'tcx>( // Eliminate assignments to, and drops of promoted temps. let promoted = |index: Local| temps[index] == TempState::PromotedOut; for block in body.basic_blocks_mut() { - block.statements.retain(|statement| { - match &statement.kind { - StatementKind::Assign(box(place, _)) => { - if let Some(index) = place.as_local() { - !promoted(index) - } else { - true - } - } - StatementKind::StorageLive(index) | - StatementKind::StorageDead(index) => { - !promoted(*index) + block.statements.retain(|statement| match &statement.kind { + StatementKind::Assign(box (place, _)) => { + if let Some(index) = place.as_local() { + !promoted(index) + } else { + true } - _ => true } + StatementKind::StorageLive(index) | StatementKind::StorageDead(index) => { + !promoted(*index) + } + _ => true, }); let terminator = block.terminator_mut(); match &terminator.kind { TerminatorKind::Drop { location: place, target, .. } => { if let Some(index) = place.as_local() { if promoted(index) { - terminator.kind = TerminatorKind::Goto { - target: *target, - }; + terminator.kind = TerminatorKind::Goto { target: *target }; } } } @@ -1175,15 +1112,15 @@ crate fn should_suggest_const_in_array_repeat_expressions_attribute<'tcx>( ) -> bool { let mut rpo = traversal::reverse_postorder(&body); let (temps, _) = collect_temps_and_candidates(tcx, &body, &mut rpo); - let validator = Validator { - item: Item::new(tcx, mir_def_id, body), - temps: &temps, - explicit: false, - }; + let validator = + Validator { item: Item::new(tcx, mir_def_id, body), temps: &temps, explicit: false }; let should_promote = validator.validate_operand(operand).is_ok(); let feature_flag = tcx.features().const_in_array_repeat_expressions; - debug!("should_suggest_const_in_array_repeat_expressions_flag: mir_def_id={:?} \ - should_promote={:?} feature_flag={:?}", mir_def_id, should_promote, feature_flag); + debug!( + "should_suggest_const_in_array_repeat_expressions_flag: mir_def_id={:?} \ + should_promote={:?} feature_flag={:?}", + mir_def_id, should_promote, feature_flag + ); should_promote && !feature_flag } diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 0d2e0bb8281e0..6064df9ba4b09 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -1,11 +1,11 @@ -use rustc::hir::def_id::DefId; use rustc::hir; +use rustc::hir::def_id::DefId; use rustc::mir::*; -use rustc::ty::{self, Predicate, Ty, TyCtxt, adjustment::{PointerCast}}; +use rustc::ty::{self, adjustment::PointerCast, Predicate, Ty, TyCtxt}; use std::borrow::Cow; -use syntax_pos::Span; -use syntax::symbol::{sym, Symbol}; use syntax::attr; +use syntax::symbol::{sym, Symbol}; +use syntax_pos::Span; type McfResult = Result<(), (Span, Cow<'static, str>)>; @@ -15,12 +15,12 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) - let predicates = tcx.predicates_of(current); for (predicate, _) in predicates.predicates { match predicate { - | Predicate::RegionOutlives(_) + Predicate::RegionOutlives(_) | Predicate::TypeOutlives(_) | Predicate::WellFormed(_) | Predicate::Projection(_) | Predicate::ConstEvaluatable(..) => continue, - | Predicate::ObjectSafe(_) => { + Predicate::ObjectSafe(_) => { bug!("object safe predicate on function: {:#?}", predicate) } Predicate::ClosureKind(..) => { @@ -81,29 +81,26 @@ fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, fn_def_id: DefId) -> Mc match ty.kind { ty::Ref(_, _, hir::Mutability::Mut) => { if !feature_allowed(tcx, fn_def_id, sym::const_mut_refs) { - return Err(( - span, - "mutable references in const fn are unstable".into(), - )) + return Err((span, "mutable references in const fn are unstable".into())); } } ty::Opaque(..) => return Err((span, "`impl Trait` in const fn is unstable".into())), ty::FnPtr(..) => { if !tcx.const_fn_is_allowed_fn_ptr(fn_def_id) { - return Err((span, "function pointers in const fn are unstable".into())) + return Err((span, "function pointers in const fn are unstable".into())); } } ty::Dynamic(preds, _) => { for pred in preds.iter() { match pred.skip_binder() { - | ty::ExistentialPredicate::AutoTrait(_) + ty::ExistentialPredicate::AutoTrait(_) | ty::ExistentialPredicate::Projection(_) => { return Err(( span, "trait bounds other than `Sized` \ on const fn parameters are unstable" .into(), - )) + )); } ty::ExistentialPredicate::Trait(trait_ref) => { if Some(trait_ref.def_id) != tcx.lang_items().sized_trait() { @@ -138,18 +135,15 @@ fn check_rvalue( Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) - | Rvalue::AddressOf(_, place) => { - check_place(tcx, place, span, def_id, body) - } + | Rvalue::AddressOf(_, place) => check_place(tcx, place, span, def_id, body), Rvalue::Cast(CastKind::Misc, operand, cast_ty) => { use rustc::ty::cast::CastTy; let cast_in = CastTy::from_ty(operand.ty(body, tcx)).expect("bad input type for cast"); let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast"); match (cast_in, cast_out) { - (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => Err(( - span, - "casting pointers to ints is unstable in const fn".into(), - )), + (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => { + Err((span, "casting pointers to ints is unstable in const fn".into())) + } _ => check_operand(tcx, operand, span, def_id, body), } } @@ -157,16 +151,14 @@ fn check_rvalue( | Rvalue::Cast(CastKind::Pointer(PointerCast::ArrayToPointer), operand, _) => { check_operand(tcx, operand, span, def_id, body) } - Rvalue::Cast(CastKind::Pointer(PointerCast::UnsafeFnPointer), _, _) | - Rvalue::Cast(CastKind::Pointer(PointerCast::ClosureFnPointer(_)), _, _) | - Rvalue::Cast(CastKind::Pointer(PointerCast::ReifyFnPointer), _, _) => Err(( - span, - "function pointer casts are not allowed in const fn".into(), - )), - Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => Err(( - span, - "unsizing casts are not allowed in const fn".into(), - )), + Rvalue::Cast(CastKind::Pointer(PointerCast::UnsafeFnPointer), _, _) + | Rvalue::Cast(CastKind::Pointer(PointerCast::ClosureFnPointer(_)), _, _) + | Rvalue::Cast(CastKind::Pointer(PointerCast::ReifyFnPointer), _, _) => { + Err((span, "function pointer casts are not allowed in const fn".into())) + } + Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => { + Err((span, "unsizing casts are not allowed in const fn".into())) + } // binops are fine on integers Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => { check_operand(tcx, lhs, span, def_id, body)?; @@ -175,26 +167,19 @@ fn check_rvalue( if ty.is_integral() || ty.is_bool() || ty.is_char() { Ok(()) } else { - Err(( - span, - "only int, `bool` and `char` operations are stable in const fn".into(), - )) + Err((span, "only int, `bool` and `char` operations are stable in const fn".into())) } } Rvalue::NullaryOp(NullOp::SizeOf, _) => Ok(()), - Rvalue::NullaryOp(NullOp::Box, _) => Err(( - span, - "heap allocations are not allowed in const fn".into(), - )), + Rvalue::NullaryOp(NullOp::Box, _) => { + Err((span, "heap allocations are not allowed in const fn".into())) + } Rvalue::UnaryOp(_, operand) => { let ty = operand.ty(body, tcx); if ty.is_integral() || ty.is_bool() { check_operand(tcx, operand, span, def_id, body) } else { - Err(( - span, - "only int and `bool` operations are stable in const fn".into(), - )) + Err((span, "only int and `bool` operations are stable in const fn".into())) } } Rvalue::Aggregate(_, operands) => { @@ -214,14 +199,14 @@ fn check_statement( ) -> McfResult { let span = statement.source_info.span; match &statement.kind { - StatementKind::Assign(box(place, rval)) => { + StatementKind::Assign(box (place, rval)) => { check_place(tcx, place, span, def_id, body)?; check_rvalue(tcx, body, def_id, rval, span) } - | StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) - if !feature_allowed(tcx, def_id, sym::const_if_match) - => { + StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) + if !feature_allowed(tcx, def_id, sym::const_if_match) => + { Err((span, "loops and conditional expressions are not stable in const fn".into())) } @@ -230,12 +215,12 @@ fn check_statement( // just an assignment StatementKind::SetDiscriminant { place, .. } => check_place(tcx, place, span, def_id, body), - | StatementKind::InlineAsm { .. } => { + StatementKind::InlineAsm { .. } => { Err((span, "cannot use inline assembly in const fn".into())) } // These are all NOPs - | StatementKind::StorageLive(_) + StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Retag { .. } | StatementKind::AscribeUserType(..) @@ -248,12 +233,10 @@ fn check_operand( operand: &Operand<'tcx>, span: Span, def_id: DefId, - body: &Body<'tcx> + body: &Body<'tcx>, ) -> McfResult { match operand { - Operand::Move(place) | Operand::Copy(place) => { - check_place(tcx, place, span, def_id, body) - } + Operand::Move(place) | Operand::Copy(place) => check_place(tcx, place, span, def_id, body), Operand::Constant(c) => match c.check_static_ptr(tcx) { Some(_) => Err((span, "cannot access `static` items in const fn".into())), None => Ok(()), @@ -266,14 +249,15 @@ fn check_place( place: &Place<'tcx>, span: Span, def_id: DefId, - body: &Body<'tcx> + body: &Body<'tcx>, ) -> McfResult { let mut cursor = place.projection.as_ref(); while let &[ref proj_base @ .., elem] = cursor { cursor = proj_base; match elem { - ProjectionElem::Downcast(..) if !feature_allowed(tcx, def_id, sym::const_if_match) - => return Err((span, "`match` or `if let` in `const fn` is unstable".into())), + ProjectionElem::Downcast(..) if !feature_allowed(tcx, def_id, sym::const_if_match) => { + return Err((span, "`match` or `if let` in `const fn` is unstable".into())); + } ProjectionElem::Downcast(_symbol, _variant_index) => {} ProjectionElem::Field(..) => { @@ -298,11 +282,7 @@ fn check_place( } /// Returns whether `allow_internal_unstable(..., , ...)` is present. -fn feature_allowed( - tcx: TyCtxt<'tcx>, - def_id: DefId, - feature_gate: Symbol, -) -> bool { +fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool { attr::allow_internal_unstable(&tcx.get_attrs(def_id), &tcx.sess.diagnostic()) .map_or(false, |mut features| features.any(|name| name == feature_gate)) } @@ -315,25 +295,19 @@ fn check_terminator( ) -> McfResult { let span = terminator.source_info.span; match &terminator.kind { - | TerminatorKind::Goto { .. } - | TerminatorKind::Return - | TerminatorKind::Resume => Ok(()), + TerminatorKind::Goto { .. } | TerminatorKind::Return | TerminatorKind::Resume => Ok(()), - TerminatorKind::Drop { location, .. } => { - check_place(tcx, location, span, def_id, body) - } + TerminatorKind::Drop { location, .. } => check_place(tcx, location, span, def_id, body), TerminatorKind::DropAndReplace { location, value, .. } => { check_place(tcx, location, span, def_id, body)?; check_operand(tcx, value, span, def_id, body) - }, + } - | TerminatorKind::FalseEdges { .. } - | TerminatorKind::SwitchInt { .. } - if !feature_allowed(tcx, def_id, sym::const_if_match) - => Err(( - span, - "loops and conditional expressions are not stable in const fn".into(), - )), + TerminatorKind::FalseEdges { .. } | TerminatorKind::SwitchInt { .. } + if !feature_allowed(tcx, def_id, sym::const_if_match) => + { + Err((span, "loops and conditional expressions are not stable in const fn".into())) + } TerminatorKind::FalseEdges { .. } => Ok(()), TerminatorKind::SwitchInt { discr, switch_ty: _, values: _, targets: _ } => { @@ -343,20 +317,14 @@ fn check_terminator( // FIXME(ecstaticmorse): We probably want to allow `Unreachable` unconditionally. TerminatorKind::Unreachable if feature_allowed(tcx, def_id, sym::const_if_match) => Ok(()), - | TerminatorKind::Abort | TerminatorKind::Unreachable => { + TerminatorKind::Abort | TerminatorKind::Unreachable => { Err((span, "const fn with unreachable code is not stable".into())) } - | TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => { + TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => { Err((span, "const fn generators are unstable".into())) } - TerminatorKind::Call { - func, - args, - from_hir_call: _, - destination: _, - cleanup: _, - } => { + TerminatorKind::Call { func, args, from_hir_call: _, destination: _, cleanup: _ } => { let fn_ty = func.ty(body, tcx); if let ty::FnDef(def_id, _) = fn_ty.kind { if !tcx.is_min_const_fn(def_id) { @@ -382,17 +350,13 @@ fn check_terminator( } } - TerminatorKind::Assert { - cond, - expected: _, - msg: _, - target: _, - cleanup: _, - } => check_operand(tcx, cond, span, def_id, body), + TerminatorKind::Assert { cond, expected: _, msg: _, target: _, cleanup: _ } => { + check_operand(tcx, cond, span, def_id, body) + } - | TerminatorKind::FalseUnwind { .. } - if feature_allowed(tcx, def_id, sym::const_loop) - => Ok(()), + TerminatorKind::FalseUnwind { .. } if feature_allowed(tcx, def_id, sym::const_loop) => { + Ok(()) + } TerminatorKind::FalseUnwind { .. } => { Err((span, "loops are not allowed in const fn".into())) diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs index 5799d0c38b01d..7ac9eccf46f56 100644 --- a/src/librustc_mir/transform/remove_noop_landing_pads.rs +++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs @@ -1,8 +1,8 @@ -use rustc::ty::TyCtxt; -use rustc::mir::*; -use rustc_index::bit_set::BitSet; use crate::transform::{MirPass, MirSource}; use crate::util::patch::MirPatch; +use rustc::mir::*; +use rustc::ty::TyCtxt; +use rustc_index::bit_set::BitSet; /// A pass that removes noop landing pads and replaces jumps to them with /// `None`. This is important because otherwise LLVM generates terrible @@ -11,7 +11,7 @@ pub struct RemoveNoopLandingPads; pub fn remove_noop_landing_pads<'tcx>(tcx: TyCtxt<'tcx>, body: &mut BodyAndCache<'tcx>) { if tcx.sess.no_landing_pads() { - return + return; } debug!("remove_noop_landing_pads({:?})", body); @@ -33,15 +33,15 @@ impl RemoveNoopLandingPads { ) -> bool { for stmt in &body[bb].statements { match &stmt.kind { - StatementKind::FakeRead(..) | - StatementKind::StorageLive(_) | - StatementKind::StorageDead(_) | - StatementKind::AscribeUserType(..) | - StatementKind::Nop => { + StatementKind::FakeRead(..) + | StatementKind::StorageLive(_) + | StatementKind::StorageDead(_) + | StatementKind::AscribeUserType(..) + | StatementKind::Nop => { // These are all nops in a landing pad } - StatementKind::Assign(box(place, Rvalue::Use(_))) => { + StatementKind::Assign(box (place, Rvalue::Use(_))) => { if place.as_local().is_some() { // Writing to a local (e.g., a drop flag) does not // turn a landing pad to a non-nop @@ -50,10 +50,10 @@ impl RemoveNoopLandingPads { } } - StatementKind::Assign { .. } | - StatementKind::SetDiscriminant { .. } | - StatementKind::InlineAsm { .. } | - StatementKind::Retag { .. } => { + StatementKind::Assign { .. } + | StatementKind::SetDiscriminant { .. } + | StatementKind::InlineAsm { .. } + | StatementKind::Retag { .. } => { return false; } } @@ -61,26 +61,22 @@ impl RemoveNoopLandingPads { let terminator = body[bb].terminator(); match terminator.kind { - TerminatorKind::Goto { .. } | - TerminatorKind::Resume | - TerminatorKind::SwitchInt { .. } | - TerminatorKind::FalseEdges { .. } | - TerminatorKind::FalseUnwind { .. } => { - terminator.successors().all(|&succ| { - nop_landing_pads.contains(succ) - }) - }, - TerminatorKind::GeneratorDrop | - TerminatorKind::Yield { .. } | - TerminatorKind::Return | - TerminatorKind::Abort | - TerminatorKind::Unreachable | - TerminatorKind::Call { .. } | - TerminatorKind::Assert { .. } | - TerminatorKind::DropAndReplace { .. } | - TerminatorKind::Drop { .. } => { - false + TerminatorKind::Goto { .. } + | TerminatorKind::Resume + | TerminatorKind::SwitchInt { .. } + | TerminatorKind::FalseEdges { .. } + | TerminatorKind::FalseUnwind { .. } => { + terminator.successors().all(|&succ| nop_landing_pads.contains(succ)) } + TerminatorKind::GeneratorDrop + | TerminatorKind::Yield { .. } + | TerminatorKind::Return + | TerminatorKind::Abort + | TerminatorKind::Unreachable + | TerminatorKind::Call { .. } + | TerminatorKind::Assert { .. } + | TerminatorKind::DropAndReplace { .. } + | TerminatorKind::Drop { .. } => false, } } diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index 4345fc66bb95e..095d8474c5d13 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -1,25 +1,25 @@ -use rustc_target::spec::abi::{Abi}; +use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::symbol::sym; use syntax_pos::Span; -use rustc::ty::{self, TyCtxt, Ty}; +use crate::transform::{MirPass, MirSource}; use rustc::hir::def_id::DefId; -use rustc::mir::{self, Body, BodyAndCache, Location, Local}; +use rustc::mir::{self, Body, BodyAndCache, Local, Location}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc_index::bit_set::BitSet; -use crate::transform::{MirPass, MirSource}; -use crate::dataflow::{do_dataflow, DebugFormatted}; -use crate::dataflow::MoveDataParamEnv; +use crate::dataflow::move_paths::{HasMoveData, MoveData}; +use crate::dataflow::move_paths::{LookupResult, MovePathIndex}; use crate::dataflow::BitDenotation; use crate::dataflow::DataflowResults; use crate::dataflow::DataflowResultsCursor; +use crate::dataflow::IndirectlyMutableLocals; +use crate::dataflow::MoveDataParamEnv; +use crate::dataflow::{do_dataflow, DebugFormatted}; use crate::dataflow::{ - DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces + DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces, }; -use crate::dataflow::IndirectlyMutableLocals; -use crate::dataflow::move_paths::{MovePathIndex, LookupResult}; -use crate::dataflow::move_paths::{HasMoveData, MoveData}; use crate::dataflow::has_rustc_mir_with; @@ -40,22 +40,42 @@ impl<'tcx> MirPass<'tcx> for SanityCheck { let move_data = MoveData::gather_moves(body, tcx, param_env).unwrap(); let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env }; let dead_unwinds = BitSet::new_empty(body.basic_blocks().len()); - let flow_inits = - do_dataflow(tcx, body, def_id, &attributes, &dead_unwinds, - MaybeInitializedPlaces::new(tcx, body, &mdpe), - |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i])); - let flow_uninits = - do_dataflow(tcx, body, def_id, &attributes, &dead_unwinds, - MaybeUninitializedPlaces::new(tcx, body, &mdpe), - |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i])); - let flow_def_inits = - do_dataflow(tcx, body, def_id, &attributes, &dead_unwinds, - DefinitelyInitializedPlaces::new(tcx, body, &mdpe), - |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i])); - let flow_indirectly_mut = - do_dataflow(tcx, body, def_id, &attributes, &dead_unwinds, - IndirectlyMutableLocals::new(tcx, body, param_env), - |_, i| DebugFormatted::new(&i)); + let flow_inits = do_dataflow( + tcx, + body, + def_id, + &attributes, + &dead_unwinds, + MaybeInitializedPlaces::new(tcx, body, &mdpe), + |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]), + ); + let flow_uninits = do_dataflow( + tcx, + body, + def_id, + &attributes, + &dead_unwinds, + MaybeUninitializedPlaces::new(tcx, body, &mdpe), + |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]), + ); + let flow_def_inits = do_dataflow( + tcx, + body, + def_id, + &attributes, + &dead_unwinds, + DefinitelyInitializedPlaces::new(tcx, body, &mdpe), + |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]), + ); + let flow_indirectly_mut = do_dataflow( + tcx, + body, + def_id, + &attributes, + &dead_unwinds, + IndirectlyMutableLocals::new(tcx, body, param_env), + |_, i| DebugFormatted::new(&i), + ); if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_init).is_some() { sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_inits); @@ -64,20 +84,10 @@ impl<'tcx> MirPass<'tcx> for SanityCheck { sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_uninits); } if has_rustc_mir_with(&attributes, sym::rustc_peek_definite_init).is_some() { - sanity_check_via_rustc_peek( - tcx, - body, - def_id, - &attributes, - &flow_def_inits); + sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_def_inits); } if has_rustc_mir_with(&attributes, sym::rustc_peek_indirectly_mutable).is_some() { - sanity_check_via_rustc_peek( - tcx, - body, - def_id, - &attributes, - &flow_indirectly_mut); + sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_indirectly_mut); } if has_rustc_mir_with(&attributes, sym::stop_after_dataflow).is_some() { tcx.sess.fatal("stop_after_dataflow ended compilation"); @@ -107,18 +117,16 @@ pub fn sanity_check_via_rustc_peek<'tcx, O>( def_id: DefId, _attributes: &[ast::Attribute], results: &DataflowResults<'tcx, O>, -) where O: RustcPeekAt<'tcx> { +) where + O: RustcPeekAt<'tcx>, +{ debug!("sanity_check_via_rustc_peek def_id: {:?}", def_id); let mut cursor = DataflowResultsCursor::new(results, body); - let peek_calls = body - .basic_blocks() - .iter_enumerated() - .filter_map(|(bb, block_data)| { - PeekCall::from_terminator(tcx, block_data.terminator()) - .map(|call| (bb, block_data, call)) - }); + let peek_calls = body.basic_blocks().iter_enumerated().filter_map(|(bb, block_data)| { + PeekCall::from_terminator(tcx, block_data.terminator()).map(|call| (bb, block_data, call)) + }); for (bb, block_data, call) in peek_calls { // Look for a sequence like the following to indicate that we should be peeking at `_1`: @@ -135,14 +143,15 @@ pub fn sanity_check_via_rustc_peek<'tcx, O>( .enumerate() .filter_map(|(i, stmt)| value_assigned_to_local(stmt, call.arg).map(|rval| (i, rval))) .next() - .expect("call to rustc_peek should be preceded by \ - assignment to temporary holding its argument"); + .expect( + "call to rustc_peek should be preceded by \ + assignment to temporary holding its argument", + ); match (call.kind, peek_rval) { - | (PeekCallKind::ByRef, mir::Rvalue::Ref(_, _, place)) + (PeekCallKind::ByRef, mir::Rvalue::Ref(_, _, place)) | (PeekCallKind::ByVal, mir::Rvalue::Use(mir::Operand::Move(place))) - | (PeekCallKind::ByVal, mir::Rvalue::Use(mir::Operand::Copy(place))) - => { + | (PeekCallKind::ByVal, mir::Rvalue::Use(mir::Operand::Copy(place))) => { let loc = Location { block: bb, statement_index }; cursor.seek(loc); let state = cursor.get(); @@ -238,11 +247,7 @@ impl PeekCall { } }; - return Some(PeekCall { - arg, - kind, - span, - }); + return Some(PeekCall { arg, kind, span }); } } @@ -261,7 +266,8 @@ pub trait RustcPeekAt<'tcx>: BitDenotation<'tcx> { } impl<'tcx, O> RustcPeekAt<'tcx> for O - where O: BitDenotation<'tcx, Idx = MovePathIndex> + HasMoveData<'tcx>, +where + O: BitDenotation<'tcx, Idx = MovePathIndex> + HasMoveData<'tcx>, { fn peek_at( &self, @@ -273,8 +279,7 @@ impl<'tcx, O> RustcPeekAt<'tcx> for O match self.move_data().rev_lookup.find(place.as_ref()) { LookupResult::Exact(peek_mpi) => { let bit_state = flow_state.contains(peek_mpi); - debug!("rustc_peek({:?} = &{:?}) bit_state: {}", - call.arg, place, bit_state); + debug!("rustc_peek({:?} = &{:?}) bit_state: {}", call.arg, place, bit_state); if !bit_state { tcx.sess.span_err(call.span, "rustc_peek: bit not set"); } diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index 628ac721adc59..fb7f4fac4dca4 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -27,15 +27,17 @@ //! naively generate still contains the `_a = ()` write in the unreachable block "after" the //! return. +use crate::transform::{MirPass, MirSource}; +use rustc::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; +use rustc::mir::*; +use rustc::ty::{self, TyCtxt}; use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; -use rustc::ty::{self, TyCtxt}; -use rustc::mir::*; -use rustc::mir::visit::{MutVisitor, Visitor, PlaceContext, MutatingUseContext}; use std::borrow::Cow; -use crate::transform::{MirPass, MirSource}; -pub struct SimplifyCfg { label: String } +pub struct SimplifyCfg { + label: String, +} impl SimplifyCfg { pub fn new(label: &str) -> Self { @@ -56,9 +58,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyCfg { Cow::Borrowed(&self.label) } - fn run_pass( - &self, _tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut BodyAndCache<'tcx> - ) { + fn run_pass(&self, _tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, body); simplify_cfg(body); } @@ -66,7 +66,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyCfg { pub struct CfgSimplifier<'a, 'tcx> { basic_blocks: &'a mut IndexVec>, - pred_count: IndexVec + pred_count: IndexVec, } impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { @@ -87,10 +87,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { let basic_blocks = body.basic_blocks_mut(); - CfgSimplifier { - basic_blocks, - pred_count, - } + CfgSimplifier { basic_blocks, pred_count } } pub fn simplify(mut self) { @@ -105,13 +102,13 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { for bb in self.basic_blocks.indices() { if self.pred_count[bb] == 0 { - continue + continue; } debug!("simplifying {:?}", bb); - let mut terminator = self.basic_blocks[bb].terminator.take() - .expect("invalid terminator state"); + let mut terminator = + self.basic_blocks[bb].terminator.take().expect("invalid terminator state"); for successor in terminator.successors_mut() { self.collapse_goto_chain(successor, &mut changed); @@ -133,7 +130,9 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { changed |= inner_changed; } - if !changed { break } + if !changed { + break; + } } if start != START_BLOCK { @@ -163,13 +162,13 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { let mut terminator = match self.basic_blocks[*start] { BasicBlockData { ref statements, - terminator: ref mut terminator @ Some(Terminator { - kind: TerminatorKind::Goto { .. }, .. - }), .. + terminator: + ref mut terminator @ Some(Terminator { kind: TerminatorKind::Goto { .. }, .. }), + .. } if statements.is_empty() => terminator.take(), // if `terminator` is None, this means we are in a loop. In that // case, let all the loop collapse to its entry. - _ => return + _ => return, }; let target = match terminator { @@ -177,7 +176,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { self.collapse_goto_chain(target, changed); *target } - _ => unreachable!() + _ => unreachable!(), }; self.basic_blocks[*start].terminator = terminator; @@ -198,16 +197,14 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } // merge a block with 1 `goto` predecessor to its parent - fn merge_successor(&mut self, - new_stmts: &mut Vec>, - terminator: &mut Terminator<'tcx>) - -> bool - { + fn merge_successor( + &mut self, + new_stmts: &mut Vec>, + terminator: &mut Terminator<'tcx>, + ) -> bool { let target = match terminator.kind { - TerminatorKind::Goto { target } - if self.pred_count[target] == 1 - => target, - _ => return false + TerminatorKind::Goto { target } if self.pred_count[target] == 1 => target, + _ => return false, }; debug!("merging block {:?} into {:?}", target, terminator); @@ -216,7 +213,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { None => { // unreachable loop - this should not be possible, as we // don't strand blocks, but handle it correctly. - return false + return false; } }; new_stmts.extend(self.basic_blocks[target].statements.drain(..)); @@ -228,8 +225,8 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { // turn a branch with all successors identical to a goto fn simplify_branch(&mut self, terminator: &mut Terminator<'tcx>) -> bool { match terminator.kind { - TerminatorKind::SwitchInt { .. } => {}, - _ => return false + TerminatorKind::SwitchInt { .. } => {} + _ => return false, }; let first_succ = { @@ -239,10 +236,10 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { self.pred_count[first_succ] -= (count - 1) as u32; first_succ } else { - return false + return false; } } else { - return false + return false; } }; @@ -253,11 +250,8 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { fn strip_nops(&mut self) { for blk in self.basic_blocks.iter_mut() { - blk.statements.retain(|stmt| if let StatementKind::Nop = stmt.kind { - false - } else { - true - }) + blk.statements + .retain(|stmt| if let StatementKind::Nop = stmt.kind { false } else { true }) } } } @@ -271,7 +265,7 @@ pub fn remove_dead_blocks(body: &mut BodyAndCache<'_>) { let basic_blocks = body.basic_blocks_mut(); let num_blocks = basic_blocks.len(); - let mut replacements : Vec<_> = (0..num_blocks).map(BasicBlock::new).collect(); + let mut replacements: Vec<_> = (0..num_blocks).map(BasicBlock::new).collect(); let mut used_blocks = 0; for alive_index in seen.iter() { replacements[alive_index] = BasicBlock::new(used_blocks); @@ -291,20 +285,14 @@ pub fn remove_dead_blocks(body: &mut BodyAndCache<'_>) { } } - pub struct SimplifyLocals; impl<'tcx> MirPass<'tcx> for SimplifyLocals { - fn run_pass( - &self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx> - ) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { trace!("running SimplifyLocals on {:?}", source); let locals = { let read_only_cache = read_only!(body); - let mut marker = DeclMarker { - locals: BitSet::new_empty(body.local_decls.len()), - body, - }; + let mut marker = DeclMarker { locals: BitSet::new_empty(body.local_decls.len()), body }; marker.visit_body(read_only_cache); // Return pointer and arguments are always live marker.locals.insert(RETURN_PLACE); @@ -357,24 +345,26 @@ impl<'a, 'tcx> Visitor<'tcx> for DeclMarker<'a, 'tcx> { // Ignore stores of constants because `ConstProp` and `CopyProp` can remove uses of many // of these locals. However, if the local is still needed, then it will be referenced in // another place and we'll mark it as being used there. - if ctx == PlaceContext::MutatingUse(MutatingUseContext::Store) || - ctx == PlaceContext::MutatingUse(MutatingUseContext::Projection) { + if ctx == PlaceContext::MutatingUse(MutatingUseContext::Store) + || ctx == PlaceContext::MutatingUse(MutatingUseContext::Projection) + { let block = &self.body.basic_blocks()[location.block]; if location.statement_index != block.statements.len() { - let stmt = - &block.statements[location.statement_index]; + let stmt = &block.statements[location.statement_index]; - if let StatementKind::Assign( - box (p, Rvalue::Use(Operand::Constant(c))) - ) = &stmt.kind { + if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(c)))) = + &stmt.kind + { match c.literal.val { // Keep assignments from unevaluated constants around, since the evaluation // may report errors, even if the use of the constant is dead code. ty::ConstKind::Unevaluated(..) => {} - _ => if !p.is_indirect() { - trace!("skipping store of const value {:?} to {:?}", c, p); - return; - }, + _ => { + if !p.is_indirect() { + trace!("skipping store of const value {:?} to {:?}", c, p); + return; + } + } } } } @@ -396,20 +386,16 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> { fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) { // Remove unnecessary StorageLive and StorageDead annotations. - data.statements.retain(|stmt| { - match &stmt.kind { - StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => { - self.map[*l].is_some() - } - StatementKind::Assign(box (place, _)) => { - if let PlaceBase::Local(local) = place.base { - self.map[local].is_some() - } else { - true - } + data.statements.retain(|stmt| match &stmt.kind { + StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => self.map[*l].is_some(), + StatementKind::Assign(box (place, _)) => { + if let PlaceBase::Local(local) = place.base { + self.map[local].is_some() + } else { + true } - _ => true } + _ => true, }); self.super_basic_block_data(block, data); } @@ -418,15 +404,10 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> { *l = self.map[*l].unwrap(); } - fn process_projection_elem( - &mut self, - elem: &PlaceElem<'tcx>, - ) -> Option> { + fn process_projection_elem(&mut self, elem: &PlaceElem<'tcx>) -> Option> { match elem { - PlaceElem::Index(local) => { - Some(PlaceElem::Index(self.map[*local].unwrap())) - } - _ => None + PlaceElem::Index(local) => Some(PlaceElem::Index(self.map[*local].unwrap())), + _ => None, } } } diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs index aa3c5b01be35f..c233d0b516e2e 100644 --- a/src/librustc_mir/transform/simplify_branches.rs +++ b/src/librustc_mir/transform/simplify_branches.rs @@ -1,12 +1,14 @@ //! A pass that simplifies branches when their condition is known. -use rustc::ty::TyCtxt; -use rustc::mir::*; use crate::transform::{MirPass, MirSource}; +use rustc::mir::*; +use rustc::ty::TyCtxt; use std::borrow::Cow; -pub struct SimplifyBranches { label: String } +pub struct SimplifyBranches { + label: String, +} impl SimplifyBranches { pub fn new(label: &str) -> Self { @@ -25,7 +27,11 @@ impl<'tcx> MirPass<'tcx> for SimplifyBranches { let terminator = block.terminator_mut(); terminator.kind = match terminator.kind { TerminatorKind::SwitchInt { - discr: Operand::Constant(ref c), switch_ty, ref values, ref targets, .. + discr: Operand::Constant(ref c), + switch_ty, + ref values, + ref targets, + .. } => { let constant = c.literal.try_eval_bits(tcx, param_env, switch_ty); if let Some(constant) = constant { @@ -39,20 +45,21 @@ impl<'tcx> MirPass<'tcx> for SimplifyBranches { } ret } else { - continue + continue; } - }, + } TerminatorKind::Assert { target, cond: Operand::Constant(ref c), expected, .. - } if (c.literal.try_eval_bool(tcx, param_env) == Some(true)) == expected => - TerminatorKind::Goto { target }, + } if (c.literal.try_eval_bool(tcx, param_env) == Some(true)) == expected => { + TerminatorKind::Goto { target } + } TerminatorKind::FalseEdges { real_target, .. } => { TerminatorKind::Goto { target: real_target } - }, + } TerminatorKind::FalseUnwind { real_target, .. } => { TerminatorKind::Goto { target: real_target } - }, - _ => continue + } + _ => continue, }; } } diff --git a/src/librustc_mir/transform/simplify_try.rs b/src/librustc_mir/transform/simplify_try.rs index 752e852895738..3b8871f86b289 100644 --- a/src/librustc_mir/transform/simplify_try.rs +++ b/src/librustc_mir/transform/simplify_try.rs @@ -9,11 +9,11 @@ //! //! into just `x`. -use crate::transform::{MirPass, MirSource, simplify}; -use rustc::ty::{TyCtxt, Ty}; +use crate::transform::{simplify, MirPass, MirSource}; +use itertools::Itertools as _; use rustc::mir::*; +use rustc::ty::{Ty, TyCtxt}; use rustc_target::abi::VariantIdx; -use itertools::Itertools as _; /// Simplifies arms of form `Variant(x) => Variant(x)` to just a move. /// @@ -119,10 +119,9 @@ fn match_set_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local /// ``` fn match_set_discr<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, VariantIdx)> { match &stmt.kind { - StatementKind::SetDiscriminant { place, variant_index } => Some(( - place.as_local()?, - *variant_index - )), + StatementKind::SetDiscriminant { place, variant_index } => { + Some((place.as_local()?, *variant_index)) + } _ => None, } } @@ -177,19 +176,14 @@ impl<'tcx> MirPass<'tcx> for SimplifyBranchSame { .peekable(); // We want to `goto -> bb_first`. - let bb_first = iter_bbs_reachable - .peek() - .map(|(idx, _)| *idx) - .unwrap_or(targets[0]); + let bb_first = iter_bbs_reachable.peek().map(|(idx, _)| *idx).unwrap_or(targets[0]); // All successor basic blocks should have the exact same form. - let all_successors_equivalent = iter_bbs_reachable - .map(|(_, bb)| bb) - .tuple_windows() - .all(|(bb_l, bb_r)| { + let all_successors_equivalent = + iter_bbs_reachable.map(|(_, bb)| bb).tuple_windows().all(|(bb_l, bb_r)| { bb_l.is_cleanup == bb_r.is_cleanup - && bb_l.terminator().kind == bb_r.terminator().kind - && bb_l.statements.iter().eq_by(&bb_r.statements, |x, y| x.kind == y.kind) + && bb_l.terminator().kind == bb_r.terminator().kind + && bb_l.statements.iter().eq_by(&bb_r.statements, |x, y| x.kind == y.kind) }); if all_successors_equivalent { diff --git a/src/librustc_mir/util/aggregate.rs b/src/librustc_mir/util/aggregate.rs index e6c3e4384d7ae..28c1c52841172 100644 --- a/src/librustc_mir/util/aggregate.rs +++ b/src/librustc_mir/util/aggregate.rs @@ -1,6 +1,6 @@ use rustc::mir::*; -use rustc::ty::{Ty, TyCtxt}; use rustc::ty::layout::VariantIdx; +use rustc::ty::{Ty, TyCtxt}; use rustc_index::vec::Idx; use std::iter::TrustedLen; @@ -14,18 +14,18 @@ use std::iter::TrustedLen; /// discriminant(lhs) = variant_index; // If lhs is an enum or generator. pub fn expand_aggregate<'tcx>( mut lhs: Place<'tcx>, - operands: impl Iterator, Ty<'tcx>)> + TrustedLen, + operands: impl Iterator, Ty<'tcx>)> + TrustedLen, kind: AggregateKind<'tcx>, source_info: SourceInfo, tcx: TyCtxt<'tcx>, -) -> impl Iterator> + TrustedLen { +) -> impl Iterator> + TrustedLen { let mut set_discriminant = None; let active_field_index = match kind { AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => { if adt_def.is_enum() { set_discriminant = Some(Statement { kind: StatementKind::SetDiscriminant { - place: box(lhs.clone()), + place: box (lhs.clone()), variant_index, }, source_info, @@ -39,10 +39,7 @@ pub fn expand_aggregate<'tcx>( // variant 0 (Unresumed). let variant_index = VariantIdx::new(0); set_discriminant = Some(Statement { - kind: StatementKind::SetDiscriminant { - place: box(lhs.clone()), - variant_index, - }, + kind: StatementKind::SetDiscriminant { place: box (lhs.clone()), variant_index }, source_info, }); @@ -51,27 +48,31 @@ pub fn expand_aggregate<'tcx>( None } - _ => None + _ => None, }; - operands.into_iter().enumerate().map(move |(i, (op, ty))| { - let lhs_field = if let AggregateKind::Array(_) = kind { - // FIXME(eddyb) `offset` should be u64. - let offset = i as u32; - assert_eq!(offset as usize, i); - tcx.mk_place_elem(lhs.clone(), ProjectionElem::ConstantIndex { - offset, - // FIXME(eddyb) `min_length` doesn't appear to be used. - min_length: offset + 1, - from_end: false - }) - } else { - let field = Field::new(active_field_index.unwrap_or(i)); - tcx.mk_place_field(lhs.clone(), field, ty) - }; - Statement { - source_info, - kind: StatementKind::Assign(box(lhs_field, Rvalue::Use(op))), - } - }).chain(set_discriminant) + operands + .into_iter() + .enumerate() + .map(move |(i, (op, ty))| { + let lhs_field = if let AggregateKind::Array(_) = kind { + // FIXME(eddyb) `offset` should be u64. + let offset = i as u32; + assert_eq!(offset as usize, i); + tcx.mk_place_elem( + lhs.clone(), + ProjectionElem::ConstantIndex { + offset, + // FIXME(eddyb) `min_length` doesn't appear to be used. + min_length: offset + 1, + from_end: false, + }, + ) + } else { + let field = Field::new(active_field_index.unwrap_or(i)); + tcx.mk_place_field(lhs.clone(), field, ty) + }; + Statement { source_info, kind: StatementKind::Assign(box (lhs_field, Rvalue::Use(op))) } + }) + .chain(set_discriminant) } diff --git a/src/librustc_mir/util/alignment.rs b/src/librustc_mir/util/alignment.rs index f949fcf0745f0..70d6aaf70eb09 100644 --- a/src/librustc_mir/util/alignment.rs +++ b/src/librustc_mir/util/alignment.rs @@ -1,5 +1,5 @@ -use rustc::ty::{self, TyCtxt}; use rustc::mir::*; +use rustc::ty::{self, TyCtxt}; /// Returns `true` if this place is allowed to be less aligned /// than its containing struct (because it is within a packed @@ -16,7 +16,7 @@ where debug!("is_disaligned({:?})", place); if !is_within_packed(tcx, local_decls, place) { debug!("is_disaligned({:?}) - not within packed", place); - return false + return false; } let ty = place.ty(local_decls, tcx).ty; @@ -48,9 +48,7 @@ where ProjectionElem::Field(..) => { let ty = Place::ty_from(&place.base, proj_base, local_decls, tcx).ty; match ty.kind { - ty::Adt(def, _) if def.repr.packed() => { - return true - } + ty::Adt(def, _) if def.repr.packed() => return true, _ => {} } } diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index 9004b5e72370c..d14168703df99 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -5,18 +5,8 @@ use syntax_pos::{MultiSpan, Span}; use rustc_error_codes::*; impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { - crate fn cannot_move_when_borrowed( - &self, - span: Span, - desc: &str, - ) -> DiagnosticBuilder<'cx> { - struct_span_err!( - self, - span, - E0505, - "cannot move out of `{}` because it is borrowed", - desc, - ) + crate fn cannot_move_when_borrowed(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx> { + struct_span_err!(self, span, E0505, "cannot move out of `{}` because it is borrowed", desc,) } crate fn cannot_use_when_mutably_borrowed( @@ -34,10 +24,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { desc, ); - err.span_label( - borrow_span, - format!("borrow of `{}` occurs here", borrow_desc), - ); + err.span_label(borrow_span, format!("borrow of `{}` occurs here", borrow_desc)); err.span_label(span, format!("use of borrowed `{}`", borrow_desc)); err } @@ -67,8 +54,8 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { old_opt_via: &str, old_load_end_span: Option, ) -> DiagnosticBuilder<'cx> { - let via = |msg: &str| - if msg.is_empty() { msg.to_string() } else { format!(" (via `{}`)", msg) }; + let via = + |msg: &str| if msg.is_empty() { msg.to_string() } else { format!(" (via `{}`)", msg) }; let mut err = struct_span_err!( self, new_loan_span, @@ -124,7 +111,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { if old_loan_span == new_loan_span { err.span_label( old_loan_span, - "closures are constructed here in different iterations of loop" + "closures are constructed here in different iterations of loop", ); } else { err.span_label(old_loan_span, "first closure is constructed here"); @@ -215,8 +202,8 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { msg_old: &str, old_load_end_span: Option, ) -> DiagnosticBuilder<'cx> { - let via = |msg: &str| - if msg.is_empty() { msg.to_string() } else { format!(" (via `{}`)", msg) }; + let via = + |msg: &str| if msg.is_empty() { msg.to_string() } else { format!(" (via `{}`)", msg) }; let mut err = struct_span_err!( self, span, @@ -242,12 +229,9 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { format!( "{} borrow of `{}` -- which overlaps with `{}` -- occurs here", kind_new, msg_new, msg_old, - ) - ); - err.span_label( - old_span, - format!("{} borrow occurs here{}", kind_old, via(msg_old)), + ), ); + err.span_label(old_span, format!("{} borrow occurs here{}", kind_old, via(msg_old))); } if let Some(old_load_end_span) = old_load_end_span { @@ -271,10 +255,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { ); err.span_label(borrow_span, format!("borrow of `{}` occurs here", desc)); - err.span_label( - span, - format!("assignment to borrowed `{}` occurs here", desc), - ); + err.span_label(span, format!("assignment to borrowed `{}` occurs here", desc)); err } @@ -284,19 +265,8 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { desc: &str, is_arg: bool, ) -> DiagnosticBuilder<'cx> { - let msg = if is_arg { - "to immutable argument" - } else { - "twice to immutable variable" - }; - struct_span_err!( - self, - span, - E0384, - "cannot assign {} `{}`", - msg, - desc, - ) + let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" }; + struct_span_err!(self, span, E0384, "cannot assign {} `{}`", msg, desc,) } crate fn cannot_assign(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx> { @@ -308,13 +278,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { move_from_span: Span, move_from_desc: &str, ) -> DiagnosticBuilder<'cx> { - struct_span_err!( - self, - move_from_span, - E0507, - "cannot move out of {}", - move_from_desc, - ) + struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc,) } /// Signal an error due to an attempt to move out of the interior @@ -366,9 +330,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { optional_adverb_for_moved: &str, moved_path: Option, ) -> DiagnosticBuilder<'cx> { - let moved_path = moved_path - .map(|mp| format!(": `{}`", mp)) - .unwrap_or_default(); + let moved_path = moved_path.map(|mp| format!(": `{}`", mp)).unwrap_or_default(); struct_span_err!( self, @@ -387,14 +349,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { path: &str, reason: &str, ) -> DiagnosticBuilder<'cx> { - struct_span_err!( - self, - span, - E0596, - "cannot borrow {} as mutable{}", - path, - reason, - ) + struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{}", path, reason,) } crate fn cannot_mutate_in_immutable_section( @@ -434,10 +389,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { err } - crate fn cannot_borrow_across_destructor( - &self, - borrow_span: Span, - ) -> DiagnosticBuilder<'cx> { + crate fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> DiagnosticBuilder<'cx> { struct_span_err!( self, borrow_span, @@ -451,13 +403,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { span: Span, path: &str, ) -> DiagnosticBuilder<'cx> { - struct_span_err!( - self, - span, - E0597, - "{} does not live long enough", - path, - ) + struct_span_err!(self, span, E0597, "{} does not live long enough", path,) } crate fn cannot_return_reference_to_local( @@ -472,9 +418,9 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { span, E0515, "cannot {RETURN} {REFERENCE} {LOCAL}", - RETURN=return_kind, - REFERENCE=reference_desc, - LOCAL=path_desc, + RETURN = return_kind, + REFERENCE = reference_desc, + LOCAL = path_desc, ); err.span_label( @@ -501,10 +447,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { borrowed_path, ); err.span_label(capture_span, format!("{} is borrowed here", borrowed_path)) - .span_label( - closure_span, - format!("may outlive borrowed value {}", borrowed_path), - ); + .span_label(closure_span, format!("may outlive borrowed value {}", borrowed_path)); err } @@ -512,24 +455,11 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> { &self, span: Span, ) -> DiagnosticBuilder<'cx> { - struct_span_err!( - self, - span, - E0712, - "thread-local variable borrowed past end of function", - ) + struct_span_err!(self, span, E0712, "thread-local variable borrowed past end of function",) } - crate fn temporary_value_borrowed_for_too_long( - &self, - span: Span, - ) -> DiagnosticBuilder<'cx> { - struct_span_err!( - self, - span, - E0716, - "temporary value dropped while borrowed", - ) + crate fn temporary_value_borrowed_for_too_long(&self, span: Span) -> DiagnosticBuilder<'cx> { + struct_span_err!(self, span, E0716, "temporary value dropped while borrowed",) } fn struct_span_err_with_code>( diff --git a/src/librustc_mir/util/collect_writes.rs b/src/librustc_mir/util/collect_writes.rs index 4006787f260fc..6cd2131649673 100644 --- a/src/librustc_mir/util/collect_writes.rs +++ b/src/librustc_mir/util/collect_writes.rs @@ -1,7 +1,7 @@ -use rustc::mir::{Local, Location}; -use rustc::mir::ReadOnlyBodyAndCache; use rustc::mir::visit::PlaceContext; use rustc::mir::visit::Visitor; +use rustc::mir::ReadOnlyBodyAndCache; +use rustc::mir::{Local, Location}; crate trait FindAssignments { // Finds all statements that assign directly to local (i.e., X = ...) @@ -9,11 +9,11 @@ crate trait FindAssignments { fn find_assignments(&self, local: Local) -> Vec; } -impl<'a, 'tcx> FindAssignments for ReadOnlyBodyAndCache<'a, 'tcx>{ - fn find_assignments(&self, local: Local) -> Vec{ - let mut visitor = FindLocalAssignmentVisitor{ needle: local, locations: vec![]}; - visitor.visit_body(*self); - visitor.locations +impl<'a, 'tcx> FindAssignments for ReadOnlyBodyAndCache<'a, 'tcx> { + fn find_assignments(&self, local: Local) -> Vec { + let mut visitor = FindLocalAssignmentVisitor { needle: local, locations: vec![] }; + visitor.visit_body(*self); + visitor.locations } } @@ -25,10 +25,7 @@ struct FindLocalAssignmentVisitor { } impl<'tcx> Visitor<'tcx> for FindLocalAssignmentVisitor { - fn visit_local(&mut self, - local: &Local, - place_context: PlaceContext, - location: Location) { + fn visit_local(&mut self, local: &Local, place_context: PlaceContext, location: Location) { if self.needle != *local { return; } diff --git a/src/librustc_mir/util/def_use.rs b/src/librustc_mir/util/def_use.rs index cf98755eb6d90..aa9ddbdbda94f 100644 --- a/src/librustc_mir/util/def_use.rs +++ b/src/librustc_mir/util/def_use.rs @@ -1,9 +1,9 @@ //! Def-use analysis. +use rustc::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc::mir::{ Body, BodyAndCache, Local, Location, PlaceElem, ReadOnlyBodyAndCache, VarDebugInfo, }; -use rustc::mir::visit::{PlaceContext, MutVisitor, Visitor}; use rustc::ty::TyCtxt; use rustc_index::vec::IndexVec; use std::mem; @@ -27,9 +27,7 @@ pub struct Use { impl DefUseAnalysis { pub fn new(body: &Body<'_>) -> DefUseAnalysis { - DefUseAnalysis { - info: IndexVec::from_elem_n(Info::new(), body.local_decls.len()), - } + DefUseAnalysis { info: IndexVec::from_elem_n(Info::new(), body.local_decls.len()) } } pub fn analyze(&mut self, body: ReadOnlyBodyAndCache<'_, '_>) { @@ -73,11 +71,13 @@ impl DefUseAnalysis { } // FIXME(pcwalton): this should update the def-use chains. - pub fn replace_all_defs_and_uses_with(&self, - local: Local, - body: &mut BodyAndCache<'tcx>, - new_local: Local, - tcx: TyCtxt<'tcx>) { + pub fn replace_all_defs_and_uses_with( + &self, + local: Local, + body: &mut BodyAndCache<'tcx>, + new_local: Local, + tcx: TyCtxt<'tcx>, + ) { self.mutate_defs_and_uses(local, body, new_local, tcx) } } @@ -89,18 +89,12 @@ struct DefUseFinder { } impl Visitor<'_> for DefUseFinder { - fn visit_local(&mut self, - &local: &Local, - context: PlaceContext, - location: Location) { + fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) { let info = &mut self.info[local]; if self.in_var_debug_info { info.var_debug_info_indices.push(self.var_debug_info_index); } else { - info.defs_and_uses.push(Use { - context, - location, - }); + info.defs_and_uses.push(Use { context, location }); } } fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo<'tcx>) { @@ -114,10 +108,7 @@ impl Visitor<'_> for DefUseFinder { impl Info { fn new() -> Info { - Info { - defs_and_uses: vec![], - var_debug_info_indices: vec![], - } + Info { defs_and_uses: vec![], var_debug_info_indices: vec![] } } fn clear(&mut self) { @@ -133,18 +124,14 @@ impl Info { self.defs_not_including_drop().count() } - pub fn defs_not_including_drop( - &self, - ) -> impl Iterator { - self.defs_and_uses.iter().filter(|place_use| { - place_use.context.is_mutating_use() && !place_use.context.is_drop() - }) + pub fn defs_not_including_drop(&self) -> impl Iterator { + self.defs_and_uses + .iter() + .filter(|place_use| place_use.context.is_mutating_use() && !place_use.context.is_drop()) } pub fn use_count(&self) -> usize { - self.defs_and_uses.iter().filter(|place_use| { - place_use.context.is_nonmutating_use() - }).count() + self.defs_and_uses.iter().filter(|place_use| place_use.context.is_nonmutating_use()).count() } } @@ -155,11 +142,7 @@ struct MutateUseVisitor<'tcx> { } impl MutateUseVisitor<'tcx> { - fn new( - query: Local, - new_local: Local, - tcx: TyCtxt<'tcx>, - ) -> MutateUseVisitor<'tcx> { + fn new(query: Local, new_local: Local, tcx: TyCtxt<'tcx>) -> MutateUseVisitor<'tcx> { MutateUseVisitor { query, new_local, tcx } } } @@ -169,19 +152,13 @@ impl MutVisitor<'tcx> for MutateUseVisitor<'tcx> { self.tcx } - fn visit_local(&mut self, - local: &mut Local, - _context: PlaceContext, - _location: Location) { + fn visit_local(&mut self, local: &mut Local, _context: PlaceContext, _location: Location) { if *local == self.query { *local = self.new_local; } } - fn process_projection_elem( - &mut self, - elem: &PlaceElem<'tcx>, - ) -> Option> { + fn process_projection_elem(&mut self, elem: &PlaceElem<'tcx>) -> Option> { match elem { PlaceElem::Index(local) if *local == self.query => { Some(PlaceElem::Index(self.new_local)) diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 6ff84996bd34a..7fd67385edd5a 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -1,28 +1,28 @@ -use std::fmt; +use crate::util::patch::MirPatch; use rustc::hir; -use rustc::mir::*; use rustc::middle::lang_items; +use rustc::mir::*; use rustc::traits::Reveal; -use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::layout::VariantIdx; use rustc::ty::subst::SubstsRef; use rustc::ty::util::IntTypeExt; +use rustc::ty::{self, Ty, TyCtxt}; use rustc_index::vec::Idx; -use crate::util::patch::MirPatch; +use std::fmt; use std::convert::TryInto; #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum DropFlagState { Present, // i.e., initialized - Absent, // i.e., deinitialized or "moved" + Absent, // i.e., deinitialized or "moved" } impl DropFlagState { pub fn value(self) -> bool { match self { DropFlagState::Present => true, - DropFlagState::Absent => false + DropFlagState::Absent => false, } } } @@ -38,20 +38,20 @@ pub enum DropStyle { #[derive(Debug)] pub enum DropFlagMode { Shallow, - Deep + Deep, } #[derive(Copy, Clone, Debug)] pub enum Unwind { To(BasicBlock), - InCleanup + InCleanup, } impl Unwind { fn is_cleanup(self) -> bool { match self { Unwind::To(..) => false, - Unwind::InCleanup => true + Unwind::InCleanup => true, } } @@ -62,16 +62,19 @@ impl Unwind { } } - fn map(self, f: F) -> Self where F: FnOnce(BasicBlock) -> BasicBlock { + fn map(self, f: F) -> Self + where + F: FnOnce(BasicBlock) -> BasicBlock, + { match self { Unwind::To(bb) => Unwind::To(f(bb)), - Unwind::InCleanup => Unwind::InCleanup + Unwind::InCleanup => Unwind::InCleanup, } } } pub trait DropElaborator<'a, 'tcx>: fmt::Debug { - type Path : Copy + fmt::Debug; + type Path: Copy + fmt::Debug; fn patch(&mut self) -> &mut MirPatch<'tcx>; fn body(&self) -> &'a Body<'tcx>; @@ -82,7 +85,6 @@ pub trait DropElaborator<'a, 'tcx>: fmt::Debug { fn get_drop_flag(&mut self, path: Self::Path) -> Option>; fn clear_drop_flag(&mut self, location: Location, path: Self::Path, mode: DropFlagMode); - fn field_subpath(&self, path: Self::Path, field: Field) -> Option; fn deref_subpath(&self, path: Self::Path) -> Option; fn downcast_subpath(&self, path: Self::Path, variant: VariantIdx) -> Option; @@ -116,9 +118,7 @@ pub fn elaborate_drop<'b, 'tcx, D>( D: DropElaborator<'b, 'tcx>, 'tcx: 'b, { - DropCtxt { - elaborator, source_info, place, path, succ, unwind - }.elaborate_drop(bb) + DropCtxt { elaborator, source_info, place, path, succ, unwind }.elaborate_drop(bb) } impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> @@ -158,85 +158,98 @@ where debug!("elaborate_drop({:?}): live - {:?}", self, style); match style { DropStyle::Dead => { - self.elaborator.patch().patch_terminator(bb, TerminatorKind::Goto { - target: self.succ - }); + self.elaborator + .patch() + .patch_terminator(bb, TerminatorKind::Goto { target: self.succ }); } DropStyle::Static => { let loc = self.terminator_loc(bb); self.elaborator.clear_drop_flag(loc, self.path, DropFlagMode::Deep); - self.elaborator.patch().patch_terminator(bb, TerminatorKind::Drop { - location: self.place.clone(), - target: self.succ, - unwind: self.unwind.into_option(), - }); + self.elaborator.patch().patch_terminator( + bb, + TerminatorKind::Drop { + location: self.place.clone(), + target: self.succ, + unwind: self.unwind.into_option(), + }, + ); } DropStyle::Conditional => { let unwind = self.unwind; // FIXME(#43234) let succ = self.succ; let drop_bb = self.complete_drop(Some(DropFlagMode::Deep), succ, unwind); - self.elaborator.patch().patch_terminator(bb, TerminatorKind::Goto { - target: drop_bb - }); + self.elaborator + .patch() + .patch_terminator(bb, TerminatorKind::Goto { target: drop_bb }); } DropStyle::Open => { let drop_bb = self.open_drop(); - self.elaborator.patch().patch_terminator(bb, TerminatorKind::Goto { - target: drop_bb - }); + self.elaborator + .patch() + .patch_terminator(bb, TerminatorKind::Goto { target: drop_bb }); } } } /// Returns the place and move path for each field of `variant`, /// (the move path is `None` if the field is a rest field). - fn move_paths_for_fields(&self, - base_place: &Place<'tcx>, - variant_path: D::Path, - variant: &'tcx ty::VariantDef, - substs: SubstsRef<'tcx>) - -> Vec<(Place<'tcx>, Option)> - { - variant.fields.iter().enumerate().map(|(i, f)| { - let field = Field::new(i); - let subpath = self.elaborator.field_subpath(variant_path, field); - let tcx = self.tcx(); - - assert_eq!(self.elaborator.param_env().reveal, Reveal::All); - let field_ty = tcx.normalize_erasing_regions( - self.elaborator.param_env(), - f.ty(tcx, substs), - ); - (tcx.mk_place_field(base_place.clone(), field, field_ty), subpath) - }).collect() + fn move_paths_for_fields( + &self, + base_place: &Place<'tcx>, + variant_path: D::Path, + variant: &'tcx ty::VariantDef, + substs: SubstsRef<'tcx>, + ) -> Vec<(Place<'tcx>, Option)> { + variant + .fields + .iter() + .enumerate() + .map(|(i, f)| { + let field = Field::new(i); + let subpath = self.elaborator.field_subpath(variant_path, field); + let tcx = self.tcx(); + + assert_eq!(self.elaborator.param_env().reveal, Reveal::All); + let field_ty = + tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs)); + (tcx.mk_place_field(base_place.clone(), field, field_ty), subpath) + }) + .collect() } - fn drop_subpath(&mut self, - place: &Place<'tcx>, - path: Option, - succ: BasicBlock, - unwind: Unwind) - -> BasicBlock - { + fn drop_subpath( + &mut self, + place: &Place<'tcx>, + path: Option, + succ: BasicBlock, + unwind: Unwind, + ) -> BasicBlock { if let Some(path) = path { debug!("drop_subpath: for std field {:?}", place); DropCtxt { elaborator: self.elaborator, source_info: self.source_info, - path, place, succ, unwind, - }.elaborated_drop_block() + path, + place, + succ, + unwind, + } + .elaborated_drop_block() } else { debug!("drop_subpath: for rest field {:?}", place); DropCtxt { elaborator: self.elaborator, source_info: self.source_info, - place, succ, unwind, + place, + succ, + unwind, // Using `self.path` here to condition the drop on // our own drop flag. - path: self.path - }.complete_drop(None, succ, unwind) + path: self.path, + } + .complete_drop(None, succ, unwind) } } @@ -246,19 +259,21 @@ where /// /// `unwind_ladder` is such a list of steps in reverse order, /// which is called if the matching step of the drop glue panics. - fn drop_halfladder(&mut self, - unwind_ladder: &[Unwind], - mut succ: BasicBlock, - fields: &[(Place<'tcx>, Option)]) - -> Vec - { - Some(succ).into_iter().chain( - fields.iter().rev().zip(unwind_ladder) - .map(|(&(ref place, path), &unwind_succ)| { + fn drop_halfladder( + &mut self, + unwind_ladder: &[Unwind], + mut succ: BasicBlock, + fields: &[(Place<'tcx>, Option)], + ) -> Vec { + Some(succ) + .into_iter() + .chain(fields.iter().rev().zip(unwind_ladder).map( + |(&(ref place, path), &unwind_succ)| { succ = self.drop_subpath(place, path, succ, unwind_succ); succ - }) - ).collect() + }, + )) + .collect() } fn drop_ladder_bottom(&mut self) -> (BasicBlock, Unwind) { @@ -270,7 +285,7 @@ where self.drop_flag_reset_block(DropFlagMode::Shallow, succ, unwind), unwind.map(|unwind| { self.drop_flag_reset_block(DropFlagMode::Shallow, unwind, Unwind::InCleanup) - }) + }), ) } @@ -314,8 +329,7 @@ where unwind_ladder }; - let normal_ladder = - self.drop_halfladder(&unwind_ladder, succ, &fields); + let normal_ladder = self.drop_halfladder(&unwind_ladder, succ, &fields); (*normal_ladder.last().unwrap(), *unwind_ladder.last().unwrap()) } @@ -323,10 +337,16 @@ where fn open_drop_for_tuple(&mut self, tys: &[Ty<'tcx>]) -> BasicBlock { debug!("open_drop_for_tuple({:?}, {:?})", self, tys); - let fields = tys.iter().enumerate().map(|(i, &ty)| { - (self.tcx().mk_place_field(self.place.clone(), Field::new(i), ty), - self.elaborator.field_subpath(self.path, Field::new(i))) - }).collect(); + let fields = tys + .iter() + .enumerate() + .map(|(i, &ty)| { + ( + self.tcx().mk_place_field(self.place.clone(), Field::new(i), ty), + self.elaborator.field_subpath(self.path, Field::new(i)), + ) + }) + .collect(); let (succ, unwind) = self.drop_ladder_bottom(); self.drop_ladder(fields, succ, unwind).0 @@ -341,9 +361,8 @@ where let succ = self.succ; // FIXME(#43234) let unwind = self.unwind; let succ = self.box_free_block(adt, substs, succ, unwind); - let unwind_succ = self.unwind.map(|unwind| { - self.box_free_block(adt, substs, unwind, Unwind::InCleanup) - }); + let unwind_succ = + self.unwind.map(|unwind| self.box_free_block(adt, substs, unwind, Unwind::InCleanup)); self.drop_subpath(&interior, interior_path, succ, unwind_succ) } @@ -355,9 +374,9 @@ where statements: vec![], terminator: Some(Terminator { source_info: self.source_info, - kind: TerminatorKind::Unreachable + kind: TerminatorKind::Unreachable, }), - is_cleanup: self.unwind.is_cleanup() + is_cleanup: self.unwind.is_cleanup(), }); } @@ -376,16 +395,18 @@ where } } - fn open_drop_for_adt_contents(&mut self, adt: &'tcx ty::AdtDef, - substs: SubstsRef<'tcx>) - -> (BasicBlock, Unwind) { + fn open_drop_for_adt_contents( + &mut self, + adt: &'tcx ty::AdtDef, + substs: SubstsRef<'tcx>, + ) -> (BasicBlock, Unwind) { let (succ, unwind) = self.drop_ladder_bottom(); if !adt.is_enum() { let fields = self.move_paths_for_fields( self.place, self.path, &adt.variants[VariantIdx::new(0)], - substs + substs, ); self.drop_ladder(fields, succ, unwind) } else { @@ -393,25 +414,23 @@ where } } - fn open_drop_for_multivariant(&mut self, adt: &'tcx ty::AdtDef, - substs: SubstsRef<'tcx>, - succ: BasicBlock, - unwind: Unwind) - -> (BasicBlock, Unwind) { + fn open_drop_for_multivariant( + &mut self, + adt: &'tcx ty::AdtDef, + substs: SubstsRef<'tcx>, + succ: BasicBlock, + unwind: Unwind, + ) -> (BasicBlock, Unwind) { let mut values = Vec::with_capacity(adt.variants.len()); let mut normal_blocks = Vec::with_capacity(adt.variants.len()); - let mut unwind_blocks = if unwind.is_cleanup() { - None - } else { - Some(Vec::with_capacity(adt.variants.len())) - }; + let mut unwind_blocks = + if unwind.is_cleanup() { None } else { Some(Vec::with_capacity(adt.variants.len())) }; let mut have_otherwise = false; let tcx = self.tcx(); for (variant_index, discr) in adt.discriminants(tcx) { - let subpath = self.elaborator.downcast_subpath( - self.path, variant_index); + let subpath = self.elaborator.downcast_subpath(self.path, variant_index); if let Some(variant_path) = subpath { let base_place = tcx.mk_place_elem( self.place.clone(), @@ -424,7 +443,8 @@ where &base_place, variant_path, &adt.variants[variant_index], - substs); + substs, + ); values.push(discr.val); if let Unwind::To(unwind) = unwind { // We can't use the half-ladder from the original @@ -447,8 +467,7 @@ where let unwind_blocks = unwind_blocks.as_mut().unwrap(); let unwind_ladder = vec![Unwind::InCleanup; fields.len() + 1]; - let halfladder = - self.drop_halfladder(&unwind_ladder, unwind, &fields); + let halfladder = self.drop_halfladder(&unwind_ladder, unwind, &fields); unwind_blocks.push(halfladder.last().cloned().unwrap()); } let (normal, _) = self.drop_ladder(fields, succ, unwind); @@ -461,29 +480,34 @@ where if have_otherwise { normal_blocks.push(self.drop_block(succ, unwind)); if let Unwind::To(unwind) = unwind { - unwind_blocks.as_mut().unwrap().push( - self.drop_block(unwind, Unwind::InCleanup) - ); + unwind_blocks.as_mut().unwrap().push(self.drop_block(unwind, Unwind::InCleanup)); } } else { values.pop(); } - (self.adt_switch_block(adt, normal_blocks, &values, succ, unwind), - unwind.map(|unwind| { - self.adt_switch_block( - adt, unwind_blocks.unwrap(), &values, unwind, Unwind::InCleanup - ) - })) - } - - fn adt_switch_block(&mut self, - adt: &'tcx ty::AdtDef, - blocks: Vec, - values: &[u128], - succ: BasicBlock, - unwind: Unwind) - -> BasicBlock { + ( + self.adt_switch_block(adt, normal_blocks, &values, succ, unwind), + unwind.map(|unwind| { + self.adt_switch_block( + adt, + unwind_blocks.unwrap(), + &values, + unwind, + Unwind::InCleanup, + ) + }), + ) + } + + fn adt_switch_block( + &mut self, + adt: &'tcx ty::AdtDef, + blocks: Vec, + values: &[u128], + succ: BasicBlock, + unwind: Unwind, + ) -> BasicBlock { // If there are multiple variants, then if something // is present within the enum the discriminant, tracked // by the rest path, must be initialized. @@ -503,7 +527,7 @@ where switch_ty: discr_ty, values: From::from(values.to_owned()), targets: blocks, - } + }, }), is_cleanup: unwind.is_cleanup(), }; @@ -519,24 +543,28 @@ where let ty = self.place_ty(self.place); let substs = tcx.mk_substs_trait(ty, &[]); - let ref_ty = tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut { - ty, - mutbl: hir::Mutability::Mut - }); + let ref_ty = + tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut { ty, mutbl: hir::Mutability::Mut }); let ref_place = self.new_temp(ref_ty); let unit_temp = Place::from(self.new_temp(tcx.mk_unit())); let result = BasicBlockData { statements: vec![self.assign( &Place::from(ref_place), - Rvalue::Ref(tcx.lifetimes.re_erased, - BorrowKind::Mut { allow_two_phase_borrow: false }, - self.place.clone()) + Rvalue::Ref( + tcx.lifetimes.re_erased, + BorrowKind::Mut { allow_two_phase_borrow: false }, + self.place.clone(), + ), )], terminator: Some(Terminator { kind: TerminatorKind::Call { - func: Operand::function_handle(tcx, drop_fn.def_id, substs, - self.source_info.span), + func: Operand::function_handle( + tcx, + drop_fn.def_id, + substs, + self.source_info.span, + ), args: vec![Operand::Move(Place::from(ref_place))], destination: Some((unit_temp, succ)), cleanup: unwind.into_option(), @@ -578,19 +606,13 @@ where let move_ = |place: Place<'tcx>| Operand::Move(place); let tcx = self.tcx(); - let ptr_ty = tcx.mk_ptr(ty::TypeAndMut { - ty: ety, - mutbl: hir::Mutability::Mut - }); + let ptr_ty = tcx.mk_ptr(ty::TypeAndMut { ty: ety, mutbl: hir::Mutability::Mut }); let ptr = &Place::from(self.new_temp(ptr_ty)); let can_go = Place::from(self.new_temp(tcx.types.bool)); let one = self.constant_usize(1); let (ptr_next, cur_next) = if ptr_based { - ( - Rvalue::Use(copy(cur.into())), - Rvalue::BinaryOp(BinOp::Offset, move_(cur.into()), one), - ) + (Rvalue::Use(copy(cur.into())), Rvalue::BinaryOp(BinOp::Offset, move_(cur.into()), one)) } else { ( Rvalue::AddressOf(Mutability::Mut, tcx.mk_place_index(self.place.clone(), cur)), @@ -599,38 +621,37 @@ where }; let drop_block = BasicBlockData { - statements: vec![ - self.assign(ptr, ptr_next), - self.assign(&Place::from(cur), cur_next) - ], + statements: vec![self.assign(ptr, ptr_next), self.assign(&Place::from(cur), cur_next)], is_cleanup: unwind.is_cleanup(), terminator: Some(Terminator { source_info: self.source_info, // this gets overwritten by drop elaboration. kind: TerminatorKind::Unreachable, - }) + }), }; let drop_block = self.elaborator.patch().new_block(drop_block); let loop_block = BasicBlockData { - statements: vec![ - self.assign(&can_go, Rvalue::BinaryOp(BinOp::Eq, - copy(Place::from(cur)), - copy(length_or_end.clone()))) - ], + statements: vec![self.assign( + &can_go, + Rvalue::BinaryOp(BinOp::Eq, copy(Place::from(cur)), copy(length_or_end.clone())), + )], is_cleanup: unwind.is_cleanup(), terminator: Some(Terminator { source_info: self.source_info, - kind: TerminatorKind::if_(tcx, move_(can_go), succ, drop_block) - }) + kind: TerminatorKind::if_(tcx, move_(can_go), succ, drop_block), + }), }; let loop_block = self.elaborator.patch().new_block(loop_block); - self.elaborator.patch().patch_terminator(drop_block, TerminatorKind::Drop { - location: tcx.mk_place_deref(ptr.clone()), - target: loop_block, - unwind: unwind.into_option() - }); + self.elaborator.patch().patch_terminator( + drop_block, + TerminatorKind::Drop { + location: tcx.mk_place_deref(ptr.clone()), + target: loop_block, + unwind: unwind.into_option(), + }, + ); loop_block } @@ -666,9 +687,9 @@ where }) .collect(); - if fields.iter().any(|(_,path)| path.is_some()) { + if fields.iter().any(|(_, path)| path.is_some()) { let (succ, unwind) = self.drop_ladder_bottom(); - return self.drop_ladder(fields, succ, unwind).0 + return self.drop_ladder(fields, succ, unwind).0; } } @@ -695,7 +716,7 @@ where self.drop_loop_pair(ety, true, len.clone()), ], }, - }) + }), }; self.elaborator.patch().new_block(base_block) } @@ -711,35 +732,17 @@ where ) -> BasicBlock { debug!("drop_loop_pair({:?}, {:?})", ety, ptr_based); let tcx = self.tcx(); - let iter_ty = if ptr_based { - tcx.mk_mut_ptr(ety) - } else { - tcx.types.usize - }; + let iter_ty = if ptr_based { tcx.mk_mut_ptr(ety) } else { tcx.types.usize }; let cur = self.new_temp(iter_ty); - let length_or_end = if ptr_based { - Place::from(self.new_temp(iter_ty)) - } else { - length.clone() - }; + let length_or_end = + if ptr_based { Place::from(self.new_temp(iter_ty)) } else { length.clone() }; let unwind = self.unwind.map(|unwind| { - self.drop_loop(unwind, - cur, - &length_or_end, - ety, - Unwind::InCleanup, - ptr_based) + self.drop_loop(unwind, cur, &length_or_end, ety, Unwind::InCleanup, ptr_based) }); - let loop_block = self.drop_loop( - self.succ, - cur, - &length_or_end, - ety, - unwind, - ptr_based); + let loop_block = self.drop_loop(self.succ, cur, &length_or_end, ety, unwind, ptr_based); let cur = Place::from(cur); let drop_block_stmts = if ptr_based { @@ -766,8 +769,8 @@ where is_cleanup: unwind.is_cleanup(), terminator: Some(Terminator { source_info: self.source_info, - kind: TerminatorKind::Goto { target: loop_block } - }) + kind: TerminatorKind::Goto { target: loop_block }, + }), }); // FIXME(#34708): handle partially-dropped array/slice elements. @@ -787,7 +790,7 @@ where let ty = self.place_ty(self.place); match ty.kind { ty::Closure(def_id, substs) => { - let tys : Vec<_> = substs.as_closure().upvar_tys(def_id, self.tcx()).collect(); + let tys: Vec<_> = substs.as_closure().upvar_tys(def_id, self.tcx()).collect(); self.open_drop_for_tuple(&tys) } // Note that `elaborate_drops` only drops the upvars of a generator, @@ -797,7 +800,7 @@ where // It effetively only contains upvars until the generator transformation runs. // See librustc_body/transform/generator.rs for more details. ty::Generator(def_id, substs, _) => { - let tys : Vec<_> = substs.as_generator().upvar_tys(def_id, self.tcx()).collect(); + let tys: Vec<_> = substs.as_generator().upvar_tys(def_id, self.tcx()).collect(); self.open_drop_for_tuple(&tys) } ty::Tuple(..) => { @@ -819,10 +822,10 @@ where ty::Array(ety, size) => { let size = size.try_eval_usize(self.tcx(), self.elaborator.param_env()); self.open_drop_for_array(ety, size) - }, + } ty::Slice(ety) => self.open_drop_for_array(ety, None), - _ => bug!("open drop from non-ADT `{:?}`", ty) + _ => bug!("open drop from non-ADT `{:?}`", ty), } } @@ -851,11 +854,12 @@ where self.drop_flag_test_block(drop_block, succ, unwind) } - fn drop_flag_reset_block(&mut self, - mode: DropFlagMode, - succ: BasicBlock, - unwind: Unwind) -> BasicBlock - { + fn drop_flag_reset_block( + &mut self, + mode: DropFlagMode, + succ: BasicBlock, + unwind: Unwind, + ) -> BasicBlock { debug!("drop_flag_reset_block({:?},{:?})", self, mode); let block = self.new_block(unwind, TerminatorKind::Goto { target: succ }); @@ -893,15 +897,18 @@ where ) -> BasicBlock { let tcx = self.tcx(); let unit_temp = Place::from(self.new_temp(tcx.mk_unit())); - let free_func = tcx.require_lang_item( - lang_items::BoxFreeFnLangItem, - Some(self.source_info.span) - ); - let args = adt.variants[VariantIdx::new(0)].fields.iter().enumerate().map(|(i, f)| { - let field = Field::new(i); - let field_ty = f.ty(tcx, substs); - Operand::Move(tcx.mk_place_field(self.place.clone(), field, field_ty)) - }).collect(); + let free_func = + tcx.require_lang_item(lang_items::BoxFreeFnLangItem, Some(self.source_info.span)); + let args = adt.variants[VariantIdx::new(0)] + .fields + .iter() + .enumerate() + .map(|(i, f)| { + let field = Field::new(i); + let field_ty = f.ty(tcx, substs); + Operand::Move(tcx.mk_place_field(self.place.clone(), field, field_ty)) + }) + .collect(); let call = TerminatorKind::Call { func: Operand::function_handle(tcx, free_func, substs, self.source_info.span), @@ -921,20 +928,22 @@ where let block = TerminatorKind::Drop { location: self.place.clone(), target, - unwind: unwind.into_option() + unwind: unwind.into_option(), }; self.new_block(unwind, block) } - fn drop_flag_test_block(&mut self, - on_set: BasicBlock, - on_unset: BasicBlock, - unwind: Unwind) - -> BasicBlock - { + fn drop_flag_test_block( + &mut self, + on_set: BasicBlock, + on_unset: BasicBlock, + unwind: Unwind, + ) -> BasicBlock { let style = self.elaborator.drop_style(self.path, DropFlagMode::Shallow); - debug!("drop_flag_test_block({:?},{:?},{:?},{:?}) - {:?}", - self, on_set, on_unset, unwind, style); + debug!( + "drop_flag_test_block({:?},{:?},{:?},{:?}) - {:?}", + self, on_set, on_unset, unwind, style + ); match style { DropStyle::Dead => on_unset, @@ -950,10 +959,8 @@ where fn new_block(&mut self, unwind: Unwind, k: TerminatorKind<'tcx>) -> BasicBlock { self.elaborator.patch().new_block(BasicBlockData { statements: vec![], - terminator: Some(Terminator { - source_info: self.source_info, kind: k - }), - is_cleanup: unwind.is_cleanup() + terminator: Some(Terminator { source_info: self.source_info, kind: k }), + is_cleanup: unwind.is_cleanup(), }) } @@ -977,7 +984,7 @@ where fn assign(&self, lhs: &Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> { Statement { source_info: self.source_info, - kind: StatementKind::Assign(box(lhs.clone(), rhs)) + kind: StatementKind::Assign(box (lhs.clone(), rhs)), } } } diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index a44d4014b42ee..fb53888b755bc 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -8,11 +8,7 @@ use std::io::{self, Write}; use super::pretty::dump_mir_def_ids; /// Write a graphviz DOT graph of a list of MIRs. -pub fn write_mir_graphviz( - tcx: TyCtxt<'_>, - single: Option, - w: &mut W, -) -> io::Result<()> +pub fn write_mir_graphviz(tcx: TyCtxt<'_>, single: Option, w: &mut W) -> io::Result<()> where W: Write, { @@ -38,11 +34,7 @@ where // Must match `[0-9A-Za-z_]*`. This does not appear in the rendered graph, so // it does not have to be user friendly. pub fn graphviz_safe_def_name(def_id: DefId) -> String { - format!( - "{}_{}", - def_id.krate.index(), - def_id.index.index(), - ) + format!("{}_{}", def_id.krate.index(), def_id.index.index(),) } /// Write a graphviz DOT graph of the MIR. @@ -88,24 +80,30 @@ where /// /// `init` and `fini` are callbacks for emitting additional rows of /// data (using HTML enclosed with `` in the emitted text). -pub fn write_node_label(block: BasicBlock, - body: &Body<'_>, - w: &mut W, - num_cols: u32, - init: INIT, - fini: FINI) -> io::Result<()> - where INIT: Fn(&mut W) -> io::Result<()>, - FINI: Fn(&mut W) -> io::Result<()> +pub fn write_node_label( + block: BasicBlock, + body: &Body<'_>, + w: &mut W, + num_cols: u32, + init: INIT, + fini: FINI, +) -> io::Result<()> +where + INIT: Fn(&mut W) -> io::Result<()>, + FINI: Fn(&mut W) -> io::Result<()>, { let data = &body[block]; write!(w, r#""#)?; // Basic block number at the top. - write!(w, r#""#, - attrs=r#"bgcolor="gray" align="center""#, - colspan=num_cols, - blk=block.index())?; + write!( + w, + r#""#, + attrs = r#"bgcolor="gray" align="center""#, + colspan = num_cols, + blk = block.index() + )?; init(w)?; @@ -179,11 +177,7 @@ fn write_graph_label<'tcx, W: Write>( if i > 0 { write!(w, ", ")?; } - write!(w, - "{:?}: {}", - Place::from(arg), - escape(&body.local_decls[arg].ty) - )?; + write!(w, "{:?}: {}", Place::from(arg), escape(&body.local_decls[arg].ty))?; } write!(w, ") -> {}", escape(&body.return_ty()))?; @@ -197,13 +191,16 @@ fn write_graph_label<'tcx, W: Write>( write!(w, "mut ")?; } - write!(w, r#"{:?}: {};
"#, - Place::from(local), escape(&decl.ty))?; + write!(w, r#"{:?}: {};
"#, Place::from(local), escape(&decl.ty))?; } for var_debug_info in &body.var_debug_info { - write!(w, r#"debug {} => {};
"#, - var_debug_info.name, escape(&var_debug_info.place))?; + write!( + w, + r#"debug {} => {};
"#, + var_debug_info.name, + escape(&var_debug_info.place) + )?; } writeln!(w, ">;") diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index 01eebeb8c55a5..1488bfe4d627a 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -24,20 +24,20 @@ //! generator yield points, all pre-existing references are invalidated, so this //! doesn't matter). +use crate::transform::MirSource; +use crate::util::pretty::{dump_enabled, write_basic_block, write_mir_intro}; use rustc::mir::visit::{ - PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext, NonUseContext, + MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, Visitor, }; use rustc::mir::Local; use rustc::mir::*; use rustc::ty::{self, TyCtxt}; +use rustc_data_structures::work_queue::WorkQueue; use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; -use rustc_data_structures::work_queue::WorkQueue; use std::fs; use std::io::{self, Write}; use std::path::{Path, PathBuf}; -use crate::transform::MirSource; -use crate::util::pretty::{dump_enabled, write_basic_block, write_mir_intro}; pub type LiveVarSet = BitSet; @@ -56,22 +56,14 @@ pub struct LivenessResult { /// Computes which local variables are live within the given function /// `mir`, including drops. -pub fn liveness_of_locals( - body: ReadOnlyBodyAndCache<'_, '_>, -) -> LivenessResult { +pub fn liveness_of_locals(body: ReadOnlyBodyAndCache<'_, '_>) -> LivenessResult { let num_live_vars = body.local_decls.len(); - let def_use: IndexVec<_, DefsUses> = body - .basic_blocks() - .iter() - .map(|b| block(b, num_live_vars)) - .collect(); + let def_use: IndexVec<_, DefsUses> = + body.basic_blocks().iter().map(|b| block(b, num_live_vars)).collect(); - let mut outs: IndexVec<_, LiveVarSet> = body - .basic_blocks() - .indices() - .map(|_| LiveVarSet::new_empty(num_live_vars)) - .collect(); + let mut outs: IndexVec<_, LiveVarSet> = + body.basic_blocks().indices().map(|_| LiveVarSet::new_empty(num_live_vars)).collect(); let mut bits = LiveVarSet::new_empty(num_live_vars); @@ -83,8 +75,7 @@ pub fn liveness_of_locals( // FIXME(ecstaticmorse): Reverse post-order on the reverse CFG may generate a better iteration // order when cycles are present, but the overhead of computing the reverse CFG may outweigh // any benefits. Benchmark this and find out. - let mut dirty_queue: WorkQueue - = WorkQueue::with_none(body.basic_blocks().len()); + let mut dirty_queue: WorkQueue = WorkQueue::with_none(body.basic_blocks().len()); for (bb, _) in traversal::postorder(&body) { dirty_queue.insert(bb); } @@ -192,8 +183,7 @@ pub fn categorize(context: PlaceContext) -> Option { } } -struct DefsUsesVisitor -{ +struct DefsUsesVisitor { defs_uses: DefsUses, } @@ -238,8 +228,7 @@ impl DefsUses { } } -impl<'tcx> Visitor<'tcx> for DefsUsesVisitor -{ +impl<'tcx> Visitor<'tcx> for DefsUsesVisitor { fn visit_local(&mut self, &local: &Local, context: PlaceContext, _: Location) { match categorize(context) { Some(DefUse::Def) => self.defs_uses.add_def(local), @@ -249,10 +238,7 @@ impl<'tcx> Visitor<'tcx> for DefsUsesVisitor } } -fn block( - b: &BasicBlockData<'_>, - locals: usize, -) -> DefsUses { +fn block(b: &BasicBlockData<'_>, locals: usize) -> DefsUses { let mut visitor = DefsUsesVisitor { defs_uses: DefsUses { defs: LiveVarSet::new_empty(locals), @@ -260,10 +246,7 @@ fn block( }, }; - let dummy_location = Location { - block: BasicBlock::new(0), - statement_index: 0, - }; + let dummy_location = Location { block: BasicBlock::new(0), statement_index: 0 }; // Visit the various parts of the basic block in reverse. If we go // forward, the logic in `add_def` and `add_use` would be wrong. @@ -325,10 +308,8 @@ pub fn write_mir_fn<'tcx>( write_mir_intro(tcx, src, body, w)?; for block in body.basic_blocks().indices() { let print = |w: &mut dyn Write, prefix, result: &IndexVec| { - let live: Vec = result[block] - .iter() - .map(|local| format!("{:?}", local)) - .collect(); + let live: Vec = + result[block].iter().map(|local| format!("{:?}", local)).collect(); writeln!(w, "{} {{{}}}", prefix, live.join(", ")) }; write_basic_block(tcx, block, body, &mut |_, _| Ok(()), w)?; diff --git a/src/librustc_mir/util/mod.rs b/src/librustc_mir/util/mod.rs index c8a90a989142f..bb9d168d9193a 100644 --- a/src/librustc_mir/util/mod.rs +++ b/src/librustc_mir/util/mod.rs @@ -1,17 +1,17 @@ pub mod aggregate; pub mod borrowck_errors; -pub mod elaborate_drops; pub mod def_use; +pub mod elaborate_drops; pub mod patch; mod alignment; +pub mod collect_writes; mod graphviz; -pub(crate) mod pretty; pub mod liveness; -pub mod collect_writes; +pub(crate) mod pretty; pub use self::aggregate::expand_aggregate; pub use self::alignment::is_disaligned; -pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty, PassWhere}; -pub use self::graphviz::{graphviz_safe_def_name, write_mir_graphviz}; pub use self::graphviz::write_node_label as write_graphviz_node_label; +pub use self::graphviz::{graphviz_safe_def_name, write_mir_graphviz}; +pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty, PassWhere}; diff --git a/src/librustc_mir/util/patch.rs b/src/librustc_mir/util/patch.rs index 575b6d25de20d..f6a4eb38a2ebb 100644 --- a/src/librustc_mir/util/patch.rs +++ b/src/librustc_mir/util/patch.rs @@ -1,6 +1,6 @@ -use rustc::ty::Ty; use rustc::mir::*; -use rustc_index::vec::{IndexVec, Idx}; +use rustc::ty::Ty; +use rustc_index::vec::{Idx, IndexVec}; use syntax_pos::Span; /// This struct represents a patch to MIR, which can add @@ -25,7 +25,7 @@ impl<'tcx> MirPatch<'tcx> { new_locals: vec![], next_local: body.local_decls.len(), resume_block: START_BLOCK, - make_nop: vec![] + make_nop: vec![], }; // make sure the MIR we create has a resume block. It is @@ -43,26 +43,23 @@ impl<'tcx> MirPatch<'tcx> { } else { resume_block = Some(bb); } - break + break; } } let resume_block = resume_block.unwrap_or_else(|| { result.new_block(BasicBlockData { statements: vec![], terminator: Some(Terminator { - source_info: SourceInfo { - span: body.span, - scope: OUTERMOST_SOURCE_SCOPE - }, - kind: TerminatorKind::Resume + source_info: SourceInfo { span: body.span, scope: OUTERMOST_SOURCE_SCOPE }, + kind: TerminatorKind::Resume, }), - is_cleanup: true - })}); + is_cleanup: true, + }) + }); result.resume_block = resume_block; if let Some(resume_stmt_block) = resume_stmt_block { - result.patch_terminator(resume_stmt_block, TerminatorKind::Goto { - target: resume_block - }); + result + .patch_terminator(resume_stmt_block, TerminatorKind::Goto { target: resume_block }); } result } @@ -78,12 +75,9 @@ impl<'tcx> MirPatch<'tcx> { pub fn terminator_loc(&self, body: &Body<'tcx>, bb: BasicBlock) -> Location { let offset = match bb.index().checked_sub(body.basic_blocks().len()) { Some(index) => self.new_blocks[index].statements.len(), - None => body[bb].statements.len() + None => body[bb].statements.len(), }; - Location { - block: bb, - statement_index: offset - } + Location { block: bb, statement_index: offset } } pub fn new_temp(&mut self, ty: Ty<'tcx>, span: Span) -> Local { @@ -120,7 +114,7 @@ impl<'tcx> MirPatch<'tcx> { } pub fn add_assign(&mut self, loc: Location, place: Place<'tcx>, rv: Rvalue<'tcx>) { - self.add_statement(loc, StatementKind::Assign(box(place, rv))); + self.add_statement(loc, StatementKind::Assign(box (place, rv))); } pub fn make_nop(&mut self, loc: Location) { @@ -132,10 +126,17 @@ impl<'tcx> MirPatch<'tcx> { for loc in self.make_nop { body.make_statement_nop(loc); } - debug!("MirPatch: {:?} new temps, starting from index {}: {:?}", - self.new_locals.len(), body.local_decls.len(), self.new_locals); - debug!("MirPatch: {} new blocks, starting from index {}", - self.new_blocks.len(), body.basic_blocks().len()); + debug!( + "MirPatch: {:?} new temps, starting from index {}: {:?}", + self.new_locals.len(), + body.local_decls.len(), + self.new_locals + ); + debug!( + "MirPatch: {} new blocks, starting from index {}", + self.new_blocks.len(), + body.basic_blocks().len() + ); body.basic_blocks_mut().extend(self.new_blocks); body.local_decls.extend(self.new_locals); for (src, patch) in self.patch_map.into_iter_enumerated() { @@ -155,17 +156,12 @@ impl<'tcx> MirPatch<'tcx> { delta = 0; last_bb = loc.block; } - debug!("MirPatch: adding statement {:?} at loc {:?}+{}", - stmt, loc, delta); + debug!("MirPatch: adding statement {:?} at loc {:?}+{}", stmt, loc, delta); loc.statement_index += delta; - let source_info = Self::source_info_for_index( - &body[loc.block], loc - ); - body[loc.block].statements.insert( - loc.statement_index, Statement { - source_info, - kind: stmt - }); + let source_info = Self::source_info_for_index(&body[loc.block], loc); + body[loc.block] + .statements + .insert(loc.statement_index, Statement { source_info, kind: stmt }); delta += 1; } } @@ -173,14 +169,14 @@ impl<'tcx> MirPatch<'tcx> { pub fn source_info_for_index(data: &BasicBlockData<'_>, loc: Location) -> SourceInfo { match data.statements.get(loc.statement_index) { Some(stmt) => stmt.source_info, - None => data.terminator().source_info + None => data.terminator().source_info, } } pub fn source_info_for_location(&self, body: &Body<'_>, loc: Location) -> SourceInfo { let data = match loc.block.index().checked_sub(body.basic_blocks().len()) { Some(new) => &self.new_blocks[new], - None => &body[loc.block] + None => &body[loc.block], }; Self::source_info_for_index(data, loc) } diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 36194335a555a..a3f85238f472e 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -1,6 +1,8 @@ +use super::graphviz::write_mir_fn_graphviz; +use crate::transform::MirSource; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; -use rustc::mir::*; use rustc::mir::visit::Visitor; +use rustc::mir::*; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::fx::FxHashMap; use rustc_index::vec::Idx; @@ -9,8 +11,6 @@ use std::fmt::Write as _; use std::fs; use std::io::{self, Write}; use std::path::{Path, PathBuf}; -use super::graphviz::write_mir_fn_graphviz; -use crate::transform::MirSource; const INDENT: &str = " "; /// Alignment for lining up comments following MIR statements @@ -178,9 +178,7 @@ fn dump_path( let mut file_path = PathBuf::new(); file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir)); - let item_name = tcx - .def_path(source.def_id()) - .to_filename_friendly_no_crate(); + let item_name = tcx.def_path(source.def_id()).to_filename_friendly_no_crate(); // All drop shims have the same DefId, so we have to add the type // to get unique file names. let shim_disambiguator = match source.instance { @@ -188,13 +186,11 @@ fn dump_path( // Unfortunately, pretty-printed typed are not very filename-friendly. // We dome some filtering. let mut s = ".".to_owned(); - s.extend(ty.to_string() - .chars() - .filter_map(|c| match c { - ' ' => None, - ':' | '<' | '>' => Some('_'), - c => Some(c) - })); + s.extend(ty.to_string().chars().filter_map(|c| match c { + ' ' => None, + ':' | '<' | '>' => Some('_'), + c => Some(c), + })); s } _ => String::new(), @@ -202,13 +198,7 @@ fn dump_path( let file_name = format!( "rustc.{}{}{}{}.{}.{}.{}", - item_name, - shim_disambiguator, - promotion_id, - pass_num, - pass_name, - disambiguator, - extension, + item_name, shim_disambiguator, promotion_id, pass_num, pass_name, disambiguator, extension, ); file_path.push(&file_name); @@ -241,14 +231,8 @@ pub fn write_mir_pretty<'tcx>( single: Option, w: &mut dyn Write, ) -> io::Result<()> { - writeln!( - w, - "// WARNING: This output format is intended for human consumers only" - )?; - writeln!( - w, - "// and is subject to change without notice. Knock yourself out." - )?; + writeln!(w, "// WARNING: This output format is intended for human consumers only")?; + writeln!(w, "// and is subject to change without notice. Knock yourself out.")?; let mut first = true; for def_id in dump_mir_def_ids(tcx, single) { @@ -265,10 +249,7 @@ pub fn write_mir_pretty<'tcx>( for (i, body) in tcx.promoted_mir(def_id).iter_enumerated() { writeln!(w, "")?; - let src = MirSource { - instance: ty::InstanceDef::Item(def_id), - promoted: Some(i), - }; + let src = MirSource { instance: ty::InstanceDef::Item(def_id), promoted: Some(i) }; write_mir_fn(tcx, src, body, &mut |_, _| Ok(()), w)?; } } @@ -316,10 +297,7 @@ where writeln!(w, "{}{:?}{}: {{", INDENT, block, cleanup_text)?; // List of statements in the middle. - let mut current_location = Location { - block: block, - statement_index: 0, - }; + let mut current_location = Location { block: block, statement_index: 0 }; for statement in &data.statements { extra_data(PassWhere::BeforeLocation(current_location), w)?; let indented_body = format!("{0}{0}{1:?};", INDENT, statement); @@ -370,10 +348,7 @@ fn write_extra<'tcx, F>(tcx: TyCtxt<'tcx>, write: &mut dyn Write, mut visit_op: where F: FnMut(&mut ExtraComments<'tcx>), { - let mut extra_comments = ExtraComments { - _tcx: tcx, - comments: vec![], - }; + let mut extra_comments = ExtraComments { _tcx: tcx, comments: vec![] }; visit_op(&mut extra_comments); for comment in extra_comments.comments { writeln!(write, "{:A$} // {}", "", comment, A = ALIGN)?; @@ -445,11 +420,7 @@ impl Visitor<'tcx> for ExtraComments<'tcx> { } fn comment(tcx: TyCtxt<'_>, SourceInfo { span, scope }: SourceInfo) -> String { - format!( - "scope {} at {}", - scope.index(), - tcx.sess.source_map().span_to_string(span) - ) + format!("scope {} at {}", scope.index(), tcx.sess.source_map().span_to_string(span)) } /// Prints local variables in a scope tree. @@ -472,10 +443,7 @@ fn write_scope_tree( let indented_debug_info = format!( "{0:1$}debug {2} => {3:?};", - INDENT, - indent, - var_debug_info.name, - var_debug_info.place, + INDENT, indent, var_debug_info.name, var_debug_info.place, ); writeln!( @@ -489,7 +457,7 @@ fn write_scope_tree( // Local variable types (including the user's name in a comment). for (local, local_decl) in body.local_decls.iter_enumerated() { - if (1..body.arg_count+1).contains(&local.index()) { + if (1..body.arg_count + 1).contains(&local.index()) { // Skip over argument locals, they're printed in the signature. continue; } @@ -499,30 +467,17 @@ fn write_scope_tree( continue; } - let mut_str = if local_decl.mutability == Mutability::Mut { - "mut " - } else { - "" - }; + let mut_str = if local_decl.mutability == Mutability::Mut { "mut " } else { "" }; - let mut indented_decl = format!( - "{0:1$}let {2}{3:?}: {4:?}", - INDENT, - indent, - mut_str, - local, - local_decl.ty - ); + let mut indented_decl = + format!("{0:1$}let {2}{3:?}: {4:?}", INDENT, indent, mut_str, local, local_decl.ty); for user_ty in local_decl.user_ty.projections() { write!(indented_decl, " as {:?}", user_ty).unwrap(); } indented_decl.push_str(";"); - let local_name = if local == RETURN_PLACE { - format!(" return place") - } else { - String::new() - }; + let local_name = + if local == RETURN_PLACE { format!(" return place") } else { String::new() }; writeln!( w, @@ -564,10 +519,7 @@ pub fn write_mir_intro<'tcx>( let mut scope_tree: FxHashMap> = Default::default(); for (index, scope_data) in body.source_scopes.iter().enumerate() { if let Some(parent) = scope_data.parent_scope { - scope_tree - .entry(parent) - .or_default() - .push(SourceScope::new(index)); + scope_tree.entry(parent).or_default().push(SourceScope::new(index)); } else { // Only the argument scope has no parent, because it's the root. assert_eq!(index, OUTERMOST_SOURCE_SCOPE.index()); @@ -593,19 +545,17 @@ fn write_mir_sig( trace!("write_mir_sig: {:?}", src.instance); let kind = tcx.def_kind(src.def_id()); let is_function = match kind { - Some(DefKind::Fn) - | Some(DefKind::Method) - | Some(DefKind::Ctor(..)) => true, + Some(DefKind::Fn) | Some(DefKind::Method) | Some(DefKind::Ctor(..)) => true, _ => tcx.is_closure(src.def_id()), }; match (kind, src.promoted) { (_, Some(i)) => write!(w, "{:?} in ", i)?, - (Some(DefKind::Const), _) - | (Some(DefKind::AssocConst), _) => write!(w, "const ")?, - (Some(DefKind::Static), _) => - write!(w, "static {}", if tcx.is_mutable_static(src.def_id()) { "mut " } else { "" })?, + (Some(DefKind::Const), _) | (Some(DefKind::AssocConst), _) => write!(w, "const ")?, + (Some(DefKind::Static), _) => { + write!(w, "static {}", if tcx.is_mutable_static(src.def_id()) { "mut " } else { "" })? + } (_, _) if is_function => write!(w, "fn ")?, - (None, _) => {}, // things like anon const, not an item + (None, _) => {} // things like anon const, not an item _ => bug!("Unexpected def kind {:?}", kind), } @@ -656,9 +606,5 @@ fn write_user_type_annotations(body: &Body<'_>, w: &mut dyn Write) -> io::Result } pub fn dump_mir_def_ids(tcx: TyCtxt<'_>, single: Option) -> Vec { - if let Some(i) = single { - vec![i] - } else { - tcx.mir_keys(LOCAL_CRATE).iter().cloned().collect() - } + if let Some(i) = single { vec![i] } else { tcx.mir_keys(LOCAL_CRATE).iter().cloned().collect() } } diff --git a/src/librustc_msan/build.rs b/src/librustc_msan/build.rs index a81786ee36d04..dc08d51b51cb0 100644 --- a/src/librustc_msan/build.rs +++ b/src/librustc_msan/build.rs @@ -1,5 +1,5 @@ -use std::env; use build_helper::sanitizer_lib_boilerplate; +use std::env; use cmake::Config; diff --git a/src/librustc_msan/lib.rs b/src/librustc_msan/lib.rs index 4c8c9d15d5629..bdbc154f4e861 100644 --- a/src/librustc_msan/lib.rs +++ b/src/librustc_msan/lib.rs @@ -3,6 +3,8 @@ #![feature(sanitizer_runtime)] #![feature(staged_api)] #![no_std] -#![unstable(feature = "sanitizer_runtime_lib", - reason = "internal implementation detail of sanitizers", - issue = "none")] +#![unstable( + feature = "sanitizer_runtime_lib", + reason = "internal implementation detail of sanitizers", + issue = "none" +)] diff --git a/src/librustc_parse/config.rs b/src/librustc_parse/config.rs index 38ae7050abe48..1ff2003e82ce0 100644 --- a/src/librustc_parse/config.rs +++ b/src/librustc_parse/config.rs @@ -9,19 +9,19 @@ //! [#64197]: https://github.com/rust-lang/rust/issues/64197 use crate::{parse_in, validate_attr}; -use rustc_feature::Features; use rustc_errors::Applicability; -use syntax::attr::HasAttrs; -use syntax::feature_gate::{feature_err, get_features}; +use rustc_feature::Features; +use syntax::ast::{self, AttrItem, Attribute, MetaItem}; use syntax::attr; -use syntax::ast::{self, Attribute, AttrItem, MetaItem}; +use syntax::attr::HasAttrs; use syntax::edition::Edition; +use syntax::feature_gate::{feature_err, get_features}; use syntax::mut_visit::*; use syntax::ptr::P; use syntax::sess::ParseSess; use syntax::util::map_in_place::MapInPlace; -use syntax_pos::Span; use syntax_pos::symbol::sym; +use syntax_pos::Span; use smallvec::SmallVec; @@ -32,20 +32,22 @@ pub struct StripUnconfigured<'a> { } // `cfg_attr`-process the crate's attributes and compute the crate's features. -pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition, - allow_features: &Option>) -> (ast::Crate, Features) { +pub fn features( + mut krate: ast::Crate, + sess: &ParseSess, + edition: Edition, + allow_features: &Option>, +) -> (ast::Crate, Features) { let features; { - let mut strip_unconfigured = StripUnconfigured { - sess, - features: None, - }; + let mut strip_unconfigured = StripUnconfigured { sess, features: None }; let unconfigured_attrs = krate.attrs.clone(); let err_count = sess.span_diagnostic.err_count(); if let Some(attrs) = strip_unconfigured.configure(krate.attrs) { krate.attrs = attrs; - } else { // the entire crate is unconfigured + } else { + // the entire crate is unconfigured krate.attrs = Vec::new(); krate.module.items = Vec::new(); return (krate, Features::default()); @@ -70,7 +72,7 @@ macro_rules! configure { Some(node) => node, None => return Default::default(), } - } + }; } const CFG_ATTR_GRAMMAR_HELP: &str = "#[cfg_attr(condition, attribute, other_attribute, ...)]"; @@ -192,26 +194,38 @@ impl<'a> StripUnconfigured<'a> { let meta_item = match validate_attr::parse_meta(self.sess, attr) { Ok(meta_item) => meta_item, - Err(mut err) => { err.emit(); return true; } + Err(mut err) => { + err.emit(); + return true; + } }; let nested_meta_items = if let Some(nested_meta_items) = meta_item.meta_item_list() { nested_meta_items } else { - return error(meta_item.span, "`cfg` is not followed by parentheses", - "cfg(/* predicate */)"); + return error( + meta_item.span, + "`cfg` is not followed by parentheses", + "cfg(/* predicate */)", + ); }; if nested_meta_items.is_empty() { return error(meta_item.span, "`cfg` predicate is not specified", ""); } else if nested_meta_items.len() > 1 { - return error(nested_meta_items.last().unwrap().span(), - "multiple `cfg` predicates are specified", ""); + return error( + nested_meta_items.last().unwrap().span(), + "multiple `cfg` predicates are specified", + "", + ); } match nested_meta_items[0].meta_item() { Some(meta_item) => attr::cfg_matches(meta_item, self.sess, self.features), - None => error(nested_meta_items[0].span(), - "`cfg` predicate key cannot be a literal", ""), + None => error( + nested_meta_items[0].span(), + "`cfg` predicate key cannot be a literal", + "", + ), } }) } @@ -227,10 +241,12 @@ impl<'a> StripUnconfigured<'a> { /// If attributes are not allowed on expressions, emit an error for `attr` pub fn maybe_emit_expr_attr_err(&self, attr: &Attribute) { if !self.features.map(|features| features.stmt_expr_attributes).unwrap_or(true) { - let mut err = feature_err(self.sess, - sym::stmt_expr_attributes, - attr.span, - "attributes on expressions are experimental"); + let mut err = feature_err( + self.sess, + sym::stmt_expr_attributes, + attr.span, + "attributes on expressions are experimental", + ); if attr.is_doc_comment() { err.help("`///` is for documentation comments. For a plain comment, use `//`."); @@ -251,16 +267,18 @@ impl<'a> StripUnconfigured<'a> { fn configure_variant_data(&mut self, vdata: &mut ast::VariantData) { match vdata { - ast::VariantData::Struct(fields, ..) | ast::VariantData::Tuple(fields, _) => - fields.flat_map_in_place(|field| self.configure(field)), + ast::VariantData::Struct(fields, ..) | ast::VariantData::Tuple(fields, _) => { + fields.flat_map_in_place(|field| self.configure(field)) + } ast::VariantData::Unit(_) => {} } } pub fn configure_item_kind(&mut self, item: &mut ast::ItemKind) { match item { - ast::ItemKind::Struct(def, _generics) | - ast::ItemKind::Union(def, _generics) => self.configure_variant_data(def), + ast::ItemKind::Struct(def, _generics) | ast::ItemKind::Union(def, _generics) => { + self.configure_variant_data(def) + } ast::ItemKind::Enum(ast::EnumDef { variants }, _generics) => { variants.flat_map_in_place(|variant| self.configure(variant)); for variant in variants { diff --git a/src/librustc_parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs index ddcfea1898004..e5d3927af8623 100644 --- a/src/librustc_parse/lexer/mod.rs +++ b/src/librustc_parse/lexer/mod.rs @@ -1,20 +1,20 @@ use rustc_data_structures::sync::Lrc; -use rustc_errors::{FatalError, DiagnosticBuilder}; -use rustc_lexer::Base; +use rustc_errors::{DiagnosticBuilder, FatalError}; use rustc_lexer::unescape; -use syntax::token::{self, Token, TokenKind}; +use rustc_lexer::Base; use syntax::sess::ParseSess; +use syntax::token::{self, Token, TokenKind}; use syntax::util::comments; use syntax_pos::symbol::{sym, Symbol}; use syntax_pos::{BytePos, Pos, Span}; +use log::debug; use std::char; use std::convert::TryInto; -use log::debug; mod tokentrees; -mod unicode_chars; mod unescape_error_reporting; +mod unicode_chars; use unescape_error_reporting::{emit_unescape_error, push_escaped_char}; #[derive(Clone, Debug)] @@ -41,12 +41,14 @@ pub struct StringReader<'a> { } impl<'a> StringReader<'a> { - pub fn new(sess: &'a ParseSess, - source_file: Lrc, - override_span: Option) -> Self { + pub fn new( + sess: &'a ParseSess, + source_file: Lrc, + override_span: Option, + ) -> Self { if source_file.src.is_none() { - sess.span_diagnostic.bug(&format!("cannot lex `source_file` without source: {}", - source_file.name)); + sess.span_diagnostic + .bug(&format!("cannot lex `source_file` without source: {}", source_file.name)); } let src = (*source_file.src.as_ref().unwrap()).clone(); @@ -78,7 +80,6 @@ impl<'a> StringReader<'a> { sr } - fn mk_sp(&self, lo: BytePos, hi: BytePos) -> Span { self.override_span.unwrap_or_else(|| Span::with_root_ctxt(lo, hi)) } @@ -137,7 +138,6 @@ impl<'a> StringReader<'a> { self.sess.span_diagnostic.struct_span_err(sp, m).emit(); } - /// Report a fatal error spanning [`from_pos`, `to_pos`). fn fatal_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) -> FatalError { self.fatal_span(self.mk_sp(from_pos, to_pos), m) @@ -148,15 +148,22 @@ impl<'a> StringReader<'a> { self.err_span(self.mk_sp(from_pos, to_pos), m) } - fn struct_span_fatal(&self, from_pos: BytePos, to_pos: BytePos, m: &str) - -> DiagnosticBuilder<'a> - { + fn struct_span_fatal( + &self, + from_pos: BytePos, + to_pos: BytePos, + m: &str, + ) -> DiagnosticBuilder<'a> { self.sess.span_diagnostic.struct_span_fatal(self.mk_sp(from_pos, to_pos), m) } - fn struct_fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) - -> DiagnosticBuilder<'a> - { + fn struct_fatal_span_char( + &self, + from_pos: BytePos, + to_pos: BytePos, + m: &str, + c: char, + ) -> DiagnosticBuilder<'a> { let mut m = m.to_string(); m.push_str(": "); push_escaped_char(&mut m, c); @@ -167,11 +174,7 @@ impl<'a> StringReader<'a> { /// Turns simple `rustc_lexer::TokenKind` enum into a rich /// `libsyntax::TokenKind`. This turns strings into interned /// symbols and runs additional validation. - fn cook_lexer_token( - &self, - token: rustc_lexer::TokenKind, - start: BytePos, - ) -> TokenKind { + fn cook_lexer_token(&self, token: rustc_lexer::TokenKind, start: BytePos) -> TokenKind { match token { rustc_lexer::TokenKind::LineComment => { let string = self.str_from(start); @@ -202,9 +205,7 @@ impl<'a> StringReader<'a> { } let tok = if is_doc_comment { - self.forbid_bare_cr(start, - string, - "bare CR not allowed in block doc-comment"); + self.forbid_bare_cr(start, string, "bare CR not allowed in block doc-comment"); token::DocComment(Symbol::intern(string)) } else { token::Comment @@ -236,14 +237,21 @@ impl<'a> StringReader<'a> { let suffix = if suffix_start < self.pos { let string = self.str_from(suffix_start); if string == "_" { - self.sess.span_diagnostic - .struct_span_warn(self.mk_sp(suffix_start, self.pos), - "underscore literal suffix is not allowed") - .warn("this was previously accepted by the compiler but is \ + self.sess + .span_diagnostic + .struct_span_warn( + self.mk_sp(suffix_start, self.pos), + "underscore literal suffix is not allowed", + ) + .warn( + "this was previously accepted by the compiler but is \ being phased out; it will become a hard error in \ - a future release!") - .note("for more information, see issue #42326 \ - ") + a future release!", + ) + .note( + "for more information, see issue #42326 \ + ", + ) .emit(); None } else { @@ -260,11 +268,7 @@ impl<'a> StringReader<'a> { // this is necessary. let lifetime_name = self.str_from(start); if starts_with_number { - self.err_span_( - start, - self.pos, - "lifetimes cannot start with a number", - ); + self.err_span_(start, self.pos, "lifetimes cannot start with a number"); } let ident = Symbol::intern(lifetime_name); token::Lifetime(ident) @@ -299,10 +303,8 @@ impl<'a> StringReader<'a> { rustc_lexer::TokenKind::Unknown => { let c = self.str_from(start).chars().next().unwrap(); - let mut err = self.struct_fatal_span_char(start, - self.pos, - "unknown start of token", - c); + let mut err = + self.struct_fatal_span_char(start, self.pos, "unknown start of token", c); // FIXME: the lexer could be used to turn the ASCII version of unicode homoglyphs, // instead of keeping a table in `check_for_substitution`into the token. Ideally, // this should be inside `rustc_lexer`. However, we should first remove compound @@ -320,13 +322,12 @@ impl<'a> StringReader<'a> { &self, start: BytePos, suffix_start: BytePos, - kind: rustc_lexer::LiteralKind + kind: rustc_lexer::LiteralKind, ) -> (token::LitKind, Symbol) { match kind { rustc_lexer::LiteralKind::Char { terminated } => { if !terminated { - self.fatal_span_(start, suffix_start, - "unterminated character literal".into()) + self.fatal_span_(start, suffix_start, "unterminated character literal".into()) .raise() } let content_start = start + BytePos(1); @@ -334,23 +335,25 @@ impl<'a> StringReader<'a> { self.validate_char_escape(content_start, content_end); let id = self.symbol_from_to(content_start, content_end); (token::Char, id) - }, + } rustc_lexer::LiteralKind::Byte { terminated } => { if !terminated { - self.fatal_span_(start + BytePos(1), suffix_start, - "unterminated byte constant".into()) - .raise() + self.fatal_span_( + start + BytePos(1), + suffix_start, + "unterminated byte constant".into(), + ) + .raise() } let content_start = start + BytePos(2); let content_end = suffix_start - BytePos(1); self.validate_byte_escape(content_start, content_end); let id = self.symbol_from_to(content_start, content_end); (token::Byte, id) - }, + } rustc_lexer::LiteralKind::Str { terminated } => { if !terminated { - self.fatal_span_(start, suffix_start, - "unterminated double quote string".into()) + self.fatal_span_(start, suffix_start, "unterminated double quote string".into()) .raise() } let content_start = start + BytePos(1); @@ -361,9 +364,12 @@ impl<'a> StringReader<'a> { } rustc_lexer::LiteralKind::ByteStr { terminated } => { if !terminated { - self.fatal_span_(start + BytePos(1), suffix_start, - "unterminated double quote byte string".into()) - .raise() + self.fatal_span_( + start + BytePos(1), + suffix_start, + "unterminated double quote byte string".into(), + ) + .raise() } let content_start = start + BytePos(2); let content_end = suffix_start - BytePos(1); @@ -409,35 +415,35 @@ impl<'a> StringReader<'a> { self.validate_int_literal(base, start, suffix_start); (token::Integer, self.symbol_from_to(start, suffix_start)) } - }, + } rustc_lexer::LiteralKind::Float { base, empty_exponent } => { if empty_exponent { let mut err = self.struct_span_fatal( - start, self.pos, - "expected at least one digit in exponent" + start, + self.pos, + "expected at least one digit in exponent", ); err.emit(); } match base { - Base::Hexadecimal => { - self.err_span_(start, suffix_start, - "hexadecimal float literal is not supported") - } + Base::Hexadecimal => self.err_span_( + start, + suffix_start, + "hexadecimal float literal is not supported", + ), Base::Octal => { - self.err_span_(start, suffix_start, - "octal float literal is not supported") + self.err_span_(start, suffix_start, "octal float literal is not supported") } Base::Binary => { - self.err_span_(start, suffix_start, - "binary float literal is not supported") + self.err_span_(start, suffix_start, "binary float literal is not supported") } - _ => () + _ => (), } let id = self.symbol_from_to(start, suffix_start); (token::Float, id) - }, + } } } @@ -448,8 +454,7 @@ impl<'a> StringReader<'a> { /// Slice of the source text from `start` up to but excluding `self.pos`, /// meaning the slice does not include the character `self.ch`. - fn str_from(&self, start: BytePos) -> &str - { + fn str_from(&self, start: BytePos) -> &str { self.str_from_to(start, self.pos) } @@ -466,8 +471,7 @@ impl<'a> StringReader<'a> { } /// Slice of the source text spanning from `start` up to but excluding `end`. - fn str_from_to(&self, start: BytePos, end: BytePos) -> &str - { + fn str_from_to(&self, start: BytePos, end: BytePos) -> &str { &self.src[self.src_index(start)..self.src_index(end)] } @@ -476,41 +480,34 @@ impl<'a> StringReader<'a> { loop { idx = match s[idx..].find('\r') { None => break, - Some(it) => idx + it + 1 + Some(it) => idx + it + 1, }; - self.err_span_(start + BytePos(idx as u32 - 1), - start + BytePos(idx as u32), - errmsg); + self.err_span_(start + BytePos(idx as u32 - 1), start + BytePos(idx as u32), errmsg); } } fn report_non_started_raw_string(&self, start: BytePos) -> ! { let bad_char = self.str_from(start).chars().last().unwrap(); - self - .struct_fatal_span_char( - start, - self.pos, - "found invalid character; only `#` is allowed \ + self.struct_fatal_span_char( + start, + self.pos, + "found invalid character; only `#` is allowed \ in raw string delimitation", - bad_char, - ) - .emit(); + bad_char, + ) + .emit(); FatalError.raise() } fn report_unterminated_raw_string(&self, start: BytePos, n_hashes: usize) -> ! { - let mut err = self.struct_span_fatal( - start, start, - "unterminated raw string", - ); - err.span_label( - self.mk_sp(start, start), - "unterminated raw string", - ); + let mut err = self.struct_span_fatal(start, start, "unterminated raw string"); + err.span_label(self.mk_sp(start, start), "unterminated raw string"); if n_hashes > 0 { - err.note(&format!("this raw string should be terminated with `\"{}`", - "#".repeat(n_hashes as usize))); + err.note(&format!( + "this raw string should be terminated with `\"{}`", + "#".repeat(n_hashes as usize) + )); } err.emit(); @@ -521,10 +518,13 @@ impl<'a> StringReader<'a> { match n_hashes.try_into() { Ok(n_hashes) => n_hashes, Err(_) => { - self.fatal_span_(start, - self.pos, - "too many `#` symbols: raw strings may be \ - delimited by up to 65535 `#` symbols").raise(); + self.fatal_span_( + start, + self.pos, + "too many `#` symbols: raw strings may be \ + delimited by up to 65535 `#` symbols", + ) + .raise(); } } } @@ -633,9 +633,7 @@ impl<'a> StringReader<'a> { if c != '_' && c.to_digit(base).is_none() { let lo = content_start + BytePos(2 + idx); let hi = content_start + BytePos(2 + idx + c.len_utf8() as u32); - self.err_span_(lo, hi, - &format!("invalid digit for a base {} literal", base)); - + self.err_span_(lo, hi, &format!("invalid digit for a base {} literal", base)); } } } diff --git a/src/librustc_parse/lexer/tokentrees.rs b/src/librustc_parse/lexer/tokentrees.rs index 5791c6396c584..e517cc9c3db21 100644 --- a/src/librustc_parse/lexer/tokentrees.rs +++ b/src/librustc_parse/lexer/tokentrees.rs @@ -4,7 +4,11 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::PResult; use syntax::print::pprust::token_to_string; use syntax::token::{self, Token}; -use syntax::tokenstream::{DelimSpan, IsJoint::{self, *}, TokenStream, TokenTree, TreeAndJoint}; +use syntax::tokenstream::{ + DelimSpan, + IsJoint::{self, *}, + TokenStream, TokenTree, TreeAndJoint, +}; use syntax_pos::Span; impl<'a> StringReader<'a> { @@ -17,7 +21,7 @@ impl<'a> StringReader<'a> { unmatched_braces: Vec::new(), matching_delim_spans: Vec::new(), last_unclosed_found_span: None, - last_delim_empty_block_spans: FxHashMap::default() + last_delim_empty_block_spans: FxHashMap::default(), }; let res = tt_reader.parse_all_token_trees(); (res, tt_reader.unmatched_braces) @@ -36,7 +40,7 @@ struct TokenTreesReader<'a> { /// Used only for error recovery when arriving to EOF with mismatched braces. matching_delim_spans: Vec<(token::DelimToken, Span, Span)>, last_unclosed_found_span: Option, - last_delim_empty_block_spans: FxHashMap + last_delim_empty_block_spans: FxHashMap, } impl<'a> TokenTreesReader<'a> { @@ -75,8 +79,8 @@ impl<'a> TokenTreesReader<'a> { match self.token.kind { token::Eof => { let msg = "this file contains an un-closed delimiter"; - let mut err = self.string_reader.sess.span_diagnostic - .struct_span_err(self.token.span, msg); + let mut err = + self.string_reader.sess.span_diagnostic.struct_span_err(self.token.span, msg); for &(_, sp) in &self.open_braces { err.span_label(sp, "un-closed delimiter"); self.unmatched_braces.push(UnmatchedBrace { @@ -89,7 +93,9 @@ impl<'a> TokenTreesReader<'a> { } if let Some((delim, _)) = self.open_braces.last() { - if let Some((_, open_sp, close_sp)) = self.matching_delim_spans.iter() + if let Some((_, open_sp, close_sp)) = self + .matching_delim_spans + .iter() .filter(|(d, open_sp, close_sp)| { if let Some(close_padding) = sm.span_to_margin(*close_sp) { if let Some(open_padding) = sm.span_to_margin(*open_sp) { @@ -97,12 +103,12 @@ impl<'a> TokenTreesReader<'a> { } } false - }).next() // these are in reverse order as they get inserted on close, but - { // we want the last open/first close - err.span_label( - *open_sp, - "this delimiter might not be properly closed...", - ); + }) + .next() + // these are in reverse order as they get inserted on close, but + { + // we want the last open/first close + err.span_label(*open_sp, "this delimiter might not be properly closed..."); err.span_label( *close_sp, "...as it matches this but it has different indentation", @@ -110,7 +116,7 @@ impl<'a> TokenTreesReader<'a> { } } Err(err) - }, + } token::OpenDelim(delim) => { // The span for beginning of the delimited section let pre_span = self.token.span; @@ -143,9 +149,11 @@ impl<'a> TokenTreesReader<'a> { // properly matched delimiters so far for an entire block. self.matching_delim_spans.clear(); } else { - self.matching_delim_spans.push( - (open_brace, open_brace_span, close_brace_span), - ); + self.matching_delim_spans.push(( + open_brace, + open_brace_span, + close_brace_span, + )); } // Parse the close delimiter. self.real_token(); @@ -200,33 +208,29 @@ impl<'a> TokenTreesReader<'a> { // Silently recover, the EOF token will be seen again // and an error emitted then. Thus we don't pop from // self.open_braces here. - }, + } _ => {} } - Ok(TokenTree::Delimited( - delim_span, - delim, - tts.into() - ).into()) - }, + Ok(TokenTree::Delimited(delim_span, delim, tts.into()).into()) + } token::CloseDelim(delim) => { // An unexpected closing delimiter (i.e., there is no // matching opening delimiter). let token_str = token_to_string(&self.token); let msg = format!("unexpected close delimiter: `{}`", token_str); - let mut err = self.string_reader.sess.span_diagnostic - .struct_span_err(self.token.span, &msg); + let mut err = + self.string_reader.sess.span_diagnostic.struct_span_err(self.token.span, &msg); if let Some(span) = self.last_delim_empty_block_spans.remove(&delim) { err.span_label( span, - "this block is empty, you might have not meant to close it" + "this block is empty, you might have not meant to close it", ); } err.span_label(self.token.span, "unexpected close delimiter"); Err(err) - }, + } _ => { let tt = TokenTree::Token(self.token.take()); self.real_token(); diff --git a/src/librustc_parse/lexer/unescape_error_reporting.rs b/src/librustc_parse/lexer/unescape_error_reporting.rs index a5749d07e62b5..3b3f9e7cce64f 100644 --- a/src/librustc_parse/lexer/unescape_error_reporting.rs +++ b/src/librustc_parse/lexer/unescape_error_reporting.rs @@ -1,12 +1,12 @@ //! Utilities for rendering escape sequence errors as diagnostics. -use std::ops::Range; use std::iter::once; +use std::ops::Range; use rustc_lexer::unescape::{EscapeError, Mode}; -use syntax_pos::{Span, BytePos}; +use syntax_pos::{BytePos, Span}; -use syntax::errors::{Handler, Applicability}; +use syntax::errors::{Applicability, Handler}; pub(crate) fn emit_unescape_error( handler: &Handler, @@ -19,16 +19,20 @@ pub(crate) fn emit_unescape_error( range: Range, error: EscapeError, ) { - log::debug!("emit_unescape_error: {:?}, {:?}, {:?}, {:?}, {:?}", - lit, span_with_quotes, mode, range, error); + log::debug!( + "emit_unescape_error: {:?}, {:?}, {:?}, {:?}, {:?}", + lit, + span_with_quotes, + mode, + range, + error + ); let span = { let Range { start, end } = range; let (start, end) = (start as u32, end as u32); let lo = span_with_quotes.lo() + BytePos(start + 1); let hi = lo + BytePos(end - start); - span_with_quotes - .with_lo(lo) - .with_hi(hi) + span_with_quotes.with_lo(lo).with_hi(hi) }; let last_char = || { let c = lit[range.clone()].chars().rev().next().unwrap(); @@ -37,12 +41,14 @@ pub(crate) fn emit_unescape_error( }; match error { EscapeError::LoneSurrogateUnicodeEscape => { - handler.struct_span_err(span, "invalid unicode character escape") + handler + .struct_span_err(span, "invalid unicode character escape") .help("unicode escape must not be a surrogate") .emit(); } EscapeError::OutOfRangeUnicodeEscape => { - handler.struct_span_err(span, "invalid unicode character escape") + handler + .struct_span_err(span, "invalid unicode character escape") .help("unicode escape must be at most 10FFFF") .emit(); } @@ -63,7 +69,8 @@ pub(crate) fn emit_unescape_error( msg, format!("\"{}\"", lit), Applicability::MachineApplicable, - ).emit() + ) + .emit() } EscapeError::EscapeOnlyChar => { let (c, _span) = last_char(); @@ -72,7 +79,8 @@ pub(crate) fn emit_unescape_error( "byte constant must be escaped: " } else { "character constant must be escaped: " - }.to_string(); + } + .to_string(); push_escaped_char(&mut msg, c); handler.span_err(span, msg.as_str()) @@ -93,11 +101,8 @@ pub(crate) fn emit_unescape_error( EscapeError::InvalidEscape => { let (c, span) = last_char(); - let label = if mode.is_bytes() { - "unknown byte escape" - } else { - "unknown character escape" - }; + let label = + if mode.is_bytes() { "unknown byte escape" } else { "unknown character escape" }; let mut msg = label.to_string(); msg.push_str(": "); push_escaped_char(&mut msg, c); @@ -105,11 +110,15 @@ pub(crate) fn emit_unescape_error( let mut diag = handler.struct_span_err(span, msg.as_str()); diag.span_label(span, label); if c == '{' || c == '}' && !mode.is_bytes() { - diag.help("if used in a formatting string, \ - curly braces are escaped with `{{` and `}}`"); + diag.help( + "if used in a formatting string, \ + curly braces are escaped with `{{` and `}}`", + ); } else if c == '\r' { - diag.help("this is an isolated carriage return; \ - consider checking your editor and version control settings"); + diag.help( + "this is an isolated carriage return; \ + consider checking your editor and version control settings", + ); } diag.emit(); } @@ -123,7 +132,8 @@ pub(crate) fn emit_unescape_error( "invalid character in numeric character escape: " } else { "invalid character in unicode escape: " - }.to_string(); + } + .to_string(); push_escaped_char(&mut msg, c); handler.span_err(span, msg.as_str()) @@ -131,18 +141,22 @@ pub(crate) fn emit_unescape_error( EscapeError::NonAsciiCharInByte => { assert!(mode.is_bytes()); let (_c, span) = last_char(); - handler.span_err(span, "byte constant must be ASCII. \ - Use a \\xHH escape for a non-ASCII byte") + handler.span_err( + span, + "byte constant must be ASCII. \ + Use a \\xHH escape for a non-ASCII byte", + ) } EscapeError::NonAsciiCharInByteString => { assert!(mode.is_bytes()); let (_c, span) = last_char(); handler.span_err(span, "raw byte string must be ASCII") } - EscapeError::OutOfRangeHexEscape => { - handler.span_err(span, "this form of character escape may only be used \ - with characters in the range [\\x00-\\x7f]") - } + EscapeError::OutOfRangeHexEscape => handler.span_err( + span, + "this form of character escape may only be used \ + with characters in the range [\\x00-\\x7f]", + ), EscapeError::LeadingUnderscoreUnicodeEscape => { let (_c, span) = last_char(); handler.span_err(span, "invalid start of unicode escape") @@ -178,26 +192,21 @@ pub(crate) fn emit_unescape_error( ); } else { diag.span_label(span, msg); - diag.help( - "format of unicode escape sequences is `\\u{...}`", - ); + diag.help("format of unicode escape sequences is `\\u{...}`"); } diag.emit(); } - EscapeError::UnicodeEscapeInByte => { - handler.span_err(span, "unicode escape sequences cannot be used \ - as a byte or in a byte string") - } + EscapeError::UnicodeEscapeInByte => handler.span_err( + span, + "unicode escape sequences cannot be used \ + as a byte or in a byte string", + ), EscapeError::EmptyUnicodeEscape => { handler.span_err(span, "empty unicode escape (must have at least 1 hex digit)") } - EscapeError::ZeroChars => { - handler.span_err(span, "empty character literal") - } - EscapeError::LoneSlash => { - handler.span_err(span, "invalid trailing slash in literal") - } + EscapeError::ZeroChars => handler.span_err(span, "empty character literal"), + EscapeError::LoneSlash => handler.span_err(span, "invalid trailing slash in literal"), } } diff --git a/src/librustc_parse/lexer/unicode_chars.rs b/src/librustc_parse/lexer/unicode_chars.rs index edfebc7de9403..fbc5dc5cc896a 100644 --- a/src/librustc_parse/lexer/unicode_chars.rs +++ b/src/librustc_parse/lexer/unicode_chars.rs @@ -4,7 +4,7 @@ use super::StringReader; use crate::token; use rustc_errors::{Applicability, DiagnosticBuilder}; -use syntax_pos::{BytePos, Pos, Span, symbol::kw}; +use syntax_pos::{symbol::kw, BytePos, Pos, Span}; #[rustfmt::skip] // for line breaks const UNICODE_ARRAY: &[(char, &str, char)] = &[ diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs index 3de7f888724b4..f35e5cbb4fd03 100644 --- a/src/librustc_parse/lib.rs +++ b/src/librustc_parse/lib.rs @@ -10,9 +10,9 @@ use syntax::sess::ParseSess; use syntax::token::{self, Nonterminal}; use syntax::tokenstream::{self, TokenStream, TokenTree}; -use rustc_errors::{PResult, FatalError, Level, Diagnostic}; use rustc_data_structures::sync::Lrc; -use syntax_pos::{Span, SourceFile, FileName}; +use rustc_errors::{Diagnostic, FatalError, Level, PResult}; +use syntax_pos::{FileName, SourceFile, Span}; use std::borrow::Cow; use std::path::Path; @@ -24,7 +24,7 @@ pub const MACRO_ARGUMENTS: Option<&'static str> = Some("macro arguments"); #[macro_use] pub mod parser; -use parser::{Parser, emit_unclosed_delims, make_unclosed_delims_error}; +use parser::{emit_unclosed_delims, make_unclosed_delims_error, Parser}; pub mod lexer; pub mod validate_attr; #[macro_use] @@ -53,9 +53,9 @@ pub enum DirectoryOwnership { /// A variant of 'panictry!' that works on a Vec instead of a single DiagnosticBuilder. macro_rules! panictry_buffer { - ($handler:expr, $e:expr) => ({ - use std::result::Result::{Ok, Err}; + ($handler:expr, $e:expr) => {{ use rustc_errors::FatalError; + use std::result::Result::{Err, Ok}; match $e { Ok(e) => e, Err(errs) => { @@ -65,7 +65,7 @@ macro_rules! panictry_buffer { FatalError.raise() } } - }) + }}; } pub fn parse_crate_from_file<'a>(input: &Path, sess: &'a ParseSess) -> PResult<'a, ast::Crate> { @@ -73,19 +73,27 @@ pub fn parse_crate_from_file<'a>(input: &Path, sess: &'a ParseSess) -> PResult<' parser.parse_crate_mod() } -pub fn parse_crate_attrs_from_file<'a>(input: &Path, sess: &'a ParseSess) - -> PResult<'a, Vec> { +pub fn parse_crate_attrs_from_file<'a>( + input: &Path, + sess: &'a ParseSess, +) -> PResult<'a, Vec> { let mut parser = new_parser_from_file(sess, input); parser.parse_inner_attributes() } -pub fn parse_crate_from_source_str(name: FileName, source: String, sess: &ParseSess) - -> PResult<'_, ast::Crate> { +pub fn parse_crate_from_source_str( + name: FileName, + source: String, + sess: &ParseSess, +) -> PResult<'_, ast::Crate> { new_parser_from_source_str(sess, name, source).parse_crate_mod() } -pub fn parse_crate_attrs_from_source_str(name: FileName, source: String, sess: &ParseSess) - -> PResult<'_, Vec> { +pub fn parse_crate_attrs_from_source_str( + name: FileName, + source: String, + sess: &ParseSess, +) -> PResult<'_, Vec> { new_parser_from_source_str(sess, name, source).parse_inner_attributes() } @@ -95,11 +103,8 @@ pub fn parse_stream_from_source_str( sess: &ParseSess, override_span: Option, ) -> TokenStream { - let (stream, mut errors) = source_file_to_stream( - sess, - sess.source_map().new_source_file(name, source), - override_span, - ); + let (stream, mut errors) = + source_file_to_stream(sess, sess.source_map().new_source_file(name, source), override_span); emit_unclosed_delims(&mut errors, &sess); stream } @@ -111,11 +116,13 @@ pub fn new_parser_from_source_str(sess: &ParseSess, name: FileName, source: Stri /// Creates a new parser from a source string. Returns any buffered errors from lexing the initial /// token stream. -pub fn maybe_new_parser_from_source_str(sess: &ParseSess, name: FileName, source: String) - -> Result, Vec> -{ - let mut parser = maybe_source_file_to_parser(sess, - sess.source_map().new_source_file(name, source))?; +pub fn maybe_new_parser_from_source_str( + sess: &ParseSess, + name: FileName, + source: String, +) -> Result, Vec> { + let mut parser = + maybe_source_file_to_parser(sess, sess.source_map().new_source_file(name, source))?; parser.recurse_into_file_modules = false; Ok(parser) } @@ -127,8 +134,10 @@ pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) -> Parser<'a> /// Creates a new parser, returning buffered diagnostics if the file doesn't exist, /// or from lexing the initial token stream. -pub fn maybe_new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) - -> Result, Vec> { +pub fn maybe_new_parser_from_file<'a>( + sess: &'a ParseSess, + path: &Path, +) -> Result, Vec> { let file = try_file_to_source_file(sess, path, None).map_err(|db| vec![db])?; maybe_source_file_to_parser(sess, file) } @@ -136,11 +145,13 @@ pub fn maybe_new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) /// Given a session, a crate config, a path, and a span, add /// the file at the given path to the `source_map`, and returns a parser. /// On an error, uses the given span as the source of the problem. -pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess, - path: &Path, - directory_ownership: DirectoryOwnership, - module_name: Option, - sp: Span) -> Parser<'a> { +pub fn new_sub_parser_from_file<'a>( + sess: &'a ParseSess, + path: &Path, + directory_ownership: DirectoryOwnership, + module_name: Option, + sp: Span, +) -> Parser<'a> { let mut p = source_file_to_parser(sess, file_to_source_file(sess, path, Some(sp))); p.directory.ownership = directory_ownership; p.root_module_name = module_name; @@ -149,8 +160,7 @@ pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess, /// Given a `source_file` and config, returns a parser. fn source_file_to_parser(sess: &ParseSess, source_file: Lrc) -> Parser<'_> { - panictry_buffer!(&sess.span_diagnostic, - maybe_source_file_to_parser(sess, source_file)) + panictry_buffer!(&sess.span_diagnostic, maybe_source_file_to_parser(sess, source_file)) } /// Given a `source_file` and config, return a parser. Returns any buffered errors from lexing the @@ -176,16 +186,17 @@ pub fn new_parser_from_tts(sess: &ParseSess, tts: Vec) -> Parser<'_> stream_to_parser(sess, tts.into_iter().collect(), crate::MACRO_ARGUMENTS) } - // Base abstractions /// Given a session and a path and an optional span (for error reporting), /// add the path to the session's source_map and return the new source_file or /// error when a file can't be read. -fn try_file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option) - -> Result, Diagnostic> { - sess.source_map().load_file(path) - .map_err(|e| { +fn try_file_to_source_file( + sess: &ParseSess, + path: &Path, + spanopt: Option, +) -> Result, Diagnostic> { + sess.source_map().load_file(path).map_err(|e| { let msg = format!("couldn't read {}: {}", path.display(), e); let mut diag = Diagnostic::new(Level::Fatal, &msg); if let Some(sp) = spanopt { @@ -197,8 +208,7 @@ fn try_file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option) /// Given a session and a path and an optional span (for error reporting), /// adds the path to the session's `source_map` and returns the new `source_file`. -fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option) - -> Lrc { +fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option) -> Lrc { match try_file_to_source_file(sess, path, spanopt) { Ok(source_file) => source_file, Err(d) => { @@ -315,9 +325,7 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke Nonterminal::NtLifetime(ident) => { Some(tokenstream::TokenTree::token(token::Lifetime(ident.name), ident.span).into()) } - Nonterminal::NtTT(ref tt) => { - Some(tt.clone().into()) - } + Nonterminal::NtTT(ref tt) => Some(tt.clone().into()), _ => None, }; @@ -351,28 +359,33 @@ pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> Toke // tokens such as extra braces and commas, don't happen. if let Some(tokens) = tokens { if tokens.probably_equal_for_proc_macro(&tokens_for_real) { - return tokens + return tokens; } - info!("cached tokens found, but they're not \"probably equal\", \ - going with stringified version"); + info!( + "cached tokens found, but they're not \"probably equal\", \ + going with stringified version" + ); } - return tokens_for_real + return tokens_for_real; } fn prepend_attrs( sess: &ParseSess, attrs: &[ast::Attribute], tokens: Option<&tokenstream::TokenStream>, - span: syntax_pos::Span + span: syntax_pos::Span, ) -> Option { let tokens = tokens?; if attrs.len() == 0 { - return Some(tokens.clone()) + return Some(tokens.clone()); } let mut builder = tokenstream::TokenStreamBuilder::new(); for attr in attrs { - assert_eq!(attr.style, ast::AttrStyle::Outer, - "inner attributes should prevent cached tokens from existing"); + assert_eq!( + attr.style, + ast::AttrStyle::Outer, + "inner attributes should prevent cached tokens from existing" + ); let source = pprust::attribute_to_string(attr); let macro_filename = FileName::macro_expansion_source_code(&source); @@ -382,7 +395,7 @@ fn prepend_attrs( ast::AttrKind::DocComment(_) => { let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span)); builder.push(stream); - continue + continue; } }; @@ -410,7 +423,10 @@ fn prepend_attrs( builder.push(tokenstream::TokenTree::token(token::Pound, attr.span)); let delim_span = tokenstream::DelimSpan::from_single(attr.span); builder.push(tokenstream::TokenTree::Delimited( - delim_span, token::DelimToken::Bracket, brackets.build().into())); + delim_span, + token::DelimToken::Bracket, + brackets.build().into(), + )); } builder.push(tokens.clone()); Some(builder.build()) diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs index 51310fb88f65a..377d43dec21a2 100644 --- a/src/librustc_parse/parser/attr.rs +++ b/src/librustc_parse/parser/attr.rs @@ -1,9 +1,9 @@ -use super::{Parser, TokenType, PathStyle}; +use super::{Parser, PathStyle, TokenType}; use rustc_errors::PResult; -use syntax::attr; use syntax::ast; -use syntax::util::comments; +use syntax::attr; use syntax::token::{self, Nonterminal}; +use syntax::util::comments; use syntax_pos::{Span, Symbol}; use log::debug; @@ -33,12 +33,11 @@ impl<'a> Parser<'a> { } else { DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG }; - let inner_parse_policy = - InnerAttributeParsePolicy::NotPermitted { - reason: inner_error_reason, - saw_doc_comment: just_parsed_doc_comment, - prev_attr_sp: attrs.last().and_then(|a| Some(a.span)) - }; + let inner_parse_policy = InnerAttributeParsePolicy::NotPermitted { + reason: inner_error_reason, + saw_doc_comment: just_parsed_doc_comment, + prev_attr_sp: attrs.last().and_then(|a| Some(a.span)), + }; let attr = self.parse_attribute_with_inner_parse_policy(inner_parse_policy)?; attrs.push(attr); just_parsed_doc_comment = false; @@ -47,8 +46,10 @@ impl<'a> Parser<'a> { let attr = self.mk_doc_comment(s); if attr.style != ast::AttrStyle::Outer { let mut err = self.fatal("expected outer doc comment"); - err.note("inner doc comments like this (starting with \ - `//!` or `/*!`) can only appear before items"); + err.note( + "inner doc comments like this (starting with \ + `//!` or `/*!`) can only appear before items", + ); return Err(err); } attrs.push(attr); @@ -71,16 +72,14 @@ impl<'a> Parser<'a> { /// If `permit_inner` is `true`, then a leading `!` indicates an inner /// attribute. pub fn parse_attribute(&mut self, permit_inner: bool) -> PResult<'a, ast::Attribute> { - debug!("parse_attribute: permit_inner={:?} self.token={:?}", - permit_inner, - self.token); + debug!("parse_attribute: permit_inner={:?} self.token={:?}", permit_inner, self.token); let inner_parse_policy = if permit_inner { InnerAttributeParsePolicy::Permitted } else { InnerAttributeParsePolicy::NotPermitted { reason: DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG, saw_doc_comment: false, - prev_attr_sp: None + prev_attr_sp: None, } }; self.parse_attribute_with_inner_parse_policy(inner_parse_policy) @@ -90,11 +89,12 @@ impl<'a> Parser<'a> { /// that prescribes how to handle inner attributes. fn parse_attribute_with_inner_parse_policy( &mut self, - inner_parse_policy: InnerAttributeParsePolicy<'_> + inner_parse_policy: InnerAttributeParsePolicy<'_>, ) -> PResult<'a, ast::Attribute> { - debug!("parse_attribute_with_inner_parse_policy: inner_parse_policy={:?} self.token={:?}", - inner_parse_policy, - self.token); + debug!( + "parse_attribute_with_inner_parse_policy: inner_parse_policy={:?} self.token={:?}", + inner_parse_policy, self.token + ); let (span, item, style) = match self.token.kind { token::Pound => { let lo = self.token.span; @@ -120,17 +120,19 @@ impl<'a> Parser<'a> { // Emit error if inner attribute is encountered and not permitted if style == ast::AttrStyle::Inner { - if let InnerAttributeParsePolicy::NotPermitted { reason, - saw_doc_comment, prev_attr_sp } = inner_parse_policy { + if let InnerAttributeParsePolicy::NotPermitted { + reason, + saw_doc_comment, + prev_attr_sp, + } = inner_parse_policy + { let prev_attr_note = if saw_doc_comment { "previous doc comment" } else { "previous outer attribute" }; - let mut diagnostic = self - .diagnostic() - .struct_span_err(attr_sp, reason); + let mut diagnostic = self.diagnostic().struct_span_err(attr_sp, reason); if let Some(prev_attr_sp) = prev_attr_sp { diagnostic @@ -139,10 +141,12 @@ impl<'a> Parser<'a> { } diagnostic - .note("inner attributes, like `#![no_std]`, annotate the item \ + .note( + "inner attributes, like `#![no_std]`, annotate the item \ enclosing them, and are usually found at the beginning of \ source files. Outer attributes, like `#[test]`, annotate the \ - item following them.") + item following them.", + ) .emit() } } @@ -226,11 +230,14 @@ impl<'a> Parser<'a> { if !lit.kind.is_unsuffixed() { let msg = "suffixed literals are not allowed in attributes"; - self.diagnostic().struct_span_err(lit.span, msg) - .help("instead of using a suffixed literal \ + self.diagnostic() + .struct_span_err(lit.span, msg) + .help( + "instead of using a suffixed literal \ (1u8, 1.0f32, etc.), use an unsuffixed version \ - (1, 1.0, etc.).") - .emit() + (1, 1.0, etc.).", + ) + .emit() } Ok(lit) @@ -288,7 +295,7 @@ impl<'a> Parser<'a> { Ok(meta) } None => self.unexpected(), - } + }; } let lo = self.token.span; diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 353f6607c1db7..f58b9a4c14441 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -1,17 +1,19 @@ -use super::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType, SeqSep, Parser}; +use super::{BlockMode, Parser, PathStyle, SemiColonMode, SeqSep, TokenExpectType, TokenType}; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{self, PResult, Applicability, DiagnosticBuilder, Handler, pluralize}; use rustc_error_codes::*; -use syntax::ast::{self, Param, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item}; -use syntax::ast::{ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, AttrVec}; -use syntax::token::{self, TokenKind, token_can_begin_expr}; +use rustc_errors::{self, pluralize, Applicability, DiagnosticBuilder, Handler, PResult}; +use syntax::ast::{ + self, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, Param, +}; +use syntax::ast::{AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind}; use syntax::print::pprust; use syntax::ptr::P; -use syntax::util::parser::AssocOp; use syntax::struct_span_err; +use syntax::token::{self, token_can_begin_expr, TokenKind}; +use syntax::util::parser::AssocOp; use syntax_pos::symbol::kw; -use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError}; +use syntax_pos::{MultiSpan, Span, SpanSnippetError, DUMMY_SP}; use log::{debug, trace}; use std::mem; @@ -25,11 +27,7 @@ pub(super) fn dummy_arg(ident: Ident) -> Param { kind: PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None), span: ident.span, }); - let ty = Ty { - kind: TyKind::Err, - span: ident.span, - id: ast::DUMMY_NODE_ID - }; + let ty = Ty { kind: TyKind::Err, span: ident.span, id: ast::DUMMY_NODE_ID }; Param { attrs: AttrVec::default(), id: ast::DUMMY_NODE_ID, @@ -57,11 +55,7 @@ pub enum Error { } impl Error { - fn span_err( - self, - sp: impl Into, - handler: &Handler, - ) -> DiagnosticBuilder<'_> { + fn span_err(self, sp: impl Into, handler: &Handler) -> DiagnosticBuilder<'_> { match self { Error::FileNotFoundForModule { ref mod_name, @@ -78,9 +72,7 @@ impl Error { ); err.help(&format!( "name the file either {} or {} inside the directory \"{}\"", - default_path, - secondary_path, - dir_path, + default_path, secondary_path, dir_path, )); err } @@ -104,17 +96,14 @@ impl Error { E0585, "found a documentation comment that doesn't document anything", ); - err.help("doc comments must come before what they document, maybe a comment was \ - intended with `//`?"); + err.help( + "doc comments must come before what they document, maybe a comment was \ + intended with `//`?", + ); err } Error::InclusiveRangeWithNoEnd => { - let mut err = struct_span_err!( - handler, - sp, - E0586, - "inclusive range with no end", - ); + let mut err = struct_span_err!(handler, sp, E0586, "inclusive range with no end",); err.help("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)"); err } @@ -134,11 +123,7 @@ impl RecoverQPath for Ty { Some(P(self.clone())) } fn recovered(qself: Option, path: ast::Path) -> Self { - Self { - span: path.span, - kind: TyKind::Path(qself, path), - id: ast::DUMMY_NODE_ID, - } + Self { span: path.span, kind: TyKind::Path(qself, path), id: ast::DUMMY_NODE_ID } } } @@ -147,11 +132,7 @@ impl RecoverQPath for Pat { self.to_ty() } fn recovered(qself: Option, path: ast::Path) -> Self { - Self { - span: path.span, - kind: PatKind::Path(qself, path), - id: ast::DUMMY_NODE_ID, - } + Self { span: path.span, kind: PatKind::Path(qself, path), id: ast::DUMMY_NODE_ID } } } @@ -233,8 +214,8 @@ impl<'a> Parser<'a> { TokenKind::CloseDelim(token::DelimToken::Paren), ]; if let token::Ident(name, false) = self.token.kind { - if Ident::new(name, self.token.span).is_raw_guess() && - self.look_ahead(1, |t| valid_follow.contains(&t.kind)) + if Ident::new(name, self.token.span).is_raw_guess() + && self.look_ahead(1, |t| valid_follow.contains(&t.kind)) { err.span_suggestion( self.token.span, @@ -268,8 +249,7 @@ impl<'a> Parser<'a> { fn tokens_to_string(tokens: &[TokenType]) -> String { let mut i = tokens.iter(); // This might be a sign we need a connect method on `Iterator`. - let b = i.next() - .map_or(String::new(), |t| t.to_string()); + let b = i.next().map_or(String::new(), |t| t.to_string()); i.enumerate().fold(b, |mut b, (i, a)| { if tokens.len() > 2 && i == tokens.len() - 2 { b.push_str(", or "); @@ -283,7 +263,8 @@ impl<'a> Parser<'a> { }) } - let mut expected = edible.iter() + let mut expected = edible + .iter() .map(|x| TokenType::Token(x.clone())) .chain(inedible.iter().map(|x| TokenType::Token(x.clone()))) .chain(self.expected_tokens.iter().cloned()) @@ -298,16 +279,23 @@ impl<'a> Parser<'a> { } else { expect.clone() }; - (format!("expected one of {}, found {}", expect, actual), - (self.sess.source_map().next_point(self.prev_span), - format!("expected one of {}", short_expect))) + ( + format!("expected one of {}, found {}", expect, actual), + ( + self.sess.source_map().next_point(self.prev_span), + format!("expected one of {}", short_expect), + ), + ) } else if expected.is_empty() { - (format!("unexpected token: {}", actual), - (self.prev_span, "unexpected token after this".to_string())) + ( + format!("unexpected token: {}", actual), + (self.prev_span, "unexpected token after this".to_string()), + ) } else { - (format!("expected {}, found {}", expect, actual), - (self.sess.source_map().next_point(self.prev_span), - format!("expected {}", expect))) + ( + format!("expected {}, found {}", expect, actual), + (self.sess.source_map().next_point(self.prev_span), format!("expected {}", expect)), + ) }; self.last_unexpected_token_span = Some(self.token.span); let mut err = self.fatal(&msg_exp); @@ -317,10 +305,16 @@ impl<'a> Parser<'a> { } else { label_sp }; - match self.recover_closing_delimiter(&expected.iter().filter_map(|tt| match tt { - TokenType::Token(t) => Some(t.clone()), - _ => None, - }).collect::>(), err) { + match self.recover_closing_delimiter( + &expected + .iter() + .filter_map(|tt| match tt { + TokenType::Token(t) => Some(t.clone()), + _ => None, + }) + .collect::>(), + err, + ) { Err(e) => err = e, Ok(recovered) => { return Ok(recovered); @@ -391,10 +385,14 @@ impl<'a> Parser<'a> { } if allow_unstable { // Give extra information about type ascription only if it's a nightly compiler. - err.note("`#![feature(type_ascription)]` lets you annotate an expression with a \ - type: `: `"); - err.note("for more information, see \ - https://github.com/rust-lang/rust/issues/23416"); + err.note( + "`#![feature(type_ascription)]` lets you annotate an expression with a \ + type: `: `", + ); + err.note( + "for more information, see \ + https://github.com/rust-lang/rust/issues/23416", + ); } } } @@ -402,12 +400,11 @@ impl<'a> Parser<'a> { /// Eats and discards tokens until one of `kets` is encountered. Respects token trees, /// passes through any errors encountered. Used for error recovery. pub(super) fn eat_to_tokens(&mut self, kets: &[&TokenKind]) { - if let Err(ref mut err) = self.parse_seq_to_before_tokens( - kets, - SeqSep::none(), - TokenExpectType::Expect, - |p| Ok(p.parse_token_tree()), - ) { + if let Err(ref mut err) = + self.parse_seq_to_before_tokens(kets, SeqSep::none(), TokenExpectType::Expect, |p| { + Ok(p.parse_token_tree()) + }) + { err.cancel(); } } @@ -444,10 +441,8 @@ impl<'a> Parser<'a> { // have already been parsed): // // `x.foo::>>(3)` - let parsed_angle_bracket_args = segment.args - .as_ref() - .map(|args| args.is_angle_bracketed()) - .unwrap_or(false); + let parsed_angle_bracket_args = + segment.args.as_ref().map(|args| args.is_angle_bracketed()).unwrap_or(false); debug!( "check_trailing_angle_brackets: parsed_angle_bracket_args={:?}", @@ -549,18 +544,15 @@ impl<'a> Parser<'a> { outer_op, ); - let mk_err_expr = |this: &Self, span| { - Ok(Some(this.mk_expr(span, ExprKind::Err, AttrVec::new()))) - }; + let mk_err_expr = + |this: &Self, span| Ok(Some(this.mk_expr(span, ExprKind::Err, AttrVec::new()))); match lhs.kind { ExprKind::Binary(op, _, _) if op.node.is_comparison() => { // Respan to include both operators. let op_span = op.span.to(self.prev_span); - let mut err = self.struct_span_err( - op_span, - "chained comparison operators require parentheses", - ); + let mut err = self + .struct_span_err(op_span, "chained comparison operators require parentheses"); let suggest = |err: &mut DiagnosticBuilder<'_>| { err.span_suggestion_verbose( @@ -573,23 +565,21 @@ impl<'a> Parser<'a> { if op.node == BinOpKind::Lt && *outer_op == AssocOp::Less || // Include `<` to provide this recommendation - *outer_op == AssocOp::Greater // even in a case like the following: - { // Foo>> + *outer_op == AssocOp::Greater + // even in a case like the following: + { + // Foo>> if *outer_op == AssocOp::Less { let snapshot = self.clone(); self.bump(); // So far we have parsed `foo(` or `foo< bar >::`, so we rewind the // parser and bail out. mem::replace(self, snapshot.clone()); @@ -657,10 +647,8 @@ impl<'a> Parser<'a> { self.bump(); // `(` // Consume the fn call arguments. - let modifiers = [ - (token::OpenDelim(token::Paren), 1), - (token::CloseDelim(token::Paren), -1), - ]; + let modifiers = + [(token::OpenDelim(token::Paren), 1), (token::CloseDelim(token::Paren), -1)]; self.consume_tts(1, &modifiers[..]); if self.token.kind == token::Eof { @@ -769,16 +757,11 @@ impl<'a> Parser<'a> { ) -> PResult<'a, P> { self.expect(&token::ModSep)?; - let mut path = ast::Path { - segments: Vec::new(), - span: DUMMY_SP, - }; + let mut path = ast::Path { segments: Vec::new(), span: DUMMY_SP }; self.parse_path_segments(&mut path.segments, T::PATH_STYLE)?; path.span = ty_span.to(self.prev_span); - let ty_str = self - .span_to_snippet(ty_span) - .unwrap_or_else(|_| pprust::ty_to_string(&ty)); + let ty_str = self.span_to_snippet(ty_span).unwrap_or_else(|_| pprust::ty_to_string(&ty)); self.diagnostic() .struct_span_err(path.span, "missing angle brackets in associated item path") .span_suggestion( @@ -791,14 +774,7 @@ impl<'a> Parser<'a> { .emit(); let path_span = ty_span.shrink_to_hi(); // Use an empty path since `position == 0`. - Ok(P(T::recovered( - Some(QSelf { - ty, - path_span, - position: 0, - }), - path, - ))) + Ok(P(T::recovered(Some(QSelf { ty, path_span, position: 0 }), path))) } pub(super) fn maybe_consume_incorrect_semicolon(&mut self, items: &[P]) -> bool { @@ -822,10 +798,7 @@ impl<'a> Parser<'a> { _ => None, }; if let Some(name) = previous_item_kind_name { - err.help(&format!( - "{} declarations are not followed by a semicolon", - name - )); + err.help(&format!("{} declarations are not followed by a semicolon", name)); } } err.emit(); @@ -896,9 +869,11 @@ impl<'a> Parser<'a> { return self.expect(&token::Semi).map(|_| ()); } else if !sm.is_multiline(self.prev_span.until(self.token.span)) { // The current token is in the same line as the prior token, not recoverable. - } else if self.look_ahead(1, |t| t == &token::CloseDelim(token::Brace) - || token_can_begin_expr(t) && t.kind != token::Colon - ) && [token::Comma, token::Colon].contains(&self.token.kind) { + } else if self.look_ahead(1, |t| { + t == &token::CloseDelim(token::Brace) + || token_can_begin_expr(t) && t.kind != token::Colon + }) && [token::Comma, token::Colon].contains(&self.token.kind) + { // Likely typo: `,` → `;` or `:` → `;`. This is triggered if the current token is // either `,` or `:`, and the next token could either start a new statement or is a // block close. For example: @@ -910,12 +885,14 @@ impl<'a> Parser<'a> { self.struct_span_err(sp, &msg) .span_suggestion(sp, "change this to `;`", ";".to_string(), appl) .emit(); - return Ok(()) - } else if self.look_ahead(0, |t| t == &token::CloseDelim(token::Brace) || ( - token_can_begin_expr(t) - && t != &token::Semi - && t != &token::Pound // Avoid triggering with too many trailing `#` in raw string. - )) { + return Ok(()); + } else if self.look_ahead(0, |t| { + t == &token::CloseDelim(token::Brace) + || ( + token_can_begin_expr(t) && t != &token::Semi && t != &token::Pound + // Avoid triggering with too many trailing `#` in raw string. + ) + }) { // Missing semicolon typo. This is triggered if the next token could either start a // new statement or is a block close. For example: // @@ -926,7 +903,7 @@ impl<'a> Parser<'a> { .span_label(self.token.span, "unexpected token") .span_suggestion_short(sp, "add `;` here", ";".to_string(), appl) .emit(); - return Ok(()) + return Ok(()); } self.expect(&token::Semi).map(|_| ()) // Error unconditionally } @@ -947,12 +924,17 @@ impl<'a> Parser<'a> { .span_label( extern_sp, "`extern` blocks define existing foreign functions and `fn`s \ - inside of them cannot have a body") - .help("you might have meant to write a function accessible through ffi, \ + inside of them cannot have a body", + ) + .help( + "you might have meant to write a function accessible through ffi, \ which can be done by writing `extern fn` outside of the \ - `extern` block") - .note("for more information, visit \ - https://doc.rust-lang.org/std/keyword.extern.html") + `extern` block", + ) + .note( + "for more information, visit \ + https://doc.rust-lang.org/std/keyword.extern.html", + ) .emit(); } Err(mut err) => { @@ -1000,15 +982,11 @@ impl<'a> Parser<'a> { // Handle `await { }`. // This needs to be handled separatedly from the next arm to avoid // interpreting `await { }?` as `?.await`. - self.parse_block_expr( - None, - self.token.span, - BlockCheckMode::Default, - AttrVec::new(), - ) + self.parse_block_expr(None, self.token.span, BlockCheckMode::Default, AttrVec::new()) } else { self.parse_expr() - }.map_err(|mut err| { + } + .map_err(|mut err| { err.span_label(await_sp, "while parsing this incorrect await expression"); err })?; @@ -1016,8 +994,8 @@ impl<'a> Parser<'a> { } fn error_on_incorrect_await(&self, lo: Span, hi: Span, expr: &Expr, is_question: bool) -> Span { - let expr_str = self.span_to_snippet(expr.span) - .unwrap_or_else(|_| pprust::expr_to_string(&expr)); + let expr_str = + self.span_to_snippet(expr.span).unwrap_or_else(|_| pprust::expr_to_string(&expr)); let suggestion = format!("{}.await{}", expr_str, if is_question { "?" } else { "" }); let sp = lo.to(hi); let app = match expr.kind { @@ -1032,8 +1010,8 @@ impl<'a> Parser<'a> { /// If encountering `future.await()`, consumes and emits an error. pub(super) fn recover_from_await_method_call(&mut self) { - if self.token == token::OpenDelim(token::Paren) && - self.look_ahead(1, |t| t == &token::CloseDelim(token::Paren)) + if self.token == token::OpenDelim(token::Paren) + && self.look_ahead(1, |t| t == &token::CloseDelim(token::Paren)) { // future.await() let lo = self.token.span; @@ -1046,7 +1024,8 @@ impl<'a> Parser<'a> { "`await` is not a method call, remove the parentheses", String::new(), Applicability::MachineApplicable, - ).emit() + ) + .emit() } } @@ -1094,23 +1073,22 @@ impl<'a> Parser<'a> { pub(super) fn could_ascription_be_path(&self, node: &ast::ExprKind) -> bool { (self.token == token::Lt && // `foo: true, _ => false, } && !self.token.is_reserved_ident() && // v `foo:bar(baz)` - self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren)) || - self.look_ahead(1, |t| t == &token::Lt) && // `foo:bar` + self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren)) + || self.look_ahead(1, |t| t == &token::Lt) && // `foo:bar` } pub(super) fn recover_seq_parse_error( @@ -1150,7 +1128,7 @@ impl<'a> Parser<'a> { // this location. Emit the diagnostic and act as if the delimiter was // present for the parser's sake. - // Don't attempt to recover from this unclosed delimiter more than once. + // Don't attempt to recover from this unclosed delimiter more than once. let unmatched = self.unclosed_delims.remove(pos); let delim = TokenType::Token(token::CloseDelim(unmatched.expected_delim)); if unmatched.found_delim.is_none() { @@ -1184,7 +1162,7 @@ impl<'a> Parser<'a> { Err(err) } else { err.emit(); - self.expected_tokens.clear(); // Reduce the number of errors. + self.expected_tokens.clear(); // Reduce the number of errors. Ok(true) } } @@ -1215,17 +1193,15 @@ impl<'a> Parser<'a> { let mut brace_depth = 0; let mut bracket_depth = 0; let mut in_block = false; - debug!("recover_stmt_ enter loop (semi={:?}, block={:?})", - break_on_semi, break_on_block); + debug!("recover_stmt_ enter loop (semi={:?}, block={:?})", break_on_semi, break_on_block); loop { debug!("recover_stmt_ loop {:?}", self.token); match self.token.kind { token::OpenDelim(token::DelimToken::Brace) => { brace_depth += 1; self.bump(); - if break_on_block == BlockMode::Break && - brace_depth == 1 && - bracket_depth == 0 { + if break_on_block == BlockMode::Break && brace_depth == 1 && bracket_depth == 0 + { in_block = true; } } @@ -1258,23 +1234,23 @@ impl<'a> Parser<'a> { } token::Semi => { self.bump(); - if break_on_semi == SemiColonMode::Break && - brace_depth == 0 && - bracket_depth == 0 { + if break_on_semi == SemiColonMode::Break + && brace_depth == 0 + && bracket_depth == 0 + { debug!("recover_stmt_ return - Semi"); break; } } - token::Comma if break_on_semi == SemiColonMode::Comma && - brace_depth == 0 && - bracket_depth == 0 => + token::Comma + if break_on_semi == SemiColonMode::Comma + && brace_depth == 0 + && bracket_depth == 0 => { debug!("recover_stmt_ return - Semi"); break; } - _ => { - self.bump() - } + _ => self.bump(), } } } @@ -1309,9 +1285,9 @@ impl<'a> Parser<'a> { .span_label(self.token.span, "doc comments are not allowed here") .emit(); self.bump(); - } else if self.token == token::Pound && self.look_ahead(1, |t| { - *t == token::OpenDelim(token::Bracket) - }) { + } else if self.token == token::Pound + && self.look_ahead(1, |t| *t == token::OpenDelim(token::Bracket)) + { let lo = self.token.span; // Skip every token until next possible arg. while self.token != token::CloseDelim(token::Bracket) { @@ -1319,12 +1295,9 @@ impl<'a> Parser<'a> { } let sp = lo.to(self.token.span); self.bump(); - self.struct_span_err( - sp, - "attributes cannot be applied to a function parameter's type", - ) - .span_label(sp, "attributes are not allowed here") - .emit(); + self.struct_span_err(sp, "attributes cannot be applied to a function parameter's type") + .span_label(sp, "attributes are not allowed here") + .emit(); } } @@ -1338,9 +1311,10 @@ impl<'a> Parser<'a> { ) -> Option { // If we find a pattern followed by an identifier, it could be an (incorrect) // C-style parameter declaration. - if self.check_ident() && self.look_ahead(1, |t| { - *t == token::Comma || *t == token::CloseDelim(token::Paren) - }) { // `fn foo(String s) {}` + if self.check_ident() + && self.look_ahead(1, |t| *t == token::Comma || *t == token::CloseDelim(token::Paren)) + { + // `fn foo(String s) {}` let ident = self.parse_ident().unwrap(); let span = pat.span.with_hi(ident.span.hi()); @@ -1352,12 +1326,13 @@ impl<'a> Parser<'a> { ); return Some(ident); } else if let PatKind::Ident(_, ident, _) = pat.kind { - if require_name && ( - is_trait_item || - self.token == token::Comma || - self.token == token::Lt || - self.token == token::CloseDelim(token::Paren) - ) { // `fn foo(a, b) {}`, `fn foo(a, b) {}` or `fn foo(usize, usize) {}` + if require_name + && (is_trait_item + || self.token == token::Comma + || self.token == token::Lt + || self.token == token::CloseDelim(token::Paren)) + { + // `fn foo(a, b) {}`, `fn foo(a, b) {}` or `fn foo(usize, usize) {}` if is_self_allowed { err.span_suggestion( pat.span, @@ -1411,11 +1386,7 @@ impl<'a> Parser<'a> { .emit(); // Pretend the pattern is `_`, to avoid duplicate errors from AST validation. - let pat = P(Pat { - kind: PatKind::Wild, - span: pat.span, - id: ast::DUMMY_NODE_ID - }); + let pat = P(Pat { kind: PatKind::Wild, span: pat.span, id: ast::DUMMY_NODE_ID }); Ok((pat, ty)) } @@ -1474,10 +1445,10 @@ impl<'a> Parser<'a> { let sp = self.sess.source_map().next_point(self.token.span); (sp, format!("expected expression, found end of {}", origin)) } - _ => (self.token.span, format!( - "expected expression, found {}", - self.this_token_descr(), - )), + _ => ( + self.token.span, + format!("expected expression, found {}", self.this_token_descr(),), + ), }; let mut err = self.struct_span_err(span, &msg); let sp = self.sess.source_map().start_point(self.token.span); @@ -1516,9 +1487,9 @@ impl<'a> Parser<'a> { pub(super) fn deduplicate_recovered_params_names(&self, fn_inputs: &mut Vec) { let mut seen_inputs = FxHashSet::default(); for input in fn_inputs.iter_mut() { - let opt_ident = if let (PatKind::Ident(_, ident, _), TyKind::Err) = ( - &input.pat.kind, &input.ty.kind, - ) { + let opt_ident = if let (PatKind::Ident(_, ident, _), TyKind::Err) = + (&input.pat.kind, &input.ty.kind) + { Some(*ident) } else { None diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 71c9e58f58fd7..fa68ddf272a84 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1,22 +1,24 @@ -use super::{Parser, Restrictions, PrevTokenKind, TokenType, PathStyle, BlockMode}; -use super::{SemiColonMode, SeqSep, TokenExpectType}; -use super::pat::{GateOr, PARAM_EXPECTED}; use super::diagnostics::Error; +use super::pat::{GateOr, PARAM_EXPECTED}; +use super::{BlockMode, Parser, PathStyle, PrevTokenKind, Restrictions, TokenType}; +use super::{SemiColonMode, SeqSep, TokenExpectType}; use crate::maybe_recover_from_interpolated_ty_qpath; -use rustc_errors::{PResult, Applicability}; -use syntax::ast::{self, DUMMY_NODE_ID, AttrVec, AttrStyle, Ident, CaptureBy, Field, Lit}; -use syntax::ast::{BlockCheckMode, Expr, ExprKind, RangeLimits, Label, Movability, IsAsync, Arm}; -use syntax::ast::{Ty, TyKind, FunctionRetTy, Param, FnDecl, BinOpKind, BinOp, UnOp, Mac, AnonConst}; -use syntax::token::{self, Token, TokenKind}; +use rustc_errors::{Applicability, PResult}; +use std::mem; +use syntax::ast::{self, AttrStyle, AttrVec, CaptureBy, Field, Ident, Lit, DUMMY_NODE_ID}; +use syntax::ast::{ + AnonConst, BinOp, BinOpKind, FnDecl, FunctionRetTy, Mac, Param, Ty, TyKind, UnOp, +}; +use syntax::ast::{Arm, BlockCheckMode, Expr, ExprKind, IsAsync, Label, Movability, RangeLimits}; use syntax::print::pprust; use syntax::ptr::P; +use syntax::token::{self, Token, TokenKind}; use syntax::util::classify; use syntax::util::literal::LitError; -use syntax::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par}; +use syntax::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity}; use syntax_pos::source_map::{self, Span}; use syntax_pos::symbol::{kw, sym, Symbol}; -use std::mem; /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression /// dropped into the token stream, which happens while parsing the result of @@ -36,21 +38,25 @@ macro_rules! maybe_whole_expr { let path = path.clone(); $p.bump(); return Ok($p.mk_expr( - $p.token.span, ExprKind::Path(None, path), AttrVec::new() + $p.token.span, + ExprKind::Path(None, path), + AttrVec::new(), )); } token::NtBlock(block) => { let block = block.clone(); $p.bump(); return Ok($p.mk_expr( - $p.token.span, ExprKind::Block(block, None), AttrVec::new() + $p.token.span, + ExprKind::Block(block, None), + AttrVec::new(), )); } // N.B., `NtIdent(ident)` is normalized to `Ident` in `fn bump`. - _ => {}, + _ => {} }; } - } + }; } #[derive(Debug)] @@ -66,11 +72,7 @@ impl From> for LhsExpr { /// /// This conversion does not allocate. fn from(o: Option) -> Self { - if let Some(attrs) = o { - LhsExpr::AttributesParsed(attrs) - } else { - LhsExpr::NotYetParsed - } + if let Some(attrs) = o { LhsExpr::AttributesParsed(attrs) } else { LhsExpr::NotYetParsed } } } @@ -99,9 +101,8 @@ impl<'a> Parser<'a> { Ok(expr) => Ok(expr), Err(mut err) => match self.token.kind { token::Ident(name, false) - if name == kw::Underscore && self.look_ahead(1, |t| { - t == &token::Comma - }) => { + if name == kw::Underscore && self.look_ahead(1, |t| t == &token::Comma) => + { // Special-case handling of `foo(_, _, _)` err.emit(); let sp = self.token.span; @@ -115,9 +116,7 @@ impl<'a> Parser<'a> { /// Parses a sequence of expressions delimited by parentheses. fn parse_paren_expr_seq(&mut self) -> PResult<'a, Vec>> { - self.parse_paren_comma_seq(|p| { - p.parse_expr_catch_underscore() - }).map(|(r, _)| r) + self.parse_paren_comma_seq(|p| p.parse_expr_catch_underscore()).map(|(r, _)| r) } /// Parses an expression, subject to the given restrictions. @@ -125,7 +124,7 @@ impl<'a> Parser<'a> { pub(super) fn parse_expr_res( &mut self, r: Restrictions, - already_parsed_attrs: Option + already_parsed_attrs: Option, ) -> PResult<'a, P> { self.with_res(r, |this| this.parse_assoc_expr(already_parsed_attrs)) } @@ -135,10 +134,7 @@ impl<'a> Parser<'a> { /// This parses an expression accounting for associativity and precedence of the operators in /// the expression. #[inline] - fn parse_assoc_expr( - &mut self, - already_parsed_attrs: Option, - ) -> PResult<'a, P> { + fn parse_assoc_expr(&mut self, already_parsed_attrs: Option) -> PResult<'a, P> { self.parse_assoc_expr_with(0, already_parsed_attrs.into()) } @@ -177,7 +173,10 @@ impl<'a> Parser<'a> { let lhs_span = match (self.prev_token_kind, &lhs.kind) { (PrevTokenKind::Interpolated, _) => self.prev_span, (PrevTokenKind::Ident, &ExprKind::Path(None, ref path)) - if path.segments.len() == 1 => self.prev_span, + if path.segments.len() == 1 => + { + self.prev_span + } _ => lhs.span, }; @@ -209,14 +208,14 @@ impl<'a> Parser<'a> { // Special cases: if op == AssocOp::As { lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?; - continue + continue; } else if op == AssocOp::Colon { let maybe_path = self.could_ascription_be_path(&lhs.kind); self.last_type_ascription = Some((self.prev_span, maybe_path)); lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?; self.sess.gated_spans.gate(sym::type_ascription, lhs.span); - continue + continue; } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq { // If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to // generalise it to the Fixity::None code. @@ -228,20 +227,14 @@ impl<'a> Parser<'a> { } else { None }; - let (lhs_span, rhs_span) = (lhs.span, if let Some(ref x) = rhs { - x.span - } else { - cur_op_span - }); - let limits = if op == AssocOp::DotDot { - RangeLimits::HalfOpen - } else { - RangeLimits::Closed - }; + let (lhs_span, rhs_span) = + (lhs.span, if let Some(ref x) = rhs { x.span } else { cur_op_span }); + let limits = + if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed }; let r = self.mk_range(Some(lhs), rhs, limits)?; lhs = self.mk_expr(lhs_span.to(rhs_span), r, AttrVec::new()); - break + break; } let fixity = op.fixity(); @@ -252,10 +245,9 @@ impl<'a> Parser<'a> { // the special cases. The code is here only for future convenience. Fixity::None => 1, }; - let rhs = self.with_res( - restrictions - Restrictions::STMT_EXPR, - |this| this.parse_assoc_expr_with(prec + prec_adjustment, LhsExpr::NotYetParsed) - )?; + let rhs = self.with_res(restrictions - Restrictions::STMT_EXPR, |this| { + this.parse_assoc_expr_with(prec + prec_adjustment, LhsExpr::NotYetParsed) + })?; // Make sure that the span of the parent node is larger than the span of lhs and rhs, // including the attributes. @@ -267,11 +259,24 @@ impl<'a> Parser<'a> { .map_or(lhs_span, |a| a.span); let span = lhs_span.to(rhs.span); lhs = match op { - AssocOp::Add | AssocOp::Subtract | AssocOp::Multiply | AssocOp::Divide | - AssocOp::Modulus | AssocOp::LAnd | AssocOp::LOr | AssocOp::BitXor | - AssocOp::BitAnd | AssocOp::BitOr | AssocOp::ShiftLeft | AssocOp::ShiftRight | - AssocOp::Equal | AssocOp::Less | AssocOp::LessEqual | AssocOp::NotEqual | - AssocOp::Greater | AssocOp::GreaterEqual => { + AssocOp::Add + | AssocOp::Subtract + | AssocOp::Multiply + | AssocOp::Divide + | AssocOp::Modulus + | AssocOp::LAnd + | AssocOp::LOr + | AssocOp::BitXor + | AssocOp::BitAnd + | AssocOp::BitOr + | AssocOp::ShiftLeft + | AssocOp::ShiftRight + | AssocOp::Equal + | AssocOp::Less + | AssocOp::LessEqual + | AssocOp::NotEqual + | AssocOp::Greater + | AssocOp::GreaterEqual => { let ast_op = op.to_ast_binop().unwrap(); let binary = self.mk_binary(source_map::respan(cur_op_span, ast_op), lhs, rhs); self.mk_expr(span, binary, AttrVec::new()) @@ -279,16 +284,16 @@ impl<'a> Parser<'a> { AssocOp::Assign => self.mk_expr(span, ExprKind::Assign(lhs, rhs), AttrVec::new()), AssocOp::AssignOp(k) => { let aop = match k { - token::Plus => BinOpKind::Add, - token::Minus => BinOpKind::Sub, - token::Star => BinOpKind::Mul, - token::Slash => BinOpKind::Div, + token::Plus => BinOpKind::Add, + token::Minus => BinOpKind::Sub, + token::Star => BinOpKind::Mul, + token::Slash => BinOpKind::Div, token::Percent => BinOpKind::Rem, - token::Caret => BinOpKind::BitXor, - token::And => BinOpKind::BitAnd, - token::Or => BinOpKind::BitOr, - token::Shl => BinOpKind::Shl, - token::Shr => BinOpKind::Shr, + token::Caret => BinOpKind::BitXor, + token::And => BinOpKind::BitAnd, + token::Or => BinOpKind::BitOr, + token::Shl => BinOpKind::Shl, + token::Shr => BinOpKind::Shr, }; let aopexpr = self.mk_assign_op(source_map::respan(cur_op_span, aop), lhs, rhs); self.mk_expr(span, aopexpr, AttrVec::new()) @@ -298,7 +303,9 @@ impl<'a> Parser<'a> { } }; - if let Fixity::None = fixity { break } + if let Fixity::None = fixity { + break; + } } if last_type_ascription_set { self.last_type_ascription = None; @@ -339,10 +346,10 @@ impl<'a> Parser<'a> { /// but the next token implies this should be parsed as an expression. /// For example: `if let Some(x) = x { x } else { 0 } / 2`. fn error_found_expr_would_be_stmt(&self, lhs: &Expr) { - let mut err = self.struct_span_err(self.token.span, &format!( - "expected expression, found `{}`", - pprust::token_to_string(&self.token), - )); + let mut err = self.struct_span_err( + self.token.span, + &format!("expected expression, found `{}`", pprust::token_to_string(&self.token),), + ); err.span_label(self.token.span, "expected expression"); self.sess.expr_parentheses_needed(&mut err, lhs.span, Some(pprust::expr_to_string(&lhs))); err.emit(); @@ -382,8 +389,8 @@ impl<'a> Parser<'a> { /// Checks if this expression is a successfully parsed statement. fn expr_is_complete(&self, e: &Expr) -> bool { - self.restrictions.contains(Restrictions::STMT_EXPR) && - !classify::expr_requires_semi_to_be_stmt(e) + self.restrictions.contains(Restrictions::STMT_EXPR) + && !classify::expr_requires_semi_to_be_stmt(e) } fn is_at_start_of_range_notation_rhs(&self) -> bool { @@ -401,16 +408,18 @@ impl<'a> Parser<'a> { /// Parses prefix-forms of range notation: `..expr`, `..`, `..=expr`. fn parse_prefix_range_expr( &mut self, - already_parsed_attrs: Option + already_parsed_attrs: Option, ) -> PResult<'a, P> { // Check for deprecated `...` syntax. if self.token == token::DotDotDot { self.err_dotdotdot_syntax(self.token.span); } - debug_assert!([token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token.kind), - "parse_prefix_range_expr: token {:?} is not DotDot/DotDotEq", - self.token); + debug_assert!( + [token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token.kind), + "parse_prefix_range_expr: token {:?} is not DotDot/DotDotEq", + self.token + ); let tok = self.token.clone(); let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?; let lo = self.token.span; @@ -419,19 +428,14 @@ impl<'a> Parser<'a> { let opt_end = if self.is_at_start_of_range_notation_rhs() { // RHS must be parsed with more associativity than the dots. let next_prec = AssocOp::from_token(&tok).unwrap().precedence() + 1; - Some(self.parse_assoc_expr_with(next_prec, LhsExpr::NotYetParsed) - .map(|x| { - hi = x.span; - x - })?) + Some(self.parse_assoc_expr_with(next_prec, LhsExpr::NotYetParsed).map(|x| { + hi = x.span; + x + })?) } else { None }; - let limits = if tok == token::DotDot { - RangeLimits::HalfOpen - } else { - RangeLimits::Closed - }; + let limits = if tok == token::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed }; let r = self.mk_range(None, opt_end, limits)?; Ok(self.mk_expr(lo.to(hi), r, attrs)) @@ -460,7 +464,7 @@ impl<'a> Parser<'a> { span_of_tilde, "use `!` to perform bitwise not", "!".to_owned(), - Applicability::MachineApplicable + Applicability::MachineApplicable, ) .emit(); (lo.to(span), self.mk_unary(UnOp::Not, e)) @@ -477,9 +481,7 @@ impl<'a> Parser<'a> { let (span, e) = self.interpolated_or_expr_span(e)?; (lo.to(span), self.mk_unary(UnOp::Deref, e)) } - token::BinOp(token::And) | token::AndAnd => { - self.parse_address_of(lo)? - } + token::BinOp(token::And) | token::AndAnd => self.parse_address_of(lo)?, token::Ident(..) if self.token.is_keyword(kw::Box) => { self.bump(); let e = self.parse_prefix_expr(None); @@ -505,16 +507,15 @@ impl<'a> Parser<'a> { // Emit the error ... self.struct_span_err( self.token.span, - &format!("unexpected {} after identifier",self.this_token_descr()) + &format!("unexpected {} after identifier", self.this_token_descr()), ) .span_suggestion_short( // Span the `not` plus trailing whitespace to avoid // trailing whitespace after the `!` in our suggestion - self.sess.source_map() - .span_until_non_whitespace(lo.to(self.token.span)), + self.sess.source_map().span_until_non_whitespace(lo.to(self.token.span)), "use `!` to perform logical negation", "!".to_owned(), - Applicability::MachineApplicable + Applicability::MachineApplicable, ) .emit(); // —and recover! (just as if we were in the block @@ -526,7 +527,9 @@ impl<'a> Parser<'a> { return self.parse_dot_or_call_expr(Some(attrs)); } } - _ => { return self.parse_dot_or_call_expr(Some(attrs)); } + _ => { + return self.parse_dot_or_call_expr(Some(attrs)); + } }; return Ok(self.mk_expr(lo.to(hi), ex, attrs)); } @@ -545,9 +548,12 @@ impl<'a> Parser<'a> { }) } - fn parse_assoc_op_cast(&mut self, lhs: P, lhs_span: Span, - expr_kind: fn(P, P) -> ExprKind) - -> PResult<'a, P> { + fn parse_assoc_op_cast( + &mut self, + lhs: P, + lhs_span: Span, + expr_kind: fn(P, P) -> ExprKind, + ) -> PResult<'a, P> { let mk_expr = |this: &mut Self, rhs: P| { this.mk_expr(lhs_span.to(rhs.span), expr_kind(lhs, rhs), AttrVec::new()) }; @@ -556,9 +562,7 @@ impl<'a> Parser<'a> { // LessThan comparison after this cast. let parser_snapshot_before_type = self.clone(); match self.parse_ty_no_plus() { - Ok(rhs) => { - Ok(mk_expr(self, rhs)) - } + Ok(rhs) => Ok(mk_expr(self, rhs)), Err(mut type_err) => { // Rewind to before attempting to parse the type with generics, to recover // from situations like `x as usize < y` in which we first tried to parse @@ -592,19 +596,23 @@ impl<'a> Parser<'a> { op_noun, ); let span_after_type = parser_snapshot_after_type.token.span; - let expr = mk_expr(self, P(Ty { - span: path.span, - kind: TyKind::Path(None, path), - id: DUMMY_NODE_ID, - })); + let expr = mk_expr( + self, + P(Ty { + span: path.span, + kind: TyKind::Path(None, path), + id: DUMMY_NODE_ID, + }), + ); - let expr_str = self.span_to_snippet(expr.span) + let expr_str = self + .span_to_snippet(expr.span) .unwrap_or_else(|_| pprust::expr_to_string(&expr)); self.struct_span_err(self.token.span, &msg) .span_label( self.look_ahead(1, |t| t.span).to(span_after_type), - "interpreted as generic arguments" + "interpreted as generic arguments", ) .span_label(self.token.span, format!("not interpreted as {}", op_noun)) .span_suggestion( @@ -631,9 +639,7 @@ impl<'a> Parser<'a> { /// Parse `& mut? ` or `& raw [ const | mut ] `. fn parse_address_of(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> { self.expect_and()?; - let (k, m) = if self.check_keyword(kw::Raw) - && self.look_ahead(1, Token::is_mutability) - { + let (k, m) = if self.check_keyword(kw::Raw) && self.look_ahead(1, Token::is_mutability) { let found_raw = self.eat_keyword(kw::Raw); assert!(found_raw); let mutability = self.parse_const_or_mut().unwrap(); @@ -668,14 +674,14 @@ impl<'a> Parser<'a> { // Stitch the list of outer attributes onto the return value. // A little bit ugly, but the best way given the current code // structure - self.parse_dot_or_call_expr_with_(e0, lo).map(|expr| + self.parse_dot_or_call_expr_with_(e0, lo).map(|expr| { expr.map(|mut expr| { attrs.extend::>(expr.attrs.into()); expr.attrs = attrs; self.error_attr_on_if_expr(&expr); expr }) - ) + }) } fn error_attr_on_if_expr(&self, expr: &Expr) { @@ -711,34 +717,33 @@ impl<'a> Parser<'a> { self.expect_no_suffix(span, "a tuple index", suffix); } token::Literal(token::Lit { kind: token::Float, symbol, .. }) => { - self.bump(); - let fstr = symbol.as_str(); - let msg = format!("unexpected token: `{}`", symbol); - let mut err = self.diagnostic().struct_span_err(self.prev_span, &msg); - err.span_label(self.prev_span, "unexpected token"); - if fstr.chars().all(|x| "0123456789.".contains(x)) { - let float = match fstr.parse::().ok() { - Some(f) => f, - None => continue, - }; - let sugg = pprust::to_string(|s| { - s.popen(); - s.print_expr(&e); - s.s.word( "."); - s.print_usize(float.trunc() as usize); - s.pclose(); - s.s.word("."); - s.s.word(fstr.splitn(2, ".").last().unwrap().to_string()) - }); - err.span_suggestion( - lo.to(self.prev_span), - "try parenthesizing the first index", - sugg, - Applicability::MachineApplicable - ); - } - return Err(err); - + self.bump(); + let fstr = symbol.as_str(); + let msg = format!("unexpected token: `{}`", symbol); + let mut err = self.diagnostic().struct_span_err(self.prev_span, &msg); + err.span_label(self.prev_span, "unexpected token"); + if fstr.chars().all(|x| "0123456789.".contains(x)) { + let float = match fstr.parse::().ok() { + Some(f) => f, + None => continue, + }; + let sugg = pprust::to_string(|s| { + s.popen(); + s.print_expr(&e); + s.s.word("."); + s.print_usize(float.trunc() as usize); + s.pclose(); + s.s.word("."); + s.s.word(fstr.splitn(2, ".").last().unwrap().to_string()) + }); + err.span_suggestion( + lo.to(self.prev_span), + "try parenthesizing the first index", + sugg, + Applicability::MachineApplicable, + ); + } + return Err(err); } _ => { // FIXME Could factor this out into non_fatal_unexpected or something. @@ -748,7 +753,9 @@ impl<'a> Parser<'a> { } continue; } - if self.expr_is_complete(&e) { break; } + if self.expr_is_complete(&e) { + break; + } match self.token.kind { // expr(...) token::OpenDelim(token::Paren) => { @@ -770,7 +777,7 @@ impl<'a> Parser<'a> { let index = self.mk_index(e, ix); e = self.mk_expr(lo.to(hi), index, AttrVec::new()) } - _ => return Ok(e) + _ => return Ok(e), } } return Ok(e); @@ -797,8 +804,7 @@ impl<'a> Parser<'a> { _ => { // Field access `expr.f` if let Some(args) = segment.args { - self.span_err(args.span(), - "field expressions may not have generic arguments"); + self.span_err(args.span(), "field expressions may not have generic arguments"); } let span = lo.to(self.prev_span); @@ -895,7 +901,8 @@ impl<'a> Parser<'a> { } else if self.token.span.rust_2018() { // `Span::rust_2018()` is somewhat expensive; don't get it repeatedly. if self.check_keyword(kw::Async) { - if self.is_async_block() { // Check for `async {` and `async move {`. + if self.is_async_block() { + // Check for `async {` and `async move {`. self.parse_async_block(attrs) } else { self.parse_closure_expr(attrs) @@ -1010,22 +1017,20 @@ impl<'a> Parser<'a> { let lo = label.ident.span; self.expect(&token::Colon)?; if self.eat_keyword(kw::While) { - return self.parse_while_expr(Some(label), lo, attrs) + return self.parse_while_expr(Some(label), lo, attrs); } if self.eat_keyword(kw::For) { - return self.parse_for_expr(Some(label), lo, attrs) + return self.parse_for_expr(Some(label), lo, attrs); } if self.eat_keyword(kw::Loop) { - return self.parse_loop_expr(Some(label), lo, attrs) + return self.parse_loop_expr(Some(label), lo, attrs); } if self.token == token::OpenDelim(token::Brace) { return self.parse_block_expr(Some(label), lo, BlockCheckMode::Default, attrs); } let msg = "expected `while`, `for`, `loop` or `{` after a label"; - self.struct_span_err(self.token.span, msg) - .span_label(self.token.span, msg) - .emit(); + self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit(); // Continue as an expression in an effort to recover on `'label: non_block_expr`. self.parse_expr() } @@ -1053,11 +1058,7 @@ impl<'a> Parser<'a> { /// Parse an expression if the token can begin one. fn parse_expr_opt(&mut self) -> PResult<'a, Option>> { - Ok(if self.token.can_begin_expr() { - Some(self.parse_expr()?) - } else { - None - }) + Ok(if self.token.can_begin_expr() { Some(self.parse_expr()?) } else { None }) } /// Parse `"return" expr?`. @@ -1107,7 +1108,7 @@ impl<'a> Parser<'a> { symbol_unescaped, }), _ => Err(Some(lit)), - } + }, None => Err(None), } } @@ -1127,8 +1128,9 @@ impl<'a> Parser<'a> { // Attempt to recover `.4` as `0.4`. We don't currently have any syntax where // dot would follow an optional literal, so we do this unconditionally. recovered = self.look_ahead(1, |next_token| { - if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) - = next_token.kind { + if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) = + next_token.kind + { if self.token.span.hi() == next_token.span.lo() { let s = String::from("0.") + &symbol.as_str(); let kind = TokenKind::lit(token::Float, Symbol::intern(&s), suffix); @@ -1156,9 +1158,7 @@ impl<'a> Parser<'a> { self.bump(); Some(lit) } - Err(LitError::NotLiteral) => { - None - } + Err(LitError::NotLiteral) => None, Err(err) => { let span = token.span; let lit = match token.kind { @@ -1180,9 +1180,7 @@ impl<'a> Parser<'a> { fn report_lit_error(&self, err: LitError, lit: token::Lit, span: Span) { // Checks if `s` looks like i32 or u1234 etc. fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool { - s.len() > 1 - && s.starts_with(first_chars) - && s[1..].chars().all(|c| c.is_ascii_digit()) + s.len() > 1 && s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit()) } let token::Lit { kind, suffix, .. } = lit; @@ -1221,9 +1219,7 @@ impl<'a> Parser<'a> { if looks_like_width_suffix(&['f'], &suf) { // If it looks like a width, try to be helpful. let msg = format!("invalid width `{}` for float literal", &suf[1..]); - self.struct_span_err(span, &msg) - .help("valid widths are 32 and 64") - .emit(); + self.struct_span_err(span, &msg).help("valid widths are 32 and 64").emit(); } else { let msg = format!("invalid suffix `{}` for float literal", suf); self.struct_span_err(span, &msg) @@ -1244,8 +1240,7 @@ impl<'a> Parser<'a> { .emit(); } LitError::IntTooLarge => { - self.struct_span_err(span, "integer literal is too large") - .emit(); + self.struct_span_err(span, "integer literal is too large").emit(); } } } @@ -1257,10 +1252,10 @@ impl<'a> Parser<'a> { { // #59553: warn instead of reject out of hand to allow the fix to percolate // through the ecosystem when people fix their macros - let mut err = self.sess.span_diagnostic.struct_span_warn( - sp, - &format!("suffixes on {} are invalid", kind), - ); + let mut err = self + .sess + .span_diagnostic + .struct_span_warn(sp, &format!("suffixes on {} are invalid", kind)); err.note(&format!( "`{}` is *temporarily* accepted on tuple index fields as it was \ incorrectly accepted on stable for a few releases", @@ -1271,9 +1266,7 @@ impl<'a> Parser<'a> { `proc_macro::Literal::*_unsuffixed` for code that will desugar \ to tuple field access", ); - err.note( - "for more context, see https://github.com/rust-lang/rust/issues/60210", - ); + err.note("for more context, see https://github.com/rust-lang/rust/issues/60210"); err } else { self.struct_span_err(sp, &format!("suffixes on {} are invalid", kind)) @@ -1328,17 +1321,11 @@ impl<'a> Parser<'a> { fn parse_closure_expr(&mut self, attrs: AttrVec) -> PResult<'a, P> { let lo = self.token.span; - let movability = if self.eat_keyword(kw::Static) { - Movability::Static - } else { - Movability::Movable - }; + let movability = + if self.eat_keyword(kw::Static) { Movability::Static } else { Movability::Movable }; - let asyncness = if self.token.span.rust_2018() { - self.parse_asyncness() - } else { - IsAsync::NotAsync - }; + let asyncness = + if self.token.span.rust_2018() { self.parse_asyncness() } else { IsAsync::NotAsync }; if asyncness.is_async() { // Feature-gate `async ||` closures. self.sess.gated_spans.gate(sym::async_closure, self.prev_span); @@ -1351,7 +1338,7 @@ impl<'a> Parser<'a> { FunctionRetTy::Default(_) => { let restrictions = self.restrictions - Restrictions::STMT_EXPR; self.parse_expr_res(restrictions, None)? - }, + } _ => { // If an explicit return type is given, require a block to appear (RFC 968). let body_lo = self.token.span; @@ -1362,16 +1349,13 @@ impl<'a> Parser<'a> { Ok(self.mk_expr( lo.to(body.span), ExprKind::Closure(capture_clause, asyncness, movability, decl, body, lo.to(decl_hi)), - attrs)) + attrs, + )) } /// Parses an optional `move` prefix to a closure lke construct. fn parse_capture_clause(&mut self) -> CaptureBy { - if self.eat_keyword(kw::Move) { - CaptureBy::Value - } else { - CaptureBy::Ref - } + if self.eat_keyword(kw::Move) { CaptureBy::Value } else { CaptureBy::Ref } } /// Parses the `|arg, arg|` header of a closure. @@ -1381,22 +1365,21 @@ impl<'a> Parser<'a> { Vec::new() } else { self.expect(&token::BinOp(token::Or))?; - let args = self.parse_seq_to_before_tokens( - &[&token::BinOp(token::Or), &token::OrOr], - SeqSep::trailing_allowed(token::Comma), - TokenExpectType::NoExpect, - |p| p.parse_fn_block_param() - )?.0; + let args = self + .parse_seq_to_before_tokens( + &[&token::BinOp(token::Or), &token::OrOr], + SeqSep::trailing_allowed(token::Comma), + TokenExpectType::NoExpect, + |p| p.parse_fn_block_param(), + )? + .0; self.expect_or()?; args } }; let output = self.parse_ret_ty(true, true)?; - Ok(P(FnDecl { - inputs: inputs_captures, - output, - })) + Ok(P(FnDecl { inputs: inputs_captures, output })) } /// Parses a parameter in a closure header (e.g., `|arg, arg|`). @@ -1407,11 +1390,7 @@ impl<'a> Parser<'a> { let t = if self.eat(&token::Colon) { self.parse_ty()? } else { - P(Ty { - id: DUMMY_NODE_ID, - kind: TyKind::Infer, - span: self.prev_span, - }) + P(Ty { id: DUMMY_NODE_ID, kind: TyKind::Infer, span: self.prev_span }) }; let span = lo.to(self.token.span); Ok(Param { @@ -1435,10 +1414,10 @@ impl<'a> Parser<'a> { // the dead code lint. if self.eat_keyword(kw::Else) || !cond.returns() { let sp = self.sess.source_map().next_point(lo); - let mut err = self.diagnostic() - .struct_span_err(sp, "missing condition for `if` expression"); + let mut err = + self.diagnostic().struct_span_err(sp, "missing condition for `if` expression"); err.span_label(sp, "expected if condition here"); - return Err(err) + return Err(err); } let not_block = self.token != token::OpenDelim(token::Brace); let thn = self.parse_block().map_err(|mut err| { @@ -1475,10 +1454,9 @@ impl<'a> Parser<'a> { let lo = self.prev_span; let pat = self.parse_top_pat(GateOr::No)?; self.expect(&token::Eq)?; - let expr = self.with_res( - Restrictions::NO_STRUCT_LITERAL, - |this| this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into()) - )?; + let expr = self.with_res(Restrictions::NO_STRUCT_LITERAL, |this| { + this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into()) + })?; let span = lo.to(expr.span); self.sess.gated_spans.gate(sym::let_chains, span); Ok(self.mk_expr(span, ExprKind::Let(pat, expr), attrs)) @@ -1499,7 +1477,7 @@ impl<'a> Parser<'a> { &mut self, opt_label: Option
{blk}
{blk}
", - id = cx.derive_id(short.to_owned()), name = name); + id = cx.derive_id(short.to_owned()), + name = name + ); } match myitem.inner { @@ -2014,69 +2056,72 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: use crate::html::format::anchor; match *src { - Some(ref src) => { - write!(w, ""); } clean::ImportItem(ref import) => { - write!(w, "", - myitem.visibility.print_with_space(), import.print()); + write!( + w, + "", + myitem.visibility.print_with_space(), + import.print() + ); } _ => { - if myitem.name.is_none() { continue } + if myitem.name.is_none() { + continue; + } let unsafety_flag = match myitem.inner { clean::FunctionItem(ref func) | clean::ForeignFunctionItem(ref func) - if func.header.unsafety == hir::Unsafety::Unsafe => { + if func.header.unsafety == hir::Unsafety::Unsafe => + { "" } _ => "", }; let stab = myitem.stability_class(); - let add = if stab.is_some() { - " " - } else { - "" - }; + let add = if stab.is_some() { " " } else { "" }; let doc_value = myitem.doc_value().unwrap_or(""); - write!(w, "\ + write!( + w, + "\ \ \ \ ", - name = *myitem.name.as_ref().unwrap(), - stab_tags = stability_tags(myitem), - docs = MarkdownSummaryLine(doc_value, &myitem.links()).to_string(), - class = myitem.type_(), - add = add, - stab = stab.unwrap_or_else(|| String::new()), - unsafety_flag = unsafety_flag, - href = item_path(myitem.type_(), myitem.name.as_ref().unwrap()), - title = [full_path(cx, myitem), myitem.type_().to_string()] - .iter() - .filter_map(|s| if !s.is_empty() { - Some(s.as_str()) - } else { - None - }) - .collect::>() - .join(" "), - ); + name = *myitem.name.as_ref().unwrap(), + stab_tags = stability_tags(myitem), + docs = MarkdownSummaryLine(doc_value, &myitem.links()).to_string(), + class = myitem.type_(), + add = add, + stab = stab.unwrap_or_else(|| String::new()), + unsafety_flag = unsafety_flag, + href = item_path(myitem.type_(), myitem.name.as_ref().unwrap()), + title = [full_path(cx, myitem), myitem.type_().to_string()] + .iter() + .filter_map(|s| if !s.is_empty() { Some(s.as_str()) } else { None }) + .collect::>() + .join(" "), + ); } } } @@ -2110,11 +2155,7 @@ fn stability_tags(item: &clean::Item) -> String { tags += &tag_html("deprecated", message); } - if let Some(stab) = item - .stability - .as_ref() - .filter(|s| s.level == stability::Unstable) - { + if let Some(stab) = item.stability.as_ref().filter(|s| s.level == stability::Unstable) { if stab.feature.as_ref().map(|s| &**s) == Some("rustc_private") { tags += &tag_html("internal", "Internal"); } else { @@ -2156,17 +2197,18 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { if let Some(note) = note { let mut ids = cx.id_map.borrow_mut(); let html = MarkdownHtml( - ¬e, &mut ids, error_codes, cx.shared.edition, &cx.shared.playground); + ¬e, + &mut ids, + error_codes, + cx.shared.edition, + &cx.shared.playground, + ); message.push_str(&format!(": {}", html.to_string())); } stability.push(format!("
{}
", message)); } - if let Some(stab) = item - .stability - .as_ref() - .filter(|stab| stab.level == stability::Unstable) - { + if let Some(stab) = item.stability.as_ref().filter(|stab| stab.level == stability::Unstable) { let is_rustc_private = stab.feature.as_ref().map(|s| &**s) == Some("rustc_private"); let mut message = if is_rustc_private { @@ -2211,23 +2253,17 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { error_codes, cx.shared.edition, &cx.shared.playground, - ).to_string() + ) + .to_string() ); } - let class = if is_rustc_private { - "internal" - } else { - "unstable" - }; + let class = if is_rustc_private { "internal" } else { "unstable" }; stability.push(format!("
{}
", class, message)); } if let Some(ref cfg) = item.attrs.cfg { - stability.push(format!( - "
{}
", - cfg.render_long_html() - )); + stability.push(format!("
{}
", cfg.render_long_html())); } stability @@ -2236,23 +2272,29 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Constant) { write!(w, "
");
     render_attributes(w, it, false);
-    write!(w, "{vis}const \
+    write!(
+        w,
+        "{vis}const \
                {name}: {typ}
", - vis = it.visibility.print_with_space(), - name = it.name.as_ref().unwrap(), - typ = c.type_.print()); + vis = it.visibility.print_with_space(), + name = it.name.as_ref().unwrap(), + typ = c.type_.print() + ); document(w, cx, it) } fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static) { write!(w, "
");
     render_attributes(w, it, false);
-    write!(w, "{vis}static {mutability}\
+    write!(
+        w,
+        "{vis}static {mutability}\
                {name}: {typ}
", - vis = it.visibility.print_with_space(), - mutability = s.mutability.print_with_space(), - name = it.name.as_ref().unwrap(), - typ = s.type_.print()); + vis = it.visibility.print_with_space(), + mutability = s.mutability.print_with_space(), + name = it.name.as_ref().unwrap(), + typ = s.type_.print() + ); document(w, cx, it) } @@ -2266,60 +2308,77 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func print_abi_with_space(f.header.abi), it.name.as_ref().unwrap(), f.generics.print() - ).len(); + ) + .len(); write!(w, "{}
", render_spotlight_traits(it));
     render_attributes(w, it, false);
-    write!(w,
-           "{vis}{constness}{unsafety}{asyncness}{abi}fn \
+    write!(
+        w,
+        "{vis}{constness}{unsafety}{asyncness}{abi}fn \
            {name}{generics}{decl}{where_clause}
", - vis = it.visibility.print_with_space(), - constness = f.header.constness.print_with_space(), - unsafety = f.header.unsafety.print_with_space(), - asyncness = f.header.asyncness.print_with_space(), - abi = print_abi_with_space(f.header.abi), - name = it.name.as_ref().unwrap(), - generics = f.generics.print(), - where_clause = WhereClause { gens: &f.generics, indent: 0, end_newline: true }, - decl = Function { - decl: &f.decl, - header_len, - indent: 0, - asyncness: f.header.asyncness, - }.print()); + vis = it.visibility.print_with_space(), + constness = f.header.constness.print_with_space(), + unsafety = f.header.unsafety.print_with_space(), + asyncness = f.header.asyncness.print_with_space(), + abi = print_abi_with_space(f.header.abi), + name = it.name.as_ref().unwrap(), + generics = f.generics.print(), + where_clause = WhereClause { gens: &f.generics, indent: 0, end_newline: true }, + decl = Function { decl: &f.decl, header_len, indent: 0, asyncness: f.header.asyncness } + .print() + ); document(w, cx, it) } -fn render_implementor(cx: &Context, implementor: &Impl, w: &mut Buffer, - implementor_dups: &FxHashMap<&str, (DefId, bool)>) { +fn render_implementor( + cx: &Context, + implementor: &Impl, + w: &mut Buffer, + implementor_dups: &FxHashMap<&str, (DefId, bool)>, +) { // If there's already another implementor that has the same abbridged name, use the // full path, for example in `std::iter::ExactSizeIterator` let use_absolute = match implementor.inner_impl().for_ { - clean::ResolvedPath { ref path, is_generic: false, .. } | - clean::BorrowedRef { + clean::ResolvedPath { ref path, is_generic: false, .. } + | clean::BorrowedRef { type_: box clean::ResolvedPath { ref path, is_generic: false, .. }, .. } => implementor_dups[path.last_name()].1, _ => false, }; - render_impl(w, cx, implementor, AssocItemLink::Anchor(None), RenderMode::Normal, - implementor.impl_item.stable_since(), false, Some(use_absolute), false, false); + render_impl( + w, + cx, + implementor, + AssocItemLink::Anchor(None), + RenderMode::Normal, + implementor.impl_item.stable_since(), + false, + Some(use_absolute), + false, + false, + ); } -fn render_impls(cx: &Context, w: &mut Buffer, - traits: &[&&Impl], - containing_item: &clean::Item) { - let mut impls = traits.iter() +fn render_impls(cx: &Context, w: &mut Buffer, traits: &[&&Impl], containing_item: &clean::Item) { + let mut impls = traits + .iter() .map(|i| { let did = i.trait_did().unwrap(); let assoc_link = AssocItemLink::GotoSource(did, &i.inner_impl().provided_trait_methods); - let mut buffer = if w.is_for_html() { - Buffer::html() - } else { - Buffer::new() - }; - render_impl(&mut buffer, cx, i, assoc_link, - RenderMode::Normal, containing_item.stable_since(), - true, None, false, true); + let mut buffer = if w.is_for_html() { Buffer::html() } else { Buffer::new() }; + render_impl( + &mut buffer, + cx, + i, + assoc_link, + RenderMode::Normal, + containing_item.stable_since(), + true, + None, + false, + true, + ); buffer.into_inner() }) .collect::>(); @@ -2351,12 +2410,7 @@ fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl) -> Ordering { name_key(&lhs).cmp(&name_key(&rhs)) } -fn item_trait( - w: &mut Buffer, - cx: &Context, - it: &clean::Item, - t: &clean::Trait, -) { +fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) { let bounds = bounds(&t.bounds, false); let types = t.items.iter().filter(|m| m.is_associated_type()).collect::>(); let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::>(); @@ -2367,13 +2421,16 @@ fn item_trait( wrap_into_docblock(w, |w| { write!(w, "
");
         render_attributes(w, it, true);
-        write!(w, "{}{}{}trait {}{}{}",
-               it.visibility.print_with_space(),
-               t.unsafety.print_with_space(),
-               if t.is_auto { "auto " } else { "" },
-               it.name.as_ref().unwrap(),
-               t.generics.print(),
-               bounds);
+        write!(
+            w,
+            "{}{}{}trait {}{}{}",
+            it.visibility.print_with_space(),
+            t.unsafety.print_with_space(),
+            if t.is_auto { "auto " } else { "" },
+            it.name.as_ref().unwrap(),
+            t.generics.print(),
+            bounds
+        );
 
         if !t.generics.where_predicates.is_empty() {
             write!(w, "{}", WhereClause { gens: &t.generics, indent: 0, end_newline: true });
@@ -2405,7 +2462,7 @@ fn item_trait(
                 write!(w, ";\n");
 
                 if pos < required.len() - 1 {
-                   write!(w, "
"); + write!(w, "
"); } } if !required.is_empty() && !provided.is_empty() { @@ -2416,13 +2473,13 @@ fn item_trait( match m.inner { clean::MethodItem(ref inner) if !inner.generics.where_predicates.is_empty() => { write!(w, ",\n {{ ... }}\n"); - }, + } _ => { write!(w, " {{ ... }}\n"); - }, + } } if pos < provided.len() - 1 { - write!(w, "
"); + write!(w, "
"); } } write!(w, "}}"); @@ -2433,16 +2490,15 @@ fn item_trait( // Trait documentation document(w, cx, it); - fn write_small_section_header( - w: &mut Buffer, - id: &str, - title: &str, - extra_content: &str, - ) { - write!(w, " + fn write_small_section_header(w: &mut Buffer, id: &str, title: &str, extra_content: &str) { + write!( + w, + "

\ {1}\ -

{2}", id, title, extra_content) + {2}", + id, title, extra_content + ) } fn write_loading_content(w: &mut Buffer, extra_content: &str) { @@ -2454,10 +2510,13 @@ fn item_trait( let item_type = m.type_(); let id = cx.derive_id(format!("{}.{}", item_type, name)); let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space())); - write!(w, "

{extra}", - extra = render_spotlight_traits(m), - id = id, - ns_id = ns_id); + write!( + w, + "

{extra}", + extra = render_spotlight_traits(m), + id = id, + ns_id = ns_id + ); render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl); write!(w, ""); render_stability_since(w, m, t); @@ -2466,8 +2525,12 @@ fn item_trait( } if !types.is_empty() { - write_small_section_header(w, "associated-types", "Associated Types", - "
"); + write_small_section_header( + w, + "associated-types", + "Associated Types", + "
", + ); for t in &types { trait_item(w, cx, *t, it); } @@ -2475,8 +2538,12 @@ fn item_trait( } if !consts.is_empty() { - write_small_section_header(w, "associated-const", "Associated Constants", - "
"); + write_small_section_header( + w, + "associated-const", + "Associated Constants", + "
", + ); for t in &consts { trait_item(w, cx, *t, it); } @@ -2485,16 +2552,24 @@ fn item_trait( // Output the documentation for each function individually if !required.is_empty() { - write_small_section_header(w, "required-methods", "Required methods", - "
"); + write_small_section_header( + w, + "required-methods", + "Required methods", + "
", + ); for m in &required { trait_item(w, cx, *m, it); } write_loading_content(w, "
"); } if !provided.is_empty() { - write_small_section_header(w, "provided-methods", "Provided methods", - "
"); + write_small_section_header( + w, + "provided-methods", + "Provided methods", + "
", + ); for m in &provided { trait_item(w, cx, *m, it); } @@ -2512,8 +2587,8 @@ fn item_trait( let mut implementor_dups: FxHashMap<&str, (DefId, bool)> = FxHashMap::default(); for implementor in implementors { match implementor.inner_impl().for_ { - clean::ResolvedPath { ref path, did, is_generic: false, .. } | - clean::BorrowedRef { + clean::ResolvedPath { ref path, did, is_generic: false, .. } + | clean::BorrowedRef { type_: box clean::ResolvedPath { ref path, did, is_generic: false, .. }, .. } => { @@ -2527,13 +2602,12 @@ fn item_trait( } } - let (local, foreign) = implementors.iter() - .partition::, _>(|i| i.inner_impl().for_.def_id() - .map_or(true, |d| cx.cache.paths.contains_key(&d))); - + let (local, foreign) = implementors.iter().partition::, _>(|i| { + i.inner_impl().for_.def_id().map_or(true, |d| cx.cache.paths.contains_key(&d)) + }); - let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) = local.iter() - .partition(|i| i.inner_impl().synthetic); + let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) = + local.iter().partition(|i| i.inner_impl().synthetic); synthetic.sort_by(compare_impl); concrete.sort_by(compare_impl); @@ -2544,29 +2618,45 @@ fn item_trait( for implementor in foreign { let assoc_link = AssocItemLink::GotoSource( implementor.impl_item.def_id, - &implementor.inner_impl().provided_trait_methods + &implementor.inner_impl().provided_trait_methods, + ); + render_impl( + w, + cx, + &implementor, + assoc_link, + RenderMode::Normal, + implementor.impl_item.stable_since(), + false, + None, + true, + false, ); - render_impl(w, cx, &implementor, assoc_link, - RenderMode::Normal, implementor.impl_item.stable_since(), false, - None, true, false); } write_loading_content(w, ""); } - write_small_section_header(w, "implementors", "Implementors", - "
"); + write_small_section_header( + w, + "implementors", + "Implementors", + "
", + ); for implementor in concrete { render_implementor(cx, implementor, w, &implementor_dups); } write_loading_content(w, "
"); if t.auto { - write_small_section_header(w, "synthetic-implementors", "Auto implementors", - "
"); + write_small_section_header( + w, + "synthetic-implementors", + "Auto implementors", + "
", + ); for implementor in synthetic { - synthetic_types.extend( - collect_paths_for_type(implementor.inner_impl().for_.clone()) - ); + synthetic_types + .extend(collect_paths_for_type(implementor.inner_impl().for_.clone())); render_implementor(cx, implementor, w, &implementor_dups); } write_loading_content(w, "
"); @@ -2574,13 +2664,21 @@ fn item_trait( } else { // even without any implementations to write in, we still want the heading and list, so the // implementors javascript file pulled in below has somewhere to write the impls into - write_small_section_header(w, "implementors", "Implementors", - "
"); + write_small_section_header( + w, + "implementors", + "Implementors", + "
", + ); write_loading_content(w, "
"); if t.auto { - write_small_section_header(w, "synthetic-implementors", "Auto implementors", - "
"); + write_small_section_header( + w, + "synthetic-implementors", + "Auto implementors", + "
", + ); write_loading_content(w, "
"); } } @@ -2590,18 +2688,21 @@ fn item_trait( serde_json::to_string(&synthetic_types).unwrap(), ); - write!(w, r#""#, - root_path = vec![".."; cx.current.len()].join("/"), - path = if it.def_id.is_local() { - cx.current.join("/") - } else { - let (ref path, _) = cx.cache.external_paths[&it.def_id]; - path[..path.len() - 1].join("/") - }, - ty = it.type_(), - name = *it.name.as_ref().unwrap()); + root_path = vec![".."; cx.current.len()].join("/"), + path = if it.def_id.is_local() { + cx.current.join("/") + } else { + let (ref path, _) = cx.cache.external_paths[&it.def_id]; + path[..path.len() - 1].join("/") + }, + ty = it.type_(), + name = *it.name.as_ref().unwrap() + ); } fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>) -> String { @@ -2610,7 +2711,7 @@ fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>) -> String { let name = it.name.as_ref().unwrap(); let ty = match it.type_() { Typedef | AssocType => AssocType, - s@_ => s, + s @ _ => s, }; let anchor = format!("#{}.{}", ty, name); @@ -2623,29 +2724,40 @@ fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>) -> String { } } -fn assoc_const(w: &mut Buffer, - it: &clean::Item, - ty: &clean::Type, - _default: Option<&String>, - link: AssocItemLink<'_>, - extra: &str) { - write!(w, "{}{}const {}: {}", - extra, - it.visibility.print_with_space(), - naive_assoc_href(it, link), - it.name.as_ref().unwrap(), - ty.print()); +fn assoc_const( + w: &mut Buffer, + it: &clean::Item, + ty: &clean::Type, + _default: Option<&String>, + link: AssocItemLink<'_>, + extra: &str, +) { + write!( + w, + "{}{}const {}: {}", + extra, + it.visibility.print_with_space(), + naive_assoc_href(it, link), + it.name.as_ref().unwrap(), + ty.print() + ); } -fn assoc_type(w: &mut Buffer, it: &clean::Item, - bounds: &[clean::GenericBound], - default: Option<&clean::Type>, - link: AssocItemLink<'_>, - extra: &str) { - write!(w, "{}type {}", - extra, - naive_assoc_href(it, link), - it.name.as_ref().unwrap()); +fn assoc_type( + w: &mut Buffer, + it: &clean::Item, + bounds: &[clean::GenericBound], + default: Option<&clean::Type>, + link: AssocItemLink<'_>, + extra: &str, +) { + write!( + w, + "{}type {}", + extra, + naive_assoc_href(it, link), + it.name.as_ref().unwrap() + ); if !bounds.is_empty() { write!(w, ": {}", print_generic_bounds(bounds)) } @@ -2666,17 +2778,21 @@ fn render_stability_since(w: &mut Buffer, item: &clean::Item, containing_item: & render_stability_since_raw(w, item.stable_since(), containing_item.stable_since()) } -fn render_assoc_item(w: &mut Buffer, - item: &clean::Item, - link: AssocItemLink<'_>, - parent: ItemType) { - fn method(w: &mut Buffer, - meth: &clean::Item, - header: hir::FnHeader, - g: &clean::Generics, - d: &clean::FnDecl, - link: AssocItemLink<'_>, - parent: ItemType) { +fn render_assoc_item( + w: &mut Buffer, + item: &clean::Item, + link: AssocItemLink<'_>, + parent: ItemType, +) { + fn method( + w: &mut Buffer, + meth: &clean::Item, + header: hir::FnHeader, + g: &clean::Generics, + d: &clean::FnDecl, + link: AssocItemLink<'_>, + parent: ItemType, + ) { let name = meth.name.as_ref().unwrap(); let anchor = format!("#{}.{}", meth.type_(), name); let href = match link { @@ -2704,7 +2820,8 @@ fn render_assoc_item(w: &mut Buffer, print_abi_with_space(header.abi), name, g.print() - ).len(); + ) + .len(); let (indent, end_newline) = if parent == ItemType::Trait { header_len += 4; (4, false) @@ -2712,47 +2829,45 @@ fn render_assoc_item(w: &mut Buffer, (0, true) }; render_attributes(w, meth, false); - write!(w, "{}{}{}{}{}{}{}fn {name}\ + write!( + w, + "{}{}{}{}{}{}{}fn {name}\ {generics}{decl}{where_clause}", - if parent == ItemType::Trait { " " } else { "" }, - meth.visibility.print_with_space(), - header.constness.print_with_space(), - header.unsafety.print_with_space(), - header.asyncness.print_with_space(), - print_default_space(meth.is_default()), - print_abi_with_space(header.abi), - href = href, - name = name, - generics = g.print(), - decl = Function { - decl: d, - header_len, - indent, - asyncness: header.asyncness, - }.print(), - where_clause = WhereClause { - gens: g, - indent, - end_newline, - }) + if parent == ItemType::Trait { " " } else { "" }, + meth.visibility.print_with_space(), + header.constness.print_with_space(), + header.unsafety.print_with_space(), + header.asyncness.print_with_space(), + print_default_space(meth.is_default()), + print_abi_with_space(header.abi), + href = href, + name = name, + generics = g.print(), + decl = Function { decl: d, header_len, indent, asyncness: header.asyncness }.print(), + where_clause = WhereClause { gens: g, indent, end_newline } + ) } match item.inner { - clean::StrippedItem(..) => {}, - clean::TyMethodItem(ref m) => { - method(w, item, m.header, &m.generics, &m.decl, link, parent) - } - clean::MethodItem(ref m) => { - method(w, item, m.header, &m.generics, &m.decl, link, parent) - } - clean::AssocConstItem(ref ty, ref default) => { - assoc_const(w, item, ty, default.as_ref(), link, - if parent == ItemType::Trait { " " } else { "" }) - } - clean::AssocTypeItem(ref bounds, ref default) => { - assoc_type(w, item, bounds, default.as_ref(), link, - if parent == ItemType::Trait { " " } else { "" }) - } - _ => panic!("render_assoc_item called on non-associated-item") + clean::StrippedItem(..) => {} + clean::TyMethodItem(ref m) => method(w, item, m.header, &m.generics, &m.decl, link, parent), + clean::MethodItem(ref m) => method(w, item, m.header, &m.generics, &m.decl, link, parent), + clean::AssocConstItem(ref ty, ref default) => assoc_const( + w, + item, + ty, + default.as_ref(), + link, + if parent == ItemType::Trait { " " } else { "" }, + ), + clean::AssocTypeItem(ref bounds, ref default) => assoc_type( + w, + item, + bounds, + default.as_ref(), + link, + if parent == ItemType::Trait { " " } else { "" }, + ), + _ => panic!("render_assoc_item called on non-associated-item"), } } @@ -2760,45 +2875,51 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct wrap_into_docblock(w, |w| { write!(w, "
");
         render_attributes(w, it, true);
-        render_struct(w,
-                      it,
-                      Some(&s.generics),
-                      s.struct_type,
-                      &s.fields,
-                      "",
-                      true);
+        render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true);
         write!(w, "
") }); document(w, cx, it); - let mut fields = s.fields.iter().filter_map(|f| { - match f.inner { + let mut fields = s + .fields + .iter() + .filter_map(|f| match f.inner { clean::StructFieldItem(ref ty) => Some((f, ty)), _ => None, - } - }).peekable(); + }) + .peekable(); if let doctree::Plain = s.struct_type { if fields.peek().is_some() { - write!(w, "

+ write!( + w, + "

Fields{}

", - document_non_exhaustive_header(it)); + document_non_exhaustive_header(it) + ); document_non_exhaustive(w, it); for (field, ty) in fields { - let id = cx.derive_id(format!("{}.{}", - ItemType::StructField, - field.name.as_ref().unwrap())); - let ns_id = cx.derive_id(format!("{}.{}", - field.name.as_ref().unwrap(), - ItemType::StructField.name_space())); - write!(w, "\ + let id = cx.derive_id(format!( + "{}.{}", + ItemType::StructField, + field.name.as_ref().unwrap() + )); + let ns_id = cx.derive_id(format!( + "{}.{}", + field.name.as_ref().unwrap(), + ItemType::StructField.name_space() + )); + write!( + w, + "\ \ {name}: {ty}\ ", - item_type = ItemType::StructField, - id = id, - ns_id = ns_id, - name = field.name.as_ref().unwrap(), - ty = ty.print()); + item_type = ItemType::StructField, + id = id, + ns_id = ns_id, + name = field.name.as_ref().unwrap(), + ty = ty.print() + ); document(w, cx, field); } } @@ -2810,39 +2931,41 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) wrap_into_docblock(w, |w| { write!(w, "
");
         render_attributes(w, it, true);
-        render_union(w,
-                     it,
-                     Some(&s.generics),
-                     &s.fields,
-                     "",
-                     true);
+        render_union(w, it, Some(&s.generics), &s.fields, "", true);
         write!(w, "
") }); document(w, cx, it); - let mut fields = s.fields.iter().filter_map(|f| { - match f.inner { + let mut fields = s + .fields + .iter() + .filter_map(|f| match f.inner { clean::StructFieldItem(ref ty) => Some((f, ty)), _ => None, - } - }).peekable(); + }) + .peekable(); if fields.peek().is_some() { - write!(w, "

- Fields

"); + write!( + w, + "

+ Fields

" + ); for (field, ty) in fields { let name = field.name.as_ref().expect("union field name"); let id = format!("{}.{}", ItemType::StructField, name); - write!(w, "\ + write!( + w, + "\ \ {name}: {ty}\ ", - id = id, - name = name, - shortty = ItemType::StructField, - ty = ty.print()); + id = id, + name = name, + shortty = ItemType::StructField, + ty = ty.print() + ); if let Some(stability_class) = field.stability_class() { - write!(w, "", - stab = stability_class); + write!(w, "", stab = stability_class); } document(w, cx, field); } @@ -2854,11 +2977,14 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { wrap_into_docblock(w, |w| { write!(w, "
");
         render_attributes(w, it, true);
-        write!(w, "{}enum {}{}{}",
-               it.visibility.print_with_space(),
-               it.name.as_ref().unwrap(),
-               e.generics.print(),
-               WhereClause { gens: &e.generics, indent: 0, end_newline: true });
+        write!(
+            w,
+            "{}enum {}{}{}",
+            it.visibility.print_with_space(),
+            it.name.as_ref().unwrap(),
+            e.generics.print(),
+            WhereClause { gens: &e.generics, indent: 0, end_newline: true }
+        );
         if e.variants.is_empty() && !e.variants_stripped {
             write!(w, " {{}}");
         } else {
@@ -2867,31 +2993,23 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) {
                 write!(w, "    ");
                 let name = v.name.as_ref().unwrap();
                 match v.inner {
-                    clean::VariantItem(ref var) => {
-                        match var.kind {
-                            clean::VariantKind::CLike => write!(w, "{}", name),
-                            clean::VariantKind::Tuple(ref tys) => {
-                                write!(w, "{}(", name);
-                                for (i, ty) in tys.iter().enumerate() {
-                                    if i > 0 {
-                                        write!(w, ", ")
-                                    }
-                                    write!(w, "{}", ty.print());
+                    clean::VariantItem(ref var) => match var.kind {
+                        clean::VariantKind::CLike => write!(w, "{}", name),
+                        clean::VariantKind::Tuple(ref tys) => {
+                            write!(w, "{}(", name);
+                            for (i, ty) in tys.iter().enumerate() {
+                                if i > 0 {
+                                    write!(w, ", ")
                                 }
-                                write!(w, ")");
-                            }
-                            clean::VariantKind::Struct(ref s) => {
-                                render_struct(w,
-                                              v,
-                                              None,
-                                              s.struct_type,
-                                              &s.fields,
-                                              "    ",
-                                              false);
+                                write!(w, "{}", ty.print());
                             }
+                            write!(w, ")");
                         }
-                    }
-                    _ => unreachable!()
+                        clean::VariantKind::Struct(ref s) => {
+                            render_struct(w, v, None, s.struct_type, &s.fields, "    ", false);
+                        }
+                    },
+                    _ => unreachable!(),
                 }
                 write!(w, ",\n");
             }
@@ -2906,23 +3024,30 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) {
 
     document(w, cx, it);
     if !e.variants.is_empty() {
-        write!(w, "

+ write!( + w, + "

Variants{}

\n", - document_non_exhaustive_header(it)); + document_non_exhaustive_header(it) + ); document_non_exhaustive(w, it); for variant in &e.variants { - let id = cx.derive_id(format!("{}.{}", - ItemType::Variant, - variant.name.as_ref().unwrap())); - let ns_id = cx.derive_id(format!("{}.{}", - variant.name.as_ref().unwrap(), - ItemType::Variant.name_space())); - write!(w, "
\ + let id = + cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.as_ref().unwrap())); + let ns_id = cx.derive_id(format!( + "{}.{}", + variant.name.as_ref().unwrap(), + ItemType::Variant.name_space() + )); + write!( + w, + "
\ \ {name}", - id = id, - ns_id = ns_id, - name = variant.name.as_ref().unwrap()); + id = id, + ns_id = ns_id, + name = variant.name.as_ref().unwrap() + ); if let clean::VariantItem(ref var) = variant.inner { if let clean::VariantKind::Tuple(ref tys) = var.kind { write!(w, "("); @@ -2940,35 +3065,45 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { document_non_exhaustive(w, variant); use crate::clean::{Variant, VariantKind}; - if let clean::VariantItem(Variant { - kind: VariantKind::Struct(ref s) - }) = variant.inner { - let variant_id = cx.derive_id(format!("{}.{}.fields", - ItemType::Variant, - variant.name.as_ref().unwrap())); - write!(w, "
", - id = variant_id); - write!(w, "

Fields of {name}

", - name = variant.name.as_ref().unwrap()); + if let clean::VariantItem(Variant { kind: VariantKind::Struct(ref s) }) = variant.inner + { + let variant_id = cx.derive_id(format!( + "{}.{}.fields", + ItemType::Variant, + variant.name.as_ref().unwrap() + )); + write!(w, "
", id = variant_id); + write!( + w, + "

Fields of {name}

", + name = variant.name.as_ref().unwrap() + ); for field in &s.fields { use crate::clean::StructFieldItem; if let StructFieldItem(ref ty) = field.inner { - let id = cx.derive_id(format!("variant.{}.field.{}", - variant.name.as_ref().unwrap(), - field.name.as_ref().unwrap())); - let ns_id = cx.derive_id(format!("{}.{}.{}.{}", - variant.name.as_ref().unwrap(), - ItemType::Variant.name_space(), - field.name.as_ref().unwrap(), - ItemType::StructField.name_space())); - write!(w, "\ + let id = cx.derive_id(format!( + "variant.{}.field.{}", + variant.name.as_ref().unwrap(), + field.name.as_ref().unwrap() + )); + let ns_id = cx.derive_id(format!( + "{}.{}.{}.{}", + variant.name.as_ref().unwrap(), + ItemType::Variant.name_space(), + field.name.as_ref().unwrap(), + ItemType::StructField.name_space() + )); + write!( + w, + "\ \ {f}: {t}\ ", - id = id, - ns_id = ns_id, - f = field.name.as_ref().unwrap(), - t = ty.print()); + id = id, + ns_id = ns_id, + f = field.name.as_ref().unwrap(), + t = ty.print() + ); document(w, cx, field); } } @@ -2988,15 +3123,12 @@ fn render_attribute(attr: &ast::MetaItem) -> Option { } else if let Some(v) = attr.value_str() { Some(format!("{} = {:?}", path, v)) } else if let Some(values) = attr.meta_item_list() { - let display: Vec<_> = values.iter().filter_map(|attr| { - attr.meta_item().and_then(|mi| render_attribute(mi)) - }).collect(); + let display: Vec<_> = values + .iter() + .filter_map(|attr| attr.meta_item().and_then(|mi| render_attribute(mi))) + .collect(); - if display.len() > 0 { - Some(format!("{}({})", path, display.join(", "))) - } else { - None - } + if display.len() > 0 { Some(format!("{}({})", path, display.join(", "))) } else { None } } else { None } @@ -3009,7 +3141,7 @@ const ATTRIBUTE_WHITELIST: &'static [Symbol] = &[ sym::must_use, sym::no_mangle, sym::repr, - sym::non_exhaustive + sym::non_exhaustive, ]; // The `top` parameter is used when generating the item declaration to ensure it doesn't have a @@ -3032,21 +3164,31 @@ fn render_attributes(w: &mut Buffer, it: &clean::Item, top: bool) { } } if attrs.len() > 0 { - write!(w, "{}", - if top { " top-attr" } else { "" }, &attrs); + write!( + w, + "{}", + if top { " top-attr" } else { "" }, + &attrs + ); } } -fn render_struct(w: &mut Buffer, it: &clean::Item, - g: Option<&clean::Generics>, - ty: doctree::StructType, - fields: &[clean::Item], - tab: &str, - structhead: bool) { - write!(w, "{}{}{}", - it.visibility.print_with_space(), - if structhead {"struct "} else {""}, - it.name.as_ref().unwrap()); +fn render_struct( + w: &mut Buffer, + it: &clean::Item, + g: Option<&clean::Generics>, + ty: doctree::StructType, + fields: &[clean::Item], + tab: &str, + structhead: bool, +) { + write!( + w, + "{}{}{}", + it.visibility.print_with_space(), + if structhead { "struct " } else { "" }, + it.name.as_ref().unwrap() + ); if let Some(g) = g { write!(w, "{}", g.print()) } @@ -3059,11 +3201,14 @@ fn render_struct(w: &mut Buffer, it: &clean::Item, write!(w, " {{"); for field in fields { if let clean::StructFieldItem(ref ty) = field.inner { - write!(w, "\n{} {}{}: {},", - tab, - field.visibility.print_with_space(), - field.name.as_ref().unwrap(), - ty.print()); + write!( + w, + "\n{} {}{}: {},", + tab, + field.visibility.print_with_space(), + field.name.as_ref().unwrap(), + ty.print() + ); has_visible_fields = true; } } @@ -3087,13 +3232,11 @@ fn render_struct(w: &mut Buffer, it: &clean::Item, write!(w, ", "); } match field.inner { - clean::StrippedItem(box clean::StructFieldItem(..)) => { - write!(w, "_") - } + clean::StrippedItem(box clean::StructFieldItem(..)) => write!(w, "_"), clean::StructFieldItem(ref ty) => { write!(w, "{}{}", field.visibility.print_with_space(), ty.print()) } - _ => unreachable!() + _ => unreachable!(), } } write!(w, ")"); @@ -3112,15 +3255,21 @@ fn render_struct(w: &mut Buffer, it: &clean::Item, } } -fn render_union(w: &mut Buffer, it: &clean::Item, - g: Option<&clean::Generics>, - fields: &[clean::Item], - tab: &str, - structhead: bool) { - write!(w, "{}{}{}", - it.visibility.print_with_space(), - if structhead {"union "} else {""}, - it.name.as_ref().unwrap()); +fn render_union( + w: &mut Buffer, + it: &clean::Item, + g: Option<&clean::Generics>, + fields: &[clean::Item], + tab: &str, + structhead: bool, +) { + write!( + w, + "{}{}{}", + it.visibility.print_with_space(), + if structhead { "union " } else { "" }, + it.name.as_ref().unwrap() + ); if let Some(g) = g { write!(w, "{}", g.print()); write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: true }); @@ -3129,11 +3278,14 @@ fn render_union(w: &mut Buffer, it: &clean::Item, write!(w, " {{\n{}", tab); for field in fields { if let clean::StructFieldItem(ref ty) = field.inner { - write!(w, " {}{}: {},\n{}", - field.visibility.print_with_space(), - field.name.as_ref().unwrap(), - ty.print(), - tab); + write!( + w, + " {}{}: {},\n{}", + field.visibility.print_with_space(), + field.name.as_ref().unwrap(), + ty.print(), + tab + ); } } @@ -3152,7 +3304,7 @@ enum AssocItemLink<'a> { impl<'a> AssocItemLink<'a> { fn anchor(&self, id: &'a String) -> Self { match *self { - AssocItemLink::Anchor(_) => { AssocItemLink::Anchor(Some(&id)) }, + AssocItemLink::Anchor(_) => AssocItemLink::Anchor(Some(&id)), ref other => *other, } } @@ -3160,7 +3312,7 @@ impl<'a> AssocItemLink<'a> { enum AssocItemRender<'a> { All, - DerefFor { trait_: &'a clean::Type, type_: &'a clean::Type, deref_mut_: bool } + DerefFor { trait_: &'a clean::Type, type_: &'a clean::Type, deref_mut_: bool }, } #[derive(Copy, Clone, PartialEq)] @@ -3169,113 +3321,148 @@ enum RenderMode { ForDeref { mut_: bool }, } -fn render_assoc_items(w: &mut Buffer, - cx: &Context, - containing_item: &clean::Item, - it: DefId, - what: AssocItemRender<'_>) { +fn render_assoc_items( + w: &mut Buffer, + cx: &Context, + containing_item: &clean::Item, + it: DefId, + what: AssocItemRender<'_>, +) { let c = &cx.cache; let v = match c.impls.get(&it) { Some(v) => v, None => return, }; - let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| { - i.inner_impl().trait_.is_none() - }); + let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none()); if !non_trait.is_empty() { let render_mode = match what { AssocItemRender::All => { - write!(w, "\ + write!( + w, + "\

\ Methods\

\ - "); + " + ); RenderMode::Normal } AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => { - write!(w, "\ + write!( + w, + "\

\ Methods from {}<Target = {}>\ \

\ - ", trait_.print(), type_.print()); + ", + trait_.print(), + type_.print() + ); RenderMode::ForDeref { mut_: deref_mut_ } } }; for i in &non_trait { - render_impl(w, cx, i, AssocItemLink::Anchor(None), render_mode, - containing_item.stable_since(), true, None, false, true); + render_impl( + w, + cx, + i, + AssocItemLink::Anchor(None), + render_mode, + containing_item.stable_since(), + true, + None, + false, + true, + ); } } if let AssocItemRender::DerefFor { .. } = what { return; } if !traits.is_empty() { - let deref_impl = traits.iter().find(|t| { - t.inner_impl().trait_.def_id() == c.deref_trait_did - }); + let deref_impl = + traits.iter().find(|t| t.inner_impl().trait_.def_id() == c.deref_trait_did); if let Some(impl_) = deref_impl { - let has_deref_mut = traits.iter().find(|t| { - t.inner_impl().trait_.def_id() == c.deref_mut_trait_did - }).is_some(); + let has_deref_mut = traits + .iter() + .find(|t| t.inner_impl().trait_.def_id() == c.deref_mut_trait_did) + .is_some(); render_deref_methods(w, cx, impl_, containing_item, has_deref_mut); } - let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = traits - .iter() - .partition(|t| t.inner_impl().synthetic); - let (blanket_impl, concrete): (Vec<&&Impl>, _) = concrete - .into_iter() - .partition(|t| t.inner_impl().blanket_impl.is_some()); + let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = + traits.iter().partition(|t| t.inner_impl().synthetic); + let (blanket_impl, concrete): (Vec<&&Impl>, _) = + concrete.into_iter().partition(|t| t.inner_impl().blanket_impl.is_some()); let mut impls = Buffer::empty_from(&w); render_impls(cx, &mut impls, &concrete, containing_item); let impls = impls.into_inner(); if !impls.is_empty() { - write!(w, "\ + write!( + w, + "\

\ Trait Implementations\

\ -
{}
", impls); +
{}
", + impls + ); } if !synthetic.is_empty() { - write!(w, "\ + write!( + w, + "\

\ Auto Trait Implementations\ \

\
\ - "); + " + ); render_impls(cx, w, &synthetic, containing_item); write!(w, "
"); } if !blanket_impl.is_empty() { - write!(w, "\ + write!( + w, + "\

\ Blanket Implementations\ \

\
\ - "); + " + ); render_impls(cx, w, &blanket_impl, containing_item); write!(w, "
"); } } } -fn render_deref_methods(w: &mut Buffer, cx: &Context, impl_: &Impl, - container_item: &clean::Item, deref_mut: bool) { +fn render_deref_methods( + w: &mut Buffer, + cx: &Context, + impl_: &Impl, + container_item: &clean::Item, + deref_mut: bool, +) { let deref_type = impl_.inner_impl().trait_.as_ref().unwrap(); - let target = impl_.inner_impl().items.iter().filter_map(|item| { - match item.inner { + let target = impl_ + .inner_impl() + .items + .iter() + .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(&t.type_), _ => None, - } - }).next().expect("Expected associated type binding"); - let what = AssocItemRender::DerefFor { trait_: deref_type, type_: target, - deref_mut_: deref_mut }; + }) + .next() + .expect("Expected associated type binding"); + let what = + AssocItemRender::DerefFor { trait_: deref_type, type_: target, deref_mut_: deref_mut }; if let Some(did) = target.def_id() { render_assoc_items(w, cx, container_item, did, what) } else { @@ -3291,18 +3478,18 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool) -> bool { let self_type_opt = match item.inner { clean::MethodItem(ref method) => method.decl.self_type(), clean::TyMethodItem(ref method) => method.decl.self_type(), - _ => None + _ => None, }; if let Some(self_ty) = self_type_opt { let (by_mut_ref, by_box, by_value) = match self_ty { - SelfTy::SelfBorrowed(_, mutability) | - SelfTy::SelfExplicit(clean::BorrowedRef { mutability, .. }) => { + SelfTy::SelfBorrowed(_, mutability) + | SelfTy::SelfExplicit(clean::BorrowedRef { mutability, .. }) => { (mutability == Mutability::Mut, false, false) - }, + } SelfTy::SelfExplicit(clean::ResolvedPath { did, .. }) => { (false, Some(did) == cache().owned_box_did, false) - }, + } SelfTy::SelfValue => (false, false, true), _ => (false, false, false), }; @@ -3315,13 +3502,11 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool) -> bool { fn render_spotlight_traits(item: &clean::Item) -> String { match item.inner { - clean::FunctionItem(clean::Function { ref decl, .. }) | - clean::TyMethodItem(clean::TyMethod { ref decl, .. }) | - clean::MethodItem(clean::Method { ref decl, .. }) | - clean::ForeignFunctionItem(clean::Function { ref decl, .. }) => { - spotlight_decl(decl) - } - _ => String::new() + clean::FunctionItem(clean::Function { ref decl, .. }) + | clean::TyMethodItem(clean::TyMethod { ref decl, .. }) + | clean::MethodItem(clean::Method { ref decl, .. }) + | clean::ForeignFunctionItem(clean::Function { ref decl, .. }) => spotlight_decl(decl), + _ => String::new(), } } @@ -3336,24 +3521,31 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String { let impl_ = i.inner_impl(); if impl_.trait_.def_id().map_or(false, |d| c.traits[&d].is_spotlight) { if out.is_empty() { - out.push_str( - &format!("

Important traits for {}

\ + out.push_str(&format!( + "

Important traits for {}

\ ", - impl_.for_.print())); + impl_.for_.print() + )); trait_.push_str(&impl_.for_.print().to_string()); } //use the "where" class here to make it small - out.push_str( - &format!("{}", impl_.print())); + out.push_str(&format!( + "{}", + impl_.print() + )); let t_did = impl_.trait_.def_id().unwrap(); for it in &impl_.items { if let clean::TypedefItem(ref tydef, _) = it.inner { out.push_str(" "); - assoc_type(&mut out, it, &[], - Some(&tydef.type_), - AssocItemLink::GotoSource(t_did, &FxHashSet::default()), - ""); + assoc_type( + &mut out, + it, + &[], + Some(&tydef.type_), + AssocItemLink::GotoSource(t_did, &FxHashSet::default()), + "", + ); out.push_str(";"); } } @@ -3363,27 +3555,42 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String { } if !out.is_empty() { - out.insert_str(0, &format!("
ⓘ\ + out.insert_str( + 0, + &format!( + "
ⓘ\ Important traits for {}
\
", - trait_)); + trait_ + ), + ); out.push_str("
"); } out.into_inner() } -fn render_impl(w: &mut Buffer, cx: &Context, i: &Impl, link: AssocItemLink<'_>, - render_mode: RenderMode, outer_version: Option<&str>, show_def_docs: bool, - use_absolute: Option, is_on_foreign_type: bool, - show_default_items: bool) { +fn render_impl( + w: &mut Buffer, + cx: &Context, + i: &Impl, + link: AssocItemLink<'_>, + render_mode: RenderMode, + outer_version: Option<&str>, + show_def_docs: bool, + use_absolute: Option, + is_on_foreign_type: bool, + show_default_items: bool, +) { if render_mode == RenderMode::Normal { let id = cx.derive_id(match i.inner_impl().trait_ { - Some(ref t) => if is_on_foreign_type { - get_id_for_impl_on_foreign_type(&i.inner_impl().for_, t) - } else { - format!("impl-{}", small_url_encode(&format!("{:#}", t.print()))) - }, + Some(ref t) => { + if is_on_foreign_type { + get_id_for_impl_on_foreign_type(&i.inner_impl().for_, t) + } else { + format!("impl-{}", small_url_encode(&format!("{:#}", t.print()))) + } + } None => "impl".to_string(), }); if let Some(use_absolute) = use_absolute { @@ -3393,39 +3600,63 @@ fn render_impl(w: &mut Buffer, cx: &Context, i: &Impl, link: AssocItemLink<'_>, for it in &i.inner_impl().items { if let clean::TypedefItem(ref tydef, _) = it.inner { write!(w, " "); - assoc_type(w, it, &vec![], Some(&tydef.type_), - AssocItemLink::Anchor(None), - ""); + assoc_type( + w, + it, + &vec![], + Some(&tydef.type_), + AssocItemLink::Anchor(None), + "", + ); write!(w, ";"); } } } write!(w, "
"); } else { - write!(w, "

{}", - id, i.inner_impl().print() + write!( + w, + "

{}", + id, + i.inner_impl().print() ); } write!(w, "", id); let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]); render_stability_since_raw(w, since, outer_version); if let Some(l) = cx.src_href(&i.impl_item) { - write!(w, "[src]", - l, "goto source code"); + write!(w, "[src]", l, "goto source code"); } write!(w, "

"); if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) { let mut ids = cx.id_map.borrow_mut(); - write!(w, "
{}
", - Markdown(&*dox, &i.impl_item.links(), &mut ids, - cx.shared.codes, cx.shared.edition, &cx.shared.playground).to_string()); + write!( + w, + "
{}
", + Markdown( + &*dox, + &i.impl_item.links(), + &mut ids, + cx.shared.codes, + cx.shared.edition, + &cx.shared.playground + ) + .to_string() + ); } } - fn doc_impl_item(w: &mut Buffer, cx: &Context, item: &clean::Item, - link: AssocItemLink<'_>, render_mode: RenderMode, - is_default_item: bool, outer_version: Option<&str>, - trait_: Option<&clean::Trait>, show_def_docs: bool) { + fn doc_impl_item( + w: &mut Buffer, + cx: &Context, + item: &clean::Item, + link: AssocItemLink<'_>, + render_mode: RenderMode, + is_default_item: bool, + outer_version: Option<&str>, + trait_: Option<&clean::Trait>, + show_def_docs: bool, + ) { let item_type = item.type_(); let name = item.name.as_ref().unwrap(); @@ -3434,32 +3665,33 @@ fn render_impl(w: &mut Buffer, cx: &Context, i: &Impl, link: AssocItemLink<'_>, RenderMode::ForDeref { mut_: deref_mut_ } => should_render_item(&item, deref_mut_), }; - let (is_hidden, extra_class) = if (trait_.is_none() || - item.doc_value().is_some() || - item.inner.is_associated()) && - !is_default_item { - (false, "") - } else { - (true, " hidden") - }; + let (is_hidden, extra_class) = + if (trait_.is_none() || item.doc_value().is_some() || item.inner.is_associated()) + && !is_default_item + { + (false, "") + } else { + (true, " hidden") + }; match item.inner { - clean::MethodItem(clean::Method { ref decl, .. }) | - clean::TyMethodItem(clean::TyMethod { ref decl, .. }) => { + clean::MethodItem(clean::Method { ref decl, .. }) + | clean::TyMethodItem(clean::TyMethod { ref decl, .. }) => { // Only render when the method is not static or we allow static methods if render_method_item { let id = cx.derive_id(format!("{}.{}", item_type, name)); - let ns_id = cx.derive_id(format!("{}.{}", - name, item_type.name_space())); - write!(w, "

", - id, item_type, extra_class); + let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space())); + write!(w, "

", id, item_type, extra_class); write!(w, "{}", spotlight_decl(decl)); write!(w, "", ns_id); render_assoc_item(w, item, link.anchor(&id), ItemType::Impl); write!(w, ""); render_stability_since_raw(w, item.stable_since(), outer_version); if let Some(l) = cx.src_href(item) { - write!(w, "[src]", - l, "goto source code"); + write!( + w, + "[src]", + l, "goto source code" + ); } write!(w, "

"); } @@ -3481,8 +3713,11 @@ fn render_impl(w: &mut Buffer, cx: &Context, i: &Impl, link: AssocItemLink<'_>, write!(w, ""); render_stability_since_raw(w, item.stable_since(), outer_version); if let Some(l) = cx.src_href(item) { - write!(w, "[src]", - l, "goto source code"); + write!( + w, + "[src]", + l, "goto source code" + ); } write!(w, "

"); } @@ -3495,7 +3730,7 @@ fn render_impl(w: &mut Buffer, cx: &Context, i: &Impl, link: AssocItemLink<'_>, write!(w, "

"); } clean::StrippedItem(..) => return, - _ => panic!("can't make docs for trait item with name {:?}", item.name) + _ => panic!("can't make docs for trait item with name {:?}", item.name), } if render_method_item { @@ -3535,17 +3770,28 @@ fn render_impl(w: &mut Buffer, cx: &Context, i: &Impl, link: AssocItemLink<'_>, write!(w, "
"); for trait_item in &i.inner_impl().items { - doc_impl_item(w, cx, trait_item, link, render_mode, - false, outer_version, trait_, show_def_docs); + doc_impl_item( + w, + cx, + trait_item, + link, + render_mode, + false, + outer_version, + trait_, + show_def_docs, + ); } - fn render_default_items(w: &mut Buffer, - cx: &Context, - t: &clean::Trait, - i: &clean::Impl, - render_mode: RenderMode, - outer_version: Option<&str>, - show_def_docs: bool) { + fn render_default_items( + w: &mut Buffer, + cx: &Context, + t: &clean::Trait, + i: &clean::Impl, + render_mode: RenderMode, + outer_version: Option<&str>, + show_def_docs: bool, + ) { for trait_item in &t.items { let n = trait_item.name.clone(); if i.items.iter().find(|m| m.name == n).is_some() { @@ -3554,8 +3800,17 @@ fn render_impl(w: &mut Buffer, cx: &Context, i: &Impl, link: AssocItemLink<'_>, let did = i.trait_.as_ref().unwrap().def_id().unwrap(); let assoc_link = AssocItemLink::GotoSource(did, &i.provided_trait_methods); - doc_impl_item(w, cx, trait_item, assoc_link, render_mode, true, - outer_version, None, show_def_docs); + doc_impl_item( + w, + cx, + trait_item, + assoc_link, + render_mode, + true, + outer_version, + None, + show_def_docs, + ); } } @@ -3565,26 +3820,31 @@ fn render_impl(w: &mut Buffer, cx: &Context, i: &Impl, link: AssocItemLink<'_>, // Implementations on Foreign Types or Implementors sections. if show_default_items { if let Some(t) = trait_ { - render_default_items(w, cx, t, &i.inner_impl(), - render_mode, outer_version, show_def_docs); + render_default_items( + w, + cx, + t, + &i.inner_impl(), + render_mode, + outer_version, + show_def_docs, + ); } } write!(w, "
"); } -fn item_opaque_ty( - w: &mut Buffer, - cx: &Context, - it: &clean::Item, - t: &clean::OpaqueTy, -) { +fn item_opaque_ty(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::OpaqueTy) { write!(w, "
");
     render_attributes(w, it, false);
-    write!(w, "type {}{}{where_clause} = impl {bounds};
", - it.name.as_ref().unwrap(), - t.generics.print(), - where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true }, - bounds = bounds(&t.bounds, false)); + write!( + w, + "type {}{}{where_clause} = impl {bounds};
", + it.name.as_ref().unwrap(), + t.generics.print(), + where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true }, + bounds = bounds(&t.bounds, false) + ); document(w, cx, it); @@ -3595,15 +3855,17 @@ fn item_opaque_ty( render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } -fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, - t: &clean::TraitAlias) { +fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::TraitAlias) { write!(w, "
");
     render_attributes(w, it, false);
-    write!(w, "trait {}{}{} = {};
", - it.name.as_ref().unwrap(), - t.generics.print(), - WhereClause { gens: &t.generics, indent: 0, end_newline: true }, - bounds(&t.bounds, true)); + write!( + w, + "trait {}{}{} = {};", + it.name.as_ref().unwrap(), + t.generics.print(), + WhereClause { gens: &t.generics, indent: 0, end_newline: true }, + bounds(&t.bounds, true) + ); document(w, cx, it); @@ -3617,11 +3879,14 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typedef) { write!(w, "
");
     render_attributes(w, it, false);
-    write!(w, "type {}{}{where_clause} = {type_};
", - it.name.as_ref().unwrap(), - t.generics.print(), - where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true }, - type_ = t.type_.print()); + write!( + w, + "type {}{}{where_clause} = {type_};", + it.name.as_ref().unwrap(), + t.generics.print(), + where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true }, + type_ = t.type_.print() + ); document(w, cx, it); @@ -3648,11 +3913,19 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { } fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) { - let parentlen = cx.current.len() - if it.is_mod() {1} else {0}; - - if it.is_struct() || it.is_trait() || it.is_primitive() || it.is_union() - || it.is_enum() || it.is_mod() || it.is_typedef() { - write!(buffer, "

{}{}

", + let parentlen = cx.current.len() - if it.is_mod() { 1 } else { 0 }; + + if it.is_struct() + || it.is_trait() + || it.is_primitive() + || it.is_union() + || it.is_enum() + || it.is_mod() + || it.is_typedef() + { + write!( + buffer, + "

{}{}

", match it.inner { clean::StructItem(..) => "Struct ", clean::TraitItem(..) => "Trait ", @@ -3661,30 +3934,37 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) { clean::EnumItem(..) => "Enum ", clean::TypedefItem(..) => "Type Definition ", clean::ForeignTypeItem => "Foreign Type ", - clean::ModuleItem(..) => if it.is_crate() { - "Crate " - } else { - "Module " - }, + clean::ModuleItem(..) => + if it.is_crate() { + "Crate " + } else { + "Module " + }, _ => "", }, - it.name.as_ref().unwrap()); + it.name.as_ref().unwrap() + ); } if it.is_crate() { if let Some(ref version) = cx.cache.crate_version { - write!(buffer, - "
\ + write!( + buffer, + "
\

Version {}

\
", - version); + version + ); } } write!(buffer, "
"); if it.is_crate() { - write!(buffer, "

See all {}'s items

", - it.name.as_ref().expect("crates always have a name")); + write!( + buffer, + "

See all {}'s items

", + it.name.as_ref().expect("crates always have a name") + ); } match it.inner { clean::StructItem(ref s) => sidebar_struct(buffer, it, s), @@ -3711,29 +3991,33 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) { if i > 0 { write!(buffer, "::"); } - write!(buffer, "{}", - &cx.root_path()[..(cx.current.len() - i - 1) * 3], - *name); + write!( + buffer, + "{}", + &cx.root_path()[..(cx.current.len() - i - 1) * 3], + *name + ); } write!(buffer, "

"); // Sidebar refers to the enclosing module, not this module. let relpath = if it.is_mod() { "../" } else { "" }; - write!(buffer, - "", - name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""), - ty = it.type_(), - path = relpath); + name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""), + ty = it.type_(), + path = relpath + ); if parentlen == 0 { // There is no sidebar-items.js beyond the crate root path // FIXME maybe dynamic crate loading can be merged here } else { - write!(buffer, "", - path = relpath); + write!(buffer, "", path = relpath); } // Closes sidebar-elems div. write!(buffer, "
"); @@ -3756,36 +4040,39 @@ fn get_methods( used_links: &mut FxHashSet, deref_mut: bool, ) -> Vec { - i.items.iter().filter_map(|item| { - match item.name { + i.items + .iter() + .filter_map(|item| match item.name { Some(ref name) if !name.is_empty() && item.is_method() => { if !for_deref || should_render_item(item, deref_mut) { - Some(format!("{}", - get_next_url(used_links, format!("method.{}", name)), - name)) + Some(format!( + "{}", + get_next_url(used_links, format!("method.{}", name)), + name + )) } else { None } } _ => None, - } - }).collect::>() + }) + .collect::>() } // The point is to url encode any potential character from a type with genericity. fn small_url_encode(s: &str) -> String { s.replace("<", "%3C") - .replace(">", "%3E") - .replace(" ", "%20") - .replace("?", "%3F") - .replace("'", "%27") - .replace("&", "%26") - .replace(",", "%2C") - .replace(":", "%3A") - .replace(";", "%3B") - .replace("[", "%5B") - .replace("]", "%5D") - .replace("\"", "%22") + .replace(">", "%3E") + .replace(" ", "%20") + .replace("?", "%3F") + .replace("'", "%27") + .replace("&", "%26") + .replace(",", "%2C") + .replace(":", "%3A") + .replace(";", "%3B") + .replace("[", "%5B") + .replace("]", "%5D") + .replace("\"", "%22") } fn sidebar_assoc_items(it: &clean::Item) -> String { @@ -3796,53 +4083,67 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { { let used_links_bor = &mut used_links; - let mut ret = v.iter() - .filter(|i| i.inner_impl().trait_.is_none()) - .flat_map(move |i| get_methods(i.inner_impl(), - false, - used_links_bor, false)) - .collect::>(); + let mut ret = v + .iter() + .filter(|i| i.inner_impl().trait_.is_none()) + .flat_map(move |i| get_methods(i.inner_impl(), false, used_links_bor, false)) + .collect::>(); // We want links' order to be reproducible so we don't use unstable sort. ret.sort(); if !ret.is_empty() { - out.push_str(&format!("Methods\ -
{}
", ret.join(""))); + out.push_str(&format!( + "Methods\ +
{}
", + ret.join("") + )); } } if v.iter().any(|i| i.inner_impl().trait_.is_some()) { - if let Some(impl_) = v.iter() - .filter(|i| i.inner_impl().trait_.is_some()) - .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) { - if let Some(target) = impl_.inner_impl().items.iter().filter_map(|item| { - match item.inner { + if let Some(impl_) = v + .iter() + .filter(|i| i.inner_impl().trait_.is_some()) + .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) + { + if let Some(target) = impl_ + .inner_impl() + .items + .iter() + .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(&t.type_), _ => None, - } - }).next() { - let inner_impl = target.def_id().or(target.primitive_type().and_then(|prim| { - c.primitive_locations.get(&prim).cloned() - })).and_then(|did| c.impls.get(&did)); + }) + .next() + { + let inner_impl = target + .def_id() + .or(target + .primitive_type() + .and_then(|prim| c.primitive_locations.get(&prim).cloned())) + .and_then(|did| c.impls.get(&did)); if let Some(impls) = inner_impl { out.push_str(""); - out.push_str(&format!("Methods from {}<Target={}>", + out.push_str(&format!( + "Methods from {}<Target={}>", Escape(&format!( - "{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print() + "{:#}", + impl_.inner_impl().trait_.as_ref().unwrap().print() )), - Escape(&format!("{:#}", target.print())))); + Escape(&format!("{:#}", target.print())) + )); out.push_str(""); - let mut ret = impls.iter() - .filter(|i| i.inner_impl().trait_.is_none()) - .flat_map(|i| get_methods(i.inner_impl(), - true, - &mut used_links, - true)) - .collect::>(); + let mut ret = impls + .iter() + .filter(|i| i.inner_impl().trait_.is_none()) + .flat_map(|i| get_methods(i.inner_impl(), true, &mut used_links, true)) + .collect::>(); // We want links' order to be reproducible so we don't use unstable sort. ret.sort(); if !ret.is_empty() { - out.push_str(&format!("
{}
", - ret.join(""))); + out.push_str(&format!( + "
{}
", + ret.join("") + )); } } } @@ -3850,22 +4151,21 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { let format_impls = |impls: Vec<&Impl>| { let mut links = FxHashSet::default(); - let mut ret = impls.iter() + let mut ret = impls + .iter() .filter_map(|i| { let is_negative_impl = is_negative_impl(i.inner_impl()); if let Some(ref i) = i.inner_impl().trait_ { let i_display = format!("{:#}", i.print()); let out = Escape(&i_display); let encoded = small_url_encode(&format!("{:#}", i.print())); - let generated = format!("{}{}", - encoded, - if is_negative_impl { "!" } else { "" }, - out); - if links.insert(generated.clone()) { - Some(generated) - } else { - None - } + let generated = format!( + "{}{}", + encoded, + if is_negative_impl { "!" } else { "" }, + out + ); + if links.insert(generated.clone()) { Some(generated) } else { None } } else { None } @@ -3875,9 +4175,8 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { ret.join("") }; - let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = v - .iter() - .partition::, _>(|i| i.inner_impl().synthetic); + let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = + v.iter().partition::, _>(|i| i.inner_impl().synthetic); let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) = concrete .into_iter() .partition::, _>(|i| i.inner_impl().blanket_impl.is_some()); @@ -3887,20 +4186,26 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { let blanket_format = format_impls(blanket_impl); if !concrete_format.is_empty() { - out.push_str("\ - Trait Implementations"); + out.push_str( + "\ + Trait Implementations", + ); out.push_str(&format!("
{}
", concrete_format)); } if !synthetic_format.is_empty() { - out.push_str("\ - Auto Trait Implementations"); + out.push_str( + "\ + Auto Trait Implementations", + ); out.push_str(&format!("
{}
", synthetic_format)); } if !blanket_format.is_empty() { - out.push_str("\ - Blanket Implementations"); + out.push_str( + "\ + Blanket Implementations", + ); out.push_str(&format!("
{}
", blanket_format)); } } @@ -3915,8 +4220,11 @@ fn sidebar_struct(buf: &mut Buffer, it: &clean::Item, s: &clean::Struct) { if !fields.is_empty() { if let doctree::Plain = s.struct_type { - sidebar.push_str(&format!("Fields\ -
{}
", fields)); + sidebar.push_str(&format!( + "Fields\ +
{}
", + fields + )); } } @@ -3942,7 +4250,7 @@ fn extract_for_impl_name(item: &clean::Item) -> Option<(String, String)> { } else { None } - }, + } _ => None, } } @@ -3954,107 +4262,108 @@ fn is_negative_impl(i: &clean::Impl) -> bool { fn sidebar_trait(buf: &mut Buffer, it: &clean::Item, t: &clean::Trait) { let mut sidebar = String::new(); - let types = t.items - .iter() - .filter_map(|m| { - match m.name { - Some(ref name) if m.is_associated_type() => { - Some(format!("{name}", - name=name)) - } - _ => None, - } - }) - .collect::(); - let consts = t.items - .iter() - .filter_map(|m| { - match m.name { - Some(ref name) if m.is_associated_const() => { - Some(format!("{name}", - name=name)) - } - _ => None, - } - }) - .collect::(); - let mut required = t.items - .iter() - .filter_map(|m| { - match m.name { - Some(ref name) if m.is_ty_method() => { - Some(format!("{name}", - name=name)) - } - _ => None, - } - }) - .collect::>(); - let mut provided = t.items - .iter() - .filter_map(|m| { - match m.name { - Some(ref name) if m.is_method() => { - Some(format!("{0}", name)) - } - _ => None, - } - }) - .collect::>(); + let types = t + .items + .iter() + .filter_map(|m| match m.name { + Some(ref name) if m.is_associated_type() => { + Some(format!("{name}", name = name)) + } + _ => None, + }) + .collect::(); + let consts = t + .items + .iter() + .filter_map(|m| match m.name { + Some(ref name) if m.is_associated_const() => { + Some(format!("{name}", name = name)) + } + _ => None, + }) + .collect::(); + let mut required = t + .items + .iter() + .filter_map(|m| match m.name { + Some(ref name) if m.is_ty_method() => { + Some(format!("{name}", name = name)) + } + _ => None, + }) + .collect::>(); + let mut provided = t + .items + .iter() + .filter_map(|m| match m.name { + Some(ref name) if m.is_method() => { + Some(format!("{0}", name)) + } + _ => None, + }) + .collect::>(); if !types.is_empty() { - sidebar.push_str(&format!("\ + sidebar.push_str(&format!( + "\ Associated Types
{}
", - types)); + types + )); } if !consts.is_empty() { - sidebar.push_str(&format!("\ + sidebar.push_str(&format!( + "\ Associated Constants
{}
", - consts)); + consts + )); } if !required.is_empty() { required.sort(); - sidebar.push_str(&format!("\ + sidebar.push_str(&format!( + "\ Required Methods
{}
", - required.join(""))); + required.join("") + )); } if !provided.is_empty() { provided.sort(); - sidebar.push_str(&format!("\ + sidebar.push_str(&format!( + "\ Provided Methods
{}
", - provided.join(""))); + provided.join("") + )); } let c = cache(); if let Some(implementors) = c.implementors.get(&it.def_id) { - let mut res = implementors.iter() - .filter(|i| i.inner_impl().for_.def_id() - .map_or(false, |d| !c.paths.contains_key(&d))) - .filter_map(|i| { - match extract_for_impl_name(&i.impl_item) { - Some((ref name, ref id)) => { - Some(format!("{}", - id, - Escape(name))) - } - _ => None, - } - }) - .collect::>(); + let mut res = implementors + .iter() + .filter(|i| i.inner_impl().for_.def_id().map_or(false, |d| !c.paths.contains_key(&d))) + .filter_map(|i| match extract_for_impl_name(&i.impl_item) { + Some((ref name, ref id)) => { + Some(format!("{}", id, Escape(name))) + } + _ => None, + }) + .collect::>(); if !res.is_empty() { res.sort(); - sidebar.push_str(&format!("\ + sidebar.push_str(&format!( + "\ Implementations on Foreign Types
{}
", - res.join(""))); + res.join("") + )); } } sidebar.push_str("Implementors"); if t.auto { - sidebar.push_str("Auto Implementors"); + sidebar.push_str( + "Auto Implementors", + ); } sidebar.push_str(&sidebar_assoc_items(it)); @@ -4079,18 +4388,18 @@ fn sidebar_typedef(buf: &mut Buffer, it: &clean::Item) { } fn get_struct_fields_name(fields: &[clean::Item]) -> String { - fields.iter() - .filter(|f| if let clean::StructFieldItem(..) = f.inner { - true - } else { - false - }) - .filter_map(|f| match f.name { - Some(ref name) => Some(format!("\ - {name}", name=name)), - _ => None, - }) - .collect() + fields + .iter() + .filter(|f| if let clean::StructFieldItem(..) = f.inner { true } else { false }) + .filter_map(|f| match f.name { + Some(ref name) => Some(format!( + "\ + {name}", + name = name + )), + _ => None, + }) + .collect() } fn sidebar_union(buf: &mut Buffer, it: &clean::Item, u: &clean::Union) { @@ -4098,8 +4407,11 @@ fn sidebar_union(buf: &mut Buffer, it: &clean::Item, u: &clean::Union) { let fields = get_struct_fields_name(&u.fields); if !fields.is_empty() { - sidebar.push_str(&format!("Fields\ -
{}
", fields)); + sidebar.push_str(&format!( + "Fields\ +
{}
", + fields + )); } sidebar.push_str(&sidebar_assoc_items(it)); @@ -4112,16 +4424,24 @@ fn sidebar_union(buf: &mut Buffer, it: &clean::Item, u: &clean::Union) { fn sidebar_enum(buf: &mut Buffer, it: &clean::Item, e: &clean::Enum) { let mut sidebar = String::new(); - let variants = e.variants.iter() - .filter_map(|v| match v.name { - Some(ref name) => Some(format!("{name}\ - ", name = name)), - _ => None, - }) - .collect::(); + let variants = e + .variants + .iter() + .filter_map(|v| match v.name { + Some(ref name) => Some(format!( + "{name}\ + ", + name = name + )), + _ => None, + }) + .collect::(); if !variants.is_empty() { - sidebar.push_str(&format!("Variants\ -
{}
", variants)); + sidebar.push_str(&format!( + "Variants\ +
{}
", + variants + )); } sidebar.push_str(&sidebar_assoc_items(it)); @@ -4133,58 +4453,77 @@ fn sidebar_enum(buf: &mut Buffer, it: &clean::Item, e: &clean::Enum) { fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) { match *ty { - ItemType::ExternCrate | - ItemType::Import => ("reexports", "Re-exports"), - ItemType::Module => ("modules", "Modules"), - ItemType::Struct => ("structs", "Structs"), - ItemType::Union => ("unions", "Unions"), - ItemType::Enum => ("enums", "Enums"), - ItemType::Function => ("functions", "Functions"), - ItemType::Typedef => ("types", "Type Definitions"), - ItemType::Static => ("statics", "Statics"), - ItemType::Constant => ("constants", "Constants"), - ItemType::Trait => ("traits", "Traits"), - ItemType::Impl => ("impls", "Implementations"), - ItemType::TyMethod => ("tymethods", "Type Methods"), - ItemType::Method => ("methods", "Methods"), - ItemType::StructField => ("fields", "Struct Fields"), - ItemType::Variant => ("variants", "Variants"), - ItemType::Macro => ("macros", "Macros"), - ItemType::Primitive => ("primitives", "Primitive Types"), - ItemType::AssocType => ("associated-types", "Associated Types"), - ItemType::AssocConst => ("associated-consts", "Associated Constants"), - ItemType::ForeignType => ("foreign-types", "Foreign Types"), - ItemType::Keyword => ("keywords", "Keywords"), - ItemType::OpaqueTy => ("opaque-types", "Opaque Types"), - ItemType::ProcAttribute => ("attributes", "Attribute Macros"), - ItemType::ProcDerive => ("derives", "Derive Macros"), - ItemType::TraitAlias => ("trait-aliases", "Trait aliases"), + ItemType::ExternCrate | ItemType::Import => ("reexports", "Re-exports"), + ItemType::Module => ("modules", "Modules"), + ItemType::Struct => ("structs", "Structs"), + ItemType::Union => ("unions", "Unions"), + ItemType::Enum => ("enums", "Enums"), + ItemType::Function => ("functions", "Functions"), + ItemType::Typedef => ("types", "Type Definitions"), + ItemType::Static => ("statics", "Statics"), + ItemType::Constant => ("constants", "Constants"), + ItemType::Trait => ("traits", "Traits"), + ItemType::Impl => ("impls", "Implementations"), + ItemType::TyMethod => ("tymethods", "Type Methods"), + ItemType::Method => ("methods", "Methods"), + ItemType::StructField => ("fields", "Struct Fields"), + ItemType::Variant => ("variants", "Variants"), + ItemType::Macro => ("macros", "Macros"), + ItemType::Primitive => ("primitives", "Primitive Types"), + ItemType::AssocType => ("associated-types", "Associated Types"), + ItemType::AssocConst => ("associated-consts", "Associated Constants"), + ItemType::ForeignType => ("foreign-types", "Foreign Types"), + ItemType::Keyword => ("keywords", "Keywords"), + ItemType::OpaqueTy => ("opaque-types", "Opaque Types"), + ItemType::ProcAttribute => ("attributes", "Attribute Macros"), + ItemType::ProcDerive => ("derives", "Derive Macros"), + ItemType::TraitAlias => ("trait-aliases", "Trait aliases"), } } fn sidebar_module(buf: &mut Buffer, items: &[clean::Item]) { let mut sidebar = String::new(); - if items.iter().any(|it| it.type_() == ItemType::ExternCrate || - it.type_() == ItemType::Import) { - sidebar.push_str(&format!("
  • {name}
  • ", - id = "reexports", - name = "Re-exports")); + if items.iter().any(|it| it.type_() == ItemType::ExternCrate || it.type_() == ItemType::Import) + { + sidebar.push_str(&format!( + "
  • {name}
  • ", + id = "reexports", + name = "Re-exports" + )); } // ordering taken from item_module, reorder, where it prioritized elements in a certain order // to print its headings - for &myty in &[ItemType::Primitive, ItemType::Module, ItemType::Macro, ItemType::Struct, - ItemType::Enum, ItemType::Constant, ItemType::Static, ItemType::Trait, - ItemType::Function, ItemType::Typedef, ItemType::Union, ItemType::Impl, - ItemType::TyMethod, ItemType::Method, ItemType::StructField, ItemType::Variant, - ItemType::AssocType, ItemType::AssocConst, ItemType::ForeignType, - ItemType::Keyword] { + for &myty in &[ + ItemType::Primitive, + ItemType::Module, + ItemType::Macro, + ItemType::Struct, + ItemType::Enum, + ItemType::Constant, + ItemType::Static, + ItemType::Trait, + ItemType::Function, + ItemType::Typedef, + ItemType::Union, + ItemType::Impl, + ItemType::TyMethod, + ItemType::Method, + ItemType::StructField, + ItemType::Variant, + ItemType::AssocType, + ItemType::AssocConst, + ItemType::ForeignType, + ItemType::Keyword, + ] { if items.iter().any(|it| !it.is_stripped() && it.type_() == myty) { let (short, name) = item_ty_to_strs(&myty); - sidebar.push_str(&format!("
  • {name}
  • ", - id = short, - name = name)); + sidebar.push_str(&format!( + "
  • {name}
  • ", + id = short, + name = name + )); } } @@ -4202,10 +4541,7 @@ fn sidebar_foreign_type(buf: &mut Buffer, it: &clean::Item) { fn item_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Macro) { wrap_into_docblock(w, |w| { - w.write_str(&highlight::render_with_highlighting(&t.source, - Some("macro"), - None, - None)) + w.write_str(&highlight::render_with_highlighting(&t.source, Some("macro"), None, None)) }); document(w, cx, it) } @@ -4282,33 +4618,32 @@ fn collect_paths_for_type(first_ty: clean::Type) -> Vec { match fqp { Some(path) => { out.push(path.join("::")); - }, + } _ => {} }; - - }, + } clean::Type::Tuple(tys) => { work.extend(tys.into_iter()); - }, + } clean::Type::Slice(ty) => { work.push_back(*ty); } clean::Type::Array(ty, _) => { work.push_back(*ty); - }, + } clean::Type::RawPointer(_, ty) => { work.push_back(*ty); - }, + } clean::Type::BorrowedRef { type_, .. } => { work.push_back(*type_); - }, + } clean::Type::QPath { self_type, trait_, .. } => { work.push_back(*self_type); work.push_back(*trait_); - }, + } _ => {} } - }; + } out } diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index d80facf4704a4..d30c9a3d33352 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -1,18 +1,18 @@ -use crate::clean::{self, GetDefId, AttributesExt}; +use crate::clean::{self, AttributesExt, GetDefId}; use crate::fold::DocFolder; -use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; +use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; use rustc::middle::privacy::AccessLevels; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use std::collections::BTreeMap; use std::mem; use std::path::{Path, PathBuf}; -use std::collections::BTreeMap; use syntax::source_map::FileName; use syntax::symbol::sym; use serde::Serialize; -use super::{ItemType, IndexItem, IndexItemFunctionType, Impl, shorten, plain_summary_line}; -use super::{Type, RenderInfo}; +use super::{plain_summary_line, shorten, Impl, IndexItem, IndexItemFunctionType, ItemType}; +use super::{RenderInfo, Type}; /// Indicates where an external crate can be found. pub enum ExternalLocation { @@ -92,7 +92,6 @@ crate struct Cache { pub crate_version: Option, // Private fields only used when initially crawling a crate to build a cache - stack: Vec, parent_stack: Vec, parent_is_trait_impl: bool, @@ -142,9 +141,8 @@ impl Cache { owned_box_did, } = renderinfo; - let external_paths = external_paths.into_iter() - .map(|(k, (v, t))| (k, (v, ItemType::from(t)))) - .collect(); + let external_paths = + external_paths.into_iter().map(|(k, (v, t))| (k, (v, ItemType::from(t)))).collect(); let mut cache = Cache { impls: Default::default(), @@ -181,8 +179,9 @@ impl Cache { _ => PathBuf::new(), }; let extern_url = extern_html_root_urls.get(&e.name).map(|u| &**u); - cache.extern_locations.insert(n, (e.name.clone(), src_root, - extern_location(e, extern_url, &dst))); + cache + .extern_locations + .insert(n, (e.name.clone(), src_root, extern_location(e, extern_url, &dst))); let did = DefId { krate: n, index: CRATE_DEF_INDEX }; cache.external_paths.insert(did, (vec![e.name.to_string()], ItemType::Module)); @@ -237,9 +236,10 @@ impl DocFolder for Cache { // If the impl is from a masked crate or references something from a // masked crate then remove it completely. if let clean::ImplItem(ref i) = item.inner { - if self.masked_crates.contains(&item.def_id.krate) || - i.trait_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate)) || - i.for_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate)) { + if self.masked_crates.contains(&item.def_id.krate) + || i.trait_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate)) + || i.for_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate)) + { return None; } } @@ -254,9 +254,10 @@ impl DocFolder for Cache { if let clean::ImplItem(ref i) = item.inner { if let Some(did) = i.trait_.def_id() { if i.blanket_impl.is_none() { - self.implementors.entry(did).or_default().push(Impl { - impl_item: item.clone(), - }); + self.implementors + .entry(did) + .or_default() + .push(Impl { impl_item: item.clone() }); } } } @@ -265,19 +266,22 @@ impl DocFolder for Cache { if let Some(ref s) = item.name { let (parent, is_inherent_impl_item) = match item.inner { clean::StrippedItem(..) => ((None, None), false), - clean::AssocConstItem(..) | - clean::TypedefItem(_, true) if self.parent_is_trait_impl => { + clean::AssocConstItem(..) | clean::TypedefItem(_, true) + if self.parent_is_trait_impl => + { // skip associated items in trait impls ((None, None), false) } - clean::AssocTypeItem(..) | - clean::TyMethodItem(..) | - clean::StructFieldItem(..) | - clean::VariantItem(..) => { - ((Some(*self.parent_stack.last().unwrap()), - Some(&self.stack[..self.stack.len() - 1])), - false) - } + clean::AssocTypeItem(..) + | clean::TyMethodItem(..) + | clean::StructFieldItem(..) + | clean::VariantItem(..) => ( + ( + Some(*self.parent_stack.last().unwrap()), + Some(&self.stack[..self.stack.len() - 1]), + ), + false, + ), clean::MethodItem(..) | clean::AssocConstItem(..) => { if self.parent_stack.is_empty() { ((None, None), false) @@ -289,18 +293,17 @@ impl DocFolder for Cache { // for where the type was defined. On the other // hand, `paths` always has the right // information if present. - Some(&(ref fqp, ItemType::Trait)) | - Some(&(ref fqp, ItemType::Struct)) | - Some(&(ref fqp, ItemType::Union)) | - Some(&(ref fqp, ItemType::Enum)) => - Some(&fqp[..fqp.len() - 1]), + Some(&(ref fqp, ItemType::Trait)) + | Some(&(ref fqp, ItemType::Struct)) + | Some(&(ref fqp, ItemType::Union)) + | Some(&(ref fqp, ItemType::Enum)) => Some(&fqp[..fqp.len() - 1]), Some(..) => Some(&*self.stack), - None => None + None => None, }; ((Some(*last), path), true) } } - _ => ((None, Some(&*self.stack)), false) + _ => ((None, Some(&*self.stack)), false), }; match parent { @@ -341,25 +344,32 @@ impl DocFolder for Cache { }; match item.inner { - clean::StructItem(..) | clean::EnumItem(..) | - clean::TypedefItem(..) | clean::TraitItem(..) | - clean::FunctionItem(..) | clean::ModuleItem(..) | - clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) | - clean::ConstantItem(..) | clean::StaticItem(..) | - clean::UnionItem(..) | clean::ForeignTypeItem | - clean::MacroItem(..) | clean::ProcMacroItem(..) - if !self.stripped_mod => { + clean::StructItem(..) + | clean::EnumItem(..) + | clean::TypedefItem(..) + | clean::TraitItem(..) + | clean::FunctionItem(..) + | clean::ModuleItem(..) + | clean::ForeignFunctionItem(..) + | clean::ForeignStaticItem(..) + | clean::ConstantItem(..) + | clean::StaticItem(..) + | clean::UnionItem(..) + | clean::ForeignTypeItem + | clean::MacroItem(..) + | clean::ProcMacroItem(..) + if !self.stripped_mod => + { // Re-exported items mean that the same id can show up twice // in the rustdoc ast that we're looking at. We know, // however, that a re-exported item doesn't show up in the // `public_items` map, so we can skip inserting into the // paths map if there was already an entry present and we're // not a public item. - if !self.paths.contains_key(&item.def_id) || - self.access_levels.is_public(item.def_id) + if !self.paths.contains_key(&item.def_id) + || self.access_levels.is_public(item.def_id) { - self.paths.insert(item.def_id, - (self.stack.clone(), item.type_())); + self.paths.insert(item.def_id, (self.stack.clone(), item.type_())); } self.add_aliases(&item); } @@ -373,8 +383,7 @@ impl DocFolder for Cache { clean::PrimitiveItem(..) => { self.add_aliases(&item); - self.paths.insert(item.def_id, (self.stack.clone(), - item.type_())); + self.paths.insert(item.def_id, (self.stack.clone(), item.type_())); } _ => {} @@ -383,8 +392,11 @@ impl DocFolder for Cache { // Maintain the parent stack let orig_parent_is_trait_impl = self.parent_is_trait_impl; let parent_pushed = match item.inner { - clean::TraitItem(..) | clean::EnumItem(..) | clean::ForeignTypeItem | - clean::StructItem(..) | clean::UnionItem(..) => { + clean::TraitItem(..) + | clean::EnumItem(..) + | clean::ForeignTypeItem + | clean::StructItem(..) + | clean::UnionItem(..) => { self.parent_stack.push(item.def_id); self.parent_is_trait_impl = false; true @@ -392,14 +404,14 @@ impl DocFolder for Cache { clean::ImplItem(ref i) => { self.parent_is_trait_impl = i.trait_.is_some(); match i.for_ { - clean::ResolvedPath{ did, .. } => { + clean::ResolvedPath { did, .. } => { self.parent_stack.push(did); true } ref t => { - let prim_did = t.primitive_type().and_then(|t| { - self.primitive_locations.get(&t).cloned() - }); + let prim_did = t + .primitive_type() + .and_then(|t| self.primitive_locations.get(&t).cloned()); match prim_did { Some(did) => { self.parent_stack.push(did); @@ -410,7 +422,7 @@ impl DocFolder for Cache { } } } - _ => false + _ => false, }; // Once we've recursively found all the generics, hoard off all the @@ -423,16 +435,16 @@ impl DocFolder for Cache { let mut dids = FxHashSet::default(); if let clean::Item { inner: clean::ImplItem(ref i), .. } = item { match i.for_ { - clean::ResolvedPath { did, .. } | - clean::BorrowedRef { + clean::ResolvedPath { did, .. } + | clean::BorrowedRef { type_: box clean::ResolvedPath { did, .. }, .. } => { dids.insert(did); } ref t => { - let did = t.primitive_type().and_then(|t| { - self.primitive_locations.get(&t).cloned() - }); + let did = t + .primitive_type() + .and_then(|t| self.primitive_locations.get(&t).cloned()); if let Some(did) = did { dids.insert(did); @@ -450,9 +462,7 @@ impl DocFolder for Cache { } else { unreachable!() }; - let impl_item = Impl { - impl_item: item, - }; + let impl_item = Impl { impl_item: item }; if impl_item.trait_did().map_or(true, |d| self.traits.contains_key(&d)) { for did in dids { self.impls.entry(did).or_insert(vec![]).push(impl_item.clone()); @@ -467,8 +477,12 @@ impl DocFolder for Cache { } }); - if pushed { self.stack.pop().unwrap(); } - if parent_pushed { self.parent_stack.pop().unwrap(); } + if pushed { + self.stack.pop().unwrap(); + } + if parent_pushed { + self.parent_stack.pop().unwrap(); + } self.stripped_mod = orig_stripped_mod; self.parent_is_trait_impl = orig_parent_is_trait_impl; ret @@ -478,30 +492,32 @@ impl DocFolder for Cache { impl Cache { fn add_aliases(&mut self, item: &clean::Item) { if item.def_id.index == CRATE_DEF_INDEX { - return + return; } if let Some(ref item_name) = item.name { - let path = self.paths.get(&item.def_id) - .map(|p| p.0[..p.0.len() - 1].join("::")) - .unwrap_or("std".to_owned()); - for alias in item.attrs.lists(sym::doc) - .filter(|a| a.check_name(sym::alias)) - .filter_map(|a| a.value_str() - .map(|s| s.to_string().replace("\"", ""))) - .filter(|v| !v.is_empty()) - .collect::>() - .into_iter() { - self.aliases.entry(alias) - .or_insert(Vec::with_capacity(1)) - .push(IndexItem { - ty: item.type_(), - name: item_name.to_string(), - path: path.clone(), - desc: shorten(plain_summary_line(item.doc_value())), - parent: None, - parent_idx: None, - search_type: get_index_search_type(&item), - }); + let path = self + .paths + .get(&item.def_id) + .map(|p| p.0[..p.0.len() - 1].join("::")) + .unwrap_or("std".to_owned()); + for alias in item + .attrs + .lists(sym::doc) + .filter(|a| a.check_name(sym::alias)) + .filter_map(|a| a.value_str().map(|s| s.to_string().replace("\"", ""))) + .filter(|v| !v.is_empty()) + .collect::>() + .into_iter() + { + self.aliases.entry(alias).or_insert(Vec::with_capacity(1)).push(IndexItem { + ty: item.type_(), + name: item_name.to_string(), + path: path.clone(), + desc: shorten(plain_summary_line(item.doc_value())), + parent: None, + parent_idx: None, + search_type: get_index_search_type(&item), + }); } } } @@ -509,9 +525,11 @@ impl Cache { /// Attempts to find where an external crate is located, given that we're /// rendering in to the specified source destination. -fn extern_location(e: &clean::ExternalCrate, extern_url: Option<&str>, dst: &Path) - -> ExternalLocation -{ +fn extern_location( + e: &clean::ExternalCrate, + extern_url: Option<&str>, + dst: &Path, +) -> ExternalLocation { use ExternalLocation::*; // See if there's documentation generated into the local directory let local_location = dst.join(&e.name); @@ -529,16 +547,19 @@ fn extern_location(e: &clean::ExternalCrate, extern_url: Option<&str>, dst: &Pat // Failing that, see if there's an attribute specifying where to find this // external crate - e.attrs.lists(sym::doc) - .filter(|a| a.check_name(sym::html_root_url)) - .filter_map(|a| a.value_str()) - .map(|url| { - let mut url = url.to_string(); - if !url.ends_with("/") { - url.push('/') - } - Remote(url) - }).next().unwrap_or(Unknown) // Well, at least we tried. + e.attrs + .lists(sym::doc) + .filter(|a| a.check_name(sym::html_root_url)) + .filter_map(|a| a.value_str()) + .map(|url| { + let mut url = url.to_string(); + if !url.ends_with("/") { + url.push('/') + } + Remote(url) + }) + .next() + .unwrap_or(Unknown) // Well, at least we tried. } /// Builds the search index from the collected metadata @@ -547,9 +568,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { let mut crate_items = Vec::with_capacity(cache.search_index.len()); let mut crate_paths = vec![]; - let Cache { ref mut search_index, - ref orphan_impl_items, - ref paths, .. } = *cache; + let Cache { ref mut search_index, ref orphan_impl_items, ref paths, .. } = *cache; // Attach all orphan items to the type's definition if the type // has since been learned. @@ -596,9 +615,11 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { crate_items.push(&*item); } - let crate_doc = krate.module.as_ref().map(|module| { - shorten(plain_summary_line(module.doc_value())) - }).unwrap_or(String::new()); + let crate_doc = krate + .module + .as_ref() + .map(|module| shorten(plain_summary_line(module.doc_value()))) + .unwrap_or(String::new()); #[derive(Serialize)] struct CrateData<'a> { @@ -630,17 +651,14 @@ fn get_index_search_type(item: &clean::Item) -> Option { _ => return None, }; - let inputs = all_types.iter().map(|arg| { - get_index_type(&arg) - }).filter(|a| a.name.is_some()).collect(); - let output = ret_types.iter().map(|arg| { - get_index_type(&arg) - }).filter(|a| a.name.is_some()).collect::>(); - let output = if output.is_empty() { - None - } else { - Some(output) - }; + let inputs = + all_types.iter().map(|arg| get_index_type(&arg)).filter(|a| a.name.is_some()).collect(); + let output = ret_types + .iter() + .map(|arg| get_index_type(&arg)) + .filter(|a| a.name.is_some()) + .collect::>(); + let output = if output.is_empty() { None } else { Some(output) }; Some(IndexItemFunctionType { inputs, output }) } @@ -667,21 +685,17 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option clean::Primitive(ref p) => Some(format!("{:?}", p)), clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_, accept_generic), // FIXME: add all from clean::Type. - _ => None + _ => None, } } fn get_generics(clean_type: &clean::Type) -> Option> { - clean_type.generics() - .and_then(|types| { - let r = types.iter() - .filter_map(|t| get_index_type_name(t, false)) - .map(|s| s.to_ascii_lowercase()) - .collect::>(); - if r.is_empty() { - None - } else { - Some(r) - } - }) + clean_type.generics().and_then(|types| { + let r = types + .iter() + .filter_map(|t| get_index_type_name(t, false)) + .map(|s| s.to_ascii_lowercase()) + .collect::>(); + if r.is_empty() { None } else { Some(r) } + }) } diff --git a/src/librustdoc/html/render/tests.rs b/src/librustdoc/html/render/tests.rs index 1848b575e4d67..99ad26549f5d3 100644 --- a/src/librustdoc/html/render/tests.rs +++ b/src/librustdoc/html/render/tests.rs @@ -14,15 +14,10 @@ fn test_name_key() { #[test] fn test_name_sorting() { - let names = ["Apple", - "Banana", - "Fruit", "Fruit0", "Fruit00", - "Fruit1", "Fruit01", - "Fruit2", "Fruit02", - "Fruit20", - "Fruit30x", - "Fruit100", - "Pear"]; + let names = [ + "Apple", "Banana", "Fruit", "Fruit0", "Fruit00", "Fruit1", "Fruit01", "Fruit2", "Fruit02", + "Fruit20", "Fruit30x", "Fruit100", "Pear", + ]; let mut sorted = names.to_owned(); sorted.sort_by_key(|&s| name_key(s)); assert_eq!(names, sorted); diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index d840683a7af87..717fc7fbabd05 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -1,24 +1,24 @@ use crate::clean; use crate::docfs::PathError; use crate::fold::DocFolder; +use crate::html::format::Buffer; +use crate::html::highlight; use crate::html::layout; use crate::html::render::{Error, SharedContext, BASIC_KEYWORDS}; -use crate::html::highlight; -use crate::html::format::Buffer; use std::ffi::OsStr; use std::fs; use std::path::{Component, Path, PathBuf}; use syntax::source_map::FileName; -crate fn render(dst: &Path, scx: &mut SharedContext, - krate: clean::Crate) -> Result { +crate fn render( + dst: &Path, + scx: &mut SharedContext, + krate: clean::Crate, +) -> Result { info!("emitting source files"); let dst = dst.join("src").join(&krate.name); scx.ensure_dir(&dst)?; - let mut folder = SourceCollector { - dst, - scx, - }; + let mut folder = SourceCollector { dst, scx }; Ok(folder.fold_crate(krate)) } @@ -38,20 +38,21 @@ impl<'a> DocFolder for SourceCollector<'a> { // skip all invalid or macro spans && item.source.filename.is_real() // skip non-local items - && item.def_id.is_local() { - + && item.def_id.is_local() + { // If it turns out that we couldn't read this file, then we probably // can't read any of the files (generating html output from json or // something like that), so just don't include sources for the // entire crate. The other option is maintaining this mapping on a // per-file basis, but that's probably not worth it... - self.scx - .include_sources = match self.emit_source(&item.source.filename) { + self.scx.include_sources = match self.emit_source(&item.source.filename) { Ok(()) => true, Err(e) => { - println!("warning: source code was requested to be rendered, \ + println!( + "warning: source code was requested to be rendered, \ but processing `{}` had an error: {}", - item.source.filename, e); + item.source.filename, e + ); println!(" skipping rendering of source code"); false } @@ -81,11 +82,8 @@ impl<'a> SourceCollector<'a> { }; // Remove the utf-8 BOM if any - let contents = if contents.starts_with("\u{feff}") { - &contents[3..] - } else { - &contents[..] - }; + let contents = + if contents.starts_with("\u{feff}") { &contents[3..] } else { &contents[..] }; // Create the intermediate directories let mut cur = self.dst.clone(); @@ -98,15 +96,15 @@ impl<'a> SourceCollector<'a> { href.push('/'); }); self.scx.ensure_dir(&cur)?; - let mut fname = p.file_name() - .expect("source has no filename") - .to_os_string(); + let mut fname = p.file_name().expect("source has no filename").to_os_string(); fname.push(".html"); cur.push(&fname); href.push_str(&fname.to_string_lossy()); - let title = format!("{} -- source", cur.file_name().expect("failed to get file name") - .to_string_lossy()); + let title = format!( + "{} -- source", + cur.file_name().expect("failed to get file name").to_string_lossy() + ); let desc = format!("Source to the Rust file `{}`.", filename); let page = layout::Page { title: &title, @@ -119,9 +117,13 @@ impl<'a> SourceCollector<'a> { extra_scripts: &[&format!("source-files{}", self.scx.resource_suffix)], static_extra_scripts: &[&format!("source-script{}", self.scx.resource_suffix)], }; - let v = layout::render(&self.scx.layout, - &page, "", |buf: &mut _| print_src(buf, &contents), - &self.scx.themes); + let v = layout::render( + &self.scx.layout, + &page, + "", + |buf: &mut _| print_src(buf, &contents), + &self.scx.themes, + ); self.scx.fs.write(&cur, v.as_bytes())?; self.scx.local_sources.insert(p.clone(), href); Ok(()) @@ -170,6 +172,5 @@ fn print_src(buf: &mut Buffer, s: &str) { write!(buf, "{0:1$}\n", i, cols); } write!(buf, ""); - write!(buf, "{}", - highlight::render_with_highlighting(s, None, None, None)); + write!(buf, "{}", highlight::render_with_highlighting(s, None, None, None)); } diff --git a/src/librustdoc/html/toc.rs b/src/librustdoc/html/toc.rs index 0fb2f8dd7962a..034fb27300027 100644 --- a/src/librustdoc/html/toc.rs +++ b/src/librustdoc/html/toc.rs @@ -16,7 +16,7 @@ pub struct Toc { /// ### A /// ## B /// ``` - entries: Vec + entries: Vec, } impl Toc { @@ -46,7 +46,7 @@ pub struct TocBuilder { /// it is the most recent one). /// /// We also have `chain[0].level <= top_level.entries[last]`. - chain: Vec + chain: Vec, } impl TocBuilder { @@ -54,7 +54,6 @@ impl TocBuilder { TocBuilder { top_level: Toc { entries: Vec::new() }, chain: Vec::new() } } - /// Converts into a true `Toc` struct. pub fn into_toc(mut self) -> Toc { // we know all levels are >= 1. @@ -100,14 +99,14 @@ impl TocBuilder { // this is the parent we want, so return it to // its rightful place. self.chain.push(next); - return + return; } else { this = Some(next); } } None => { this.map(|e| self.top_level.entries.push(e)); - return + return; } } } @@ -152,7 +151,7 @@ impl TocBuilder { name, sec_number, id, - children: Toc { entries: Vec::new() } + children: Toc { entries: Vec::new() }, }); // get the thing we just pushed, so we can borrow the string @@ -167,9 +166,12 @@ impl Toc { v.push_str("
    {}extern crate {} as {};", - myitem.visibility.print_with_space(), - anchor(myitem.def_id, src), - name) - } - None => { - write!(w, "
    {}extern crate {};", - myitem.visibility.print_with_space(), - anchor(myitem.def_id, name)) - } + Some(ref src) => write!( + w, + "
    {}extern crate {} as {};", + myitem.visibility.print_with_space(), + anchor(myitem.def_id, src), + name + ), + None => write!( + w, + "
    {}extern crate {};", + myitem.visibility.print_with_space(), + anchor(myitem.def_id, name) + ), } write!(w, "
    {}{}
    {}{}
    {name}{unsafety_flag}{stab_tags}{docs}

    (&mut self, mut predicate: P) -> Option + where P: FnMut(&Self::Item) -> bool, { match self.state { @@ -150,7 +152,7 @@ impl Iterator for Chain where self.state = ChainState::Back; self.b.find(predicate) } - v => v + v => v, }, ChainState::Front => self.a.find(predicate), ChainState::Back => self.b.find(predicate), @@ -165,9 +167,9 @@ impl Iterator for Chain where let a_last = self.a.last(); let b_last = self.b.last(); b_last.or(a_last) - }, + } ChainState::Front => self.a.last(), - ChainState::Back => self.b.last() + ChainState::Back => self.b.last(), } } @@ -182,7 +184,7 @@ impl Iterator for Chain where let upper = match (a_upper, b_upper) { (Some(x), Some(y)) => x.checked_add(y), - _ => None + _ => None, }; (lower, upper) @@ -194,9 +196,10 @@ impl Iterator for Chain where } #[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Chain where +impl DoubleEndedIterator for Chain +where A: DoubleEndedIterator, - B: DoubleEndedIterator, + B: DoubleEndedIterator, { #[inline] fn next_back(&mut self) -> Option { @@ -219,7 +222,7 @@ impl DoubleEndedIterator for Chain where ChainState::Both | ChainState::Back => { for x in self.b.by_ref().rev() { if n == 0 { - return Some(x) + return Some(x); } n -= 1; } @@ -229,15 +232,14 @@ impl DoubleEndedIterator for Chain where } ChainState::Front => {} } - if let ChainState::Front = self.state { - self.a.nth_back(n) - } else { - None - } + if let ChainState::Front = self.state { self.a.nth_back(n) } else { None } } - fn try_rfold(&mut self, init: Acc, mut f: F) -> R where - Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try + fn try_rfold(&mut self, init: Acc, mut f: F) -> R + where + Self: Sized, + F: FnMut(Acc, Self::Item) -> R, + R: Try, { let mut accum = init; match self.state { @@ -247,7 +249,7 @@ impl DoubleEndedIterator for Chain where self.state = ChainState::Front; } } - _ => { } + _ => {} } if let ChainState::Front = self.state { accum = self.a.try_rfold(accum, &mut f)?; @@ -256,34 +258,39 @@ impl DoubleEndedIterator for Chain where } fn rfold(self, init: Acc, mut f: F) -> Acc - where F: FnMut(Acc, Self::Item) -> Acc, + where + F: FnMut(Acc, Self::Item) -> Acc, { let mut accum = init; match self.state { ChainState::Both | ChainState::Back => { accum = self.b.rfold(accum, &mut f); } - _ => { } + _ => {} } match self.state { ChainState::Both | ChainState::Front => { accum = self.a.rfold(accum, &mut f); } - _ => { } + _ => {} } accum } - } // Note: *both* must be fused to handle double-ended iterators. #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Chain - where A: FusedIterator, - B: FusedIterator, -{} +where + A: FusedIterator, + B: FusedIterator, +{ +} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for Chain - where A: TrustedLen, B: TrustedLen, -{} +where + A: TrustedLen, + B: TrustedLen, +{ +} diff --git a/src/libcore/iter/adapters/zip.rs b/src/libcore/iter/adapters/zip.rs index 14d9d5499b880..b13e12e2e8608 100644 --- a/src/libcore/iter/adapters/zip.rs +++ b/src/libcore/iter/adapters/zip.rs @@ -2,7 +2,7 @@ use crate::cmp; -use super::super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen}; +use super::super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen}; /// An iterator that iterates two other iterators simultaneously. /// @@ -27,7 +27,9 @@ impl Zip { } fn super_nth(&mut self, mut n: usize) -> Option<(A::Item, B::Item)> { while let Some(x) = Iterator::next(self) { - if n == 0 { return Some(x) } + if n == 0 { + return Some(x); + } n -= 1; } None @@ -35,7 +37,10 @@ impl Zip { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Zip where A: Iterator, B: Iterator +impl Iterator for Zip +where + A: Iterator, + B: Iterator, { type Item = (A::Item, B::Item); @@ -56,7 +61,8 @@ impl Iterator for Zip where A: Iterator, B: Iterator } #[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Zip where +impl DoubleEndedIterator for Zip +where A: DoubleEndedIterator + ExactSizeIterator, B: DoubleEndedIterator + ExactSizeIterator, { @@ -75,14 +81,17 @@ trait ZipImpl { fn size_hint(&self) -> (usize, Option); fn nth(&mut self, n: usize) -> Option; fn next_back(&mut self) -> Option - where A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator; + where + A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator; } // General Zip impl #[doc(hidden)] impl ZipImpl for Zip - where A: Iterator, B: Iterator +where + A: Iterator, + B: Iterator, { type Item = (A::Item, B::Item); default fn new(a: A, b: B) -> Self { @@ -90,7 +99,7 @@ impl ZipImpl for Zip a, b, index: 0, // unused - len: 0, // unused + len: 0, // unused } } @@ -108,17 +117,22 @@ impl ZipImpl for Zip #[inline] default fn next_back(&mut self) -> Option<(A::Item, B::Item)> - where A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator + where + A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator, { let a_sz = self.a.len(); let b_sz = self.b.len(); if a_sz != b_sz { // Adjust a, b to equal length if a_sz > b_sz { - for _ in 0..a_sz - b_sz { self.a.next_back(); } + for _ in 0..a_sz - b_sz { + self.a.next_back(); + } } else { - for _ in 0..b_sz - a_sz { self.b.next_back(); } + for _ in 0..b_sz - a_sz { + self.b.next_back(); + } } } match (self.a.next_back(), self.b.next_back()) { @@ -136,10 +150,10 @@ impl ZipImpl for Zip let lower = cmp::min(a_lower, b_lower); let upper = match (a_upper, b_upper) { - (Some(x), Some(y)) => Some(cmp::min(x,y)), + (Some(x), Some(y)) => Some(cmp::min(x, y)), (Some(x), None) => Some(x), (None, Some(y)) => Some(y), - (None, None) => None + (None, None) => None, }; (lower, upper) @@ -148,16 +162,13 @@ impl ZipImpl for Zip #[doc(hidden)] impl ZipImpl for Zip - where A: TrustedRandomAccess, B: TrustedRandomAccess +where + A: TrustedRandomAccess, + B: TrustedRandomAccess, { fn new(a: A, b: B) -> Self { let len = cmp::min(a.len(), b.len()); - Zip { - a, - b, - index: 0, - len, - } + Zip { a, b, index: 0, len } } #[inline] @@ -165,9 +176,7 @@ impl ZipImpl for Zip if self.index < self.len { let i = self.index; self.index += 1; - unsafe { - Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) - } + unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) } } else if A::may_have_side_effect() && self.index < self.a.len() { // match the base implementation's potential side effects unsafe { @@ -194,10 +203,14 @@ impl ZipImpl for Zip let i = self.index; self.index += 1; if A::may_have_side_effect() { - unsafe { self.a.get_unchecked(i); } + unsafe { + self.a.get_unchecked(i); + } } if B::may_have_side_effect() { - unsafe { self.b.get_unchecked(i); } + unsafe { + self.b.get_unchecked(i); + } } } @@ -206,8 +219,9 @@ impl ZipImpl for Zip #[inline] fn next_back(&mut self) -> Option<(A::Item, B::Item)> - where A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator + where + A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator, { // Adjust a, b to equal length if A::may_have_side_effect() { @@ -229,9 +243,7 @@ impl ZipImpl for Zip if self.index < self.len { self.len -= 1; let i = self.len; - unsafe { - Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) - } + unsafe { Some((self.a.get_unchecked(i), self.b.get_unchecked(i))) } } else { None } @@ -240,12 +252,17 @@ impl ZipImpl for Zip #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for Zip - where A: ExactSizeIterator, B: ExactSizeIterator {} +where + A: ExactSizeIterator, + B: ExactSizeIterator, +{ +} #[doc(hidden)] unsafe impl TrustedRandomAccess for Zip - where A: TrustedRandomAccess, - B: TrustedRandomAccess, +where + A: TrustedRandomAccess, + B: TrustedRandomAccess, { unsafe fn get_unchecked(&mut self, i: usize) -> (A::Item, B::Item) { (self.a.get_unchecked(i), self.b.get_unchecked(i)) @@ -258,12 +275,19 @@ unsafe impl TrustedRandomAccess for Zip #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Zip - where A: FusedIterator, B: FusedIterator, {} +where + A: FusedIterator, + B: FusedIterator, +{ +} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for Zip - where A: TrustedLen, B: TrustedLen, -{} +where + A: TrustedLen, + B: TrustedLen, +{ +} /// An iterator whose items are random-accessible efficiently /// @@ -275,7 +299,7 @@ unsafe impl TrustedLen for Zip /// .get_unchecked() must return distinct mutable references for distinct /// indices (if applicable), and must return a valid reference if index is in /// 0..self.len(). -pub(crate) unsafe trait TrustedRandomAccess : ExactSizeIterator { +pub(crate) unsafe trait TrustedRandomAccess: ExactSizeIterator { unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item; /// Returns `true` if getting an iterator element may have /// side effects. Remember to take inner iterators into account. diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index fac6ff0f06b6d..80294de714d25 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -309,56 +309,58 @@ use crate::ops::Try; #[stable(feature = "rust1", since = "1.0.0")] pub use self::traits::Iterator; -#[unstable(feature = "step_trait", - reason = "likely to be replaced by finer-grained traits", - issue = "42168")] +#[unstable( + feature = "step_trait", + reason = "likely to be replaced by finer-grained traits", + issue = "42168" +)] pub use self::range::Step; -#[stable(feature = "rust1", since = "1.0.0")] -pub use self::sources::{Repeat, repeat}; -#[stable(feature = "iterator_repeat_with", since = "1.28.0")] -pub use self::sources::{RepeatWith, repeat_with}; #[stable(feature = "iter_empty", since = "1.2.0")] -pub use self::sources::{Empty, empty}; +pub use self::sources::{empty, Empty}; +#[stable(feature = "iter_from_fn", since = "1.34.0")] +pub use self::sources::{from_fn, FromFn}; #[stable(feature = "iter_once", since = "1.2.0")] -pub use self::sources::{Once, once}; +pub use self::sources::{once, Once}; #[unstable(feature = "iter_once_with", issue = "57581")] -pub use self::sources::{OnceWith, once_with}; -#[stable(feature = "iter_from_fn", since = "1.34.0")] -pub use self::sources::{FromFn, from_fn}; +pub use self::sources::{once_with, OnceWith}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::sources::{repeat, Repeat}; +#[stable(feature = "iterator_repeat_with", since = "1.28.0")] +pub use self::sources::{repeat_with, RepeatWith}; #[stable(feature = "iter_successors", since = "1.34.0")] -pub use self::sources::{Successors, successors}; +pub use self::sources::{successors, Successors}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use self::traits::{ExactSizeIterator, Sum, Product}; #[stable(feature = "fused", since = "1.26.0")] pub use self::traits::FusedIterator; #[unstable(feature = "trusted_len", issue = "37572")] pub use self::traits::TrustedLen; - #[stable(feature = "rust1", since = "1.0.0")] -pub use self::adapters::{Rev, Cycle, Chain, Zip, Map, Filter, FilterMap, Enumerate}; +pub use self::traits::{DoubleEndedIterator, Extend, FromIterator, IntoIterator}; #[stable(feature = "rust1", since = "1.0.0")] -pub use self::adapters::{Peekable, SkipWhile, TakeWhile, Skip, Take, Scan, FlatMap}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use self::adapters::{Fuse, Inspect}; +pub use self::traits::{ExactSizeIterator, Product, Sum}; + #[stable(feature = "iter_cloned", since = "1.1.0")] pub use self::adapters::Cloned; -#[stable(feature = "iterator_step_by", since = "1.28.0")] -pub use self::adapters::StepBy; -#[stable(feature = "iterator_flatten", since = "1.29.0")] -pub use self::adapters::Flatten; #[stable(feature = "iter_copied", since = "1.36.0")] pub use self::adapters::Copied; +#[stable(feature = "iterator_flatten", since = "1.29.0")] +pub use self::adapters::Flatten; +#[stable(feature = "iterator_step_by", since = "1.28.0")] +pub use self::adapters::StepBy; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::adapters::{Chain, Cycle, Enumerate, Filter, FilterMap, Map, Rev, Zip}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::adapters::{FlatMap, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::adapters::{Fuse, Inspect}; -pub(crate) use self::adapters::{TrustedRandomAccess, process_results}; +pub(crate) use self::adapters::{process_results, TrustedRandomAccess}; +mod adapters; mod range; mod sources; mod traits; -mod adapters; /// Used to make try_fold closures more like normal loops #[derive(PartialEq)] @@ -378,9 +380,13 @@ impl Try for LoopState { } } #[inline] - fn from_error(v: Self::Error) -> Self { LoopState::Break(v) } + fn from_error(v: Self::Error) -> Self { + LoopState::Break(v) + } #[inline] - fn from_ok(v: Self::Ok) -> Self { LoopState::Continue(v) } + fn from_ok(v: Self::Ok) -> Self { + LoopState::Continue(v) + } } impl LoopState { diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 63036f516a0a4..eac3c107d2283 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -9,9 +9,11 @@ use super::{FusedIterator, TrustedLen}; /// /// The `steps_between` function provides a way to efficiently compare /// two `Step` objects. -#[unstable(feature = "step_trait", - reason = "likely to be replaced by finer-grained traits", - issue = "42168")] +#[unstable( + feature = "step_trait", + reason = "likely to be replaced by finer-grained traits", + issue = "42168" +)] pub trait Step: Clone + PartialOrd + Sized { /// Returns the number of steps between two step objects. The count is /// inclusive of `start` and exclusive of `end`. @@ -170,8 +172,8 @@ macro_rules! step_impl_signed { } step_impl_unsigned!(usize u8 u16 u32 u64 u128); -step_impl_signed!([isize: usize] [i8: u8] [i16: u16]); -step_impl_signed!([i32: u32] [i64: u64] [i128: u128]); +step_impl_signed!([isize: usize][i8: u8][i16: u16]); +step_impl_signed!([i32: u32][i64: u64][i128: u128]); macro_rules! range_exact_iter_impl { ($($t:ty)*) => ($( @@ -227,7 +229,7 @@ impl Iterator for ops::Range { fn size_hint(&self) -> (usize, Option) { match Step::steps_between(&self.start, &self.end) { Some(hint) => (hint, Some(hint)), - None => (usize::MAX, None) + None => (usize::MAX, None), } } @@ -236,7 +238,7 @@ impl Iterator for ops::Range { if let Some(plus_n) = self.start.add_usize(n) { if plus_n < self.end { self.start = plus_n.add_one(); - return Some(plus_n) + return Some(plus_n); } } @@ -291,7 +293,7 @@ impl DoubleEndedIterator for ops::Range { if let Some(minus_n) = self.end.sub_usize(n) { if minus_n > self.start { self.end = minus_n.sub_one(); - return Some(self.end.clone()) + return Some(self.end.clone()); } } @@ -396,7 +398,9 @@ impl Iterator for ops::RangeInclusive { #[inline] fn try_fold(&mut self, init: B, mut f: F) -> R where - Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try, { self.compute_is_empty(); @@ -484,8 +488,11 @@ impl DoubleEndedIterator for ops::RangeInclusive { } #[inline] - fn try_rfold(&mut self, init: B, mut f: F) -> R where - Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try + fn try_rfold(&mut self, init: B, mut f: F) -> R + where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try, { self.compute_is_empty(); diff --git a/src/libcore/iter/traits/marker.rs b/src/libcore/iter/traits/marker.rs index 602619bce5a96..404cc84495c96 100644 --- a/src/libcore/iter/traits/marker.rs +++ b/src/libcore/iter/traits/marker.rs @@ -38,7 +38,7 @@ impl FusedIterator for &mut I {} /// [`usize::MAX`]: ../../std/usize/constant.MAX.html /// [`.size_hint`]: ../../std/iter/trait.Iterator.html#method.size_hint #[unstable(feature = "trusted_len", issue = "37572")] -pub unsafe trait TrustedLen : Iterator {} +pub unsafe trait TrustedLen: Iterator {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for &mut I {} diff --git a/src/libcore/iter/traits/mod.rs b/src/libcore/iter/traits/mod.rs index cf3013f423c94..efd1580a54807 100644 --- a/src/libcore/iter/traits/mod.rs +++ b/src/libcore/iter/traits/mod.rs @@ -1,15 +1,15 @@ -mod iterator; +mod accum; +mod collect; mod double_ended; mod exact_size; -mod collect; -mod accum; +mod iterator; mod marker; -#[stable(feature = "rust1", since = "1.0.0")] -pub use self::iterator::Iterator; +pub use self::accum::{Product, Sum}; +pub use self::collect::{Extend, FromIterator, IntoIterator}; pub use self::double_ended::DoubleEndedIterator; pub use self::exact_size::ExactSizeIterator; -pub use self::collect::{FromIterator, IntoIterator, Extend}; -pub use self::accum::{Sum, Product}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::iterator::Iterator; #[stable(feature = "rust1", since = "1.0.0")] pub use self::marker::{FusedIterator, TrustedLen}; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index a2ab85e64baa1..7c5e06ace6729 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -49,22 +49,21 @@ // // This cfg won't affect doc tests. #![cfg(not(test))] - #![stable(feature = "core", since = "1.6.0")] -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", - html_playground_url = "https://play.rust-lang.org/", - issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", - test(no_crate_inject, attr(deny(warnings))), - test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] +#![doc( + html_root_url = "https://doc.rust-lang.org/nightly/", + html_playground_url = "https://play.rust-lang.org/", + issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", + test(no_crate_inject, attr(deny(warnings))), + test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))) +)] #![no_core] - #![warn(deprecated_in_future)] #![warn(missing_docs)] #![warn(missing_debug_implementations)] #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings #![allow(explicit_outlives_requirements)] #![allow(incomplete_features)] - #![feature(allow_internal_unstable)] #![feature(arbitrary_self_types)] #![feature(asm)] @@ -148,22 +147,36 @@ mod int_macros; #[macro_use] mod uint_macros; -#[path = "num/isize.rs"] pub mod isize; -#[path = "num/i8.rs"] pub mod i8; -#[path = "num/i16.rs"] pub mod i16; -#[path = "num/i32.rs"] pub mod i32; -#[path = "num/i64.rs"] pub mod i64; -#[path = "num/i128.rs"] pub mod i128; +#[path = "num/i128.rs"] +pub mod i128; +#[path = "num/i16.rs"] +pub mod i16; +#[path = "num/i32.rs"] +pub mod i32; +#[path = "num/i64.rs"] +pub mod i64; +#[path = "num/i8.rs"] +pub mod i8; +#[path = "num/isize.rs"] +pub mod isize; -#[path = "num/usize.rs"] pub mod usize; -#[path = "num/u8.rs"] pub mod u8; -#[path = "num/u16.rs"] pub mod u16; -#[path = "num/u32.rs"] pub mod u32; -#[path = "num/u64.rs"] pub mod u64; -#[path = "num/u128.rs"] pub mod u128; +#[path = "num/u128.rs"] +pub mod u128; +#[path = "num/u16.rs"] +pub mod u16; +#[path = "num/u32.rs"] +pub mod u32; +#[path = "num/u64.rs"] +pub mod u64; +#[path = "num/u8.rs"] +pub mod u8; +#[path = "num/usize.rs"] +pub mod usize; -#[path = "num/f32.rs"] pub mod f32; -#[path = "num/f64.rs"] pub mod f64; +#[path = "num/f32.rs"] +pub mod f32; +#[path = "num/f64.rs"] +pub mod f64; #[macro_use] pub mod num; @@ -174,24 +187,24 @@ pub mod prelude; /* Core modules for ownership management */ +pub mod hint; pub mod intrinsics; pub mod mem; pub mod ptr; -pub mod hint; /* Core language traits */ +pub mod borrow; #[cfg(not(test))] // See #65860 -pub mod marker; -pub mod ops; +pub mod clone; #[cfg(not(test))] // See #65860 pub mod cmp; -#[cfg(not(test))] // See #65860 -pub mod clone; +pub mod convert; #[cfg(not(test))] // See #65860 pub mod default; -pub mod convert; -pub mod borrow; +#[cfg(not(test))] // See #65860 +pub mod marker; +pub mod ops; /* Core types and methods on primitives */ @@ -199,27 +212,27 @@ pub mod any; #[cfg(not(test))] // See #65860 pub mod array; pub mod ascii; -pub mod sync; pub mod cell; pub mod char; +pub mod ffi; +#[cfg(not(test))] // See #65860 +pub mod iter; +pub mod option; pub mod panic; pub mod panicking; #[cfg(not(test))] // See #65860 pub mod pin; -#[cfg(not(test))] // See #65860 -pub mod iter; -pub mod option; pub mod raw; pub mod result; -pub mod ffi; +pub mod sync; -pub mod slice; #[cfg(not(test))] // See #65860 -pub mod str; +pub mod fmt; #[cfg(not(test))] // See #65860 pub mod hash; +pub mod slice; #[cfg(not(test))] // See #65860 -pub mod fmt; +pub mod str; pub mod time; pub mod unicode; diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 1b586c3e5fe30..978d622156413 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -31,17 +31,17 @@ use crate::hash::Hasher; #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "send_trait")] #[rustc_on_unimplemented( - message="`{Self}` cannot be sent between threads safely", - label="`{Self}` cannot be sent between threads safely" + message = "`{Self}` cannot be sent between threads safely", + label = "`{Self}` cannot be sent between threads safely" )] pub unsafe auto trait Send { // empty. } #[stable(feature = "rust1", since = "1.0.0")] -impl !Send for *const T { } +impl !Send for *const T {} #[stable(feature = "rust1", since = "1.0.0")] -impl !Send for *mut T { } +impl !Send for *mut T {} /// Types with a constant size known at compile time. /// @@ -83,11 +83,11 @@ impl !Send for *mut T { } #[stable(feature = "rust1", since = "1.0.0")] #[lang = "sized"] #[rustc_on_unimplemented( - on(parent_trait="std::path::Path", label="borrow the `Path` instead"), - message="the size for values of type `{Self}` cannot be known at compilation time", - label="doesn't have a size known at compile-time", - note="to learn more, visit ", + on(parent_trait = "std::path::Path", label = "borrow the `Path` instead"), + message = "the size for values of type `{Self}` cannot be known at compilation time", + label = "doesn't have a size known at compile-time", + note = "to learn more, visit " )] #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable pub trait Sized { @@ -148,7 +148,7 @@ pub trait Unsize { /// [RFC1445]: https://github.com/rust-lang/rfcs/blob/master/text/1445-restrict-constants-in-patterns.md /// [issue 63438]: https://github.com/rust-lang/rust/issues/63438 #[unstable(feature = "structural_match", issue = "31434")] -#[rustc_on_unimplemented(message="the type `{Self}` does not `#[derive(PartialEq)]`")] +#[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")] #[lang = "structural_peq"] pub trait StructuralPartialEq { // Empty. @@ -198,7 +198,7 @@ pub trait StructuralPartialEq { /// of the two derives (`#[derive(PartialEq)]` and `#[derive(Eq)]`) and check /// that both of them are present as part of structural-match checking. #[unstable(feature = "structural_match", issue = "31434")] -#[rustc_on_unimplemented(message="the type `{Self}` does not `#[derive(Eq)]`")] +#[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")] #[lang = "structural_teq"] pub trait StructuralEq { // Empty. @@ -362,7 +362,7 @@ pub trait StructuralEq { /// [impls]: #implementors #[stable(feature = "rust1", since = "1.0.0")] #[lang = "copy"] -pub trait Copy : Clone { +pub trait Copy: Clone { // Empty. } @@ -370,7 +370,9 @@ pub trait Copy : Clone { #[rustc_builtin_macro] #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] #[allow_internal_unstable(core_intrinsics, derive_clone_copy)] -pub macro Copy($item:item) { /* compiler built-in */ } +pub macro Copy($item:item) { + /* compiler built-in */ +} /// Types for which it is safe to share references between threads. /// @@ -444,8 +446,8 @@ pub macro Copy($item:item) { /* compiler built-in */ } #[cfg_attr(not(test), rustc_diagnostic_item = "sync_trait")] #[lang = "sync"] #[rustc_on_unimplemented( - message="`{Self}` cannot be shared between threads safely", - label="`{Self}` cannot be shared between threads safely" + message = "`{Self}` cannot be shared between threads safely", + label = "`{Self}` cannot be shared between threads safely" )] pub unsafe auto trait Sync { // FIXME(estebank): once support to add notes in `rustc_on_unimplemented` @@ -462,67 +464,65 @@ pub unsafe auto trait Sync { } #[stable(feature = "rust1", since = "1.0.0")] -impl !Sync for *const T { } +impl !Sync for *const T {} #[stable(feature = "rust1", since = "1.0.0")] -impl !Sync for *mut T { } +impl !Sync for *mut T {} -macro_rules! impls{ - ($t: ident) => ( +macro_rules! impls { + ($t: ident) => { #[stable(feature = "rust1", since = "1.0.0")] - impl Hash for $t { + impl Hash for $t { #[inline] - fn hash(&self, _: &mut H) { - } + fn hash(&self, _: &mut H) {} } #[stable(feature = "rust1", since = "1.0.0")] - impl cmp::PartialEq for $t { + impl cmp::PartialEq for $t { fn eq(&self, _other: &$t) -> bool { true } } #[stable(feature = "rust1", since = "1.0.0")] - impl cmp::Eq for $t { - } + impl cmp::Eq for $t {} #[stable(feature = "rust1", since = "1.0.0")] - impl cmp::PartialOrd for $t { + impl cmp::PartialOrd for $t { fn partial_cmp(&self, _other: &$t) -> Option { Option::Some(cmp::Ordering::Equal) } } #[stable(feature = "rust1", since = "1.0.0")] - impl cmp::Ord for $t { + impl cmp::Ord for $t { fn cmp(&self, _other: &$t) -> cmp::Ordering { cmp::Ordering::Equal } } #[stable(feature = "rust1", since = "1.0.0")] - impl Copy for $t { } + impl Copy for $t {} #[stable(feature = "rust1", since = "1.0.0")] - impl Clone for $t { + impl Clone for $t { fn clone(&self) -> $t { $t } } #[stable(feature = "rust1", since = "1.0.0")] - impl Default for $t { + impl Default for $t { fn default() -> $t { $t } } #[unstable(feature = "structural_match", issue = "31434")] - impl StructuralPartialEq for $t { } + impl StructuralPartialEq for $t {} #[unstable(feature = "structural_match", issue = "31434")] - impl StructuralEq for $t { } - ) + impl StructuralEq for $t {} + }; } /// Zero-sized type used to mark things that "act like" they own a `T`. @@ -661,7 +661,7 @@ macro_rules! impls{ #[lang = "phantom_data"] #[structural_match] #[stable(feature = "rust1", since = "1.0.0")] -pub struct PhantomData; +pub struct PhantomData; impls! { PhantomData } @@ -788,5 +788,4 @@ mod copy_impls { // Shared references can be copied, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] impl Copy for &T {} - } diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index de3b837fb686b..5fb3c651b6b38 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -304,14 +304,15 @@ impl MaybeUninit { #[unstable(feature = "maybe_uninit_uninit_array", issue = "none")] #[inline(always)] pub fn uninit_array() -> [Self; LEN] { - unsafe { - MaybeUninit::<[MaybeUninit; LEN]>::uninit().assume_init() - } + unsafe { MaybeUninit::<[MaybeUninit; LEN]>::uninit().assume_init() } } /// A promotable constant, equivalent to `uninit()`. - #[unstable(feature = "internal_uninit_const", issue = "none", - reason = "hack to work around promotability")] + #[unstable( + feature = "internal_uninit_const", + issue = "none", + reason = "hack to work around promotability" + )] pub const UNINIT: Self = Self::uninit(); /// Creates a new `MaybeUninit` in an uninitialized state, with the memory being diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs index db5d2650331f4..e11072db0dcc6 100644 --- a/src/libcore/mem/mod.rs +++ b/src/libcore/mem/mod.rs @@ -745,7 +745,7 @@ pub fn replace(dest: &mut T, mut src: T) -> T { /// [`Copy`]: ../../std/marker/trait.Copy.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] -pub fn drop(_x: T) { } +pub fn drop(_x: T) {} /// Interprets `src` as having type `&U`, and then reads `src` without moving /// the contained value. @@ -834,9 +834,7 @@ impl hash::Hash for Discriminant { #[stable(feature = "discriminant_value", since = "1.21.0")] impl fmt::Debug for Discriminant { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_tuple("Discriminant") - .field(&self.0) - .finish() + fmt.debug_tuple("Discriminant").field(&self.0).finish() } } diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 9e379e638103e..e1e6c57a0fb7d 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -342,7 +342,7 @@ impl f32 { /// /// assert!(abs_difference <= f32::EPSILON); /// ``` - #[stable(feature = "f32_deg_rad_conversions", since="1.7.0")] + #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")] #[inline] pub fn to_degrees(self) -> f32 { // Use a constant for better precision. @@ -361,7 +361,7 @@ impl f32 { /// /// assert!(abs_difference <= f32::EPSILON); /// ``` - #[stable(feature = "f32_deg_rad_conversions", since="1.7.0")] + #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")] #[inline] pub fn to_radians(self) -> f32 { let value: f32 = consts::PI; @@ -424,7 +424,10 @@ impl f32 { /// * Be representable in the return type `Int`, after truncating off its fractional part #[unstable(feature = "float_approx_unchecked_to", issue = "67058")] #[inline] - pub unsafe fn approx_unchecked_to(self) -> Int where Self: FloatToInt { + pub unsafe fn approx_unchecked_to(self) -> Int + where + Self: FloatToInt, + { FloatToInt::::approx_unchecked(self) } diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs index a90b025c09351..dbfcbca3ffcbf 100644 --- a/src/libcore/panic.rs +++ b/src/libcore/panic.rs @@ -37,10 +37,12 @@ pub struct PanicInfo<'a> { } impl<'a> PanicInfo<'a> { - #[unstable(feature = "panic_internals", - reason = "internal details of the implementation of the `panic!` \ + #[unstable( + feature = "panic_internals", + reason = "internal details of the implementation of the `panic!` \ and related macros", - issue = "none")] + issue = "none" + )] #[doc(hidden)] #[inline] pub fn internal_constructor( @@ -48,17 +50,15 @@ impl<'a> PanicInfo<'a> { location: &'a Location<'a>, ) -> Self { struct NoPayload; - PanicInfo { - location, - message, - payload: &NoPayload, - } + PanicInfo { location, message, payload: &NoPayload } } - #[unstable(feature = "panic_internals", - reason = "internal details of the implementation of the `panic!` \ + #[unstable( + feature = "panic_internals", + reason = "internal details of the implementation of the `panic!` \ and related macros", - issue = "none")] + issue = "none" + )] #[doc(hidden)] #[inline] pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) { @@ -222,9 +222,11 @@ impl<'a> Location<'a> { /// assert_ne!(this_location.line(), another_location.line()); /// assert_ne!(this_location.column(), another_location.column()); /// ``` - #[unstable(feature = "track_caller", - reason = "uses #[track_caller] which is not yet stable", - issue = "47809")] + #[unstable( + feature = "track_caller", + reason = "uses #[track_caller] which is not yet stable", + issue = "47809" + )] #[track_caller] pub const fn caller() -> &'static Location<'static> { crate::intrinsics::caller_location() @@ -232,10 +234,12 @@ impl<'a> Location<'a> { } impl<'a> Location<'a> { - #![unstable(feature = "panic_internals", - reason = "internal details of the implementation of the `panic!` \ + #![unstable( + feature = "panic_internals", + reason = "internal details of the implementation of the `panic!` \ and related macros", - issue = "none")] + issue = "none" + )] #[doc(hidden)] pub const fn internal_constructor(file: &'a str, line: u32, col: u32) -> Self { Location { file, line, col } diff --git a/src/libcore/ptr/const_ptr.rs b/src/libcore/ptr/const_ptr.rs index be2b7ff5f773b..e5297a0c1e094 100644 --- a/src/libcore/ptr/const_ptr.rs +++ b/src/libcore/ptr/const_ptr.rs @@ -1,7 +1,7 @@ -use crate::cmp::Ordering::{self, Less, Equal, Greater}; +use super::*; +use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::intrinsics; use crate::mem; -use super::*; // ignore-tidy-undocumented-unsafe @@ -154,8 +154,8 @@ impl *const T { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub unsafe fn offset(self, count: isize) -> *const T - where - T: Sized, + where + T: Sized, { intrinsics::offset(self, count) } @@ -212,8 +212,8 @@ impl *const T { #[stable(feature = "ptr_wrapping_offset", since = "1.16.0")] #[inline] pub fn wrapping_offset(self, count: isize) -> *const T - where - T: Sized, + where + T: Sized, { unsafe { intrinsics::arith_offset(self, count) } } @@ -284,8 +284,8 @@ impl *const T { #[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "41079")] #[inline] pub const unsafe fn offset_from(self, origin: *const T) -> isize - where - T: Sized, + where + T: Sized, { let pointee_size = mem::size_of::(); let ok = 0 < pointee_size && pointee_size <= isize::max_value() as usize; @@ -332,8 +332,8 @@ impl *const T { #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")] #[inline] pub fn wrapping_offset_from(self, origin: *const T) -> isize - where - T: Sized, + where + T: Sized, { let pointee_size = mem::size_of::(); assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize); @@ -396,8 +396,8 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn add(self, count: usize) -> Self - where - T: Sized, + where + T: Sized, { self.offset(count as isize) } @@ -457,8 +457,8 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn sub(self, count: usize) -> Self - where - T: Sized, + where + T: Sized, { self.offset((count as isize).wrapping_neg()) } @@ -512,8 +512,8 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub fn wrapping_add(self, count: usize) -> Self - where - T: Sized, + where + T: Sized, { self.wrapping_offset(count as isize) } @@ -567,8 +567,8 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub fn wrapping_sub(self, count: usize) -> Self - where - T: Sized, + where + T: Sized, { self.wrapping_offset((count as isize).wrapping_neg()) } @@ -582,8 +582,8 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn read(self) -> T - where - T: Sized, + where + T: Sized, { read(self) } @@ -601,8 +601,8 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn read_volatile(self) -> T - where - T: Sized, + where + T: Sized, { read_volatile(self) } @@ -618,8 +618,8 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn read_unaligned(self) -> T - where - T: Sized, + where + T: Sized, { read_unaligned(self) } @@ -635,8 +635,8 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn copy_to(self, dest: *mut T, count: usize) - where - T: Sized, + where + T: Sized, { copy(self, dest, count) } @@ -652,8 +652,8 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) - where - T: Sized, + where + T: Sized, { copy_nonoverlapping(self, dest, count) } @@ -699,8 +699,8 @@ impl *const T { /// ``` #[stable(feature = "align_offset", since = "1.36.0")] pub fn align_offset(self, align: usize) -> usize - where - T: Sized, + where + T: Sized, { if !align.is_power_of_two() { panic!("align_offset: align is not a power-of-two"); @@ -713,7 +713,9 @@ impl *const T { #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for *const T { #[inline] - fn eq(&self, other: &*const T) -> bool { *self == *other } + fn eq(&self, other: &*const T) -> bool { + *self == *other + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -742,14 +744,22 @@ impl PartialOrd for *const T { } #[inline] - fn lt(&self, other: &*const T) -> bool { *self < *other } + fn lt(&self, other: &*const T) -> bool { + *self < *other + } #[inline] - fn le(&self, other: &*const T) -> bool { *self <= *other } + fn le(&self, other: &*const T) -> bool { + *self <= *other + } #[inline] - fn gt(&self, other: &*const T) -> bool { *self > *other } + fn gt(&self, other: &*const T) -> bool { + *self > *other + } #[inline] - fn ge(&self, other: &*const T) -> bool { *self >= *other } + fn ge(&self, other: &*const T) -> bool { + *self >= *other + } } diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs index d42b673ff6596..d7b351f13458a 100644 --- a/src/libcore/ptr/mod.rs +++ b/src/libcore/ptr/mod.rs @@ -69,11 +69,11 @@ #![stable(feature = "rust1", since = "1.0.0")] -use crate::intrinsics; +use crate::cmp::Ordering; use crate::fmt; use crate::hash; +use crate::intrinsics; use crate::mem::{self, MaybeUninit}; -use crate::cmp::Ordering; #[stable(feature = "rust1", since = "1.0.0")] pub use crate::intrinsics::copy_nonoverlapping; diff --git a/src/libcore/ptr/mut_ptr.rs b/src/libcore/ptr/mut_ptr.rs index fd5decbd7eac5..b3bb2f179b17e 100644 --- a/src/libcore/ptr/mut_ptr.rs +++ b/src/libcore/ptr/mut_ptr.rs @@ -1,6 +1,6 @@ -use crate::cmp::Ordering::{self, Less, Equal, Greater}; -use crate::intrinsics; use super::*; +use crate::cmp::Ordering::{self, Equal, Greater, Less}; +use crate::intrinsics; // ignore-tidy-undocumented-unsafe @@ -148,8 +148,8 @@ impl *mut T { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub unsafe fn offset(self, count: isize) -> *mut T - where - T: Sized, + where + T: Sized, { intrinsics::offset(self, count) as *mut T } @@ -205,8 +205,8 @@ impl *mut T { #[stable(feature = "ptr_wrapping_offset", since = "1.16.0")] #[inline] pub fn wrapping_offset(self, count: isize) -> *mut T - where - T: Sized, + where + T: Sized, { unsafe { intrinsics::arith_offset(self, count) as *mut T } } @@ -322,8 +322,8 @@ impl *mut T { #[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "41079")] #[inline] pub const unsafe fn offset_from(self, origin: *const T) -> isize - where - T: Sized, + where + T: Sized, { (self as *const T).offset_from(origin) } @@ -365,8 +365,8 @@ impl *mut T { #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")] #[inline] pub fn wrapping_offset_from(self, origin: *const T) -> isize - where - T: Sized, + where + T: Sized, { (self as *const T).wrapping_offset_from(origin) } @@ -425,8 +425,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn add(self, count: usize) -> Self - where - T: Sized, + where + T: Sized, { self.offset(count as isize) } @@ -486,8 +486,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn sub(self, count: usize) -> Self - where - T: Sized, + where + T: Sized, { self.offset((count as isize).wrapping_neg()) } @@ -541,8 +541,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub fn wrapping_add(self, count: usize) -> Self - where - T: Sized, + where + T: Sized, { self.wrapping_offset(count as isize) } @@ -596,8 +596,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub fn wrapping_sub(self, count: usize) -> Self - where - T: Sized, + where + T: Sized, { self.wrapping_offset((count as isize).wrapping_neg()) } @@ -611,8 +611,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn read(self) -> T - where - T: Sized, + where + T: Sized, { read(self) } @@ -630,8 +630,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn read_volatile(self) -> T - where - T: Sized, + where + T: Sized, { read_volatile(self) } @@ -647,8 +647,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn read_unaligned(self) -> T - where - T: Sized, + where + T: Sized, { read_unaligned(self) } @@ -664,8 +664,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn copy_to(self, dest: *mut T, count: usize) - where - T: Sized, + where + T: Sized, { copy(self, dest, count) } @@ -681,8 +681,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) - where - T: Sized, + where + T: Sized, { copy_nonoverlapping(self, dest, count) } @@ -698,8 +698,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn copy_from(self, src: *const T, count: usize) - where - T: Sized, + where + T: Sized, { copy(src, self, count) } @@ -715,8 +715,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn copy_from_nonoverlapping(self, src: *const T, count: usize) - where - T: Sized, + where + T: Sized, { copy_nonoverlapping(src, self, count) } @@ -741,8 +741,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn write(self, val: T) - where - T: Sized, + where + T: Sized, { write(self, val) } @@ -756,8 +756,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn write_bytes(self, val: u8, count: usize) - where - T: Sized, + where + T: Sized, { write_bytes(self, val, count) } @@ -775,8 +775,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn write_volatile(self, val: T) - where - T: Sized, + where + T: Sized, { write_volatile(self, val) } @@ -792,8 +792,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn write_unaligned(self, val: T) - where - T: Sized, + where + T: Sized, { write_unaligned(self, val) } @@ -807,8 +807,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn replace(self, src: T) -> T - where - T: Sized, + where + T: Sized, { replace(self, src) } @@ -823,8 +823,8 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn swap(self, with: *mut T) - where - T: Sized, + where + T: Sized, { swap(self, with) } @@ -870,8 +870,8 @@ impl *mut T { /// ``` #[stable(feature = "align_offset", since = "1.36.0")] pub fn align_offset(self, align: usize) -> usize - where - T: Sized, + where + T: Sized, { if !align.is_power_of_two() { panic!("align_offset: align is not a power-of-two"); @@ -884,7 +884,9 @@ impl *mut T { #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for *mut T { #[inline] - fn eq(&self, other: &*mut T) -> bool { *self == *other } + fn eq(&self, other: &*mut T) -> bool { + *self == *other + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -912,14 +914,22 @@ impl PartialOrd for *mut T { } #[inline] - fn lt(&self, other: &*mut T) -> bool { *self < *other } + fn lt(&self, other: &*mut T) -> bool { + *self < *other + } #[inline] - fn le(&self, other: &*mut T) -> bool { *self <= *other } + fn le(&self, other: &*mut T) -> bool { + *self <= *other + } #[inline] - fn gt(&self, other: &*mut T) -> bool { *self > *other } + fn gt(&self, other: &*mut T) -> bool { + *self > *other + } #[inline] - fn ge(&self, other: &*mut T) -> bool { *self >= *other } + fn ge(&self, other: &*mut T) -> bool { + *self >= *other + } } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index fb4dc62d8c176..ce4c8995a3c48 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -283,7 +283,7 @@ impl Result { pub fn is_ok(&self) -> bool { match *self { Ok(_) => true, - Err(_) => false + Err(_) => false, } } @@ -328,10 +328,13 @@ impl Result { #[must_use] #[inline] #[unstable(feature = "option_result_contains", issue = "62358")] - pub fn contains(&self, x: &U) -> bool where U: PartialEq { + pub fn contains(&self, x: &U) -> bool + where + U: PartialEq, + { match self { Ok(y) => x == y, - Err(_) => false + Err(_) => false, } } @@ -354,10 +357,13 @@ impl Result { #[must_use] #[inline] #[unstable(feature = "result_contains_err", issue = "62358")] - pub fn contains_err(&self, f: &F) -> bool where F: PartialEq { + pub fn contains_err(&self, f: &F) -> bool + where + F: PartialEq, + { match self { Ok(_) => false, - Err(e) => f == e + Err(e) => f == e, } } @@ -387,7 +393,7 @@ impl Result { #[stable(feature = "rust1", since = "1.0.0")] pub fn ok(self) -> Option { match self { - Ok(x) => Some(x), + Ok(x) => Some(x), Err(_) => None, } } @@ -414,7 +420,7 @@ impl Result { #[stable(feature = "rust1", since = "1.0.0")] pub fn err(self) -> Option { match self { - Ok(_) => None, + Ok(_) => None, Err(x) => Some(x), } } @@ -507,10 +513,10 @@ impl Result { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn map U>(self, op: F) -> Result { + pub fn map U>(self, op: F) -> Result { match self { Ok(t) => Ok(op(t)), - Err(e) => Err(e) + Err(e) => Err(e), } } @@ -591,10 +597,10 @@ impl Result { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn map_err F>(self, op: O) -> Result { + pub fn map_err F>(self, op: O) -> Result { match self { Ok(t) => Ok(t), - Err(e) => Err(op(e)) + Err(e) => Err(op(e)), } } @@ -813,7 +819,7 @@ impl Result { pub fn unwrap_or(self, optb: T) -> T { match self { Ok(t) => t, - Err(_) => optb + Err(_) => optb, } } @@ -838,7 +844,7 @@ impl Result { pub fn unwrap_or_else T>(self, op: F) -> T { match self { Ok(t) => t, - Err(e) => op(e) + Err(e) => op(e), } } } @@ -923,7 +929,6 @@ impl Result<&mut T, E> { } } - impl Result { /// Unwraps a result, yielding the content of an [`Ok`]. /// @@ -1100,8 +1105,7 @@ impl Result { /// /// Leaves the original `Result` in-place, creating a new one containing a reference to the /// `Err` type's `Deref::Target` type. - pub fn as_deref_err(&self) -> Result<&T, &E::Target> - { + pub fn as_deref_err(&self) -> Result<&T, &E::Target> { self.as_ref().map_err(|e| e.deref()) } } @@ -1112,8 +1116,7 @@ impl Result { /// /// Leaves the original `Result` in-place, creating a new one containing a reference to both /// the `Ok` and `Err` types' `Deref::Target` types. - pub fn as_deref(&self) -> Result<&T::Target, &E::Target> - { + pub fn as_deref(&self) -> Result<&T::Target, &E::Target> { self.as_ref().map(|t| t.deref()).map_err(|e| e.deref()) } } @@ -1135,8 +1138,7 @@ impl Result { /// /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to /// the `Err` type's `Deref::Target` type. - pub fn as_deref_mut_err(&mut self) -> Result<&mut T, &mut E::Target> - { + pub fn as_deref_mut_err(&mut self) -> Result<&mut T, &mut E::Target> { self.as_mut().map_err(|e| e.deref_mut()) } } @@ -1148,8 +1150,7 @@ impl Result { /// /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to /// both the `Ok` and `Err` types' `Deref::Target` types. - pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E::Target> - { + pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E::Target> { self.as_mut().map(|t| t.deref_mut()).map_err(|e| e.deref_mut()) } } @@ -1212,7 +1213,6 @@ impl Clone for Result { } } - #[stable(feature = "rust1", since = "1.0.0")] impl IntoIterator for Result { type Item = T; @@ -1276,17 +1276,21 @@ impl<'a, T, E> IntoIterator for &'a mut Result { /// [`Result::iter`]: enum.Result.html#method.iter #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] -pub struct Iter<'a, T: 'a> { inner: Option<&'a T> } +pub struct Iter<'a, T: 'a> { + inner: Option<&'a T>, +} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Iterator for Iter<'a, T> { type Item = &'a T; #[inline] - fn next(&mut self) -> Option<&'a T> { self.inner.take() } + fn next(&mut self) -> Option<&'a T> { + self.inner.take() + } #[inline] fn size_hint(&self) -> (usize, Option) { - let n = if self.inner.is_some() {1} else {0}; + let n = if self.inner.is_some() { 1 } else { 0 }; (n, Some(n)) } } @@ -1294,7 +1298,9 @@ impl<'a, T> Iterator for Iter<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> DoubleEndedIterator for Iter<'a, T> { #[inline] - fn next_back(&mut self) -> Option<&'a T> { self.inner.take() } + fn next_back(&mut self) -> Option<&'a T> { + self.inner.take() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1309,7 +1315,9 @@ unsafe impl TrustedLen for Iter<'_, A> {} #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Iter<'_, T> { #[inline] - fn clone(&self) -> Self { Iter { inner: self.inner } } + fn clone(&self) -> Self { + Iter { inner: self.inner } + } } /// An iterator over a mutable reference to the [`Ok`] variant of a [`Result`]. @@ -1321,17 +1329,21 @@ impl Clone for Iter<'_, T> { /// [`Result::iter_mut`]: enum.Result.html#method.iter_mut #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] -pub struct IterMut<'a, T: 'a> { inner: Option<&'a mut T> } +pub struct IterMut<'a, T: 'a> { + inner: Option<&'a mut T>, +} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Iterator for IterMut<'a, T> { type Item = &'a mut T; #[inline] - fn next(&mut self) -> Option<&'a mut T> { self.inner.take() } + fn next(&mut self) -> Option<&'a mut T> { + self.inner.take() + } #[inline] fn size_hint(&self) -> (usize, Option) { - let n = if self.inner.is_some() {1} else {0}; + let n = if self.inner.is_some() { 1 } else { 0 }; (n, Some(n)) } } @@ -1339,7 +1351,9 @@ impl<'a, T> Iterator for IterMut<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { #[inline] - fn next_back(&mut self) -> Option<&'a mut T> { self.inner.take() } + fn next_back(&mut self) -> Option<&'a mut T> { + self.inner.take() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1364,17 +1378,21 @@ unsafe impl TrustedLen for IterMut<'_, A> {} /// [`IntoIterator`]: ../iter/trait.IntoIterator.html #[derive(Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] -pub struct IntoIter { inner: Option } +pub struct IntoIter { + inner: Option, +} #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for IntoIter { type Item = T; #[inline] - fn next(&mut self) -> Option { self.inner.take() } + fn next(&mut self) -> Option { + self.inner.take() + } #[inline] fn size_hint(&self) -> (usize, Option) { - let n = if self.inner.is_some() {1} else {0}; + let n = if self.inner.is_some() { 1 } else { 0 }; (n, Some(n)) } } @@ -1382,7 +1400,9 @@ impl Iterator for IntoIter { #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for IntoIter { #[inline] - fn next_back(&mut self) -> Option { self.inner.take() } + fn next_back(&mut self) -> Option { + self.inner.take() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1443,7 +1463,7 @@ impl> FromIterator> for Result { /// Since the third element caused an underflow, no further elements were taken, /// so the final value of `shared` is 6 (= `3 + 2 + 1`), not 16. #[inline] - fn from_iter>>(iter: I) -> Result { + fn from_iter>>(iter: I) -> Result { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. @@ -1452,7 +1472,7 @@ impl> FromIterator> for Result { } #[unstable(feature = "try_trait", issue = "42327")] -impl ops::Try for Result { +impl ops::Try for Result { type Ok = T; type Error = E; diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 68e12e877893d..5ddf5d48965d5 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -23,23 +23,26 @@ // * The `raw` and `bytes` submodules. // * Boilerplate trait implementations. -use crate::cmp::Ordering::{self, Less, Equal, Greater}; use crate::cmp; +use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::fmt; -use crate::intrinsics::{assume, exact_div, unchecked_sub, is_aligned_and_not_null}; +use crate::intrinsics::{assume, exact_div, is_aligned_and_not_null, unchecked_sub}; use crate::isize; use crate::iter::*; -use crate::ops::{FnMut, Range, self}; +use crate::marker::{self, Copy, Send, Sized, Sync}; +use crate::mem; +use crate::ops::{self, FnMut, Range}; use crate::option::Option; use crate::option::Option::{None, Some}; -use crate::result::Result; -use crate::result::Result::{Ok, Err}; use crate::ptr; -use crate::mem; -use crate::marker::{Copy, Send, Sync, Sized, self}; +use crate::result::Result; +use crate::result::Result::{Err, Ok}; -#[unstable(feature = "slice_internals", issue = "none", - reason = "exposed from core to be reused in std; use the memchr crate")] +#[unstable( + feature = "slice_internals", + issue = "none", + reason = "exposed from core to be reused in std; use the memchr crate" +)] /// Pure rust memchr implementation, taken from rust-memchr pub mod memchr; @@ -68,9 +71,7 @@ impl [T] { #[allow(unused_attributes)] #[allow_internal_unstable(const_fn_union)] pub const fn len(&self) -> usize { - unsafe { - crate::ptr::Repr { rust: self }.raw.len - } + unsafe { crate::ptr::Repr { rust: self }.raw.len } } /// Returns `true` if the slice has a length of 0. @@ -158,7 +159,9 @@ impl [T] { #[stable(feature = "slice_splits", since = "1.5.0")] #[inline] pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> { - if self.is_empty() { None } else { + if self.is_empty() { + None + } else { let split = self.split_at_mut(1); Some((&mut split.0[0], split.1)) } @@ -201,11 +204,12 @@ impl [T] { #[inline] pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> { let len = self.len(); - if len == 0 { None } else { + if len == 0 { + None + } else { let split = self.split_at_mut(len - 1); Some((&mut split.1[0], split.0)) } - } /// Returns the last element of the slice, or `None` if it is empty. @@ -265,7 +269,8 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn get(&self, index: I) -> Option<&I::Output> - where I: SliceIndex + where + I: SliceIndex, { index.get(self) } @@ -288,7 +293,8 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn get_mut(&mut self, index: I) -> Option<&mut I::Output> - where I: SliceIndex + where + I: SliceIndex, { index.get_mut(self) } @@ -316,7 +322,8 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub unsafe fn get_unchecked(&self, index: I) -> &I::Output - where I: SliceIndex + where + I: SliceIndex, { index.get_unchecked(self) } @@ -346,7 +353,8 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub unsafe fn get_unchecked_mut(&mut self, index: I) -> &mut I::Output - where I: SliceIndex + where + I: SliceIndex, { index.get_unchecked_mut(self) } @@ -549,8 +557,7 @@ impl [T] { // will be, when the length is odd -- so there's no way of emitting // pre- and postludes to use fully-aligned SIMD in the middle.) - let fast_unaligned = - cfg!(any(target_arch = "x86", target_arch = "x86_64")); + let fast_unaligned = cfg!(any(target_arch = "x86", target_arch = "x86_64")); if fast_unaligned && mem::size_of::() == 1 { // Use the llvm.bswap intrinsic to reverse u8s in a usize @@ -621,11 +628,7 @@ impl [T] { ptr.add(self.len()) }; - Iter { - ptr, - end, - _marker: marker::PhantomData - } + Iter { ptr, end, _marker: marker::PhantomData } } } @@ -653,11 +656,7 @@ impl [T] { ptr.add(self.len()) }; - IterMut { - ptr, - end, - _marker: marker::PhantomData - } + IterMut { ptr, end, _marker: marker::PhantomData } } } @@ -1081,8 +1080,7 @@ impl [T] { unsafe { assert!(mid <= len); - (from_raw_parts_mut(ptr, mid), - from_raw_parts_mut(ptr.add(mid), len - mid)) + (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) } } @@ -1129,13 +1127,10 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn split(&self, pred: F) -> Split<'_, T, F> - where F: FnMut(&T) -> bool + where + F: FnMut(&T) -> bool, { - Split { - v: self, - pred, - finished: false - } + Split { v: self, pred, finished: false } } /// Returns an iterator over mutable subslices separated by elements that @@ -1154,7 +1149,8 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn split_mut(&mut self, pred: F) -> SplitMut<'_, T, F> - where F: FnMut(&T) -> bool + where + F: FnMut(&T) -> bool, { SplitMut { v: self, pred, finished: false } } @@ -1189,7 +1185,8 @@ impl [T] { #[stable(feature = "slice_rsplit", since = "1.27.0")] #[inline] pub fn rsplit(&self, pred: F) -> RSplit<'_, T, F> - where F: FnMut(&T) -> bool + where + F: FnMut(&T) -> bool, { RSplit { inner: self.split(pred) } } @@ -1214,7 +1211,8 @@ impl [T] { #[stable(feature = "slice_rsplit", since = "1.27.0")] #[inline] pub fn rsplit_mut(&mut self, pred: F) -> RSplitMut<'_, T, F> - where F: FnMut(&T) -> bool + where + F: FnMut(&T) -> bool, { RSplitMut { inner: self.split_mut(pred) } } @@ -1241,14 +1239,10 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn splitn(&self, n: usize, pred: F) -> SplitN<'_, T, F> - where F: FnMut(&T) -> bool + where + F: FnMut(&T) -> bool, { - SplitN { - inner: GenericSplitN { - iter: self.split(pred), - count: n - } - } + SplitN { inner: GenericSplitN { iter: self.split(pred), count: n } } } /// Returns an iterator over subslices separated by elements that match @@ -1271,14 +1265,10 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn splitn_mut(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F> - where F: FnMut(&T) -> bool + where + F: FnMut(&T) -> bool, { - SplitNMut { - inner: GenericSplitN { - iter: self.split_mut(pred), - count: n - } - } + SplitNMut { inner: GenericSplitN { iter: self.split_mut(pred), count: n } } } /// Returns an iterator over subslices separated by elements that match @@ -1304,14 +1294,10 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn rsplitn(&self, n: usize, pred: F) -> RSplitN<'_, T, F> - where F: FnMut(&T) -> bool + where + F: FnMut(&T) -> bool, { - RSplitN { - inner: GenericSplitN { - iter: self.rsplit(pred), - count: n - } - } + RSplitN { inner: GenericSplitN { iter: self.rsplit(pred), count: n } } } /// Returns an iterator over subslices separated by elements that match @@ -1335,14 +1321,10 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn rsplitn_mut(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F> - where F: FnMut(&T) -> bool + where + F: FnMut(&T) -> bool, { - RSplitNMut { - inner: GenericSplitN { - iter: self.rsplit_mut(pred), - count: n - } - } + RSplitNMut { inner: GenericSplitN { iter: self.rsplit_mut(pred), count: n } } } /// Returns `true` if the slice contains an element with the given value. @@ -1365,7 +1347,8 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains(&self, x: &T) -> bool - where T: PartialEq + where + T: PartialEq, { x.slice_contains(self) } @@ -1392,7 +1375,8 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn starts_with(&self, needle: &[T]) -> bool - where T: PartialEq + where + T: PartialEq, { let n = needle.len(); self.len() >= n && needle == &self[..n] @@ -1420,10 +1404,11 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn ends_with(&self, needle: &[T]) -> bool - where T: PartialEq + where + T: PartialEq, { let (m, n) = (self.len(), needle.len()); - m >= n && needle == &self[m-n..] + m >= n && needle == &self[m - n..] } /// Binary searches this sorted slice for a given element. @@ -1462,7 +1447,8 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn binary_search(&self, x: &T) -> Result - where T: Ord + where + T: Ord, { self.binary_search_by(|p| p.cmp(x)) } @@ -1502,7 +1488,8 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result - where F: FnMut(&'a T) -> Ordering + where + F: FnMut(&'a T) -> Ordering, { let s = self; let mut size = s.len(); @@ -1523,7 +1510,6 @@ impl [T] { // base is always in [0, size) because base <= mid. let cmp = f(unsafe { s.get_unchecked(base) }); if cmp == Equal { Ok(base) } else { Err(base + (cmp == Less) as usize) } - } /// Binary searches this sorted slice with a key extraction function. @@ -1560,8 +1546,9 @@ impl [T] { #[stable(feature = "slice_binary_search_by_key", since = "1.10.0")] #[inline] pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result - where F: FnMut(&'a T) -> B, - B: Ord + where + F: FnMut(&'a T) -> B, + B: Ord, { self.binary_search_by(|k| f(k).cmp(b)) } @@ -1595,7 +1582,8 @@ impl [T] { #[stable(feature = "sort_unstable", since = "1.20.0")] #[inline] pub fn sort_unstable(&mut self) - where T: Ord + where + T: Ord, { sort::quicksort(self, |a, b| a.lt(b)); } @@ -1649,7 +1637,8 @@ impl [T] { #[stable(feature = "sort_unstable", since = "1.20.0")] #[inline] pub fn sort_unstable_by(&mut self, mut compare: F) - where F: FnMut(&T, &T) -> Ordering + where + F: FnMut(&T, &T) -> Ordering, { sort::quicksort(self, |a, b| compare(a, b) == Ordering::Less); } @@ -1686,7 +1675,9 @@ impl [T] { #[stable(feature = "sort_unstable", since = "1.20.0")] #[inline] pub fn sort_unstable_by_key(&mut self, mut f: F) - where F: FnMut(&T) -> K, K: Ord + where + F: FnMut(&T) -> K, + K: Ord, { sort::quicksort(self, |a, b| f(a).lt(&f(b))); } @@ -1732,7 +1723,8 @@ impl [T] { #[unstable(feature = "slice_partition_at_index", issue = "55300")] #[inline] pub fn partition_at_index(&mut self, index: usize) -> (&mut [T], &mut T, &mut [T]) - where T: Ord + where + T: Ord, { let mut f = |a: &T, b: &T| a.lt(b); sort::partition_at_index(self, index, &mut f) @@ -1780,9 +1772,13 @@ impl [T] { /// ``` #[unstable(feature = "slice_partition_at_index", issue = "55300")] #[inline] - pub fn partition_at_index_by(&mut self, index: usize, mut compare: F) - -> (&mut [T], &mut T, &mut [T]) - where F: FnMut(&T, &T) -> Ordering + pub fn partition_at_index_by( + &mut self, + index: usize, + mut compare: F, + ) -> (&mut [T], &mut T, &mut [T]) + where + F: FnMut(&T, &T) -> Ordering, { let mut f = |a: &T, b: &T| compare(a, b) == Less; sort::partition_at_index(self, index, &mut f) @@ -1830,9 +1826,14 @@ impl [T] { /// ``` #[unstable(feature = "slice_partition_at_index", issue = "55300")] #[inline] - pub fn partition_at_index_by_key(&mut self, index: usize, mut f: F) - -> (&mut [T], &mut T, &mut [T]) - where F: FnMut(&T) -> K, K: Ord + pub fn partition_at_index_by_key( + &mut self, + index: usize, + mut f: F, + ) -> (&mut [T], &mut T, &mut [T]) + where + F: FnMut(&T) -> K, + K: Ord, { let mut g = |a: &T, b: &T| f(a).lt(&f(b)); sort::partition_at_index(self, index, &mut g) @@ -1861,7 +1862,8 @@ impl [T] { #[unstable(feature = "slice_partition_dedup", issue = "54279")] #[inline] pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T]) - where T: PartialEq + where + T: PartialEq, { self.partition_dedup_by(|a, b| a == b) } @@ -1894,7 +1896,8 @@ impl [T] { #[unstable(feature = "slice_partition_dedup", issue = "54279")] #[inline] pub fn partition_dedup_by(&mut self, mut same_bucket: F) -> (&mut [T], &mut [T]) - where F: FnMut(&mut T, &mut T) -> bool + where + F: FnMut(&mut T, &mut T) -> bool, { // Although we have a mutable reference to `self`, we cannot make // *arbitrary* changes. The `same_bucket` calls could panic, so we @@ -1955,7 +1958,7 @@ impl [T] { let len = self.len(); if len <= 1 { - return (self, &mut []) + return (self, &mut []); } let ptr = self.as_mut_ptr(); @@ -2004,8 +2007,9 @@ impl [T] { #[unstable(feature = "slice_partition_dedup", issue = "54279")] #[inline] pub fn partition_dedup_by_key(&mut self, mut key: F) -> (&mut [T], &mut [T]) - where F: FnMut(&mut T) -> K, - K: PartialEq, + where + F: FnMut(&mut T) -> K, + K: PartialEq, { self.partition_dedup_by(|a, b| key(a) == key(b)) } @@ -2148,9 +2152,11 @@ impl [T] { /// [`copy_from_slice`]: #method.copy_from_slice /// [`split_at_mut`]: #method.split_at_mut #[stable(feature = "clone_from_slice", since = "1.7.0")] - pub fn clone_from_slice(&mut self, src: &[T]) where T: Clone { - assert!(self.len() == src.len(), - "destination and source slices have different lengths"); + pub fn clone_from_slice(&mut self, src: &[T]) + where + T: Clone, + { + assert!(self.len() == src.len(), "destination and source slices have different lengths"); // NOTE: We need to explicitly slice them to the same length // for bounds checking to be elided, and the optimizer will // generate memcpy for simple cases (for example T = u8). @@ -2159,7 +2165,6 @@ impl [T] { for i in 0..len { self[i].clone_from(&src[i]); } - } /// Copies all elements from `src` into `self`, using a memcpy. @@ -2217,12 +2222,13 @@ impl [T] { /// [`clone_from_slice`]: #method.clone_from_slice /// [`split_at_mut`]: #method.split_at_mut #[stable(feature = "copy_from_slice", since = "1.9.0")] - pub fn copy_from_slice(&mut self, src: &[T]) where T: Copy { - assert_eq!(self.len(), src.len(), - "destination and source slices have different lengths"); + pub fn copy_from_slice(&mut self, src: &[T]) + where + T: Copy, + { + assert_eq!(self.len(), src.len(), "destination and source slices have different lengths"); unsafe { - ptr::copy_nonoverlapping( - src.as_ptr(), self.as_mut_ptr(), self.len()); + ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), self.len()); } } @@ -2257,15 +2263,15 @@ impl [T] { { let src_start = match src.start_bound() { ops::Bound::Included(&n) => n, - ops::Bound::Excluded(&n) => n - .checked_add(1) - .unwrap_or_else(|| slice_index_overflow_fail()), + ops::Bound::Excluded(&n) => { + n.checked_add(1).unwrap_or_else(|| slice_index_overflow_fail()) + } ops::Bound::Unbounded => 0, }; let src_end = match src.end_bound() { - ops::Bound::Included(&n) => n - .checked_add(1) - .unwrap_or_else(|| slice_index_overflow_fail()), + ops::Bound::Included(&n) => { + n.checked_add(1).unwrap_or_else(|| slice_index_overflow_fail()) + } ops::Bound::Excluded(&n) => n, ops::Bound::Unbounded => self.len(), }; @@ -2274,11 +2280,7 @@ impl [T] { let count = src_end - src_start; assert!(dest <= self.len() - count, "dest is out of bounds"); unsafe { - ptr::copy( - self.as_ptr().add(src_start), - self.as_mut_ptr().add(dest), - count, - ); + ptr::copy(self.as_ptr().add(src_start), self.as_mut_ptr().add(dest), count); } } @@ -2331,11 +2333,9 @@ impl [T] { /// [`split_at_mut`]: #method.split_at_mut #[stable(feature = "swap_with_slice", since = "1.27.0")] pub fn swap_with_slice(&mut self, other: &mut [T]) { - assert!(self.len() == other.len(), - "destination and source slices have different lengths"); + assert!(self.len() == other.len(), "destination and source slices have different lengths"); unsafe { - ptr::swap_nonoverlapping( - self.as_mut_ptr(), other.as_mut_ptr(), self.len()); + ptr::swap_nonoverlapping(self.as_mut_ptr(), other.as_mut_ptr(), self.len()); } } @@ -2366,8 +2366,12 @@ impl [T] { // We should still make this `const fn` (and revert to recursive algorithm if we do) // because relying on llvm to consteval all this is… well, it makes me uncomfortable. let (ctz_a, mut ctz_b) = unsafe { - if a == 0 { return b; } - if b == 0 { return a; } + if a == 0 { + return b; + } + if b == 0 { + return a; + } (intrinsics::cttz_nonzero(a), intrinsics::cttz_nonzero(b)) }; let k = ctz_a.min(ctz_b); @@ -2448,9 +2452,11 @@ impl [T] { let (left, rest) = self.split_at(offset); // now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay let (us_len, ts_len) = rest.align_to_offsets::(); - (left, - from_raw_parts(rest.as_ptr() as *const U, us_len), - from_raw_parts(rest.as_ptr().add(rest.len() - ts_len), ts_len)) + ( + left, + from_raw_parts(rest.as_ptr() as *const U, us_len), + from_raw_parts(rest.as_ptr().add(rest.len() - ts_len), ts_len), + ) } } @@ -2503,9 +2509,11 @@ impl [T] { // now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay let (us_len, ts_len) = rest.align_to_offsets::(); let mut_ptr = rest.as_mut_ptr(); - (left, - from_raw_parts_mut(mut_ptr as *mut U, us_len), - from_raw_parts_mut(mut_ptr.add(rest.len() - ts_len), ts_len)) + ( + left, + from_raw_parts_mut(mut_ptr as *mut U, us_len), + from_raw_parts_mut(mut_ptr.add(rest.len() - ts_len), ts_len), + ) } } @@ -2549,7 +2557,7 @@ impl [T] { #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] pub fn is_sorted_by(&self, mut compare: F) -> bool where - F: FnMut(&T, &T) -> Option + F: FnMut(&T, &T) -> Option, { self.iter().is_sorted_by(|a, b| compare(*a, *b)) } @@ -2575,7 +2583,7 @@ impl [T] { pub fn is_sorted_by_key(&self, f: F) -> bool where F: FnMut(&T) -> K, - K: PartialOrd + K: PartialOrd, { self.iter().is_sorted_by_key(f) } @@ -2598,10 +2606,7 @@ impl [u8] { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool { - self.len() == other.len() && - self.iter().zip(other).all(|(a, b)| { - a.eq_ignore_ascii_case(b) - }) + self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a.eq_ignore_ascii_case(b)) } /// Converts this slice to its ASCII upper case equivalent in-place. @@ -2637,12 +2642,12 @@ impl [u8] { byte.make_ascii_lowercase(); } } - } #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index for [T] - where I: SliceIndex<[T]> +where + I: SliceIndex<[T]>, { type Output = I::Output; @@ -2654,7 +2659,8 @@ impl ops::Index for [T] #[stable(feature = "rust1", since = "1.0.0")] impl ops::IndexMut for [T] - where I: SliceIndex<[T]> +where + I: SliceIndex<[T]>, { #[inline] fn index_mut(&mut self, index: I) -> &mut I::Output { @@ -2704,17 +2710,14 @@ mod private_slice_index { /// A helper trait used for indexing operations. #[stable(feature = "slice_get_slice", since = "1.28.0")] #[rustc_on_unimplemented( + on(T = "str", label = "string indices are ranges of `usize`",), on( - T = "str", - label = "string indices are ranges of `usize`", - ), - on( - all(any(T = "str", T = "&str", T = "std::string::String"), _Self="{integer}"), - note="you can use `.chars().nth()` or `.bytes().nth()` + all(any(T = "str", T = "&str", T = "std::string::String"), _Self = "{integer}"), + note = "you can use `.chars().nth()` or `.bytes().nth()` see chapter in The Book " ), message = "the type `{T}` cannot be indexed by `{Self}`", - label = "slice indices are of type `usize` or ranges of `usize`", + label = "slice indices are of type `usize` or ranges of `usize`" )] pub trait SliceIndex: private_slice_index::Sealed { /// The output type returned by methods. @@ -2764,24 +2767,12 @@ impl SliceIndex<[T]> for usize { #[inline] fn get(self, slice: &[T]) -> Option<&T> { - if self < slice.len() { - unsafe { - Some(self.get_unchecked(slice)) - } - } else { - None - } + if self < slice.len() { unsafe { Some(self.get_unchecked(slice)) } } else { None } } #[inline] fn get_mut(self, slice: &mut [T]) -> Option<&mut T> { - if self < slice.len() { - unsafe { - Some(self.get_unchecked_mut(slice)) - } - } else { - None - } + if self < slice.len() { unsafe { Some(self.get_unchecked_mut(slice)) } } else { None } } #[inline] @@ -2808,7 +2799,7 @@ impl SliceIndex<[T]> for usize { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -impl SliceIndex<[T]> for ops::Range { +impl SliceIndex<[T]> for ops::Range { type Output = [T]; #[inline] @@ -2816,9 +2807,7 @@ impl SliceIndex<[T]> for ops::Range { if self.start > self.end || self.end > slice.len() { None } else { - unsafe { - Some(self.get_unchecked(slice)) - } + unsafe { Some(self.get_unchecked(slice)) } } } @@ -2827,9 +2816,7 @@ impl SliceIndex<[T]> for ops::Range { if self.start > self.end || self.end > slice.len() { None } else { - unsafe { - Some(self.get_unchecked_mut(slice)) - } + unsafe { Some(self.get_unchecked_mut(slice)) } } } @@ -2850,9 +2837,7 @@ impl SliceIndex<[T]> for ops::Range { } else if self.end > slice.len() { slice_index_len_fail(self.end, slice.len()); } - unsafe { - self.get_unchecked(slice) - } + unsafe { self.get_unchecked(slice) } } #[inline] @@ -2862,9 +2847,7 @@ impl SliceIndex<[T]> for ops::Range { } else if self.end > slice.len() { slice_index_len_fail(self.end, slice.len()); } - unsafe { - self.get_unchecked_mut(slice) - } + unsafe { self.get_unchecked_mut(slice) } } } @@ -2973,21 +2956,26 @@ impl SliceIndex<[T]> for ops::RangeFull { } } - #[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex<[T]> for ops::RangeInclusive { type Output = [T]; #[inline] fn get(self, slice: &[T]) -> Option<&[T]> { - if *self.end() == usize::max_value() { None } - else { (*self.start()..self.end() + 1).get(slice) } + if *self.end() == usize::max_value() { + None + } else { + (*self.start()..self.end() + 1).get(slice) + } } #[inline] fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { - if *self.end() == usize::max_value() { None } - else { (*self.start()..self.end() + 1).get_mut(slice) } + if *self.end() == usize::max_value() { + None + } else { + (*self.start()..self.end() + 1).get_mut(slice) + } } #[inline] @@ -3002,13 +2990,17 @@ impl SliceIndex<[T]> for ops::RangeInclusive { #[inline] fn index(self, slice: &[T]) -> &[T] { - if *self.end() == usize::max_value() { slice_index_overflow_fail(); } + if *self.end() == usize::max_value() { + slice_index_overflow_fail(); + } (*self.start()..self.end() + 1).index(slice) } #[inline] fn index_mut(self, slice: &mut [T]) -> &mut [T] { - if *self.end() == usize::max_value() { slice_index_overflow_fail(); } + if *self.end() == usize::max_value() { + slice_index_overflow_fail(); + } (*self.start()..self.end() + 1).index_mut(slice) } } @@ -3055,13 +3047,17 @@ impl SliceIndex<[T]> for ops::RangeToInclusive { #[stable(feature = "rust1", since = "1.0.0")] impl Default for &[T] { /// Creates an empty slice. - fn default() -> Self { &[] } + fn default() -> Self { + &[] + } } #[stable(feature = "mut_slice_default", since = "1.5.0")] impl Default for &mut [T] { /// Creates a mutable empty slice. - fn default() -> Self { &mut [] } + fn default() -> Self { + &mut [] + } } // @@ -3098,7 +3094,9 @@ fn size_from_ptr(_: *const T) -> usize { macro_rules! is_empty { // The way we encode the length of a ZST iterator, this works both for ZST // and non-ZST. - ($self: ident) => {$self.ptr == $self.end} + ($self: ident) => { + $self.ptr == $self.end + }; } // To get rid of some bounds checks (see `position`), we compute the length in a somewhat // unexpected way. (Tested by `codegen/slice-position-bounds-check`.) @@ -3125,7 +3123,7 @@ macro_rules! len { // distance between them must be a multiple of pointee size unsafe { exact_div(diff, size) } } - }} + }}; } // The shared definition of the `Iter` and `IterMut` iterators @@ -3369,17 +3367,15 @@ macro_rules! iterator { pub struct Iter<'a, T: 'a> { ptr: *const T, end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that - // ptr == end is a quick test for the Iterator being empty, that works - // for both ZST and non-ZST. + // ptr == end is a quick test for the Iterator being empty, that works + // for both ZST and non-ZST. _marker: marker::PhantomData<&'a T>, } #[stable(feature = "core_impl_debug", since = "1.9.0")] impl fmt::Debug for Iter<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Iter") - .field(&self.as_slice()) - .finish() + f.debug_tuple("Iter").field(&self.as_slice()).finish() } } @@ -3419,7 +3415,7 @@ impl<'a, T> Iter<'a, T> { } } -iterator!{struct Iter -> *const T, &'a T, const, {/* no mut */}, { +iterator! {struct Iter -> *const T, &'a T, const, {/* no mut */}, { fn is_sorted_by(self, mut compare: F) -> bool where Self: Sized, @@ -3433,7 +3429,9 @@ iterator!{struct Iter -> *const T, &'a T, const, {/* no mut */}, { #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Iter<'_, T> { - fn clone(&self) -> Self { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } } + fn clone(&self) -> Self { + Iter { ptr: self.ptr, end: self.end, _marker: self._marker } + } } #[stable(feature = "slice_iter_as_ref", since = "1.13.0")] @@ -3471,17 +3469,15 @@ impl AsRef<[T]> for Iter<'_, T> { pub struct IterMut<'a, T: 'a> { ptr: *mut T, end: *mut T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that - // ptr == end is a quick test for the Iterator being empty, that works - // for both ZST and non-ZST. + // ptr == end is a quick test for the Iterator being empty, that works + // for both ZST and non-ZST. _marker: marker::PhantomData<&'a mut T>, } #[stable(feature = "core_impl_debug", since = "1.9.0")] impl fmt::Debug for IterMut<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("IterMut") - .field(&self.make_slice()) - .finish() + f.debug_tuple("IterMut").field(&self.make_slice()).finish() } } @@ -3558,7 +3554,7 @@ impl<'a, T> IterMut<'a, T> { } } -iterator!{struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}} +iterator! {struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}} /// An internal abstraction over the splitting iterators, so that /// splitn, splitn_mut etc can be implemented once. @@ -3577,41 +3573,48 @@ trait SplitIter: DoubleEndedIterator { /// [`split`]: ../../std/primitive.slice.html#method.split /// [slices]: ../../std/primitive.slice.html #[stable(feature = "rust1", since = "1.0.0")] -pub struct Split<'a, T:'a, P> where P: FnMut(&T) -> bool { +pub struct Split<'a, T: 'a, P> +where + P: FnMut(&T) -> bool, +{ v: &'a [T], pred: P, - finished: bool + finished: bool, } #[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for Split<'_, T, P> where P: FnMut(&T) -> bool { +impl fmt::Debug for Split<'_, T, P> +where + P: FnMut(&T) -> bool, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Split") - .field("v", &self.v) - .field("finished", &self.finished) - .finish() + f.debug_struct("Split").field("v", &self.v).field("finished", &self.finished).finish() } } // FIXME(#26925) Remove in favor of `#[derive(Clone)]` #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Split<'_, T, P> where P: Clone + FnMut(&T) -> bool { +impl Clone for Split<'_, T, P> +where + P: Clone + FnMut(&T) -> bool, +{ fn clone(&self) -> Self { - Split { - v: self.v, - pred: self.pred.clone(), - finished: self.finished, - } + Split { v: self.v, pred: self.pred.clone(), finished: self.finished } } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, P> Iterator for Split<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> Iterator for Split<'a, T, P> +where + P: FnMut(&T) -> bool, +{ type Item = &'a [T]; #[inline] fn next(&mut self) -> Option<&'a [T]> { - if self.finished { return None; } + if self.finished { + return None; + } match self.v.iter().position(|x| (self.pred)(x)) { None => self.finish(), @@ -3625,19 +3628,20 @@ impl<'a, T, P> Iterator for Split<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn size_hint(&self) -> (usize, Option) { - if self.finished { - (0, Some(0)) - } else { - (1, Some(self.v.len() + 1)) - } + if self.finished { (0, Some(0)) } else { (1, Some(self.v.len() + 1)) } } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, P> DoubleEndedIterator for Split<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> DoubleEndedIterator for Split<'a, T, P> +where + P: FnMut(&T) -> bool, +{ #[inline] fn next_back(&mut self) -> Option<&'a [T]> { - if self.finished { return None; } + if self.finished { + return None; + } match self.v.iter().rposition(|x| (self.pred)(x)) { None => self.finish(), @@ -3650,10 +3654,18 @@ impl<'a, T, P> DoubleEndedIterator for Split<'a, T, P> where P: FnMut(&T) -> boo } } -impl<'a, T, P> SplitIter for Split<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> SplitIter for Split<'a, T, P> +where + P: FnMut(&T) -> bool, +{ #[inline] fn finish(&mut self) -> Option<&'a [T]> { - if self.finished { None } else { self.finished = true; Some(self.v) } + if self.finished { + None + } else { + self.finished = true; + Some(self.v) + } } } @@ -3668,23 +3680,29 @@ impl FusedIterator for Split<'_, T, P> where P: FnMut(&T) -> bool {} /// [`split_mut`]: ../../std/primitive.slice.html#method.split_mut /// [slices]: ../../std/primitive.slice.html #[stable(feature = "rust1", since = "1.0.0")] -pub struct SplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool { +pub struct SplitMut<'a, T: 'a, P> +where + P: FnMut(&T) -> bool, +{ v: &'a mut [T], pred: P, - finished: bool + finished: bool, } #[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for SplitMut<'_, T, P> where P: FnMut(&T) -> bool { +impl fmt::Debug for SplitMut<'_, T, P> +where + P: FnMut(&T) -> bool, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("SplitMut") - .field("v", &self.v) - .field("finished", &self.finished) - .finish() + f.debug_struct("SplitMut").field("v", &self.v).field("finished", &self.finished).finish() } } -impl<'a, T, P> SplitIter for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> SplitIter for SplitMut<'a, T, P> +where + P: FnMut(&T) -> bool, +{ #[inline] fn finish(&mut self) -> Option<&'a mut [T]> { if self.finished { @@ -3697,14 +3715,20 @@ impl<'a, T, P> SplitIter for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, P> Iterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> Iterator for SplitMut<'a, T, P> +where + P: FnMut(&T) -> bool, +{ type Item = &'a mut [T]; #[inline] fn next(&mut self) -> Option<&'a mut [T]> { - if self.finished { return None; } + if self.finished { + return None; + } - let idx_opt = { // work around borrowck limitations + let idx_opt = { + // work around borrowck limitations let pred = &mut self.pred; self.v.iter().position(|x| (*pred)(x)) }; @@ -3732,14 +3756,18 @@ impl<'a, T, P> Iterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P> where +impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P> +where P: FnMut(&T) -> bool, { #[inline] fn next_back(&mut self) -> Option<&'a mut [T]> { - if self.finished { return None; } + if self.finished { + return None; + } - let idx_opt = { // work around borrowck limitations + let idx_opt = { + // work around borrowck limitations let pred = &mut self.pred; self.v.iter().rposition(|x| (*pred)(x)) }; @@ -3767,12 +3795,18 @@ impl FusedIterator for SplitMut<'_, T, P> where P: FnMut(&T) -> bool {} /// [slices]: ../../std/primitive.slice.html #[stable(feature = "slice_rsplit", since = "1.27.0")] #[derive(Clone)] // Is this correct, or does it incorrectly require `T: Clone`? -pub struct RSplit<'a, T:'a, P> where P: FnMut(&T) -> bool { - inner: Split<'a, T, P> +pub struct RSplit<'a, T: 'a, P> +where + P: FnMut(&T) -> bool, +{ + inner: Split<'a, T, P>, } #[stable(feature = "slice_rsplit", since = "1.27.0")] -impl fmt::Debug for RSplit<'_, T, P> where P: FnMut(&T) -> bool { +impl fmt::Debug for RSplit<'_, T, P> +where + P: FnMut(&T) -> bool, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("RSplit") .field("v", &self.inner.v) @@ -3782,7 +3816,10 @@ impl fmt::Debug for RSplit<'_, T, P> where P: FnMut(&T) -> boo } #[stable(feature = "slice_rsplit", since = "1.27.0")] -impl<'a, T, P> Iterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> Iterator for RSplit<'a, T, P> +where + P: FnMut(&T) -> bool, +{ type Item = &'a [T]; #[inline] @@ -3797,7 +3834,10 @@ impl<'a, T, P> Iterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool { } #[stable(feature = "slice_rsplit", since = "1.27.0")] -impl<'a, T, P> DoubleEndedIterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> DoubleEndedIterator for RSplit<'a, T, P> +where + P: FnMut(&T) -> bool, +{ #[inline] fn next_back(&mut self) -> Option<&'a [T]> { self.inner.next() @@ -3805,7 +3845,10 @@ impl<'a, T, P> DoubleEndedIterator for RSplit<'a, T, P> where P: FnMut(&T) -> bo } #[stable(feature = "slice_rsplit", since = "1.27.0")] -impl<'a, T, P> SplitIter for RSplit<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> SplitIter for RSplit<'a, T, P> +where + P: FnMut(&T) -> bool, +{ #[inline] fn finish(&mut self) -> Option<&'a [T]> { self.inner.finish() @@ -3823,12 +3866,18 @@ impl FusedIterator for RSplit<'_, T, P> where P: FnMut(&T) -> bool {} /// [`rsplit_mut`]: ../../std/primitive.slice.html#method.rsplit_mut /// [slices]: ../../std/primitive.slice.html #[stable(feature = "slice_rsplit", since = "1.27.0")] -pub struct RSplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool { - inner: SplitMut<'a, T, P> +pub struct RSplitMut<'a, T: 'a, P> +where + P: FnMut(&T) -> bool, +{ + inner: SplitMut<'a, T, P>, } #[stable(feature = "slice_rsplit", since = "1.27.0")] -impl fmt::Debug for RSplitMut<'_, T, P> where P: FnMut(&T) -> bool { +impl fmt::Debug for RSplitMut<'_, T, P> +where + P: FnMut(&T) -> bool, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("RSplitMut") .field("v", &self.inner.v) @@ -3838,7 +3887,10 @@ impl fmt::Debug for RSplitMut<'_, T, P> where P: FnMut(&T) -> } #[stable(feature = "slice_rsplit", since = "1.27.0")] -impl<'a, T, P> SplitIter for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> SplitIter for RSplitMut<'a, T, P> +where + P: FnMut(&T) -> bool, +{ #[inline] fn finish(&mut self) -> Option<&'a mut [T]> { self.inner.finish() @@ -3846,7 +3898,10 @@ impl<'a, T, P> SplitIter for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool { } #[stable(feature = "slice_rsplit", since = "1.27.0")] -impl<'a, T, P> Iterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> Iterator for RSplitMut<'a, T, P> +where + P: FnMut(&T) -> bool, +{ type Item = &'a mut [T]; #[inline] @@ -3861,7 +3916,8 @@ impl<'a, T, P> Iterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool { } #[stable(feature = "slice_rsplit", since = "1.27.0")] -impl<'a, T, P> DoubleEndedIterator for RSplitMut<'a, T, P> where +impl<'a, T, P> DoubleEndedIterator for RSplitMut<'a, T, P> +where P: FnMut(&T) -> bool, { #[inline] @@ -3882,15 +3938,21 @@ struct GenericSplitN { count: usize, } -impl> Iterator for GenericSplitN { +impl> Iterator for GenericSplitN { type Item = T; #[inline] fn next(&mut self) -> Option { match self.count { 0 => None, - 1 => { self.count -= 1; self.iter.finish() } - _ => { self.count -= 1; self.iter.next() } + 1 => { + self.count -= 1; + self.iter.finish() + } + _ => { + self.count -= 1; + self.iter.next() + } } } @@ -3909,16 +3971,20 @@ impl> Iterator for GenericSplitN { /// [`splitn`]: ../../std/primitive.slice.html#method.splitn /// [slices]: ../../std/primitive.slice.html #[stable(feature = "rust1", since = "1.0.0")] -pub struct SplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { - inner: GenericSplitN> +pub struct SplitN<'a, T: 'a, P> +where + P: FnMut(&T) -> bool, +{ + inner: GenericSplitN>, } #[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for SplitN<'_, T, P> where P: FnMut(&T) -> bool { +impl fmt::Debug for SplitN<'_, T, P> +where + P: FnMut(&T) -> bool, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("SplitN") - .field("inner", &self.inner) - .finish() + f.debug_struct("SplitN").field("inner", &self.inner).finish() } } @@ -3931,16 +3997,20 @@ impl fmt::Debug for SplitN<'_, T, P> where P: FnMut(&T) -> boo /// [`rsplitn`]: ../../std/primitive.slice.html#method.rsplitn /// [slices]: ../../std/primitive.slice.html #[stable(feature = "rust1", since = "1.0.0")] -pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { - inner: GenericSplitN> +pub struct RSplitN<'a, T: 'a, P> +where + P: FnMut(&T) -> bool, +{ + inner: GenericSplitN>, } #[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for RSplitN<'_, T, P> where P: FnMut(&T) -> bool { +impl fmt::Debug for RSplitN<'_, T, P> +where + P: FnMut(&T) -> bool, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("RSplitN") - .field("inner", &self.inner) - .finish() + f.debug_struct("RSplitN").field("inner", &self.inner).finish() } } @@ -3952,16 +4022,20 @@ impl fmt::Debug for RSplitN<'_, T, P> where P: FnMut(&T) -> bo /// [`splitn_mut`]: ../../std/primitive.slice.html#method.splitn_mut /// [slices]: ../../std/primitive.slice.html #[stable(feature = "rust1", since = "1.0.0")] -pub struct SplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { - inner: GenericSplitN> +pub struct SplitNMut<'a, T: 'a, P> +where + P: FnMut(&T) -> bool, +{ + inner: GenericSplitN>, } #[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for SplitNMut<'_, T, P> where P: FnMut(&T) -> bool { +impl fmt::Debug for SplitNMut<'_, T, P> +where + P: FnMut(&T) -> bool, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("SplitNMut") - .field("inner", &self.inner) - .finish() + f.debug_struct("SplitNMut").field("inner", &self.inner).finish() } } @@ -3974,24 +4048,29 @@ impl fmt::Debug for SplitNMut<'_, T, P> where P: FnMut(&T) -> /// [`rsplitn_mut`]: ../../std/primitive.slice.html#method.rsplitn_mut /// [slices]: ../../std/primitive.slice.html #[stable(feature = "rust1", since = "1.0.0")] -pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { - inner: GenericSplitN> +pub struct RSplitNMut<'a, T: 'a, P> +where + P: FnMut(&T) -> bool, +{ + inner: GenericSplitN>, } #[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for RSplitNMut<'_, T, P> where P: FnMut(&T) -> bool { +impl fmt::Debug for RSplitNMut<'_, T, P> +where + P: FnMut(&T) -> bool, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("RSplitNMut") - .field("inner", &self.inner) - .finish() + f.debug_struct("RSplitNMut").field("inner", &self.inner).finish() } } macro_rules! forward_iterator { ($name:ident: $elem:ident, $iter_of:ty) => { #[stable(feature = "rust1", since = "1.0.0")] - impl<'a, $elem, P> Iterator for $name<'a, $elem, P> where - P: FnMut(&T) -> bool + impl<'a, $elem, P> Iterator for $name<'a, $elem, P> + where + P: FnMut(&T) -> bool, { type Item = $iter_of; @@ -4007,9 +4086,8 @@ macro_rules! forward_iterator { } #[stable(feature = "fused", since = "1.26.0")] - impl<'a, $elem, P> FusedIterator for $name<'a, $elem, P> - where P: FnMut(&T) -> bool {} - } + impl<'a, $elem, P> FusedIterator for $name<'a, $elem, P> where P: FnMut(&T) -> bool {} + }; } forward_iterator! { SplitN: T, &'a [T] } @@ -4025,19 +4103,16 @@ forward_iterator! { RSplitNMut: T, &'a mut [T] } /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] -pub struct Windows<'a, T:'a> { +pub struct Windows<'a, T: 'a> { v: &'a [T], - size: usize + size: usize, } // FIXME(#26925) Remove in favor of `#[derive(Clone)]` #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Windows<'_, T> { fn clone(&self) -> Self { - Windows { - v: self.v, - size: self.size, - } + Windows { v: self.v, size: self.size } } } @@ -4079,7 +4154,7 @@ impl<'a, T> Iterator for Windows<'a, T> { None } else { let nth = &self.v[n..end]; - self.v = &self.v[n+1..]; + self.v = &self.v[n + 1..]; Some(nth) } } @@ -4102,8 +4177,8 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> { if self.size > self.v.len() { None } else { - let ret = Some(&self.v[self.v.len()-self.size..]); - self.v = &self.v[..self.v.len()-1]; + let ret = Some(&self.v[self.v.len() - self.size..]); + self.v = &self.v[..self.v.len() - 1]; ret } } @@ -4115,8 +4190,8 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> { self.v = &[]; None } else { - let ret = &self.v[end-self.size..end]; - self.v = &self.v[..end-1]; + let ret = &self.v[end - self.size..end]; + self.v = &self.v[..end - 1]; Some(ret) } } @@ -4136,7 +4211,9 @@ unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> { unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T] { from_raw_parts(self.v.as_ptr().add(i), self.size) } - fn may_have_side_effect() -> bool { false } + fn may_have_side_effect() -> bool { + false + } } /// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a @@ -4151,19 +4228,16 @@ unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> { /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] -pub struct Chunks<'a, T:'a> { +pub struct Chunks<'a, T: 'a> { v: &'a [T], - chunk_size: usize + chunk_size: usize, } // FIXME(#26925) Remove in favor of `#[derive(Clone)]` #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Chunks<'_, T> { fn clone(&self) -> Self { - Chunks { - v: self.v, - chunk_size: self.chunk_size, - } + Chunks { v: self.v, chunk_size: self.chunk_size } } } @@ -4190,7 +4264,7 @@ impl<'a, T> Iterator for Chunks<'a, T> { } else { let n = self.v.len() / self.chunk_size; let rem = self.v.len() % self.chunk_size; - let n = if rem > 0 { n+1 } else { n }; + let n = if rem > 0 { n + 1 } else { n }; (n, Some(n)) } } @@ -4281,7 +4355,9 @@ unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> { }; from_raw_parts(self.v.as_ptr().add(start), end - start) } - fn may_have_side_effect() -> bool { false } + fn may_have_side_effect() -> bool { + false + } } /// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size` @@ -4296,9 +4372,9 @@ unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> { /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] -pub struct ChunksMut<'a, T:'a> { +pub struct ChunksMut<'a, T: 'a> { v: &'a mut [T], - chunk_size: usize + chunk_size: usize, } #[stable(feature = "rust1", since = "1.0.0")] @@ -4348,7 +4424,7 @@ impl<'a, T> Iterator for ChunksMut<'a, T> { }; let tmp = mem::replace(&mut self.v, &mut []); let (head, tail) = tmp.split_at_mut(end); - let (_, nth) = head.split_at_mut(start); + let (_, nth) = head.split_at_mut(start); self.v = tail; Some(nth) } @@ -4421,7 +4497,9 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> { }; from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start) } - fn may_have_side_effect() -> bool { false } + fn may_have_side_effect() -> bool { + false + } } /// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a @@ -4438,10 +4516,10 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> { /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[stable(feature = "chunks_exact", since = "1.31.0")] -pub struct ChunksExact<'a, T:'a> { +pub struct ChunksExact<'a, T: 'a> { v: &'a [T], rem: &'a [T], - chunk_size: usize + chunk_size: usize, } impl<'a, T> ChunksExact<'a, T> { @@ -4458,11 +4536,7 @@ impl<'a, T> ChunksExact<'a, T> { #[stable(feature = "chunks_exact", since = "1.31.0")] impl Clone for ChunksExact<'_, T> { fn clone(&self) -> Self { - ChunksExact { - v: self.v, - rem: self.rem, - chunk_size: self.chunk_size, - } + ChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size } } } @@ -4560,7 +4634,9 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> { let start = i * self.chunk_size; from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) } - fn may_have_side_effect() -> bool { false } + fn may_have_side_effect() -> bool { + false + } } /// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size` @@ -4577,10 +4653,10 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> { /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[stable(feature = "chunks_exact", since = "1.31.0")] -pub struct ChunksExactMut<'a, T:'a> { +pub struct ChunksExactMut<'a, T: 'a> { v: &'a mut [T], rem: &'a mut [T], - chunk_size: usize + chunk_size: usize, } impl<'a, T> ChunksExactMut<'a, T> { @@ -4692,7 +4768,9 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> { let start = i * self.chunk_size; from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) } - fn may_have_side_effect() -> bool { false } + fn may_have_side_effect() -> bool { + false + } } /// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a @@ -4707,19 +4785,16 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> { /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] -pub struct RChunks<'a, T:'a> { +pub struct RChunks<'a, T: 'a> { v: &'a [T], - chunk_size: usize + chunk_size: usize, } // FIXME(#26925) Remove in favor of `#[derive(Clone)]` #[stable(feature = "rchunks", since = "1.31.0")] impl Clone for RChunks<'_, T> { fn clone(&self) -> Self { - RChunks { - v: self.v, - chunk_size: self.chunk_size, - } + RChunks { v: self.v, chunk_size: self.chunk_size } } } @@ -4746,7 +4821,7 @@ impl<'a, T> Iterator for RChunks<'a, T> { } else { let n = self.v.len() / self.chunk_size; let rem = self.v.len() % self.chunk_size; - let n = if rem > 0 { n+1 } else { n }; + let n = if rem > 0 { n + 1 } else { n }; (n, Some(n)) } } @@ -4840,7 +4915,9 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> { }; from_raw_parts(self.v.as_ptr().add(start), end - start) } - fn may_have_side_effect() -> bool { false } + fn may_have_side_effect() -> bool { + false + } } /// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size` @@ -4855,9 +4932,9 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> { /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] -pub struct RChunksMut<'a, T:'a> { +pub struct RChunksMut<'a, T: 'a> { v: &'a mut [T], - chunk_size: usize + chunk_size: usize, } #[stable(feature = "rchunks", since = "1.31.0")] @@ -4983,7 +5060,9 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> { }; from_raw_parts_mut(self.v.as_mut_ptr().add(start), end - start) } - fn may_have_side_effect() -> bool { false } + fn may_have_side_effect() -> bool { + false + } } /// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a @@ -5000,10 +5079,10 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> { /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] -pub struct RChunksExact<'a, T:'a> { +pub struct RChunksExact<'a, T: 'a> { v: &'a [T], rem: &'a [T], - chunk_size: usize + chunk_size: usize, } impl<'a, T> RChunksExact<'a, T> { @@ -5020,11 +5099,7 @@ impl<'a, T> RChunksExact<'a, T> { #[stable(feature = "rchunks", since = "1.31.0")] impl<'a, T> Clone for RChunksExact<'a, T> { fn clone(&self) -> RChunksExact<'a, T> { - RChunksExact { - v: self.v, - rem: self.rem, - chunk_size: self.chunk_size, - } + RChunksExact { v: self.v, rem: self.rem, chunk_size: self.chunk_size } } } @@ -5126,7 +5201,9 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> { let start = end - self.chunk_size; from_raw_parts(self.v.as_ptr().add(start), self.chunk_size) } - fn may_have_side_effect() -> bool { false } + fn may_have_side_effect() -> bool { + false + } } /// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size` @@ -5143,10 +5220,10 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> { /// [slices]: ../../std/primitive.slice.html #[derive(Debug)] #[stable(feature = "rchunks", since = "1.31.0")] -pub struct RChunksExactMut<'a, T:'a> { +pub struct RChunksExactMut<'a, T: 'a> { v: &'a mut [T], rem: &'a mut [T], - chunk_size: usize + chunk_size: usize, } impl<'a, T> RChunksExactMut<'a, T> { @@ -5263,7 +5340,9 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> { let start = end - self.chunk_size; from_raw_parts_mut(self.v.as_mut_ptr().add(start), self.chunk_size) } - fn may_have_side_effect() -> bool { false } + fn may_have_side_effect() -> bool { + false + } } // @@ -5322,8 +5401,10 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); - debug_assert!(mem::size_of::().saturating_mul(len) <= isize::MAX as usize, - "attempt to create slice covering at least half the address space"); + debug_assert!( + mem::size_of::().saturating_mul(len) <= isize::MAX as usize, + "attempt to create slice covering at least half the address space" + ); &*ptr::slice_from_raw_parts(data, len) } @@ -5360,32 +5441,31 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); - debug_assert!(mem::size_of::().saturating_mul(len) <= isize::MAX as usize, - "attempt to create slice covering at least half the address space"); + debug_assert!( + mem::size_of::().saturating_mul(len) <= isize::MAX as usize, + "attempt to create slice covering at least half the address space" + ); &mut *ptr::slice_from_raw_parts_mut(data, len) } /// Converts a reference to T into a slice of length 1 (without copying). #[stable(feature = "from_ref", since = "1.28.0")] pub fn from_ref(s: &T) -> &[T] { - unsafe { - from_raw_parts(s, 1) - } + unsafe { from_raw_parts(s, 1) } } /// Converts a reference to T into a slice of length 1 (without copying). #[stable(feature = "from_ref", since = "1.28.0")] pub fn from_mut(s: &mut T) -> &mut [T] { - unsafe { - from_raw_parts_mut(s, 1) - } + unsafe { from_raw_parts_mut(s, 1) } } // This function is public only because there is no other way to unit test heapsort. #[unstable(feature = "sort_internals", reason = "internal to sort module", issue = "none")] #[doc(hidden)] pub fn heapsort(v: &mut [T], mut is_less: F) - where F: FnMut(&T, &T) -> bool +where + F: FnMut(&T, &T) -> bool, { sort::heapsort(v, &mut is_less); } @@ -5394,7 +5474,7 @@ pub fn heapsort(v: &mut [T], mut is_less: F) // Comparison traits // -extern { +extern "C" { /// Calls implementation provided memcmp. /// /// Interprets the data as u8. @@ -5406,7 +5486,10 @@ extern { } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq<[B]> for [A] where A: PartialEq { +impl PartialEq<[B]> for [A] +where + A: PartialEq, +{ fn eq(&self, other: &[B]) -> bool { SlicePartialEq::equal(self, other) } @@ -5440,12 +5523,15 @@ impl PartialOrd for [T] { trait SlicePartialEq { fn equal(&self, other: &[B]) -> bool; - fn not_equal(&self, other: &[B]) -> bool { !self.equal(other) } + fn not_equal(&self, other: &[B]) -> bool { + !self.equal(other) + } } // Generic slice equality impl SlicePartialEq for [A] - where A: PartialEq +where + A: PartialEq, { default fn equal(&self, other: &[B]) -> bool { if self.len() != other.len() { @@ -5458,7 +5544,8 @@ impl SlicePartialEq for [A] // Use an equal-pointer optimization when types are `Eq` impl SlicePartialEq for [A] - where A: PartialEq + Eq +where + A: PartialEq + Eq, { default fn equal(&self, other: &[A]) -> bool { if self.len() != other.len() { @@ -5475,7 +5562,8 @@ impl SlicePartialEq for [A] // Use memcmp for bytewise equality when the types allow impl SlicePartialEq for [A] - where A: PartialEq + BytewiseEquality +where + A: PartialEq + BytewiseEquality, { fn equal(&self, other: &[A]) -> bool { if self.len() != other.len() { @@ -5486,8 +5574,7 @@ impl SlicePartialEq for [A] } unsafe { let size = mem::size_of_val(self); - memcmp(self.as_ptr() as *const u8, - other.as_ptr() as *const u8, size) == 0 + memcmp(self.as_ptr() as *const u8, other.as_ptr() as *const u8, size) == 0 } } } @@ -5499,7 +5586,8 @@ trait SlicePartialOrd { } impl SlicePartialOrd for [A] - where A: PartialOrd +where + A: PartialOrd, { default fn partial_compare(&self, other: &[A]) -> Option { let l = cmp::min(self.len(), other.len()); @@ -5521,7 +5609,8 @@ impl SlicePartialOrd for [A] } impl SlicePartialOrd for [A] - where A: Ord +where + A: Ord, { default fn partial_compare(&self, other: &[A]) -> Option { Some(SliceOrd::compare(self, other)) @@ -5535,7 +5624,8 @@ trait SliceOrd { } impl SliceOrd for [A] - where A: Ord +where + A: Ord, { default fn compare(&self, other: &[A]) -> Ordering { let l = cmp::min(self.len(), other.len()); @@ -5561,10 +5651,8 @@ impl SliceOrd for [A] impl SliceOrd for [u8] { #[inline] fn compare(&self, other: &[u8]) -> Ordering { - let order = unsafe { - memcmp(self.as_ptr(), other.as_ptr(), - cmp::min(self.len(), other.len())) - }; + let order = + unsafe { memcmp(self.as_ptr(), other.as_ptr(), cmp::min(self.len(), other.len())) }; if order == 0 { self.len().cmp(&other.len()) } else if order < 0 { @@ -5578,7 +5666,7 @@ impl SliceOrd for [u8] { #[doc(hidden)] /// Trait implemented for types that can be compared for equality using /// their bytewise representation -trait BytewiseEquality: Eq + Copy { } +trait BytewiseEquality: Eq + Copy {} macro_rules! impl_marker_for { ($traitname:ident, $($ty:ty)*) => { @@ -5596,7 +5684,9 @@ unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> { unsafe fn get_unchecked(&mut self, i: usize) -> &'a T { &*self.ptr.add(i) } - fn may_have_side_effect() -> bool { false } + fn may_have_side_effect() -> bool { + false + } } #[doc(hidden)] @@ -5604,14 +5694,19 @@ unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> { unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut T { &mut *self.ptr.add(i) } - fn may_have_side_effect() -> bool { false } + fn may_have_side_effect() -> bool { + false + } } trait SliceContains: Sized { fn slice_contains(&self, x: &[Self]) -> bool; } -impl SliceContains for T where T: PartialEq { +impl SliceContains for T +where + T: PartialEq, +{ default fn slice_contains(&self, x: &[Self]) -> bool { x.iter().any(|y| *y == *self) } diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs index cf6ee6ed5935d..8a1fb9de54667 100644 --- a/src/libcore/str/lossy.rs +++ b/src/libcore/str/lossy.rs @@ -1,14 +1,14 @@ use crate::char; -use crate::str as core_str; use crate::fmt::{self, Write}; use crate::mem; +use crate::str as core_str; // ignore-tidy-undocumented-unsafe /// Lossy UTF-8 string. #[unstable(feature = "str_internals", issue = "none")] pub struct Utf8Lossy { - bytes: [u8] + bytes: [u8], } impl Utf8Lossy { @@ -25,7 +25,6 @@ impl Utf8Lossy { } } - /// Iterator over lossy UTF-8 string #[unstable(feature = "str_internals", issue = "none")] #[allow(missing_debug_implementations)] @@ -65,20 +64,21 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { i += 1; if byte < 128 { - } else { let w = core_str::utf8_char_width(byte); - macro_rules! error { () => ({ - unsafe { - let r = Utf8LossyChunk { - valid: core_str::from_utf8_unchecked(&self.source[0..i_]), - broken: &self.source[i_..i], - }; - self.source = &self.source[i..]; - return Some(r); - } - })} + macro_rules! error { + () => {{ + unsafe { + let r = Utf8LossyChunk { + valid: core_str::from_utf8_unchecked(&self.source[0..i_]), + broken: &self.source[i_..i], + }; + self.source = &self.source[i..]; + return Some(r); + } + }}; + } match w { 2 => { @@ -89,10 +89,10 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { } 3 => { match (byte, safe_get(self.source, i)) { - (0xE0, 0xA0 ..= 0xBF) => (), - (0xE1 ..= 0xEC, 0x80 ..= 0xBF) => (), - (0xED, 0x80 ..= 0x9F) => (), - (0xEE ..= 0xEF, 0x80 ..= 0xBF) => (), + (0xE0, 0xA0..=0xBF) => (), + (0xE1..=0xEC, 0x80..=0xBF) => (), + (0xED, 0x80..=0x9F) => (), + (0xEE..=0xEF, 0x80..=0xBF) => (), _ => { error!(); } @@ -105,9 +105,9 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { } 4 => { match (byte, safe_get(self.source, i)) { - (0xF0, 0x90 ..= 0xBF) => (), - (0xF1 ..= 0xF3, 0x80 ..= 0xBF) => (), - (0xF4, 0x80 ..= 0x8F) => (), + (0xF0, 0x90..=0xBF) => (), + (0xF1..=0xF3, 0x80..=0xBF) => (), + (0xF4, 0x80..=0x8F) => (), _ => { error!(); } @@ -138,13 +138,12 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { } } - impl fmt::Display for Utf8Lossy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // If we're the empty string then our iterator won't actually yield // anything, so perform the formatting manually if self.bytes.is_empty() { - return "".fmt(f) + return "".fmt(f); } for Utf8LossyChunk { valid, broken } in self.chunks() { @@ -153,7 +152,7 @@ impl fmt::Display for Utf8Lossy { // respect various formatting flags if possible. if valid.len() == self.bytes.len() { assert!(broken.is_empty()); - return valid.fmt(f) + return valid.fmt(f); } f.write_str(valid)?; @@ -170,7 +169,6 @@ impl fmt::Debug for Utf8Lossy { f.write_char('"')?; for Utf8LossyChunk { valid, broken } in self.chunks() { - // Valid part. // Here we partially parse UTF-8 again which is suboptimal. { diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 15b65ed76555a..ab771b1164bad 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -8,16 +8,16 @@ #![stable(feature = "rust1", since = "1.0.0")] use self::pattern::Pattern; -use self::pattern::{Searcher, SearchStep, ReverseSearcher, DoubleEndedSearcher}; +use self::pattern::{DoubleEndedSearcher, ReverseSearcher, SearchStep, Searcher}; use crate::char; use crate::fmt::{self, Write}; -use crate::iter::{Map, Cloned, FusedIterator, TrustedLen, TrustedRandomAccess, Filter}; -use crate::iter::{Flatten, FlatMap, Chain}; -use crate::slice::{self, SliceIndex, Split as SliceSplit}; +use crate::iter::{Chain, FlatMap, Flatten}; +use crate::iter::{Cloned, Filter, FusedIterator, Map, TrustedLen, TrustedRandomAccess}; use crate::mem; use crate::ops::Try; use crate::option; +use crate::slice::{self, SliceIndex, Split as SliceSplit}; pub mod pattern; @@ -133,9 +133,9 @@ impl FromStr for bool { #[inline] fn from_str(s: &str) -> Result { match s { - "true" => Ok(true), + "true" => Ok(true), "false" => Ok(false), - _ => Err(ParseBoolError { _priv: () }), + _ => Err(ParseBoolError { _priv: () }), } } } @@ -145,7 +145,9 @@ impl FromStr for bool { /// [`from_str`]: ../../std/primitive.bool.html#method.from_str #[derive(Debug, Clone, PartialEq, Eq)] #[stable(feature = "rust1", since = "1.0.0")] -pub struct ParseBoolError { _priv: () } +pub struct ParseBoolError { + _priv: (), +} #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for ParseBoolError { @@ -230,7 +232,9 @@ impl Utf8Error { /// assert_eq!(1, error.valid_up_to()); /// ``` #[stable(feature = "utf8_error", since = "1.5.0")] - pub fn valid_up_to(&self) -> usize { self.valid_up_to } + pub fn valid_up_to(&self) -> usize { + self.valid_up_to + } /// Provides more information about the failure: /// @@ -444,8 +448,11 @@ pub unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str { impl fmt::Display for Utf8Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(error_len) = self.error_len { - write!(f, "invalid utf-8 sequence of {} bytes from index {}", - error_len, self.valid_up_to) + write!( + f, + "invalid utf-8 sequence of {} bytes from index {}", + error_len, self.valid_up_to + ) } else { write!(f, "incomplete utf-8 byte sequence from index {}", self.valid_up_to) } @@ -468,23 +475,29 @@ Section: Iterators #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Chars<'a> { - iter: slice::Iter<'a, u8> + iter: slice::Iter<'a, u8>, } /// Returns the initial codepoint accumulator for the first byte. /// The first byte is special, only want bottom 5 bits for width 2, 4 bits /// for width 3, and 3 bits for width 4. #[inline] -fn utf8_first_byte(byte: u8, width: u32) -> u32 { (byte & (0x7F >> width)) as u32 } +fn utf8_first_byte(byte: u8, width: u32) -> u32 { + (byte & (0x7F >> width)) as u32 +} /// Returns the value of `ch` updated with continuation byte `byte`. #[inline] -fn utf8_acc_cont_byte(ch: u32, byte: u8) -> u32 { (ch << 6) | (byte & CONT_MASK) as u32 } +fn utf8_acc_cont_byte(ch: u32, byte: u8) -> u32 { + (ch << 6) | (byte & CONT_MASK) as u32 +} /// Checks whether the byte is a UTF-8 continuation byte (i.e., starts with the /// bits `10`). #[inline] -fn utf8_is_cont_byte(byte: u8) -> bool { (byte & !CONT_MASK) == TAG_CONT_U8 } +fn utf8_is_cont_byte(byte: u8) -> bool { + (byte & !CONT_MASK) == TAG_CONT_U8 +} #[inline] fn unwrap_or_0(opt: Option<&u8>) -> u8 { @@ -502,7 +515,7 @@ pub fn next_code_point<'a, I: Iterator>(bytes: &mut I) -> Option< // Decode UTF-8 let x = *bytes.next()?; if x < 128 { - return Some(x as u32) + return Some(x as u32); } // Multibyte case follows @@ -532,7 +545,8 @@ pub fn next_code_point<'a, I: Iterator>(bytes: &mut I) -> Option< /// UTF-8-like encoding). #[inline] fn next_code_point_reverse<'a, I>(bytes: &mut I) -> Option - where I: DoubleEndedIterator, +where + I: DoubleEndedIterator, { // Decode UTF-8 let w = match *bytes.next_back()? { @@ -568,9 +582,7 @@ impl<'a> Iterator for Chars<'a> { fn next(&mut self) -> Option { next_code_point(&mut self.iter).map(|ch| { // str invariant says `ch` is a valid Unicode Scalar Value - unsafe { - char::from_u32_unchecked(ch) - } + unsafe { char::from_u32_unchecked(ch) } }) } @@ -617,9 +629,7 @@ impl<'a> DoubleEndedIterator for Chars<'a> { fn next_back(&mut self) -> Option { next_code_point_reverse(&mut self.iter).map(|ch| { // str invariant says `ch` is a valid Unicode Scalar Value - unsafe { - char::from_u32_unchecked(ch) - } + unsafe { char::from_u32_unchecked(ch) } }) } } @@ -770,32 +780,41 @@ impl Iterator for Bytes<'_> { } #[inline] - fn all(&mut self, f: F) -> bool where F: FnMut(Self::Item) -> bool { + fn all(&mut self, f: F) -> bool + where + F: FnMut(Self::Item) -> bool, + { self.0.all(f) } #[inline] - fn any(&mut self, f: F) -> bool where F: FnMut(Self::Item) -> bool { + fn any(&mut self, f: F) -> bool + where + F: FnMut(Self::Item) -> bool, + { self.0.any(f) } #[inline] - fn find