-------------------------------------------------------------------------------- -- Metadata -------------------------------------------------------------------------------- Invocation: /usr/local/bin/cg_annotate --auto=yes --show-percs=yes aug04/cgout-Orig-type-system-chess-Check-Full Command: /home/njn/dev/rust0/build/x86_64-unknown-linux-gnu/stage1/bin/rustc --crate-name rust --edition=2021 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type bin --emit=dep-info,metadata -C embed-bitcode=no -C debuginfo=2 -C metadata=e0175e68e72e2a0e -C extra-filename=-e0175e68e72e2a0e --out-dir /tmp/.tmpFxSgeY/target/debug/deps -L dependency=/tmp/.tmpFxSgeY/target/debug/deps -C link-arg=-fuse-ld=mold -Adeprecated -Aunknown-lints -Zincremental-verify-ich Events recorded: Ir Events shown: Ir Event sort order: Ir Threshold: 0.1% Annotation: on -------------------------------------------------------------------------------- -- Summary -------------------------------------------------------------------------------- Ir______________________ 241,248,551,799 (100.0%) PROGRAM TOTALS -------------------------------------------------------------------------------- -- File:function summary -------------------------------------------------------------------------------- Ir___________________________ file:function < 46,854,389,399 (19.4%, 19.4%) /home/njn/dev/rust0/compiler/rustc_middle/src/traits/mod.rs: 30,392,219,234 (12.6%) ::eq 12,686,667,288 (5.3%) ::eq 3,317,562,154 (1.4%) , (), core::hash::BuildHasherDefault>>::insert < 24,964,239,018 (10.3%, 29.8%) /home/njn/dev/rust0/library/alloc/src/rc.rs: 24,113,400,873 (10.0%) , (), core::hash::BuildHasherDefault>>::insert 345,641,342 (0.1%) ::eq < 22,855,773,813 (9.5%, 39.2%) /home/njn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.0/src/raw/mod.rs: 19,024,719,473 (7.9%) , (), core::hash::BuildHasherDefault>>::insert 2,085,099,662 (0.9%) , ())>>::reserve_rehash::, (), core::hash::BuildHasherDefault>::{closure#0}> 413,033,653 (0.2%) ), rustc_middle::traits::select::EvaluationResult>>::get:: < 18,531,203,986 (7.7%, 46.9%) /home/njn/dev/rust0/library/core/src/option.rs: 15,563,322,110 (6.5%) , (), core::hash::BuildHasherDefault>>::insert 1,901,030,901 (0.8%) ::eq 307,937,370 (0.1%) > as core::clone::Clone>::clone 262,183,820 (0.1%) >>::retain:: < 10,947,096,244 (4.5%, 51.5%) /home/njn/dev/rust0/compiler/rustc_span/src/def_id.rs: 8,862,057,385 (3.7%) ::eq 1,658,781,077 (0.7%) , (), core::hash::BuildHasherDefault>>::insert < 10,325,985,574 (4.3%, 55.7%) /home/njn/dev/rust0/compiler/rustc_span/src/span_encoding.rs: 9,952,686,462 (4.1%) , (), core::hash::BuildHasherDefault>>::insert < 10,221,080,160 (4.2%, 60.0%) /home/njn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.0/src/raw/bitmask.rs: 9,306,391,703 (3.9%) , (), core::hash::BuildHasherDefault>>::insert 427,337,120 (0.2%) , ())> as core::ops::drop::Drop>::drop < 9,644,134,546 (4.0%, 64.0%) /home/njn/dev/rust0/library/alloc/src/boxed.rs: 9,597,542,916 (4.0%) ::eq < 8,751,453,233 (3.6%, 67.6%) /home/njn/dev/rust0/compiler/rustc_infer/src/traits/mod.rs: 7,472,954,959 (3.1%) , (), core::hash::BuildHasherDefault>>::insert 786,551,460 (0.3%) >>::retain:: < 6,534,110,106 (2.7%, 70.3%) /home/njn/dev/rust0/compiler/rustc_middle/src/ty/sty.rs: 6,184,431,308 (2.6%) ::eq < 6,428,151,277 (2.7%, 73.0%) ./string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: 6,428,142,967 (2.7%) __memcpy_avx_unaligned_erms < 5,083,593,564 (2.1%, 75.1%) /home/njn/dev/rust0/library/core/src/ptr/mod.rs: 1,492,625,168 (0.6%) ::eq 659,493,958 (0.3%) , (), core::hash::BuildHasherDefault>>::insert 552,111,348 (0.2%) >>::retain:: 449,298,795 (0.2%) >, ::confirm_candidate::{closure#1}> as core::iter::traits::iterator::Iterator>::try_fold::>, alloc::vec::in_place_collect::write_in_place_with_drop>::{closure#0}, core::result::Result>, !>> 295,991,157 (0.1%) > as core::ops::drop::Drop>::drop 267,096,316 (0.1%) , ())> as core::ops::drop::Drop>::drop < 4,856,609,786 (2.0%, 77.1%) /home/njn/dev/rust0/compiler/rustc_middle/src/ty/mod.rs: 2,529,551,114 (1.0%) ::eq 718,280,334 (0.3%) ::without_const < 4,653,346,506 (1.9%, 79.0%) /home/njn/dev/rust0/compiler/rustc_trait_selection/src/traits/select/mod.rs: 1,961,316,101 (0.8%) ::evaluate_trait_predicate_recursively 1,700,922,978 (0.7%) ::evaluate_predicate_recursively 485,153,690 (0.2%) ::evaluate_predicates_recursively::>> < 4,565,909,600 (1.9%, 80.9%) /home/njn/dev/rust0/library/core/src/ptr/mut_ptr.rs: 3,451,110,312 (1.4%) , (), core::hash::BuildHasherDefault>>::insert 376,242,024 (0.2%) >>::retain:: < 4,064,842,344 (1.7%, 82.6%) /home/njn/dev/rust0/library/core/src/num/mod.rs: 1,792,329,235 (0.7%) , (), core::hash::BuildHasherDefault>>::insert 1,520,402,712 (0.6%) , ())>>::reserve_rehash::, (), core::hash::BuildHasherDefault>::{closure#0}> 273,525,371 (0.1%) ), rustc_middle::traits::select::EvaluationResult>>::get:: < 3,986,415,368 (1.7%, 84.3%) /home/njn/dev/rust0/library/core/src/cmp.rs: 3,330,892,318 (1.4%) ::eq < 3,842,171,822 (1.6%, 85.8%) /home/njn/dev/rust0/compiler/rustc_data_structures/src/sso/map.rs: 3,673,442,463 (1.5%) , ()>>::insert < 2,799,745,449 (1.2%, 87.0%) /home/njn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.0/src/map.rs: 2,156,803,957 (0.9%) , (), core::hash::BuildHasherDefault>>::insert 250,233,434 (0.1%) >, (), core::hash::BuildHasherDefault>>::search::>>::{closure#0}> < 2,007,181,687 (0.8%, 87.8%) /home/njn/dev/rust0/library/core/src/../../stdarch/crates/core_arch/src/x86/sse2.rs: 1,553,718,728 (0.6%) , (), core::hash::BuildHasherDefault>>::insert < 1,778,398,547 (0.7%, 88.6%) /home/njn/dev/rust0/library/core/src/intrinsics.rs: 723,325,372 (0.3%) , ())>>::reserve_rehash::, (), core::hash::BuildHasherDefault>::{closure#0}> 698,317,046 (0.3%) , (), core::hash::BuildHasherDefault>>::insert < 1,638,167,555 (0.7%, 89.3%) : < 1,623,664,047 (0.7%, 89.9%) /home/njn/dev/rust0/compiler/rustc_middle/src/ty/generic_args.rs: 585,148,809 (0.2%) <&rustc_middle::ty::list::List as rustc_type_ir::fold::TypeFoldable>::try_fold_with:: < 1,449,243,285 (0.6%, 90.5%) /home/njn/dev/rust0/library/core/src/iter/traits/iterator.rs: 718,878,072 (0.3%) >, ::confirm_candidate::{closure#1}> as core::iter::traits::iterator::Iterator>::try_fold::>, alloc::vec::in_place_collect::write_in_place_with_drop>::{closure#0}, core::result::Result>, !>> 479,556,993 (0.2%) ::evaluate_trait_predicate_recursively < 1,265,034,552 (0.5%, 91.1%) /home/njn/dev/rust0/library/alloc/src/vec/mod.rs: 1,060,139,760 (0.4%) >>::retain:: < 1,253,663,244 (0.5%, 91.6%) /home/njn/dev/rust0/library/core/src/hash/mod.rs: 784,792,248 (0.3%) , (), core::hash::BuildHasherDefault>>::insert 378,454,160 (0.2%) , ())>>::reserve_rehash::, (), core::hash::BuildHasherDefault>::{closure#0}> < 1,244,060,806 (0.5%, 92.1%) /home/njn/dev/rust0/compiler/rustc_middle/src/ty/context.rs: 362,942,500 (0.2%) ::mk_args 241,677,887 (0.1%) ::intern_ty < 1,216,993,125 (0.5%, 92.6%) /home/njn/dev/rust0/library/core/src/num/nonzero.rs: 855,401,682 (0.4%) , (), core::hash::BuildHasherDefault>>::insert 295,689,382 (0.1%) , ())>>::reserve_rehash::, (), core::hash::BuildHasherDefault>::{closure#0}> < 947,104,573 (0.4%, 93.0%) /home/njn/dev/rust0/library/core/src/ptr/non_null.rs: 261,597,416 (0.1%) , (), core::hash::BuildHasherDefault>>::insert < 852,069,998 (0.4%, 93.3%) /home/njn/dev/rust0/compiler/rustc_trait_selection/src/traits/select/confirmation.rs: 808,737,831 (0.3%) >, ::confirm_candidate::{closure#1}> as core::iter::traits::iterator::Iterator>::try_fold::>, alloc::vec::in_place_collect::write_in_place_with_drop>::{closure#0}, core::result::Result>, !>> < 770,110,577 (0.3%, 93.7%) /home/njn/dev/rust0/library/core/src/mem/maybe_uninit.rs: 769,843,425 (0.3%) > as core::clone::Clone>::clone < 765,801,215 (0.3%, 94.0%) /home/njn/dev/rust0/library/core/src/ops/bit.rs: 567,681,240 (0.2%) , ())>>::reserve_rehash::, (), core::hash::BuildHasherDefault>::{closure#0}> < 743,438,624 (0.3%, 94.3%) /home/njn/dev/rust0/compiler/rustc_infer/src/infer/generalize.rs: 432,279,335 (0.2%) as rustc_middle::ty::relate::TypeRelation>::tys < 695,525,891 (0.3%, 94.6%) /home/njn/dev/rust0/compiler/rustc_middle/src/ty/relate.rs: 387,645,024 (0.2%) rustc_middle::ty::relate::structurally_relate_tys::> < 592,118,454 (0.2%, 94.8%) /home/njn/dev/rust0/library/std/src/collections/hash/map.rs: 521,017,840 (0.2%) , ()>>::insert < 525,790,429 (0.2%, 95.0%) /home/njn/dev/rust0/compiler/rustc_query_system/src/cache.rs: 505,774,110 (0.2%) ), rustc_middle::traits::select::EvaluationResult>>::get:: < 468,058,722 (0.2%, 95.2%) /home/njn/dev/rust0/library/core/src/iter/adapters/take.rs: 461,906,055 (0.2%) > as core::clone::Clone>::clone < 402,856,585 (0.2%, 95.4%) /home/njn/dev/rust0/library/alloc/src/vec/into_iter.rs: 271,200,214 (0.1%) >, ::confirm_candidate::{closure#1}> as core::iter::traits::iterator::Iterator>::try_fold::>, alloc::vec::in_place_collect::write_in_place_with_drop>::{closure#0}, core::result::Result>, !>> < 396,963,825 (0.2%, 95.6%) /home/njn/dev/rust0/library/core/src/iter/adapters/map.rs: 367,128,480 (0.2%) >, ::confirm_candidate::{closure#1}> as core::iter::traits::iterator::Iterator>::try_fold::>, alloc::vec::in_place_collect::write_in_place_with_drop>::{closure#0}, core::result::Result>, !>> < 262,980,014 (0.1%, 95.7%) /home/njn/dev/rust0/compiler/rustc_data_structures/src/sso/set.rs: 262,183,820 (0.1%) >>::retain:: -------------------------------------------------------------------------------- -- Function:file summary -------------------------------------------------------------------------------- Ir____________________________ function:file > 102,690,157,472 (42.6%, 42.6%) , (), core::hash::BuildHasherDefault>>::insert: 24,113,400,873 (10.0%) /home/njn/dev/rust0/library/alloc/src/rc.rs 19,024,719,473 (7.9%) /home/njn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.0/src/raw/mod.rs 15,563,322,110 (6.5%) /home/njn/dev/rust0/library/core/src/option.rs 9,952,686,462 (4.1%) /home/njn/dev/rust0/compiler/rustc_span/src/span_encoding.rs 9,306,391,703 (3.9%) /home/njn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.0/src/raw/bitmask.rs 7,472,954,959 (3.1%) /home/njn/dev/rust0/compiler/rustc_infer/src/traits/mod.rs 3,451,110,312 (1.4%) /home/njn/dev/rust0/library/core/src/ptr/mut_ptr.rs 3,317,562,154 (1.4%) /home/njn/dev/rust0/compiler/rustc_middle/src/traits/mod.rs 2,156,803,957 (0.9%) /home/njn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.0/src/map.rs 1,792,329,235 (0.7%) /home/njn/dev/rust0/library/core/src/num/mod.rs 1,658,781,077 (0.7%) /home/njn/dev/rust0/compiler/rustc_span/src/def_id.rs 1,553,718,728 (0.6%) /home/njn/dev/rust0/library/core/src/../../stdarch/crates/core_arch/src/x86/sse2.rs 855,401,682 (0.4%) /home/njn/dev/rust0/library/core/src/num/nonzero.rs 784,792,248 (0.3%) /home/njn/dev/rust0/library/core/src/hash/mod.rs 698,317,046 (0.3%) /home/njn/dev/rust0/library/core/src/intrinsics.rs 659,493,958 (0.3%) /home/njn/dev/rust0/library/core/src/ptr/mod.rs 261,597,416 (0.1%) /home/njn/dev/rust0/library/core/src/ptr/non_null.rs > 39,989,762,150 (16.6%, 59.1%) ::eq: 30,392,219,234 (12.6%) /home/njn/dev/rust0/compiler/rustc_middle/src/traits/mod.rs 9,597,542,916 (4.0%) /home/njn/dev/rust0/library/alloc/src/boxed.rs > 37,332,896,824 (15.5%, 74.6%) ::eq: 12,686,667,288 (5.3%) /home/njn/dev/rust0/compiler/rustc_middle/src/traits/mod.rs 8,862,057,385 (3.7%) /home/njn/dev/rust0/compiler/rustc_span/src/def_id.rs 6,184,431,308 (2.6%) /home/njn/dev/rust0/compiler/rustc_middle/src/ty/sty.rs 3,330,892,318 (1.4%) /home/njn/dev/rust0/library/core/src/cmp.rs 2,529,551,114 (1.0%) /home/njn/dev/rust0/compiler/rustc_middle/src/ty/mod.rs 1,901,030,901 (0.8%) /home/njn/dev/rust0/library/core/src/option.rs 1,492,625,168 (0.6%) /home/njn/dev/rust0/library/core/src/ptr/mod.rs 345,641,342 (0.1%) /home/njn/dev/rust0/library/alloc/src/rc.rs > 6,452,414,484 (2.7%, 77.3%) , ())>>::reserve_rehash::, (), core::hash::BuildHasherDefault>::{closure#0}>: 2,085,099,662 (0.9%) /home/njn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.0/src/raw/mod.rs 1,520,402,712 (0.6%) /home/njn/dev/rust0/library/core/src/num/mod.rs 723,325,372 (0.3%) /home/njn/dev/rust0/library/core/src/intrinsics.rs 567,681,240 (0.2%) /home/njn/dev/rust0/library/core/src/ops/bit.rs 378,454,160 (0.2%) /home/njn/dev/rust0/library/core/src/hash/mod.rs 295,689,382 (0.1%) /home/njn/dev/rust0/library/core/src/num/nonzero.rs > 6,428,142,967 (2.7%, 80.0%) __memcpy_avx_unaligned_erms:./string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S > 4,387,525,675 (1.8%, 81.8%) , ()>>::insert: 3,673,442,463 (1.5%) /home/njn/dev/rust0/compiler/rustc_data_structures/src/sso/map.rs 521,017,840 (0.2%) /home/njn/dev/rust0/library/std/src/collections/hash/map.rs > 4,374,387,644 (1.8%, 83.6%) >>::retain::: 1,060,139,760 (0.4%) /home/njn/dev/rust0/library/alloc/src/vec/mod.rs 786,551,460 (0.3%) /home/njn/dev/rust0/compiler/rustc_infer/src/traits/mod.rs 552,111,348 (0.2%) /home/njn/dev/rust0/library/core/src/ptr/mod.rs 376,242,024 (0.2%) /home/njn/dev/rust0/library/core/src/ptr/mut_ptr.rs 262,183,820 (0.1%) /home/njn/dev/rust0/library/core/src/option.rs 262,183,820 (0.1%) /home/njn/dev/rust0/compiler/rustc_data_structures/src/sso/set.rs > 3,407,216,708 (1.4%, 85.0%) ::evaluate_trait_predicate_recursively: 1,961,316,101 (0.8%) /home/njn/dev/rust0/compiler/rustc_trait_selection/src/traits/select/mod.rs 479,556,993 (0.2%) /home/njn/dev/rust0/library/core/src/iter/traits/iterator.rs > 3,260,880,171 (1.4%, 86.4%) > as core::clone::Clone>::clone: 769,843,425 (0.3%) /home/njn/dev/rust0/library/core/src/mem/maybe_uninit.rs 461,906,055 (0.2%) /home/njn/dev/rust0/library/core/src/iter/adapters/take.rs 307,937,370 (0.1%) /home/njn/dev/rust0/library/core/src/option.rs > 3,064,542,187 (1.3%, 87.6%) >, ::confirm_candidate::{closure#1}> as core::iter::traits::iterator::Iterator>::try_fold::>, alloc::vec::in_place_collect::write_in_place_with_drop>::{closure#0}, core::result::Result>, !>>: 808,737,831 (0.3%) /home/njn/dev/rust0/compiler/rustc_trait_selection/src/traits/select/confirmation.rs 718,878,072 (0.3%) /home/njn/dev/rust0/library/core/src/iter/traits/iterator.rs 449,298,795 (0.2%) /home/njn/dev/rust0/library/core/src/ptr/mod.rs 367,128,480 (0.2%) /home/njn/dev/rust0/library/core/src/iter/adapters/map.rs 271,200,214 (0.1%) /home/njn/dev/rust0/library/alloc/src/vec/into_iter.rs > 2,351,864,172 (1.0%, 88.6%) ::evaluate_predicate_recursively: 1,700,922,978 (0.7%) /home/njn/dev/rust0/compiler/rustc_trait_selection/src/traits/select/mod.rs > 2,183,562,529 (0.9%, 89.5%) ), rustc_middle::traits::select::EvaluationResult>>::get::: 505,774,110 (0.2%) /home/njn/dev/rust0/compiler/rustc_query_system/src/cache.rs 413,033,653 (0.2%) /home/njn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.0/src/raw/mod.rs 273,525,371 (0.1%) /home/njn/dev/rust0/library/core/src/num/mod.rs > 1,638,167,555 (0.7%, 90.2%) : > 1,193,479,637 (0.5%, 90.7%) , ())> as core::ops::drop::Drop>::drop: 427,337,120 (0.2%) /home/njn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.0/src/raw/bitmask.rs 267,096,316 (0.1%) /home/njn/dev/rust0/library/core/src/ptr/mod.rs > 1,164,666,288 (0.5%, 91.2%) ::evaluate_predicates_recursively::>>: 485,153,690 (0.2%) /home/njn/dev/rust0/compiler/rustc_trait_selection/src/traits/select/mod.rs > 931,429,658 (0.4%, 91.5%) >, (), core::hash::BuildHasherDefault>>::search::>>::{closure#0}>: 250,233,434 (0.1%) /home/njn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.0/src/map.rs > 857,738,083 (0.4%, 91.9%) ::mk_args: 362,942,500 (0.2%) /home/njn/dev/rust0/compiler/rustc_middle/src/ty/context.rs > 814,865,971 (0.3%, 92.2%) ::intern_ty: 241,677,887 (0.1%) /home/njn/dev/rust0/compiler/rustc_middle/src/ty/context.rs > 731,224,313 (0.3%, 92.5%) as rustc_middle::ty::relate::TypeRelation>::tys: 432,279,335 (0.2%) /home/njn/dev/rust0/compiler/rustc_infer/src/infer/generalize.rs > 718,280,334 (0.3%, 92.8%) ::without_const:/home/njn/dev/rust0/compiler/rustc_middle/src/ty/mod.rs > 704,132,755 (0.3%, 93.1%) <&rustc_middle::ty::list::List as rustc_type_ir::fold::TypeFoldable>::try_fold_with::: 585,148,809 (0.2%) /home/njn/dev/rust0/compiler/rustc_middle/src/ty/generic_args.rs > 500,073,577 (0.2%, 93.3%) rustc_middle::ty::relate::structurally_relate_tys::>: 387,645,024 (0.2%) /home/njn/dev/rust0/compiler/rustc_middle/src/ty/relate.rs > 339,771,682 (0.1%, 93.5%) > as core::ops::drop::Drop>::drop: 295,991,157 (0.1%) /home/njn/dev/rust0/library/core/src/ptr/mod.rs -------------------------------------------------------------------------------- -- Annotated source file: ./string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S -------------------------------------------------------------------------------- Unannotated because one or more of these original files are unreadable: - ./string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.0/src/map.rs -------------------------------------------------------------------------------- Ir__________________ 94,799,263 (0.0%) -- line 187 ---------------------------------------- . /// ``` . pub struct HashMap { . pub(crate) hash_builder: S, . pub(crate) table: RawTable<(K, V), A>, . } . . impl Clone for HashMap { . fn clone(&self) -> Self { 21,568 (0.0%) HashMap { . hash_builder: self.hash_builder.clone(), 5,392 (0.0%) table: self.table.clone(), . } . } . . fn clone_from(&mut self, source: &Self) { . self.table.clone_from(&source.table); . . // Update hash_builder only if we successfully cloned all elements. . self.hash_builder.clone_from(&source.hash_builder); -- line 205 ---------------------------------------- -- line 219 ---------------------------------------- . . /// Ensures that a single closure type across uses of this which, in turn prevents multiple . /// instances of any functions like RawTable::reserve from being generated . #[cfg_attr(feature = "inline-more", inline)] . fn equivalent_key(k: &Q) -> impl Fn(&(K, V)) -> bool + '_ . where . Q: ?Sized + Equivalent, . { 192 (0.0%) move |x| k.equivalent(&x.0) . } . . /// Ensures that a single closure type across uses of this which, in turn prevents multiple . /// instances of any functions like RawTable::reserve from being generated . #[cfg_attr(feature = "inline-more", inline)] . fn equivalent(k: &Q) -> impl Fn(&K) -> bool + '_ . where . Q: ?Sized + Equivalent, . { 30,668,135 (0.0%) move |x| k.equivalent(x) . } . . #[cfg(not(feature = "nightly"))] . #[cfg_attr(feature = "inline-more", inline)] . pub(crate) fn make_hash(hash_builder: &S, val: &Q) -> u64 . where . Q: Hash + ?Sized, . S: BuildHasher, -- line 245 ---------------------------------------- -- line 252 ---------------------------------------- . . #[cfg(feature = "nightly")] . #[cfg_attr(feature = "inline-more", inline)] . pub(crate) fn make_hash(hash_builder: &S, val: &Q) -> u64 . where . Q: Hash + ?Sized, . S: BuildHasher, . { 218 (0.0%) hash_builder.hash_one(val) . } . . #[cfg(feature = "ahash")] . impl HashMap { . /// Creates an empty `HashMap`. . /// . /// The hash map is initially created with a capacity of 0, so it will not allocate until it . /// is first inserted into. -- line 268 ---------------------------------------- -- line 493 ---------------------------------------- . /// let mut map = HashMap::with_capacity_and_hasher(10, s); . /// assert_eq!(map.len(), 0); . /// assert!(map.capacity() >= 10); . /// . /// map.insert(1, 2); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self { 8 (0.0%) Self { . hash_builder, . table: RawTable::with_capacity(capacity), . } . } . } . . impl HashMap { . /// Returns a reference to the underlying allocator. -- line 509 ---------------------------------------- -- line 536 ---------------------------------------- . /// use hashbrown::hash_map::DefaultHashBuilder; . /// . /// let s = DefaultHashBuilder::default(); . /// let mut map = HashMap::with_hasher(s); . /// map.insert(1, 2); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . pub const fn with_hasher_in(hash_builder: S, alloc: A) -> Self { 290,866 (0.0%) Self { . hash_builder, . table: RawTable::new_in(alloc), . } . } . . /// Creates an empty `HashMap` with the specified capacity, using `hash_builder` . /// to hash the keys. It will be allocated with the given allocator. . /// -- line 552 ---------------------------------------- -- line 838 ---------------------------------------- . /// . /// let mut a = HashMap::new(); . /// assert!(a.is_empty()); . /// a.insert(1, "a"); . /// assert!(!a.is_empty()); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . pub fn is_empty(&self) -> bool { 3,806 (0.0%) self.len() == 0 . } . . /// Clears the map, returning all key-value pairs as an iterator. Keeps the . /// allocated memory for reuse. . /// . /// If the returned iterator is dropped before being fully consumed, it . /// drops the remaining key-value pairs. The returned iterator keeps a . /// mutable borrow on the vector to optimize its implementation. -- line 854 ---------------------------------------- -- line 881 ---------------------------------------- . /// let d = a.drain(); . /// } . /// . /// // But the map is empty even if we do not use Drain iterator. . /// assert!(a.is_empty()); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . pub fn drain(&mut self) -> Drain<'_, K, V, A> { 328 (0.0%) Drain { . inner: self.table.drain(), . } . } . . /// Retains only the elements specified by the predicate. Keeps the . /// allocated memory for reuse. . /// . /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. -- line 897 ---------------------------------------- -- line 909 ---------------------------------------- . /// . /// // We can see, that the number of elements inside map is changed. . /// assert_eq!(map.len(), 4); . /// . /// let mut vec: Vec<(i32, i32)> = map.iter().map(|(&k, &v)| (k, v)).collect(); . /// vec.sort_unstable(); . /// assert_eq!(vec, [(0, 0), (2, 20), (4, 40), (6, 60)]); . /// ``` 16,945 (0.0%) pub fn retain(&mut self, mut f: F) . where . F: FnMut(&K, &mut V) -> bool, . { . // Here we only use `iter` as a temporary, preventing use-after-free . unsafe { . for item in self.table.iter() { . let &mut (ref key, ref mut value) = item.as_mut(); . if !f(key, value) { . self.table.erase(item); . } . } . } 20,334 (0.0%) } . . /// Drains elements which are true under the given predicate, . /// and returns an iterator over the removed items. . /// . /// In other words, move all pairs `(k, v)` such that `f(&k, &mut v)` returns `true` out . /// into another iterator. . /// . /// Note that `extract_if` lets you mutate every value in the filter closure, regardless of -- line 938 ---------------------------------------- -- line 1301 ---------------------------------------- . /// assert_eq!(map.get(&2), None); . /// ``` . #[inline] . pub fn get(&self, k: &Q) -> Option<&V> . where . Q: Hash + Equivalent, . { . // Avoid `Option::map` because it bloats LLVM IR. 37,135 (0.0%) match self.get_inner(k) { . Some((_, v)) => Some(v), . None => None, . } . } . . /// Returns the key-value pair corresponding to the supplied key. . /// . /// The supplied key may be any borrowed form of the map's key type, but -- line 1317 ---------------------------------------- -- line 1339 ---------------------------------------- . // Avoid `Option::map` because it bloats LLVM IR. . match self.get_inner(k) { . Some((key, value)) => Some((key, value)), . None => None, . } . } . . #[inline] 114 (0.0%) fn get_inner(&self, k: &Q) -> Option<&(K, V)> . where . Q: Hash + Equivalent, . { 56,875,056 (0.0%) if self.table.is_empty() { . None . } else { . let hash = make_hash::(&self.hash_builder, k); 76,556,340 (0.0%) self.table.get(hash, equivalent_key(k)) . } 152 (0.0%) } . . /// Returns the key-value pair corresponding to the supplied key, with a mutable reference to value. . /// . /// The supplied key may be any borrowed form of the map's key type, but . /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for . /// the key type. . /// . /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html -- line 1365 ---------------------------------------- -- line 1453 ---------------------------------------- . } . } . . #[inline] . fn get_inner_mut(&mut self, k: &Q) -> Option<&mut (K, V)> . where . Q: Hash + Equivalent, . { 102 (0.0%) if self.table.is_empty() { . None . } else { . let hash = make_hash::(&self.hash_builder, k); 102 (0.0%) self.table.get_mut(hash, equivalent_key(k)) . } . } . . /// Attempts to get mutable references to `N` values in the map at once. . /// . /// Returns an array of length `N` with the results of each query. For soundness, at most one . /// mutable reference will be returned to any value. `None` will be returned if any of the . /// keys are duplicates or missing. -- line 1473 ---------------------------------------- -- line 1739 ---------------------------------------- . /// assert_eq!(map.insert(37, "a"), None); . /// assert_eq!(map.is_empty(), false); . /// . /// map.insert(37, "b"); . /// assert_eq!(map.insert(37, "c"), Some("b")); . /// assert_eq!(map[&37], "c"); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] 968,806,120 (0.4%) pub fn insert(&mut self, k: K, v: V) -> Option { . let hash = make_hash::(&self.hash_builder, &k); . let hasher = make_hasher::<_, V, S>(&self.hash_builder); . match self . .table . .find_or_find_insert_slot(hash, equivalent_key(&k), hasher) . { 944 (0.0%) Ok(bucket) => Some(mem::replace(unsafe { &mut bucket.as_mut().1 }, v)), . Err(slot) => { . unsafe { 4,277,322 (0.0%) self.table.insert_in_slot(hash, slot, (k, v)); . } 894,935 (0.0%) None . } . } 1,216,872,546 (0.5%) } . . /// Insert a key-value pair into the map without checking . /// if the key already exists in the map. . /// . /// Returns a reference to the key and value just inserted. . /// . /// This operation is safe if a key does not exist in the map. . /// -- line 1770 ---------------------------------------- -- line 1888 ---------------------------------------- . /// assert!(map.is_empty()); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . pub fn remove(&mut self, k: &Q) -> Option . where . Q: Hash + Equivalent, . { . // Avoid `Option::map` because it bloats LLVM IR. 792,506 (0.0%) match self.remove_entry(k) { 1,540,565 (0.0%) Some((_, v)) => Some(v), . None => None, . } . } . . /// Removes a key from the map, returning the stored key and value if the . /// key was previously in the map. Keeps the allocated memory for reuse. . /// . /// The key may be any borrowed form of the map's key type, but -- line 1905 ---------------------------------------- -- line 1927 ---------------------------------------- . /// assert!(map.is_empty()); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . pub fn remove_entry(&mut self, k: &Q) -> Option<(K, V)> . where . Q: Hash + Equivalent, . { . let hash = make_hash::(&self.hash_builder, k); 751,406 (0.0%) self.table.remove_entry(hash, equivalent_key(k)) . } . } . . impl HashMap { . /// Creates a raw entry builder for the HashMap. . /// . /// Raw entries provide the lowest level of control for searching and . /// manipulating a map. They must be manually initialized with a hash and -- line 1943 ---------------------------------------- -- line 2215 ---------------------------------------- . /// // You can specify all types of HashMap, including hasher and allocator. . /// // Created map is empty and don't allocate memory . /// let map: HashMap = Default::default(); . /// assert_eq!(map.capacity(), 0); . /// let map: HashMap = HashMap::default(); . /// assert_eq!(map.capacity(), 0); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] 155 (0.0%) fn default() -> Self { . Self::with_hasher_in(Default::default(), Default::default()) 155 (0.0%) } . } . . impl Index<&Q> for HashMap . where . K: Eq + Hash, . Q: Hash + Equivalent, . S: BuildHasher, . A: Allocator + Clone, -- line 2233 ---------------------------------------- -- line 3229 ---------------------------------------- . /// assert_eq!(map[&"a"], 100); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . #[allow(clippy::wrong_self_convention)] . pub fn from_hash(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S, A> . where . for<'b> F: FnMut(&'b K) -> bool, . { 58,803,696 (0.0%) self.search(hash, is_match) . } . . #[cfg_attr(feature = "inline-more", inline)] 102,907,962 (0.0%) fn search(self, hash: u64, mut is_match: F) -> RawEntryMut<'a, K, V, S, A> . where . for<'b> F: FnMut(&'b K) -> bool, . { . match self.map.table.find(hash, |(k, _)| is_match(k)) { 43,112,506 (0.0%) Some(elem) => RawEntryMut::Occupied(RawOccupiedEntryMut { . elem, . table: &mut self.map.table, . hash_builder: &self.map.hash_builder, . }), 1,322,088 (0.0%) None => RawEntryMut::Vacant(RawVacantEntryMut { . table: &mut self.map.table, . hash_builder: &self.map.hash_builder, . }), . } 102,907,215 (0.0%) } . } . . impl<'a, K, V, S, A: Allocator + Clone> RawEntryBuilder<'a, K, V, S, A> { . /// Access an immutable entry by key. . /// . /// # Examples . /// . /// ``` -- line 3264 ---------------------------------------- -- line 3304 ---------------------------------------- . pub fn from_key_hashed_nocheck(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)> . where . Q: Equivalent, . { . self.from_hash(hash, equivalent(k)) . } . . #[cfg_attr(feature = "inline-more", inline)] 1,220 (0.0%) fn search(self, hash: u64, mut is_match: F) -> Option<(&'a K, &'a V)> . where . F: FnMut(&K) -> bool, . { 18,736,381 (0.0%) match self.map.table.get(hash, |(k, _)| is_match(k)) { . Some((key, value)) => Some((key, value)), . None => None, . } 7,899 (0.0%) } . . /// Access an immutable entry by hash and matching function. . /// . /// # Examples . /// . /// ``` . /// use core::hash::{BuildHasher, Hash}; . /// use hashbrown::HashMap; -- line 3328 ---------------------------------------- -- line 3340 ---------------------------------------- . /// assert_eq!(map.raw_entry().from_hash(hash, |k| k == &key), Some((&"a", &100))); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . #[allow(clippy::wrong_self_convention)] . pub fn from_hash(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)> . where . F: FnMut(&K) -> bool, . { 14,405 (0.0%) self.search(hash, is_match) . } . } . . impl<'a, K, V, S, A: Allocator + Clone> RawEntryMut<'a, K, V, S, A> { . /// Sets the value of the entry, and returns a RawOccupiedEntryMut. . /// . /// # Examples . /// -- line 3356 ---------------------------------------- -- line 4002 ---------------------------------------- . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . #[allow(clippy::shadow_unrelated)] . pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V) . where . K: Hash, . S: BuildHasher, . { 4,418,555 (0.0%) let &mut (ref mut k, ref mut v) = self.table.insert_entry( . hash, . (key, value), . make_hasher::<_, V, S>(self.hash_builder), . ); . (k, v) . } . . /// Set the value of an entry with a custom hasher function. -- line 4018 ---------------------------------------- -- line 4715 ---------------------------------------- . /// let mut vec: Vec<(&str, i32)> = map.into_iter().collect(); . /// // The `IntoIter` iterator produces items in arbitrary order, so . /// // the items must be sorted to test them against a sorted array. . /// vec.sort_unstable(); . /// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3)]); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . fn into_iter(self) -> IntoIter { 9 (0.0%) IntoIter { . inner: self.table.into_iter(), . } . } . } . . impl<'a, K, V> Iterator for Iter<'a, K, V> { . type Item = (&'a K, &'a V); . . #[cfg_attr(feature = "inline-more", inline)] . fn next(&mut self) -> Option<(&'a K, &'a V)> { . // Avoid `Option::map` because it bloats LLVM IR. 7,849 (0.0%) match self.inner.next() { . Some(x) => unsafe { . let r = x.as_ref(); . Some((&r.0, &r.1)) . }, . None => None, . } . } . #[cfg_attr(feature = "inline-more", inline)] -- line 4743 ---------------------------------------- -- line 4755 ---------------------------------------- . impl FusedIterator for Iter<'_, K, V> {} . . impl<'a, K, V> Iterator for IterMut<'a, K, V> { . type Item = (&'a K, &'a mut V); . . #[cfg_attr(feature = "inline-more", inline)] . fn next(&mut self) -> Option<(&'a K, &'a mut V)> { . // Avoid `Option::map` because it bloats LLVM IR. 5 (0.0%) match self.inner.next() { . Some(x) => unsafe { . let r = x.as_mut(); . Some((&r.0, &mut r.1)) . }, . None => None, . } . } . #[cfg_attr(feature = "inline-more", inline)] -- line 4771 ---------------------------------------- -- line 5617 ---------------------------------------- . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . pub fn insert(self, value: V) -> &'a mut V . where . K: Hash, . S: BuildHasher, . { . let table = &mut self.table.table; 78 (0.0%) let entry = table.insert_entry( . self.hash, . (self.key, value), . make_hasher::<_, V, S>(&self.table.hash_builder), . ); . &mut entry.1 . } . . #[cfg_attr(feature = "inline-more", inline)] -- line 5633 ---------------------------------------- -- line 6435 ---------------------------------------- . /// . /// let mut vec: Vec<_> = new_map.into_iter().collect(); . /// // The `IntoIter` iterator produces items in arbitrary order, so the . /// // items must be sorted to test them against a sorted array. . /// vec.sort_unstable(); . /// assert_eq!(vec, [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] 1,740,099 (0.0%) fn extend>(&mut self, iter: T) { . // Keys may be already present or show multiple times in the iterator. . // Reserve the entire hint lower bound if the map is empty. . // Otherwise reserve half the hint (rounded up), so the map . // will only resize twice in the worst case. . let iter = iter.into_iter(); 1,128,627 (0.0%) let reserve = if self.is_empty() { . iter.size_hint().0 . } else { . (iter.size_hint().0 + 1) / 2 . }; . self.reserve(reserve); 2,307,221 (0.0%) iter.for_each(move |(k, v)| { 7,628,889 (0.0%) self.insert(k, v); . }); 1,468,035 (0.0%) } . . #[inline] . #[cfg(feature = "nightly")] . fn extend_one(&mut self, (k, v): (K, V)) { . self.insert(k, v); . } . . #[inline] -- line 6466 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.0/src/raw/bitmask.rs -------------------------------------------------------------------------------- Ir__________________ 424,033 (0.0%) -- line 23 ---------------------------------------- . . #[allow(clippy::use_self)] . impl BitMask { . /// Returns a new `BitMask` with all bits inverted. . #[inline] . #[must_use] . #[allow(dead_code)] . pub(crate) fn invert(self) -> Self { 6,685,211 (0.0%) BitMask(self.0 ^ BITMASK_MASK) . } . . /// Returns a new `BitMask` with the lowest bit removed. . #[inline] . #[must_use] . fn remove_lowest_bit(self) -> Self { 1,895,156,841 (0.8%) BitMask(self.0 & (self.0 - 1)) . } . . /// Returns whether the `BitMask` has at least one set bit. . #[inline] . pub(crate) fn any_bit_set(self) -> bool { 296,975,512 (0.1%) self.0 != 0 . } . . /// Returns the first set bit in the `BitMask`, if there is one. . #[inline] . pub(crate) fn lowest_set_bit(self) -> Option { 5,874,983,826 (2.4%) if let Some(nonzero) = NonZeroBitMaskWord::new(self.0) { . Some(Self::nonzero_trailing_zeros(nonzero)) . } else { . None . } . } . . /// Returns the number of trailing zeroes in the `BitMask`. . #[inline] -- line 58 ---------------------------------------- -- line 121 ---------------------------------------- . } . } . . impl Iterator for BitMaskIter { . type Item = usize; . . #[inline] . fn next(&mut self) -> Option { 2,146,854,517 (0.9%) let bit = self.0.lowest_set_bit()?; 220 (0.0%) self.0 = self.0.remove_lowest_bit(); . Some(bit) . } . } -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.14.0/src/raw/mod.rs -------------------------------------------------------------------------------- Ir__________________ 3,717,090,257 (1.5%) -- line 97 ---------------------------------------- . const EMPTY: u8 = 0b1111_1111; . . /// Control byte value for a deleted bucket. . const DELETED: u8 = 0b1000_0000; . . /// Checks whether a control byte represents a full bucket (top bit is clear). . #[inline] . fn is_full(ctrl: u8) -> bool { 285,782,276 (0.1%) ctrl & 0x80 == 0 . } . . /// Checks whether a control byte represents a special value (top bit is set). . #[inline] . fn is_special(ctrl: u8) -> bool { . ctrl & 0x80 != 0 . } . . /// Checks whether a special control value is EMPTY (just check 1 bit). . #[inline] . fn special_is_empty(ctrl: u8) -> bool { . debug_assert!(is_special(ctrl)); 72,370,029 (0.0%) ctrl & 0x01 != 0 . } . . /// Primary hash function, used to select the initial bucket to probe from. . #[inline] . #[allow(clippy::cast_possible_truncation)] . fn h1(hash: u64) -> usize { . // On 32-bit platforms we simply ignore the higher hash bits. . hash as usize -- line 126 ---------------------------------------- -- line 136 ---------------------------------------- . /// Secondary hash function, saved in the low 7 bits of the control byte. . #[inline] . #[allow(clippy::cast_possible_truncation)] . fn h2(hash: u64) -> u8 { . // Grab the top 7 bits of the hash. While the hash is normally a full 64-bit . // value, some hash functions (such as FxHash) produce a usize result . // instead, which means that the top 32 bits are 0 on 32-bit platforms. . // So we use MIN_HASH_LEN constant to handle this. 2,695,078,094 (1.1%) let top7 = hash >> (MIN_HASH_LEN * 8 - 7); 5 (0.0%) (top7 & 0x7f) as u8 // truncation . } . . /// Probe sequence based on triangular numbers, which is guaranteed (since our . /// table size is a power of two) to visit every group of elements exactly once. . /// . /// A triangular probe has us jump by 1 more group every time. So first we . /// jump by 1 group (meaning we just continue our linear scan), then 2 groups . /// (skipping over 1 group), then 3 groups (skipping over 2 groups), and so on. -- line 153 ---------------------------------------- -- line 163 ---------------------------------------- . #[inline] . fn move_next(&mut self, bucket_mask: usize) { . // We should have found an empty bucket by now and ended the probe. . debug_assert!( . self.stride <= bucket_mask, . "Went past end of probe sequence" . ); . 443,093,954 (0.2%) self.stride += Group::WIDTH; 442,584,252 (0.2%) self.pos += self.stride; 118,897,398 (0.0%) self.pos &= bucket_mask; . } . } . . /// Returns the number of buckets needed to hold the given number of items, . /// taking the maximum load factor into account. . /// . /// Returns `None` if an overflow occurs. . // Workaround for emscripten bug emscripten-core/emscripten-fastcomp#258 . #[cfg_attr(target_os = "emscripten", inline(never))] . #[cfg_attr(not(target_os = "emscripten"), inline)] . fn capacity_to_buckets(cap: usize) -> Option { . debug_assert_ne!(cap, 0); . . // For small tables we require at least 1 empty bucket so that lookups are . // guaranteed to terminate if an element doesn't exist in the table. 1,471,306 (0.0%) if cap < 8 { . // We don't bother with a table size of 2 buckets since that can only . // hold a single element. Instead we skip directly to a 4 bucket table . // which can hold 3 elements. 469,290 (0.0%) return Some(if cap < 4 { 4 } else { 8 }); . } . . // Otherwise require 1/8 buckets to be empty (87.5% load) . // . // Be careful when modifying this, calculate_layout relies on the . // overflow check here. 4,015,848 (0.0%) let adjusted_cap = cap.checked_mul(8)? / 7; . . // Any overflows will have been caught by the checked_mul. Also, any . // rounding errors from the division above will be cleaned up by . // next_power_of_two (which can't overflow because of the previous division). . Some(adjusted_cap.next_power_of_two()) . } . . /// Returns the maximum effective capacity for the given bucket mask, taking . /// the maximum load factor into account. . #[inline] . fn bucket_mask_to_capacity(bucket_mask: usize) -> usize { 10,330,338 (0.0%) if bucket_mask < 8 { . // For tables with 1/2/4/8 buckets, we always reserve one empty slot. . // Keep in mind that the bucket mask is one less than the bucket count. . bucket_mask . } else { . // For larger tables we reserve 12.5% of the slots as empty. . ((bucket_mask + 1) / 8) * 7 . } . } -- line 220 ---------------------------------------- -- line 243 ---------------------------------------- . . #[inline] . fn calculate_layout_for(self, buckets: usize) -> Option<(Layout, usize)> { . debug_assert!(buckets.is_power_of_two()); . . let TableLayout { size, ctrl_align } = self; . // Manual layout calculation since Layout methods are not yet stable. . let ctrl_offset = 1,077,572 (0.0%) size.checked_mul(buckets)?.checked_add(ctrl_align - 1)? & !(ctrl_align - 1); 3,522,623 (0.0%) let len = ctrl_offset.checked_add(buckets + Group::WIDTH)?; . . // We need an additional check to ensure that the allocation doesn't . // exceed `isize::MAX` (https://github.com/rust-lang/rust/pull/95295). 450 (0.0%) if len > isize::MAX as usize - (ctrl_align - 1) { . return None; . } . . Some(( . unsafe { Layout::from_size_align_unchecked(len, ctrl_align) }, . ctrl_offset, . )) . } -- line 264 ---------------------------------------- -- line 573 ---------------------------------------- . /// If we drop data, but do not erase `data control byte` it leads to . /// double drop when [`RawTable`] goes out of scope. . /// . /// [`ptr::drop_in_place`]: https://doc.rust-lang.org/core/ptr/fn.drop_in_place.html . /// [`RawTable`]: crate::raw::RawTable . /// [`RawTable::erase`]: crate::raw::RawTable::erase . #[cfg_attr(feature = "inline-more", inline)] . pub(crate) unsafe fn drop(&self) { 92 (0.0%) self.as_ptr().drop_in_place(); . } . . /// Reads the `value` from `self` without moving it. This leaves the . /// memory in `self` unchanged. . /// . /// # Safety . /// . /// See [`ptr::read`] for safety concerns. -- line 589 ---------------------------------------- -- line 819 ---------------------------------------- . #[cfg(feature = "raw")] . pub fn try_with_capacity(capacity: usize) -> Result { . Self::try_with_capacity_in(capacity, Global) . } . . /// Allocates a new hash table with at least enough capacity for inserting . /// the given number of elements without reallocating. . pub fn with_capacity(capacity: usize) -> Self { 2,106 (0.0%) Self::with_capacity_in(capacity, Global) . } . } . . impl RawTable { . const TABLE_LAYOUT: TableLayout = TableLayout::new::(); . const DATA_NEEDS_DROP: bool = mem::needs_drop::(); . . /// Creates a new empty hash table without allocating any memory, using the . /// given allocator. . /// . /// In effect this returns a table with exactly 1 bucket. However we can . /// leave the data pointer dangling since that bucket is never written to . /// due to our load factor forcing us to always have at least 1 free bucket. . #[inline] . pub const fn new_in(alloc: A) -> Self { 24,705 (0.0%) Self { . table: RawTableInner::new_in(alloc), . marker: PhantomData, . } . } . . /// Allocates a new hash table with the given number of buckets. . /// . /// The control bytes are left uninitialized. -- line 851 ---------------------------------------- -- line 890 ---------------------------------------- . /// capacity for inserting the given number of elements without reallocating. . #[cfg(feature = "raw")] . pub fn try_with_capacity_in(capacity: usize, alloc: A) -> Result { . Self::fallible_with_capacity(alloc, capacity, Fallibility::Fallible) . } . . /// Allocates a new hash table using the given allocator, with at least enough capacity for . /// inserting the given number of elements without reallocating. 6,392 (0.0%) pub fn with_capacity_in(capacity: usize, alloc: A) -> Self { . // Avoid `Result::unwrap_or_else` because it bloats LLVM IR. . match Self::fallible_with_capacity(alloc, capacity, Fallibility::Infallible) { 3,196 (0.0%) Ok(capacity) => capacity, . Err(_) => unsafe { hint::unreachable_unchecked() }, . } 7,191 (0.0%) } . . /// Returns a reference to the underlying allocator. . #[inline] . pub fn allocator(&self) -> &A { . &self.table.alloc . } . . /// Deallocates the table without dropping any entries. -- line 912 ---------------------------------------- -- line 913 ---------------------------------------- . #[cfg_attr(feature = "inline-more", inline)] . unsafe fn free_buckets(&mut self) { . self.table.free_buckets(Self::TABLE_LAYOUT); . } . . /// Returns pointer to one past last element of data table. . #[inline] . pub unsafe fn data_end(&self) -> NonNull { 130,656 (0.0%) NonNull::new_unchecked(self.table.ctrl.as_ptr().cast()) . } . . /// Returns pointer to start of data table. . #[inline] . #[cfg(any(feature = "raw", feature = "nightly"))] . pub unsafe fn data_start(&self) -> NonNull { . NonNull::new_unchecked(self.data_end().as_ptr().wrapping_sub(self.buckets())) . } -- line 929 ---------------------------------------- -- line 999 ---------------------------------------- . InsertSlot { . index: self.bucket_index(&item), . }, . ) . } . . /// Finds and removes an element from the table, returning it. . #[cfg_attr(feature = "inline-more", inline)] 2,298,085 (0.0%) pub fn remove_entry(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option { . // Avoid `Option::map` because it bloats LLVM IR. . match self.find(hash, eq) { 7,402 (0.0%) Some(bucket) => Some(unsafe { self.remove(bucket).0 }), 77,930 (0.0%) None => None, . } 2,364,644 (0.0%) } . . /// Marks all table buckets as empty without dropping their contents. . #[cfg_attr(feature = "inline-more", inline)] . pub fn clear_no_drop(&mut self) { . self.table.clear_no_drop(); . } . . /// Removes all elements from the table without freeing the backing memory. . #[cfg_attr(feature = "inline-more", inline)] . pub fn clear(&mut self) { 6,346 (0.0%) if self.is_empty() { . // Special case empty table to avoid surprising O(capacity) time. . return; . } . // Ensure that the table is reset even if one of the drops panic . let mut self_ = guard(self, |self_| self_.clear_no_drop()); . unsafe { . self_.drop_elements(); . } . } . . unsafe fn drop_elements(&mut self) { 126,351 (0.0%) if Self::DATA_NEEDS_DROP && !self.is_empty() { . for item in self.iter() { . item.drop(); . } . } . } . . /// Shrinks the table to fit `max(self.len(), min_size)` elements. . #[cfg_attr(feature = "inline-more", inline)] -- line 1044 ---------------------------------------- -- line 1076 ---------------------------------------- . } . } . } . . /// Ensures that at least `additional` items can be inserted into the table . /// without reallocation. . #[cfg_attr(feature = "inline-more", inline)] . pub fn reserve(&mut self, additional: usize, hasher: impl Fn(&T) -> u64) { 403,911,530 (0.2%) if unlikely(additional > self.table.growth_left) { . // Avoid `Result::unwrap_or_else` because it bloats LLVM IR. 2,902,920 (0.0%) if self . .reserve_rehash(additional, hasher, Fallibility::Infallible) . .is_err() . { . unsafe { hint::unreachable_unchecked() } . } . } . } . -- line 1094 ---------------------------------------- -- line 1105 ---------------------------------------- . } else { . Ok(()) . } . } . . /// Out-of-line slow path for `reserve` and `try_reserve`. . #[cold] . #[inline(never)] 5,144,282 (0.0%) fn reserve_rehash( . &mut self, . additional: usize, . hasher: impl Fn(&T) -> u64, . fallibility: Fallibility, . ) -> Result<(), TryReserveError> { . unsafe { . self.table.reserve_rehash_inner( . additional, 170,200 (0.0%) &|table, index| hasher(table.bucket::(index).as_ref()), . fallibility, . Self::TABLE_LAYOUT, . if Self::DATA_NEEDS_DROP { . Some(mem::transmute(ptr::drop_in_place:: as unsafe fn(*mut T))) . } else { . None . }, . ) . } 6,597,956 (0.0%) } . . /// Allocates a new table of a different size and moves the contents of the . /// current table into it. . fn resize( . &mut self, . capacity: usize, . hasher: impl Fn(&T) -> u64, . fallibility: Fallibility, -- line 1140 ---------------------------------------- -- line 1148 ---------------------------------------- . ) . } . } . . /// Inserts a new element into the table, and returns its raw bucket. . /// . /// This does not check if the given element already exists in the table. . #[cfg_attr(feature = "inline-more", inline)] 76,518 (0.0%) pub fn insert(&mut self, hash: u64, value: T, hasher: impl Fn(&T) -> u64) -> Bucket { . unsafe { 1,802,794 (0.0%) let mut slot = self.table.find_insert_slot(hash); . . // We can avoid growing the table once we have reached our load . // factor if we are replacing a tombstone. This works since the . // number of EMPTY slots does not change in this case. . let old_ctrl = *self.table.ctrl(slot.index); 1,805,112 (0.0%) if unlikely(self.table.growth_left == 0 && special_is_empty(old_ctrl)) { . self.reserve(1, hasher); 2,954 (0.0%) slot = self.table.find_insert_slot(hash); . } . . self.insert_in_slot(hash, slot, value) . } 51,012 (0.0%) } . . /// Attempts to insert a new element without growing the table and return its raw bucket. . /// . /// Returns an `Err` containing the given element if inserting it would require growing the . /// table. . /// . /// This does not check if the given element already exists in the table. . #[cfg(feature = "raw")] -- line 1179 ---------------------------------------- -- line 1190 ---------------------------------------- . } . } . } . . /// Inserts a new element into the table, and returns a mutable reference to it. . /// . /// This does not check if the given element already exists in the table. . #[cfg_attr(feature = "inline-more", inline)] 5,302,788 (0.0%) pub fn insert_entry(&mut self, hash: u64, value: T, hasher: impl Fn(&T) -> u64) -> &mut T { . unsafe { self.insert(hash, value, hasher).as_mut() } 3,535,192 (0.0%) } . . /// Inserts a new element into the table, without growing the table. . /// . /// There must be enough space in the table to insert the new element. . /// . /// This does not check if the given element already exists in the table. . #[cfg_attr(feature = "inline-more", inline)] . #[cfg(any(feature = "raw", feature = "rustc-internal-api"))] . pub unsafe fn insert_no_grow(&mut self, hash: u64, value: T) -> Bucket { 469,421 (0.0%) let (index, old_ctrl) = self.table.prepare_insert_slot(hash); . let bucket = self.table.bucket(index); . . // If we are replacing a DELETED entry then we don't need to update . // the load counter. 522,369 (0.0%) self.table.growth_left -= special_is_empty(old_ctrl) as usize; . . bucket.write(value); 384,285 (0.0%) self.table.items += 1; . bucket . } . . /// Temporary removes a bucket, applying the given function to the removed . /// element and optionally put back the returned value in the same bucket. . /// . /// Returns `true` if the bucket still contains an element . /// -- line 1226 ---------------------------------------- -- line 1256 ---------------------------------------- . pub fn find_or_find_insert_slot( . &mut self, . hash: u64, . mut eq: impl FnMut(&T) -> bool, . hasher: impl Fn(&T) -> u64, . ) -> Result, InsertSlot> { . self.reserve(1, hasher); . 272,624,057 (0.1%) match self . .table . .find_or_find_insert_slot_inner(hash, &mut |index| unsafe { 6,635,684,423 (2.8%) eq(self.bucket(index).as_ref()) . }) { . Ok(index) => Ok(unsafe { self.bucket(index) }), . Err(slot) => Err(slot), . } . } . . /// Inserts a new element into the table in the given slot, and returns its . /// raw bucket. -- line 1275 ---------------------------------------- -- line 1276 ---------------------------------------- . /// . /// # Safety . /// . /// `slot` must point to a slot previously returned by . /// `find_or_find_insert_slot`, and no mutation of the table must have . /// occurred since that call. . #[inline] . pub unsafe fn insert_in_slot(&mut self, hash: u64, slot: InsertSlot, value: T) -> Bucket { 2,752 (0.0%) let old_ctrl = *self.table.ctrl(slot.index); . self.table.record_item_insert_at(slot.index, old_ctrl, hash); . . let bucket = self.bucket(slot.index); . bucket.write(value); . bucket . } . . /// Searches for an element in the table. . #[inline] 7,173 (0.0%) pub fn find(&self, hash: u64, mut eq: impl FnMut(&T) -> bool) -> Option> { 83,167,323 (0.0%) let result = self.table.find_inner(hash, &mut |index| unsafe { 22,645,655 (0.0%) eq(self.bucket(index).as_ref()) 217,323 (0.0%) }); . . // Avoid `Option::map` because it bloats LLVM IR. 20,122,450 (0.0%) match result { . Some(index) => Some(unsafe { self.bucket(index) }), . None => None, . } 6,376 (0.0%) } . . /// Gets a reference to an element in the table. . #[inline] . pub fn get(&self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&T> { . // Avoid `Option::map` because it bloats LLVM IR. 6,722,752 (0.0%) match self.find(hash, eq) { . Some(bucket) => Some(unsafe { bucket.as_ref() }), . None => None, . } . } . . /// Gets a mutable reference to an element in the table. . #[inline] . pub fn get_mut(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&mut T> { -- line 1318 ---------------------------------------- -- line 1381 ---------------------------------------- . } . . /// Returns the number of elements the map can hold without reallocating. . /// . /// This number is a lower bound; the table might be able to hold . /// more, but is guaranteed to be able to hold at least this many. . #[inline] . pub fn capacity(&self) -> usize { 28,199 (0.0%) self.table.items + self.table.growth_left . } . . /// Returns the number of elements in the table. . #[inline] . pub fn len(&self) -> usize { 198,639 (0.0%) self.table.items . } . . /// Returns `true` if the table contains no elements. . #[inline] . pub fn is_empty(&self) -> bool { 126,351 (0.0%) self.len() == 0 . } . . /// Returns the number of buckets in the table. . #[inline] . pub fn buckets(&self) -> usize { 148 (0.0%) self.table.bucket_mask + 1 . } . . /// Checks whether the bucket at `index` is full. . /// . /// # Safety . /// . /// The caller must ensure `index` is less than the number of buckets. . #[inline] -- line 1415 ---------------------------------------- -- line 1419 ---------------------------------------- . . /// Returns an iterator over every element in the table. It is up to . /// the caller to ensure that the `RawTable` outlives the `RawIter`. . /// Because we cannot make the `next` method unsafe on the `RawIter` . /// struct, we have to make the `iter` method unsafe. . #[inline] . pub unsafe fn iter(&self) -> RawIter { . let data = Bucket::from_base_index(self.data_end(), 0); 3,728 (0.0%) RawIter { . iter: RawIterRange::new(self.table.ctrl.as_ptr(), data, self.table.buckets()), 37,073 (0.0%) items: self.table.items, . } . } . . /// Returns an iterator over occupied buckets that could match a given hash. . /// . /// `RawTable` only stores 7 bits of the hash value, so this iterator may . /// return items that have a hash value different than the one provided. You . /// should always validate the returned values before using them. -- line 1437 ---------------------------------------- -- line 1460 ---------------------------------------- . /// . /// Iteration starts at the provided iterator's current location. . /// . /// It is up to the caller to ensure that the iterator is valid for this . /// `RawTable` and covers all items that remain in the table. . #[cfg_attr(feature = "inline-more", inline)] . pub unsafe fn drain_iter_from(&mut self, iter: RawIter) -> RawDrain<'_, T, A> { . debug_assert_eq!(iter.len(), self.len()); 3 (0.0%) RawDrain { 5 (0.0%) iter, . table: ManuallyDrop::new(mem::replace(self, Self::new_in(self.table.alloc.clone()))), . orig_table: NonNull::from(self), . marker: PhantomData, . } . } . . /// Returns an iterator which consumes all elements from the table. . /// -- line 1477 ---------------------------------------- -- line 1491 ---------------------------------------- . alloc, . } . } . . /// Converts the table into a raw allocation. The contents of the table . /// should be dropped using a `RawIter` before freeing the allocation. . #[cfg_attr(feature = "inline-more", inline)] . pub(crate) fn into_allocation(self) -> Option<(NonNull, Layout)> { 1,051 (0.0%) let alloc = if self.table.is_empty_singleton() { . None . } else { . // Avoid `Option::unwrap_or_else` because it bloats LLVM IR. . let (layout, ctrl_offset) = . match Self::TABLE_LAYOUT.calculate_layout_for(self.table.buckets()) { . Some(lco) => lco, . None => unsafe { hint::unreachable_unchecked() }, . }; -- line 1507 ---------------------------------------- -- line 1570 ---------------------------------------- . debug_assert!(buckets.is_power_of_two()); . . // Avoid `Option::ok_or_else` because it bloats LLVM IR. . let (layout, ctrl_offset) = match table_layout.calculate_layout_for(buckets) { . Some(lco) => lco, . None => return Err(fallibility.capacity_overflow()), . }; . 1,472,428 (0.0%) let ptr: NonNull = match do_alloc(&alloc, layout) { . Ok(block) => block.cast(), . Err(_) => return Err(fallibility.alloc_err(layout)), . }; . . // SAFETY: null pointer will be caught in above check . let ctrl = NonNull::new_unchecked(ptr.as_ptr().add(ctrl_offset)); . Ok(Self { . ctrl, 735,613 (0.0%) bucket_mask: buckets - 1, . items: 0, . growth_left: bucket_mask_to_capacity(buckets - 1), . alloc, . }) . } . . /// Attempts to allocate a new [`RawTableInner`] with at least enough . /// capacity for inserting the given number of elements without reallocating. -- line 1595 ---------------------------------------- -- line 1597 ---------------------------------------- . /// All the control bytes are initialized with the [`EMPTY`] bytes. . #[inline] . fn fallible_with_capacity( . alloc: A, . table_layout: TableLayout, . capacity: usize, . fallibility: Fallibility, . ) -> Result { 1,598 (0.0%) if capacity == 0 { . Ok(Self::new_in(alloc)) . } else { . // SAFETY: We checked that we could successfully allocate the new table, and then . // initialized all control bytes with the constant `EMPTY` byte. . unsafe { . let buckets = . capacity_to_buckets(capacity).ok_or_else(|| fallibility.capacity_overflow())?; . -- line 1613 ---------------------------------------- -- line 1631 ---------------------------------------- . // bytes outside the range of the table are filled with . // EMPTY entries. These will unfortunately trigger a . // match, but once masked may point to a full bucket that . // is already occupied. We detect this situation here and . // perform a second scan starting at the beginning of the . // table. This second scan is guaranteed to find an empty . // slot (due to the load factor) before hitting the trailing . // control bytes (containing EMPTY). 171,917,908 (0.1%) if unlikely(self.is_bucket_full(index)) { . debug_assert!(self.bucket_mask < Group::WIDTH); . // SAFETY: . // . // * We are in range and `ptr = self.ctrl(0)` are valid for reads . // and properly aligned, because the table is already allocated . // (see `TableLayout::calculate_layout_for` and `ptr::read`); . // . // * For tables larger than the group width (self.buckets() >= Group::WIDTH), -- line 1647 ---------------------------------------- -- line 1661 ---------------------------------------- . } . . /// Finds the position to insert something in a group. . /// This may have false positives and must be fixed up with `fix_insert_slot` before it's used. . #[inline] . fn find_insert_slot_in_group(&self, group: &Group, probe_seq: &ProbeSeq) -> Option { . let bit = group.match_empty_or_deleted().lowest_set_bit(); . 1,065,945,119 (0.4%) if likely(bit.is_some()) { . Some((probe_seq.pos + bit.unwrap()) & self.bucket_mask) . } else { . None . } . } . . /// Searches for an element in the table, or a potential slot where that element could be . /// inserted. -- line 1677 ---------------------------------------- -- line 1687 ---------------------------------------- . let mut insert_slot = None; . . let h2_hash = h2(hash); . let mut probe_seq = self.probe_seq(hash); . . loop { . let group = unsafe { Group::load(self.ctrl(probe_seq.pos)) }; . 123,543 (0.0%) for bit in group.match_byte(h2_hash) { 3,319,238,566 (1.4%) let index = (probe_seq.pos + bit) & self.bucket_mask; . 1,903,765 (0.0%) if likely(eq(index)) { . return Ok(index); . } . } . . // We didn't find the element we were looking for in the group, try to get an . // insertion slot from the group if we don't have one yet. 289,719,477 (0.1%) if likely(insert_slot.is_none()) { . insert_slot = self.find_insert_slot_in_group(&group, &probe_seq); . } . . // Only stop the search if the group contains at least one empty element. . // Otherwise, the element that we are looking for might be in a following group. 289,747,623 (0.1%) if likely(group.match_empty().any_bit_set()) { . // We must have found a insert slot by now, since the current group contains at . // least one. For tables smaller than the group width, there will still be an . // empty element in the current (and only) group due to the load factor. . unsafe { . return Err(self.fix_insert_slot(insert_slot.unwrap_unchecked())); . } . } . -- line 1719 ---------------------------------------- -- line 1723 ---------------------------------------- . . /// Searches for an empty or deleted bucket which is suitable for inserting . /// a new element and sets the hash for that slot. . /// . /// There must be at least 1 empty bucket in the table. . #[inline] . unsafe fn prepare_insert_slot(&self, hash: u64) -> (usize, u8) { . let index = self.find_insert_slot(hash).index; 2,278 (0.0%) let old_ctrl = *self.ctrl(index); . self.set_ctrl_h2(index, hash); . (index, old_ctrl) . } . . /// Searches for an empty or deleted bucket which is suitable for inserting . /// a new element, returning the `index` for the new [`Bucket`]. . /// . /// This function does not make any changes to the `data` part of the table, or any -- line 1739 ---------------------------------------- -- line 1770 ---------------------------------------- . // . // * Also, even if `RawTableInner` is not already allocated, `ProbeSeq.pos` will . // always return "0" (zero), so Group::load will read unaligned `Group::static_empty()` . // bytes, which is safe (see RawTableInner::new_in). . unsafe { . let group = Group::load(self.ctrl(probe_seq.pos)); . let index = self.find_insert_slot_in_group(&group, &probe_seq); . 121,233,972 (0.1%) if likely(index.is_some()) { . return self.fix_insert_slot(index.unwrap_unchecked()); . } . } . probe_seq.move_next(self.bucket_mask); . } . } . . /// Searches for an element in a table, returning the `index` of the found element. -- line 1786 ---------------------------------------- -- line 1808 ---------------------------------------- . // `self.bucket_mask + 1 + Group::WIDTH` (in fact, this means that the last control . // byte will never be read for the allocated table); . // . // * Also, even if `RawTableInner` is not already allocated, `ProbeSeq.pos` will . // always return "0" (zero), so Group::load will read unaligned `Group::static_empty()` . // bytes, which is safe (see RawTableInner::new_in). . let group = unsafe { Group::load(self.ctrl(probe_seq.pos)) }; . 3,466 (0.0%) for bit in group.match_byte(h2_hash) { . // This is the same as `(probe_seq.pos + bit) % self.buckets()` because the number . // of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`. 132,203,012 (0.1%) let index = (probe_seq.pos + bit) & self.bucket_mask; . 159,063,355 (0.1%) if likely(eq(index)) { . return Some(index); . } . } . 7,136,884 (0.0%) if likely(group.match_empty().any_bit_set()) { . return None; . } . . probe_seq.move_next(self.bucket_mask); . } . } . . /// Prepares for rehashing data in place (that is, without allocating new memory). -- line 1834 ---------------------------------------- -- line 1907 ---------------------------------------- . Bucket::from_base_index(self.data_end(), index) . } . . #[inline] . unsafe fn bucket_ptr(&self, index: usize, size_of: usize) -> *mut u8 { . debug_assert_ne!(self.bucket_mask, 0); . debug_assert!(index < self.buckets()); . let base: *mut u8 = self.data_end().as_ptr(); 684,121,100 (0.3%) base.sub((index + 1) * size_of) . } . . #[inline] . unsafe fn data_end(&self) -> NonNull { . NonNull::new_unchecked(self.ctrl.as_ptr().cast()) . } . . /// Returns an iterator-like object for a probe sequence on the table. . /// . /// This iterator never terminates, but is guaranteed to visit each bucket . /// group exactly once. The loop using `probe_seq` must terminate upon . /// reaching a group containing an empty bucket. . #[inline] . fn probe_seq(&self, hash: u64) -> ProbeSeq { . ProbeSeq { 201,004,703 (0.1%) pos: h1(hash) & self.bucket_mask, . stride: 0, . } . } . . /// Returns the index of a bucket for which a value must be inserted if there is enough rooom . /// in the table, otherwise returns error . #[cfg(feature = "raw")] . #[inline] -- line 1939 ---------------------------------------- -- line 1945 ---------------------------------------- . } else { . self.record_item_insert_at(index, old_ctrl, hash); . Ok(index) . } . } . . #[inline] . unsafe fn record_item_insert_at(&mut self, index: usize, old_ctrl: u8, hash: u64) { 72,108,620 (0.0%) self.growth_left -= usize::from(special_is_empty(old_ctrl)); . self.set_ctrl_h2(index, hash); 72,136,490 (0.0%) self.items += 1; . } . . #[inline] . fn is_in_same_group(&self, i: usize, new_i: usize, hash: u64) -> bool { . let probe_seq_pos = self.probe_seq(hash).pos; . let probe_index = . |pos: usize| (pos.wrapping_sub(probe_seq_pos) & self.bucket_mask) / Group::WIDTH; . probe_index(i) == probe_index(new_i) -- line 1963 ---------------------------------------- -- line 2074 ---------------------------------------- . // . // Real | Replicated . // --------------------------------------------- . // | [A] | [B] | [EMPTY] | [EMPTY] | [A] | [B] | . // --------------------------------------------- . . // This is the same as `(index.wrapping_sub(Group::WIDTH)) % self.buckets() + Group::WIDTH` . // because the number of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`. 238,895,209 (0.1%) let index2 = ((index.wrapping_sub(Group::WIDTH)) & self.bucket_mask) + Group::WIDTH; . . // SAFETY: The caller must uphold the safety rules for the [`RawTableInner::set_ctrl`] 172,228,164 (0.1%) *self.ctrl(index) = ctrl; 172,228,164 (0.1%) *self.ctrl(index2) = ctrl; . } . . /// Returns a pointer to a control byte. . /// . /// # Safety . /// . /// For the allocated [`RawTableInner`], the result is [`Undefined Behavior`], . /// if the `index` is greater than the `self.bucket_mask + 1 + Group::WIDTH`. -- line 2094 ---------------------------------------- -- line 2108 ---------------------------------------- . /// or saving `data element` from / into the [`RawTable`] / [`RawTableInner`]. . /// . /// [`Bucket::as_ptr()`]: Bucket::as_ptr() . /// [`Undefined Behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html . #[inline] . unsafe fn ctrl(&self, index: usize) -> *mut u8 { . debug_assert!(index < self.num_ctrl_bytes()); . // SAFETY: The caller must uphold the safety rules for the [`RawTableInner::ctrl`] 66,850,464 (0.0%) self.ctrl.as_ptr().add(index) . } . . #[inline] . fn buckets(&self) -> usize { 272,881 (0.0%) self.bucket_mask + 1 . } . . /// Checks whether the bucket at `index` is full. . /// . /// # Safety . /// . /// The caller must ensure `index` is less than the number of buckets. . #[inline] . unsafe fn is_bucket_full(&self, index: usize) -> bool { . debug_assert!(index < self.buckets()); 4,685,492 (0.0%) is_full(*self.ctrl(index)) . } . . #[inline] . fn num_ctrl_bytes(&self) -> usize { 2,275 (0.0%) self.bucket_mask + 1 + Group::WIDTH . } . . #[inline] . fn is_empty_singleton(&self) -> bool { 5,301,761 (0.0%) self.bucket_mask == 0 . } . . #[allow(clippy::mut_mut)] . #[inline] . unsafe fn prepare_resize( . &self, . table_layout: TableLayout, . capacity: usize, -- line 2150 ---------------------------------------- -- line 2154 ---------------------------------------- . . // Allocate and initialize the new table. . let mut new_table = RawTableInner::fallible_with_capacity( . self.alloc.clone(), . table_layout, . capacity, . fallibility, . )?; 2,135,699 (0.0%) new_table.growth_left -= self.items; . new_table.items = self.items; . . // The hash function may panic, in which case we simply free the new . // table without dropping any elements that may have been copied into . // it. . // . // This guard is also used to free the old table on success, see . // the comment at the bottom of this function. . Ok(guard(new_table, move |self_| { 16,170 (0.0%) if !self_.is_empty_singleton() { . self_.free_buckets(table_layout); . } . })) . } . . /// Reserves or rehashes to make room for `additional` more elements. . /// . /// This uses dynamic dispatch to reduce the amount of -- line 2180 ---------------------------------------- -- line 2185 ---------------------------------------- . &mut self, . additional: usize, . hasher: &dyn Fn(&mut Self, usize) -> u64, . fallibility: Fallibility, . layout: TableLayout, . drop: Option, . ) -> Result<(), TryReserveError> { . // Avoid `Option::ok_or_else` because it bloats LLVM IR. 1,469,792 (0.0%) let new_items = match self.items.checked_add(additional) { . Some(new_items) => new_items, . None => return Err(fallibility.capacity_overflow()), . }; 734,896 (0.0%) let full_capacity = bucket_mask_to_capacity(self.bucket_mask); 3,290,147 (0.0%) if new_items <= full_capacity / 2 { . // Rehash in-place without re-allocating if we have plenty of spare . // capacity that is locked up due to DELETED entries. . self.rehash_in_place(hasher, layout.size, drop); . Ok(()) . } else { . // Otherwise, conservatively resize to at least the next size up . // to avoid churning deletes into frequent rehashes. . self.resize_inner( 734,896 (0.0%) usize::max(new_items, full_capacity + 1), . hasher, . fallibility, . layout, . ) . } . } . . /// Allocates a new table of a different size and moves the contents of the -- line 2215 ---------------------------------------- -- line 2221 ---------------------------------------- . #[inline(always)] . unsafe fn resize_inner( . &mut self, . capacity: usize, . hasher: &dyn Fn(&mut Self, usize) -> u64, . fallibility: Fallibility, . layout: TableLayout, . ) -> Result<(), TryReserveError> { 102,465 (0.0%) let mut new_table = self.prepare_resize(layout, capacity, fallibility)?; . . // Copy all elements to the new table. . for i in 0..self.buckets() { 114,043,109 (0.0%) if !self.is_bucket_full(i) { . continue; . } . . // This may panic. . let hash = hasher(self, i); . . // We can use a simpler version of insert() here since: . // - there are no DELETED entries. -- line 2241 ---------------------------------------- -- line 2380 ---------------------------------------- . } else { . self.allocation_info(table_layout) . } . } . . /// Marks all table buckets as empty without dropping their contents. . #[inline] . fn clear_no_drop(&mut self) { 2,317 (0.0%) if !self.is_empty_singleton() { . unsafe { . self.ctrl(0).write_bytes(EMPTY, self.num_ctrl_bytes()); . } . } 2,317 (0.0%) self.items = 0; 2,317 (0.0%) self.growth_left = bucket_mask_to_capacity(self.bucket_mask); . } . . /// Erases the [`Bucket`]'s control byte at the given index so that it does not . /// triggered as full, decreases the `items` of the table and, if it can be done, . /// increases `self.growth_left`. . /// . /// This function does not actually erase / drop the [`Bucket`] itself, i.e. it . /// does not make any changes to the `data` parts of the table. The caller of this -- line 2402 ---------------------------------------- -- line 2428 ---------------------------------------- . /// [`Bucket::as_ptr`]: Bucket::as_ptr . /// [`undefined behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html . #[inline] . unsafe fn erase(&mut self, index: usize) { . debug_assert!(self.is_bucket_full(index)); . . // This is the same as `index.wrapping_sub(Group::WIDTH) % self.buckets()` because . // the number of buckets is a power of two, and `self.bucket_mask = self.buckets() - 1`. 402,933 (0.0%) let index_before = index.wrapping_sub(Group::WIDTH) & self.bucket_mask; . // SAFETY: . // - The caller must uphold the safety contract for `erase` method; . // - `index_before` is guaranteed to be in range due to masking with `self.bucket_mask` . let empty_before = Group::load(self.ctrl(index_before)).match_empty(); . let empty_after = Group::load(self.ctrl(index)).match_empty(); . . // Inserting and searching in the map is performed by two key functions: . // -- line 2444 ---------------------------------------- -- line 2471 ---------------------------------------- . // upon an `EMPTY` byte, so we can safely mark our erased byte as `EMPTY` as well. . // . // Finally, since `index_before == (index.wrapping_sub(Group::WIDTH) & self.bucket_mask) == index` . // and given all of the above, tables smaller than the group width (self.buckets() < Group::WIDTH) . // cannot have `DELETED` bytes. . // . // Note that in this context `leading_zeros` refers to the bytes at the end of a group, while . // `trailing_zeros` refers to the bytes at the beginning of a group. 1,604,557 (0.0%) let ctrl = if empty_before.leading_zeros() + empty_after.trailing_zeros() >= Group::WIDTH { . DELETED . } else { 683,546 (0.0%) self.growth_left += 1; . EMPTY . }; . // SAFETY: the caller must uphold the safety contract for `erase` method. . self.set_ctrl(index, ctrl); 401,905 (0.0%) self.items -= 1; . } . } . . impl Clone for RawTable { 37,744 (0.0%) fn clone(&self) -> Self { 11,416 (0.0%) if self.table.is_empty_singleton() { . Self::new_in(self.table.alloc.clone()) . } else { . unsafe { . // Avoid `Result::ok_or_else` because it bloats LLVM IR. . let new_table = match Self::new_uninitialized( . self.table.alloc.clone(), . self.table.buckets(), . Fallibility::Infallible, -- line 2501 ---------------------------------------- -- line 2509 ---------------------------------------- . // bytes are not initialized yet. . let mut guard = guard(ManuallyDrop::new(new_table), |new_table| { . new_table.free_buckets(); . }); . . guard.clone_from_spec(self); . . // Disarm the scope guard and return the newly created table. 3,608 (0.0%) ManuallyDrop::into_inner(ScopeGuard::into_inner(guard)) . } . } 48,077 (0.0%) } . . fn clone_from(&mut self, source: &Self) { 296 (0.0%) if source.table.is_empty_singleton() { . *self = Self::new_in(self.table.alloc.clone()); . } else { . unsafe { . // Make sure that if any panics occurs, we clear the table and . // leave it in an empty state. . let mut self_ = guard(self, |self_| { . self_.clear_no_drop(); . }); -- line 2531 ---------------------------------------- -- line 2536 ---------------------------------------- . // . // This leak is unavoidable: we can't try dropping more elements . // since this could lead to another panic and abort the process. . self_.drop_elements(); . . // If necessary, resize our table to match the source. . if self_.buckets() != source.buckets() { . // Skip our drop by using ptr::write. 148 (0.0%) if !self_.table.is_empty_singleton() { . self_.free_buckets(); . } . (&mut **self_ as *mut Self).write( . // Avoid `Result::unwrap_or_else` because it bloats LLVM IR. . match Self::new_uninitialized( . self_.table.alloc.clone(), . source.buckets(), . Fallibility::Infallible, -- line 2552 ---------------------------------------- -- line 2587 ---------------------------------------- . .ctrl(0) . .copy_to_nonoverlapping(self.table.ctrl(0), self.table.num_ctrl_bytes()); . source . .data_start() . .as_ptr() . .copy_to_nonoverlapping(self.data_start().as_ptr(), self.table.buckets()); . . self.table.items = source.table.items; 6 (0.0%) self.table.growth_left = source.table.growth_left; . } . } . . impl RawTable { . /// Common code for clone and clone_from. Assumes: . /// - `self.buckets() == source.buckets()`. . /// - Any existing elements have been dropped. . /// - The control bytes are not initialized yet. -- line 2603 ---------------------------------------- -- line 2620 ---------------------------------------- . } . } . } . }); . . for from in source.iter() { . let index = source.bucket_index(&from); . let to = guard.1.bucket(index); 280 (0.0%) to.write(from.as_ref().clone()); . . // Update the index in case we need to unwind. . guard.0 = index; . } . . // Successfully cloned all items, no need to clean up. . mem::forget(guard); . 1,050 (0.0%) self.table.items = source.table.items; 1,346 (0.0%) self.table.growth_left = source.table.growth_left; . } . . /// Variant of `clone_from` to use when a hasher is available. . #[cfg(feature = "raw")] 1,480 (0.0%) pub fn clone_from_with_hasher(&mut self, source: &Self, hasher: impl Fn(&T) -> u64) { . // If we have enough capacity in the table, just clear it and insert . // elements one by one. We don't do this if we have the same number of . // buckets as the source since we can just copy the contents directly . // in that case. 444 (0.0%) if self.table.buckets() != source.table.buckets() 148 (0.0%) && bucket_mask_to_capacity(self.table.bucket_mask) >= source.len() . { . self.clear(); . . let guard_self = guard(&mut *self, |self_| { . // Clear the partially copied table if a panic occurs, otherwise . // items and growth_left will be out of sync with the contents . // of the table. . self_.clear(); -- line 2657 ---------------------------------------- -- line 2675 ---------------------------------------- . // Successfully cloned all items, no need to clean up. . mem::forget(guard_self); . . self.table.items = source.table.items; . self.table.growth_left -= source.table.items; . } else { . self.clone_from(source); . } 1,184 (0.0%) } . } . . impl Default for RawTable { . #[inline] . fn default() -> Self { . Self::new_in(Default::default()) . } . } . . #[cfg(feature = "nightly")] . unsafe impl<#[may_dangle] T, A: Allocator + Clone> Drop for RawTable { . #[cfg_attr(feature = "inline-more", inline)] 1,351,091 (0.0%) fn drop(&mut self) { 1,358,919 (0.0%) if !self.table.is_empty_singleton() { . unsafe { . self.drop_elements(); 87,887 (0.0%) self.free_buckets(); . } . } 546,926 (0.0%) } . } . #[cfg(not(feature = "nightly"))] . impl Drop for RawTable { . #[cfg_attr(feature = "inline-more", inline)] . fn drop(&mut self) { 391,039 (0.0%) if !self.table.is_empty_singleton() { . unsafe { . self.drop_elements(); 2,725 (0.0%) self.free_buckets(); . } . } . } . } . . impl IntoIterator for RawTable { . type Item = T; . type IntoIter = RawIntoIter; -- line 2720 ---------------------------------------- -- line 2755 ---------------------------------------- . debug_assert_ne!(len, 0); . debug_assert_eq!(ctrl as usize % Group::WIDTH, 0); . let end = ctrl.add(len); . . // Load the first group and advance ctrl to point to the next group . let current_group = Group::load_aligned(ctrl).match_full(); . let next_ctrl = ctrl.add(Group::WIDTH); . 3,119 (0.0%) Self { . current_group: current_group.into_iter(), . data, . next_ctrl, . end, . } . } . . /// Splits a `RawIterRange` into two halves. -- line 2771 ---------------------------------------- -- line 3012 ---------------------------------------- . } . } . } else { . // We must have already iterated past the removed item. . } . } . . unsafe fn drop_elements(&mut self) { 244 (0.0%) if Self::DATA_NEEDS_DROP && self.len() != 0 { . for item in self { . item.drop(); . } . } . } . } . . impl Clone for RawIter { -- line 3028 ---------------------------------------- -- line 3037 ---------------------------------------- . . impl Iterator for RawIter { . type Item = Bucket; . . #[cfg_attr(feature = "inline-more", inline)] . fn next(&mut self) -> Option> { . // Inner iterator iterates over buckets . // so it can do unnecessary work if we already yielded all items. 133,965,824 (0.1%) if self.items == 0 { . return None; . } . . let nxt = unsafe { . // SAFETY: We check number of items to yield using `items` field. . self.iter.next_impl::() . }; . . debug_assert!(nxt.is_some()); 66,930,043 (0.0%) self.items -= 1; . . nxt 314 (0.0%) } . . #[inline] . fn size_hint(&self) -> (usize, Option) { . (self.items, Some(self.items)) . } . } . . impl ExactSizeIterator for RawIter {} -- line 3066 ---------------------------------------- -- line 3092 ---------------------------------------- . T: Sync, . A: Sync, . { . } . . #[cfg(feature = "nightly")] . unsafe impl<#[may_dangle] T, A: Allocator + Clone> Drop for RawIntoIter { . #[cfg_attr(feature = "inline-more", inline)] 968 (0.0%) fn drop(&mut self) { . unsafe { . // Drop all remaining elements . self.iter.drop_elements(); . . // Free the table 1,251 (0.0%) if let Some((ptr, layout)) = self.allocation { . self.alloc.deallocate(ptr, layout); . } . } 968 (0.0%) } . } . #[cfg(not(feature = "nightly"))] . impl Drop for RawIntoIter { . #[cfg_attr(feature = "inline-more", inline)] . fn drop(&mut self) { . unsafe { . // Drop all remaining elements . self.iter.drop_elements(); -- line 3118 ---------------------------------------- -- line 3125 ---------------------------------------- . } . } . . impl Iterator for RawIntoIter { . type Item = T; . . #[cfg_attr(feature = "inline-more", inline)] . fn next(&mut self) -> Option { 611 (0.0%) unsafe { Some(self.iter.next()?.read()) } . } . . #[inline] . fn size_hint(&self) -> (usize, Option) { . self.iter.size_hint() . } . } . -- line 3141 ---------------------------------------- -- line 3174 ---------------------------------------- . where . T: Sync, . A: Sync, . { . } . . impl Drop for RawDrain<'_, T, A> { . #[cfg_attr(feature = "inline-more", inline)] 8 (0.0%) fn drop(&mut self) { . unsafe { . // Drop all remaining elements. Note that this may panic. . self.iter.drop_elements(); . . // Reset the contents of the table now that all elements have been . // dropped. 1 (0.0%) self.table.clear_no_drop(); . . // Move the now empty table back to its original location. 42 (0.0%) self.orig_table . .as_ptr() . .copy_from_nonoverlapping(&*self.table, 1); . } 8 (0.0%) } . } . . impl Iterator for RawDrain<'_, T, A> { . type Item = T; . . #[cfg_attr(feature = "inline-more", inline)] . fn next(&mut self) -> Option { . unsafe { -- line 3204 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_data_structures/src/sso/map.rs -------------------------------------------------------------------------------- Ir__________________ 3,903,412 (0.0%) -- line 225 ---------------------------------------- . /// Inserts a key-value pair into the map. . /// . /// If the map did not have this key present, [`None`] is returned. . /// . /// If the map did have this key present, the value is updated, and the old . /// value is returned. The key is not updated, though; this matters for . /// types that can be `==` without being identical. See the [module-level . /// documentation] for more. 1,229,300,533 (0.5%) pub fn insert(&mut self, key: K, value: V) -> Option { 274,564,812 (0.1%) match self { 5,272,889 (0.0%) SsoHashMap::Array(array) => { . for (k, v) in array.iter_mut() { 15,714,640 (0.0%) if *k == key { . let old_value = std::mem::replace(v, value); . return Some(old_value); . } . } 10,232,300 (0.0%) if let Err(error) = array.try_push((key, value)) { . let mut map: FxHashMap = array.drain(..).collect(); 1,088,496 (0.0%) let (key, value) = error.element(); . map.insert(key, value); 2,527,148 (0.0%) *self = SsoHashMap::Map(map); . } . None . } 1,039,981,001 (0.4%) SsoHashMap::Map(map) => map.insert(key, value), . } 1,203,152,987 (0.5%) } . . /// Removes a key from the map, returning the value at the key if the key . /// was previously in the map. . pub fn remove(&mut self, key: &K) -> Option { . match self { . SsoHashMap::Array(array) => { . array.iter().position(|(k, _v)| k == key).map(|index| array.swap_remove(index).1) . } -- line 260 ---------------------------------------- -- line 271 ---------------------------------------- . array.iter().position(|(k, _v)| k == key).map(|index| array.swap_remove(index)) . } . SsoHashMap::Map(map) => map.remove_entry(key), . } . } . . /// Returns a reference to the value corresponding to the key. . pub fn get(&self, key: &K) -> Option<&V> { 19,896,840 (0.0%) match self { . SsoHashMap::Array(array) => { 17,587,077 (0.0%) for (k, v) in array { 18,944,213 (0.0%) if k == key { . return Some(v); . } . } . None . } . SsoHashMap::Map(map) => map.get(key), . } . } -- line 290 ---------------------------------------- -- line 401 ---------------------------------------- . impl IntoIterator for SsoHashMap { . type IntoIter = Either< . as IntoIterator>::IntoIter, . as IntoIterator>::IntoIter, . >; . type Item = ::Item; . . fn into_iter(self) -> Self::IntoIter { 782 (0.0%) match self { 4,692 (0.0%) SsoHashMap::Array(array) => Either::Left(array.into_iter()), . SsoHashMap::Map(map) => Either::Right(map.into_iter()), . } . } . } . . /// adapts Item of array reference iterator to Item of hashmap reference iterator. . #[inline(always)] . fn adapt_array_ref_it(pair: &(K, V)) -> (&K, &V) { -- line 418 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_data_structures/src/sso/set.rs -------------------------------------------------------------------------------- Ir________________ -- line 33 ---------------------------------------- . fn entry_to_key((k, _v): (K, V)) -> K { . k . } . . impl SsoHashSet { . /// Creates an empty `SsoHashSet`. . #[inline] . pub fn new() -> Self { 720,666 (0.0%) Self { map: SsoHashMap::new() } . } . . /// Creates an empty `SsoHashSet` with the specified capacity. . #[inline] . pub fn with_capacity(cap: usize) -> Self { . Self { map: SsoHashMap::with_capacity(cap) } . } . -- line 49 ---------------------------------------- -- line 126 ---------------------------------------- . /// Adds a value to the set. . /// . /// Returns whether the value was newly inserted. That is: . /// . /// - If the set did not previously contain this value, `true` is returned. . /// - If the set already contained this value, `false` is returned. . #[inline] . pub fn insert(&mut self, elem: T) -> bool { 262,259,348 (0.1%) self.map.insert(elem, ()).is_none() . } . . /// Removes a value from the set. Returns whether the value was . /// present in the set. . #[inline] . pub fn remove(&mut self, value: &T) -> bool { . self.map.remove(value).is_some() . } -- line 142 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_infer/src/infer/generalize.rs -------------------------------------------------------------------------------- Ir________________ 45,145,035 (0.0%) -- line 8 ---------------------------------------- . . use crate::infer::nll_relate::TypeRelatingDelegate; . use crate::infer::type_variable::TypeVariableValue; . use crate::infer::{InferCtxt, RegionVariableOrigin}; . . /// Attempts to generalize `term` for the type variable `for_vid`. . /// This checks for cycles -- that is, whether the type `term` . /// references `for_vid`. 17,798,364 (0.0%) pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into> + Relate<'tcx>>( . infcx: &InferCtxt<'tcx>, . delegate: &mut D, . term: T, . for_vid: impl Into>, . ambient_variance: ty::Variance, . ) -> RelateResult<'tcx, Generalization> { 5,932,788 (0.0%) let (for_universe, root_vid) = match for_vid.into() { . ty::TermVid::Ty(ty_vid) => ( 1,483,169 (0.0%) infcx.probe_ty_var(ty_vid).unwrap_err(), 1,483,255 (0.0%) ty::TermVid::Ty(infcx.inner.borrow_mut().type_variables().sub_root_var(ty_vid)), . ), . ty::TermVid::Const(ct_vid) => ( 1,483,225 (0.0%) infcx.probe_const_var(ct_vid).unwrap_err(), 28 (0.0%) ty::TermVid::Const(infcx.inner.borrow_mut().const_unification_table().find(ct_vid)), . ), . }; . 19,281,561 (0.0%) let mut generalizer = Generalizer { . infcx, . delegate, . ambient_variance, . root_vid, . for_universe, . root_term: term.into(), . needs_wf: false, . cache: Default::default(), . }; . 1,483,225 (0.0%) assert!(!term.has_escaping_bound_vars()); . let value = generalizer.relate(term, term)?; 1,483,197 (0.0%) let needs_wf = generalizer.needs_wf; 4,449,591 (0.0%) Ok(Generalization { value, needs_wf }) 19,551,576 (0.0%) } . . /// Abstracts the handling of region vars between HIR and MIR/NLL typechecking . /// in the generalizer code. . pub trait GeneralizerDelegate<'tcx> { . fn param_env(&self) -> ty::ParamEnv<'tcx>; . . fn forbid_inference_vars() -> bool; . -- line 57 ---------------------------------------- -- line 71 ---------------------------------------- . . fn forbid_inference_vars() -> bool { . false . } . . fn generalize_region(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> { . // FIXME: This is non-ideal because we don't give a . // very descriptive origin for this region variable. 2,223 (0.0%) self.infcx 2,964 (0.0%) .next_region_var_in_universe(RegionVariableOrigin::MiscVariable(self.span), universe) . } . } . . impl<'tcx, T> GeneralizerDelegate<'tcx> for T . where . T: TypeRelatingDelegate<'tcx>, . { . fn param_env(&self) -> ty::ParamEnv<'tcx> { -- line 88 ---------------------------------------- -- line 153 ---------------------------------------- . } . } . . impl<'tcx, D> TypeRelation<'tcx> for Generalizer<'_, 'tcx, D> . where . D: GeneralizerDelegate<'tcx>, . { . fn tcx(&self) -> TyCtxt<'tcx> { 11,838,528 (0.0%) self.infcx.tcx . } . . fn param_env(&self) -> ty::ParamEnv<'tcx> { . self.delegate.param_env() . } . . fn tag(&self) -> &'static str { . "Generalizer" . } . . fn a_is_expected(&self) -> bool { . true . } . 59,138,691 (0.0%) fn relate_item_args( . &mut self, . item_def_id: DefId, . a_subst: ty::GenericArgsRef<'tcx>, . b_subst: ty::GenericArgsRef<'tcx>, . ) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> { 5,913,872 (0.0%) 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 . // (e.g., #41849). . relate::relate_args(self, a_subst, b_subst) . } else { . let tcx = self.tcx(); . let opt_variances = tcx.variances_of(item_def_id); . relate::relate_args_with_variances( -- line 190 ---------------------------------------- -- line 191 ---------------------------------------- . self, . item_def_id, . opt_variances, . a_subst, . b_subst, . true, . ) . } 53,224,848 (0.0%) } . 32,985,142 (0.0%) #[instrument(level = "debug", skip(self, variance, b), ret)] . fn relate_with_variance>( . &mut self, . variance: ty::Variance, . _info: ty::VarianceDiagInfo<'tcx>, . a: T, . b: T, . ) -> RelateResult<'tcx, T> { 8,452,744 (0.0%) let old_ambient_variance = self.ambient_variance; 39,309,400 (0.0%) self.ambient_variance = self.ambient_variance.xform(variance); . debug!(?self.ambient_variance, "new ambient variance"); . let r = self.relate(a, b)?; 16,904,511 (0.0%) self.ambient_variance = old_ambient_variance; . Ok(r) . } . 268,606,572 (0.1%) #[instrument(level = "debug", skip(self, t2), ret)] . fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { 9,948,392 (0.0%) assert_eq!(t, t2); // we are misusing TypeRelation here; both LHS and RHS ought to be == . 11,204,085 (0.0%) if let Some(&result) = self.cache.get(&t) { . return Ok(result); . } . . // Check to see whether the type we are generalizing references . // any other type variable related to `vid` via . // subtyping. This is basically our "occurs check", preventing . // us from creating infinitely sized types. 31,495,997 (0.0%) let g = match *t.kind() { . 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: {t}"); . } . . ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { . bug!("unexpected infer type: {t}") . } . 61,071 (0.0%) ty::Infer(ty::TyVar(vid)) => { 61,071 (0.0%) let mut inner = self.infcx.inner.borrow_mut(); . let vid = inner.type_variables().root_var(vid); . let sub_vid = inner.type_variables().sub_root_var(vid); . 183,213 (0.0%) if ty::TermVid::Ty(sub_vid) == self.root_vid { . // If sub-roots are equal, then `root_vid` and . // `vid` are related via subtyping. . Err(self.cyclic_term_error()) . } else { . let probe = inner.type_variables().probe(vid); 122,142 (0.0%) match probe { . TypeVariableValue::Known { value: u } => { . drop(inner); . self.relate(u, u) . } . TypeVariableValue::Unknown { universe } => { 243,300 (0.0%) match self.ambient_variance { . // Invariant: no need to make a fresh type variable . // if we can name the universe. . ty::Invariant => { 194,304 (0.0%) if self.for_universe.can_name(universe) { . return Ok(t); . } . } . . // Bivariant: make a fresh var, but we . // may need a WF predicate. See . // comment on `needs_wf` field for . // more info. . ty::Bivariant => self.needs_wf = true, . . // Co/contravariant: this will be . // sufficiently constrained later on. . ty::Covariant | ty::Contravariant => (), . } . 336 (0.0%) let origin = *inner.type_variables().var_origin(vid); . let new_var_id = 336 (0.0%) inner.type_variables().new_var(self.for_universe, origin); 168 (0.0%) let u = Ty::new_var(self.tcx(), new_var_id); . . // Record that we replaced `vid` with `new_var_id` as part of a generalization . // operation. This is needed to detect cyclic types. To see why, see the . // docs in the `type_variables` module. 168 (0.0%) inner.type_variables().sub(vid, new_var_id); . debug!("replacing original vid={:?} with new={:?}", vid, u); 168 (0.0%) Ok(u) . } . } . } . } . . ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => { . // No matter what mode we are in, . // integer/floating-point types must be equal to be -- line 295 ---------------------------------------- -- line 304 ---------------------------------------- . debug!( . "root universe {:?} cannot name placeholder in universe {:?}", . self.for_universe, placeholder.universe . ); . Err(TypeError::Mismatch) . } . } . 30,763,112 (0.0%) _ => relate::structurally_relate_tys(self, t, t), . }?; . 43,155,844 (0.0%) self.cache.insert(t, g); . Ok(g) . } . 22,025 (0.0%) #[instrument(level = "debug", skip(self, r2), ret)] . fn regions( . &mut self, . r: ty::Region<'tcx>, . r2: ty::Region<'tcx>, . ) -> RelateResult<'tcx, ty::Region<'tcx>> { 1,479 (0.0%) assert_eq!(r, r2); // we are misusing TypeRelation here; both LHS and RHS ought to be == . 7,395 (0.0%) match *r { . // Never make variables for regions bound within the type itself, . // nor for erased regions. . ty::ReLateBound(..) | ty::ReErased => { . return Ok(r); . } . . // It doesn't really matter for correctness if we generalize ReError, . // since we're already on a doomed compilation path. -- line 335 ---------------------------------------- -- line 344 ---------------------------------------- . | ty::ReFree(..) => { . // see common code below . } . } . . // If we are in an invariant context, we can re-use the region . // as is, unless it happens to be in some universe that we . // can't name. 2,946 (0.0%) if let ty::Invariant = self.ambient_variance { 2,196 (0.0%) let r_universe = self.infcx.universe_of_region(r); 3,660 (0.0%) if self.for_universe.can_name(r_universe) { . return Ok(r); . } . } . 1,482 (0.0%) Ok(self.delegate.generalize_region(self.for_universe)) . } . 6,138 (0.0%) #[instrument(level = "debug", skip(self, c2), ret)] . fn consts( . &mut self, . c: ty::Const<'tcx>, . c2: ty::Const<'tcx>, . ) -> RelateResult<'tcx, ty::Const<'tcx>> { 198 (0.0%) assert_eq!(c, c2); // we are misusing TypeRelation here; both LHS and RHS ought to be == . 16 (0.0%) match c.kind() { . ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => { . bug!("unexpected inference variable encountered in NLL generalization: {:?}", c); . } . ty::ConstKind::Infer(InferConst::Var(vid)) => { . // If root const vids are equal, then `root_vid` and . // `vid` are related and we'd be inferring an infinitely . // deep const. 32 (0.0%) if ty::TermVid::Const( 8 (0.0%) self.infcx.inner.borrow_mut().const_unification_table().find(vid), . ) == self.root_vid . { . return Err(self.cyclic_term_error()); . } . 16 (0.0%) let mut inner = self.infcx.inner.borrow_mut(); . let variable_table = &mut inner.const_unification_table(); . let var_value = variable_table.probe_value(vid); 16 (0.0%) match var_value.val { . ConstVariableValue::Known { value: u } => { . drop(inner); . self.relate(u, u) . } . ConstVariableValue::Unknown { universe } => { 32 (0.0%) if self.for_universe.can_name(universe) { . Ok(c) . } else { . let new_var_id = variable_table.new_key(ConstVarValue { . origin: var_value.origin, . val: ConstVariableValue::Unknown { universe: self.for_universe }, . }); . Ok(ty::Const::new_var(self.tcx(), new_var_id, c.ty())) . } -- line 402 ---------------------------------------- -- line 424 ---------------------------------------- . } else { . debug!( . "root universe {:?} cannot name placeholder in universe {:?}", . self.for_universe, placeholder.universe . ); . Err(TypeError::Mismatch) . } . } 760 (0.0%) _ => relate::structurally_relate_consts(self, c, c), . } . } . 1,773 (0.0%) #[instrument(level = "debug", skip(self), ret)] . fn binders( . &mut self, . a: ty::Binder<'tcx, T>, . _: ty::Binder<'tcx, T>, . ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> . where . T: Relate<'tcx>, . { 236 (0.0%) let result = self.relate(a.skip_binder(), a.skip_binder())?; . Ok(a.rebind(result)) . } . } . . /// Result from a generalization operation. This includes . /// not only the generalized type, but also a bool flag . /// indicating whether further WF checks are needed. . #[derive(Debug)] -- line 453 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_infer/src/traits/mod.rs -------------------------------------------------------------------------------- Ir__________________ 322,895,555 (0.1%) -- line 31 ---------------------------------------- . pub use rustc_middle::traits::*; . . /// An `Obligation` represents some trait reference (e.g., `i32: Eq`) for . /// which the "impl_source" must be found. The process of finding an "impl_source" is . /// called "resolving" the `Obligation`. This process consists of . /// either identifying an `impl` (e.g., `impl Eq for i32`) that . /// satisfies the obligation, or else finding a bound that is in . /// scope. The eventual result is usually a `Selection` (defined below). 891,581,307 (0.4%) #[derive(Clone, PartialEq, Eq, Hash)] . pub struct Obligation<'tcx, T> { . /// The reason we have to prove this thing. . pub cause: ObligationCause<'tcx>, . . /// The environment in which we should prove this thing. . pub param_env: ty::ParamEnv<'tcx>, . . /// The thing we are trying to prove. 6,903,702,667 (2.9%) pub predicate: T, . . /// If we started proving this as a result of trying to prove . /// something else, track the total depth to ensure termination. . /// If this goes over a certain threshold, we abort compilation -- . /// in such cases, we can not say whether or not the predicate . /// holds for certain. Stupid halting problem; such a drag. 256,112,931 (0.1%) pub recursion_depth: usize, . } . . impl<'tcx, P> From> for solve::Goal<'tcx, P> { . fn from(value: Obligation<'tcx, P>) -> Self { . solve::Goal { param_env: value.param_env, predicate: value.predicate } . } . } . -- line 63 ---------------------------------------- -- line 73 ---------------------------------------- . Some(PredicateObligation { . cause: self.cause.clone(), . param_env: self.param_env, . predicate: self.predicate.flip_polarity(tcx)?, . recursion_depth: self.recursion_depth, . }) . } . 2,695 (0.0%) pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> PredicateObligation<'tcx> { 1,540 (0.0%) if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = self.predicate.kind().skip_binder() && trait_pred.is_const_if_const() { . self.predicate = tcx.mk_predicate(self.predicate.kind().map_bound(|_| ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred.without_const())))); . } 3,080 (0.0%) self 2,695 (0.0%) } . } . . impl<'tcx> PolyTraitObligation<'tcx> { . pub fn derived_cause( . &self, . variant: impl FnOnce(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>, . ) -> ObligationCause<'tcx> { . self.cause.clone().derived_cause(self.predicate, variant) -- line 94 ---------------------------------------- -- line 129 ---------------------------------------- . . impl<'tcx, O> Obligation<'tcx, O> { . pub fn new( . tcx: TyCtxt<'tcx>, . cause: ObligationCause<'tcx>, . param_env: ty::ParamEnv<'tcx>, . predicate: impl ToPredicate<'tcx, O>, . ) -> Obligation<'tcx, O> { 4,776 (0.0%) Self::with_depth(tcx, cause, 0, param_env, predicate) . } . . /// We often create nested obligations without setting the correct depth. . /// . /// To deal with this evaluate and fulfill explicitly update the depth . /// of nested obligations using this function. . pub fn set_depth_from_parent(&mut self, parent_depth: usize) { 242,683,194 (0.1%) self.recursion_depth = cmp::max(parent_depth + 1, self.recursion_depth); . } . 22,926 (0.0%) pub fn with_depth( . tcx: TyCtxt<'tcx>, . cause: ObligationCause<'tcx>, . recursion_depth: usize, . param_env: ty::ParamEnv<'tcx>, . predicate: impl ToPredicate<'tcx, O>, . ) -> Obligation<'tcx, O> { 306 (0.0%) let predicate = predicate.to_predicate(tcx); 4,939,931 (0.0%) Obligation { cause, param_env, recursion_depth, predicate } 16,793 (0.0%) } . . pub fn misc( . tcx: TyCtxt<'tcx>, . span: Span, . body_id: LocalDefId, . param_env: ty::ParamEnv<'tcx>, . trait_ref: impl ToPredicate<'tcx, O>, . ) -> Obligation<'tcx, O> { -- line 165 ---------------------------------------- -- line 166 ---------------------------------------- . Obligation::new(tcx, ObligationCause::misc(span, body_id), param_env, trait_ref) . } . . pub fn with

( . &self, . tcx: TyCtxt<'tcx>, . value: impl ToPredicate<'tcx, P>, . ) -> Obligation<'tcx, P> { 127,027,895 (0.1%) Obligation::with_depth(tcx, self.cause.clone(), self.recursion_depth, self.param_env, value) . } . } . . impl<'tcx> FulfillmentError<'tcx> { . pub fn new( . obligation: PredicateObligation<'tcx>, . code: FulfillmentErrorCode<'tcx>, . root_obligation: PredicateObligation<'tcx>, -- line 182 ---------------------------------------- -- line 185 ---------------------------------------- . } . } . . impl<'tcx> PolyTraitObligation<'tcx> { . pub fn polarity(&self) -> ty::ImplPolarity { . self.predicate.skip_binder().polarity . } . 409,157 (0.0%) pub fn self_ty(&self) -> ty::Binder<'tcx, Ty<'tcx>> { 818,314 (0.0%) self.predicate.map_bound(|p| p.self_ty()) 1,227,471 (0.0%) } . } -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_middle/src/traits/mod.rs -------------------------------------------------------------------------------- Ir___________________ 10,051,332,279 (4.2%) -- line 81 ---------------------------------------- . /// The reason why we incurred this obligation; used for error reporting. . /// . /// Non-misc `ObligationCauseCode`s are stored on the heap. This gives the . /// best trade-off between keeping the type small (which makes copies cheaper) . /// while not doing too many heap allocations. . /// . /// We do not want to intern this as there are a lot of obligation causes which . /// only live for a short period of time. 363,964,180 (0.2%) #[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)] . #[derive(TypeVisitable, TypeFoldable)] . pub struct ObligationCause<'tcx> { . pub span: Span, . . /// The ID of the fn body that triggered this obligation. This is . /// used for region obligations to determine the precise . /// environment in which the region obligation should be evaluated . /// (in particular, closures can add new assumptions). See the . /// field `region_obligations` of the `FulfillmentContext` for more . /// information. 1,663,627,882 (0.7%) pub body_id: LocalDefId, . 1,663,627,882 (0.7%) code: InternedObligationCauseCode<'tcx>, . } . . // This custom hash function speeds up hashing for `Obligation` deduplication . // greatly by skipping the `code` field, which can be large and complex. That . // shouldn't affect hash quality much since there are several other fields in . // `Obligation` which should be unique enough, especially the predicate itself . // which is hashed as an interned pointer. See #90996. . impl Hash for ObligationCause<'_> { -- line 110 ---------------------------------------- -- line 116 ---------------------------------------- . . impl<'tcx> ObligationCause<'tcx> { . #[inline] . pub fn new( . span: Span, . body_id: LocalDefId, . code: ObligationCauseCode<'tcx>, . ) -> ObligationCause<'tcx> { 2,125,949 (0.0%) ObligationCause { span, body_id, code: code.into() } . } . 96,460 (0.0%) pub fn misc(span: Span, body_id: LocalDefId) -> ObligationCause<'tcx> { 27,560 (0.0%) ObligationCause::new(span, body_id, MiscObligation) 82,680 (0.0%) } . . #[inline(always)] . pub fn dummy() -> ObligationCause<'tcx> { . ObligationCause::dummy_with_span(DUMMY_SP) . } . . #[inline(always)] . pub fn dummy_with_span(span: Span) -> ObligationCause<'tcx> { 65,191 (0.0%) ObligationCause { span, body_id: CRATE_DEF_ID, code: Default::default() } . } . . pub fn span(&self) -> Span { 97,592 (0.0%) match *self.code() { . ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { . arm_span, . .. . }) => arm_span, . _ => self.span, . } 24,398 (0.0%) } . . #[inline] . pub fn code(&self) -> &ObligationCauseCode<'tcx> { 1,436 (0.0%) &self.code . } . . pub fn map_code( . &mut self, . f: impl FnOnce(InternedObligationCauseCode<'tcx>) -> ObligationCauseCode<'tcx>, . ) { . self.code = f(std::mem::take(&mut self.code)).into(); . } . 23,202,231 (0.0%) pub fn derived_cause( . mut self, . parent_trait_pred: ty::PolyTraitPredicate<'tcx>, . variant: impl FnOnce(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>, . ) -> ObligationCause<'tcx> { . /*! . * Creates a cause for obligations that are derived from . * `obligation` by a recursive search (e.g., for a builtin . * bound, or eventually a `auto trait Foo`). If `obligation` -- line 171 ---------------------------------------- -- line 173 ---------------------------------------- . * otherwise we create a "derived obligation" cause so as to . * keep track of the original root obligation for error . * reporting. . */ . . // NOTE(flaper87): As of now, it keeps track of the whole error . // chain. Ideally, we should have a way to configure this either . // by using -Z verbose or just a CLI argument. 2,320,172 (0.0%) self.code = 2,320,683 (0.0%) variant(DerivedObligationCause { parent_trait_pred, parent_code: self.code }).into(); 13,923,675 (0.0%) self 20,881,548 (0.0%) } . 20,658 (0.0%) pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> { 34,988 (0.0%) match self.code() { 372 (0.0%) MatchImpl(cause, _) => cause.to_constraint_category(), . AscribeUserTypeProvePredicate(predicate_span) => { 24 (0.0%) ConstraintCategory::Predicate(*predicate_span) . } . _ => ConstraintCategory::BoringNoLocation, . } 6,886 (0.0%) } . } . . #[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)] . #[derive(TypeVisitable, TypeFoldable)] . pub struct UnifyReceiverContext<'tcx> { . pub assoc_item: ty::AssocItem, . pub param_env: ty::ParamEnv<'tcx>, . pub args: GenericArgsRef<'tcx>, -- line 202 ---------------------------------------- -- line 216 ---------------------------------------- . cause.fmt(f) . } . } . . impl<'tcx> ObligationCauseCode<'tcx> { . #[inline(always)] . fn into(self) -> InternedObligationCauseCode<'tcx> { . InternedObligationCauseCode { 4,228 (0.0%) code: if let ObligationCauseCode::MiscObligation = self { . None . } else { 4,783,705 (0.0%) Some(Lrc::new(self)) . }, . } 20,321 (0.0%) } . } . . impl<'tcx> std::ops::Deref for InternedObligationCauseCode<'tcx> { . type Target = ObligationCauseCode<'tcx>; . . fn deref(&self) -> &Self::Target { . self.code.as_deref().unwrap_or(&ObligationCauseCode::MiscObligation) 487 (0.0%) } . } . 20,794,676,850 (8.6%) #[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)] . #[derive(TypeVisitable, TypeFoldable)] . pub enum ObligationCauseCode<'tcx> { . /// Not well classified or should be obvious from the span. . MiscObligation, . . /// A slice or array is WF only if `T: Sized`. . SliceOrArrayElem, . -- line 249 ---------------------------------------- -- line 465 ---------------------------------------- . function: LocalDefId, . /// The index of the parameter to use. . /// Parameters are indexed from 0, with the return type . /// being the last 'parameter' . param_idx: u16, . }, . } . 11,197,133,402 (4.6%) #[derive(Clone, Debug, PartialEq, Eq, Lift, HashStable, TyEncodable, TyDecodable)] . #[derive(TypeVisitable, TypeFoldable)] . pub struct ImplDerivedObligationCause<'tcx> { . pub derived: DerivedObligationCause<'tcx>, . /// The `DefId` of the `impl` that gave rise to the `derived` obligation. . /// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic impl, . /// then this will be the `DefId` of that trait alias. Care should therefore be taken to handle . /// that exceptional case where appropriate. 640 (0.0%) pub impl_or_alias_def_id: DefId, . /// The index of the derived predicate in the parent impl's predicates. 345,641,982 (0.1%) pub impl_def_predicate_index: Option, 172,820,991 (0.1%) pub span: Span, . } . . impl<'tcx> ObligationCauseCode<'tcx> { . /// Returns the base obligation, ignoring derived obligations. 75 (0.0%) pub fn peel_derives(&self) -> &Self { . let mut base_cause = self; . while let Some((parent_code, _)) = base_cause.parent() { . base_cause = parent_code; . } . base_cause 25 (0.0%) } . . pub fn parent(&self) -> Option<(&Self, Option>)> { 100 (0.0%) match self { . FunctionArgumentObligation { parent_code, .. } => Some((parent_code, None)), . BuiltinDerivedObligation(derived) . | DerivedObligation(derived) . | ImplDerivedObligation(box ImplDerivedObligationCause { derived, .. }) => { . Some((&derived.parent_code, Some(derived.parent_trait_pred))) . } . _ => None, . } -- line 506 ---------------------------------------- -- line 563 ---------------------------------------- . pub struct DerivedObligationCause<'tcx> { . /// The trait predicate of the parent obligation that led to the . /// current obligation. Note that only trait obligations lead to . /// derived obligations, so we just store the trait predicate here . /// directly. . pub parent_trait_pred: ty::PolyTraitPredicate<'tcx>, . . /// The parent trait had this cause. 518,462,973 (0.2%) pub parent_code: InternedObligationCauseCode<'tcx>, . } . 74,740 (0.0%) #[derive(Clone, Debug, TypeVisitable, Lift)] . pub enum SelectionError<'tcx> { . /// The trait is not implemented. . Unimplemented, . /// After a closure impl has selected, its "outputs" were evaluated . /// (which for closures includes the "input" type params) and they . /// didn't resolve. See `confirm_poly_trait_refs` for more. . OutputTypeParameterMismatch(Box>), . /// The trait pointed by `DefId` is not object safe. -- line 582 ---------------------------------------- -- line 635 ---------------------------------------- . /// mixed.clone(); // ImplSource(Impl_1, [ImplSource::Param]) . /// } . /// ``` . /// . /// ### The type parameter `N` . /// . /// See explanation on `ImplSourceUserDefinedData`. . #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)] 434 (0.0%) #[derive(TypeFoldable, TypeVisitable)] . pub enum ImplSource<'tcx, N> { . /// ImplSource identifying a particular impl. . UserDefined(ImplSourceUserDefinedData<'tcx, N>), . . /// Successful resolution to an obligation provided by the caller . /// for some type parameter. The `Vec` represents the . /// obligations incurred from normalizing the where-clause (if . /// any). -- line 651 ---------------------------------------- -- line 652 ---------------------------------------- . Param(ty::BoundConstness, Vec), . . /// Successful resolution for a builtin impl. . Builtin(BuiltinImplSource, Vec), . } . . impl<'tcx, N> ImplSource<'tcx, N> { . pub fn nested_obligations(self) -> Vec { 398,536 (0.0%) match self { 101,203 (0.0%) ImplSource::UserDefined(i) => i.nested, 47,220 (0.0%) ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => n, . } . } . . pub fn borrow_nested_obligations(&self) -> &[N] { 6 (0.0%) match self { 1 (0.0%) ImplSource::UserDefined(i) => &i.nested, . ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => &n, . } . } . . pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] { . match self { . ImplSource::UserDefined(i) => &mut i.nested, 25,273 (0.0%) ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => n, . } . } . 3,296,078 (0.0%) pub fn map(self, f: F) -> ImplSource<'tcx, M> . where . F: FnMut(N) -> M, . { 1,149,426 (0.0%) match self { 4,431,856 (0.0%) ImplSource::UserDefined(i) => ImplSource::UserDefined(ImplSourceUserDefinedData { . impl_def_id: i.impl_def_id, . args: i.args, 84 (0.0%) nested: i.nested.into_iter().map(f).collect(), . }), 95,555 (0.0%) ImplSource::Param(ct, n) => ImplSource::Param(ct, n.into_iter().map(f).collect()), 47,445 (0.0%) ImplSource::Builtin(source, n) => { 94,890 (0.0%) ImplSource::Builtin(source, n.into_iter().map(f).collect()) . } . } 3,296,078 (0.0%) } . } . . /// Identifies a particular impl in the source, along with a set of . /// substitutions from the impl's type/lifetime parameters. The . /// `nested` vector corresponds to the nested obligations attached to . /// the impl's type parameters. . /// . /// The type parameter `N` indicates the type used for "nested . /// obligations" that are required by the impl. During type-check, this . /// is `Obligation`, as one might expect. During codegen, however, this . /// is `()`, because codegen only requires a shallow resolution of an . /// impl, and nested obligations are satisfied later. . #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)] 69 (0.0%) #[derive(TypeFoldable, TypeVisitable)] . pub struct ImplSourceUserDefinedData<'tcx, N> { . pub impl_def_id: DefId, . pub args: GenericArgsRef<'tcx>, . pub nested: Vec, . } . . #[derive(Copy, Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Debug)] . pub enum BuiltinImplSource { -- line 717 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_middle/src/ty/context.rs -------------------------------------------------------------------------------- Ir________________ 47,690,623 (0.0%) -- line 158 ---------------------------------------- . adt_def: InternedSet<'tcx, AdtDefData>, . external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>, . predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<'tcx>>, . fields: InternedSet<'tcx, List>, . } . . impl<'tcx> CtxtInterners<'tcx> { . fn new(arena: &'tcx WorkerLocal>) -> CtxtInterners<'tcx> { 56 (0.0%) CtxtInterners { . arena, . type_: Default::default(), . const_lists: Default::default(), . args: Default::default(), . type_lists: Default::default(), . region: Default::default(), . poly_existential_predicates: Default::default(), . canonical_var_infos: Default::default(), -- line 174 ---------------------------------------- -- line 185 ---------------------------------------- . predefined_opaques_in_body: Default::default(), . fields: Default::default(), . } . } . . /// Interns a type. (Use `mk_*` functions instead, where possible.) . #[allow(rustc::usage_of_ty_tykind)] . #[inline(never)] 119,695,037 (0.0%) fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> { . Ty(Interned::new_unchecked( 21,762,734 (0.0%) self.type_ . .intern(kind, |kind| { 449,440 (0.0%) let flags = super::flags::FlagComputation::for_kind(&kind); . let stable_hash = self.stable_hash(&flags, sess, untracked, &kind); . 898,880 (0.0%) InternedInSet(self.arena.alloc(WithCachedTypeInfo { . internee: kind, . stable_hash, . flags: flags.flags, . outer_exclusive_binder: flags.outer_exclusive_binder, . })) . }) . .0, . )) 97,932,303 (0.0%) } . . fn stable_hash<'a, T: HashStable>>( . &self, . flags: &ty::flags::FlagComputation, . sess: &'a Session, . untracked: &'a Untracked, . val: &T, . ) -> Fingerprint { . // It's impossible to hash inference variables (and will ICE), so we don't need to try to cache them. . // Without incremental, we rarely stable-hash types, so let's not do it proactively. 637,735 (0.0%) if flags.flags.intersects(TypeFlags::HAS_INFER) || sess.opts.incremental.is_none() { . Fingerprint::ZERO . } else { . let mut hasher = StableHasher::new(); . let mut hcx = StableHashingContext::new(sess, untracked); . val.hash_stable(&mut hcx, &mut hasher); . hasher.finish() . } . } . . /// Interns a predicate. (Use `mk_predicate` instead, where possible.) . #[inline(never)] 48,897,590 (0.0%) fn intern_predicate( . &self, . kind: Binder<'tcx, PredicateKind<'tcx>>, . sess: &Session, . untracked: &Untracked, . ) -> Predicate<'tcx> { . Predicate(Interned::new_unchecked( 39,118,072 (0.0%) self.predicate . .intern(kind, |kind| { 1,621,275 (0.0%) let flags = super::flags::FlagComputation::for_predicate(kind); . . let stable_hash = self.stable_hash(&flags, sess, untracked, &kind); . 972,765 (0.0%) InternedInSet(self.arena.alloc(WithCachedTypeInfo { . internee: kind, . stable_hash, . flags: flags.flags, . outer_exclusive_binder: flags.outer_exclusive_binder, . })) . }) . .0, . )) 44,007,831 (0.0%) } . } . . // For these preinterned values, an alternative would be to have . // variable-length vectors that grow as needed. But that turned out to be . // slightly more complex and no faster. . . const NUM_PREINTERNED_TY_VARS: u32 = 100; . const NUM_PREINTERNED_FRESH_TYS: u32 = 20; -- line 262 ---------------------------------------- -- line 332 ---------------------------------------- . } . . impl<'tcx> CommonTypes<'tcx> { . fn new( . interners: &CtxtInterners<'tcx>, . sess: &Session, . untracked: &Untracked, . ) -> CommonTypes<'tcx> { 750 (0.0%) let mk = |ty| interners.intern_ty(ty, sess, untracked); . . let ty_vars = 300 (0.0%) (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect(); . let fresh_tys: Vec<_> = 60 (0.0%) (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect(); . let fresh_int_tys: Vec<_> = 9 (0.0%) (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect(); . let fresh_float_tys: Vec<_> = 9 (0.0%) (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect(); . 34 (0.0%) CommonTypes { 3 (0.0%) unit: mk(Tuple(List::empty())), 1 (0.0%) bool: mk(Bool), 1 (0.0%) char: mk(Char), 1 (0.0%) never: mk(Never), 1 (0.0%) isize: mk(Int(ty::IntTy::Isize)), 1 (0.0%) i8: mk(Int(ty::IntTy::I8)), 1 (0.0%) i16: mk(Int(ty::IntTy::I16)), 1 (0.0%) i32: mk(Int(ty::IntTy::I32)), 1 (0.0%) i64: mk(Int(ty::IntTy::I64)), 1 (0.0%) i128: mk(Int(ty::IntTy::I128)), 1 (0.0%) usize: mk(Uint(ty::UintTy::Usize)), 1 (0.0%) u8: mk(Uint(ty::UintTy::U8)), 1 (0.0%) u16: mk(Uint(ty::UintTy::U16)), 1 (0.0%) u32: mk(Uint(ty::UintTy::U32)), 1 (0.0%) u64: mk(Uint(ty::UintTy::U64)), 1 (0.0%) u128: mk(Uint(ty::UintTy::U128)), 1 (0.0%) f32: mk(Float(ty::FloatTy::F32)), 1 (0.0%) f64: mk(Float(ty::FloatTy::F64)), 1 (0.0%) str_: mk(Str), 2 (0.0%) self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })), . 2 (0.0%) trait_object_dummy_self: fresh_tys[0], . 4 (0.0%) ty_vars, 4 (0.0%) fresh_tys, 4 (0.0%) fresh_int_tys, 5 (0.0%) fresh_float_tys, . } . } . } . . impl<'tcx> CommonLifetimes<'tcx> { . fn new(interners: &CtxtInterners<'tcx>) -> CommonLifetimes<'tcx> { 4,339 (0.0%) let mk = |r| { . Region(Interned::new_unchecked( 3,794 (0.0%) interners.region.intern(r, |r| InternedInSet(interners.arena.alloc(r))).0, . )) 4,878 (0.0%) }; . . let re_vars = 2,500 (0.0%) (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect(); . . let re_late_bounds = (0..NUM_PREINTERNED_RE_LATE_BOUNDS_I) . .map(|i| { . (0..NUM_PREINTERNED_RE_LATE_BOUNDS_V) . .map(|v| { 280 (0.0%) mk(ty::ReLateBound( 40 (0.0%) ty::DebruijnIndex::from(i), . ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BrAnon(None) }, . )) . }) . .collect() . }) . .collect(); . 2 (0.0%) CommonLifetimes { 4 (0.0%) re_static: mk(ty::ReStatic), 4 (0.0%) re_erased: mk(ty::ReErased), 4 (0.0%) re_vars, 4 (0.0%) re_late_bounds, . } . } . } . . impl<'tcx> CommonConsts<'tcx> { . fn new(interners: &CtxtInterners<'tcx>, types: &CommonTypes<'tcx>) -> CommonConsts<'tcx> { 27 (0.0%) let mk_const = |c| { . Const(Interned::new_unchecked( 15 (0.0%) interners.const_.intern(c, |c| InternedInSet(interners.arena.alloc(c))).0, . )) 27 (0.0%) }; . . CommonConsts { 11 (0.0%) unit: mk_const(ty::ConstData { . kind: ty::ConstKind::Value(ty::ValTree::zst()), . ty: types.unit, . }), 9 (0.0%) true_: mk_const(ty::ConstData { . kind: ty::ConstKind::Value(ty::ValTree::Leaf(ty::ScalarInt::TRUE)), . ty: types.bool, . }), 9 (0.0%) false_: mk_const(ty::ConstData { . kind: ty::ConstKind::Value(ty::ValTree::Leaf(ty::ScalarInt::FALSE)), . ty: types.bool, . }), . } . } . } . . /// This struct contains information regarding the `ReFree(FreeRegion)` corresponding to a lifetime -- line 441 ---------------------------------------- -- line 501 ---------------------------------------- . /// `GlobalCtxt`, and in practice `TyCtxt` is passed around everywhere, and all . /// operations are done via `TyCtxt`. A `TyCtxt` is obtained for a `GlobalCtxt` . /// by calling `enter` with a closure `f`. That function creates both the . /// `TyCtxt`, and an `ImplicitCtxt` around it that is put into TLS. Within `f`: . /// - The `ImplicitCtxt` is available implicitly via TLS. . /// - The `TyCtxt` is available explicitly via the `tcx` parameter, and also . /// implicitly within the `ImplicitCtxt`. Explicit access is preferred when . /// possible. 1 (0.0%) #[derive(Copy, Clone)] . #[rustc_diagnostic_item = "TyCtxt"] . #[rustc_pass_by_value] . pub struct TyCtxt<'tcx> { . gcx: &'tcx GlobalCtxt<'tcx>, . } . . impl<'tcx> Deref for TyCtxt<'tcx> { . type Target = &'tcx GlobalCtxt<'tcx>; -- line 517 ---------------------------------------- -- line 576 ---------------------------------------- . . /// Stores memory for globals (statics/consts). . pub(crate) alloc_map: Lock>, . } . . impl<'tcx> GlobalCtxt<'tcx> { . /// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of . /// `f`. 51 (0.0%) pub fn enter<'a: 'tcx, F, R>(&'a self, f: F) -> R . where . F: FnOnce(TyCtxt<'tcx>) -> R, . { 17 (0.0%) let icx = tls::ImplicitCtxt::new(self); 10 (0.0%) tls::enter_context(&icx, || f(icx.tcx)) 46 (0.0%) } . } . . impl<'tcx> TyCtxt<'tcx> { . /// Expects a body and returns its codegen attributes. . /// . /// Unlike `codegen_fn_attrs`, this returns `CodegenFnAttrs::EMPTY` for . /// constants. 3,230 (0.0%) pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs { 969 (0.0%) let def_kind = self.def_kind(def_id); 1,292 (0.0%) if def_kind.has_codegen_attrs() { . self.codegen_fn_attrs(def_id) . } else if matches!( . def_kind, . DefKind::AnonConst | DefKind::AssocConst | DefKind::Const | DefKind::InlineConst . ) { . CodegenFnAttrs::EMPTY . } else { . bug!( . "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}", . def_id, . def_kind . ) . } 1,938 (0.0%) } . 468 (0.0%) pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal> { 468 (0.0%) self.arena.alloc(Steal::new(thir)) 780 (0.0%) } . 1,404 (0.0%) pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal> { 1,404 (0.0%) self.arena.alloc(Steal::new(mir)) 2,340 (0.0%) } . 312 (0.0%) pub fn alloc_steal_promoted( . self, . promoted: IndexVec>, . ) -> &'tcx Steal>> { 780 (0.0%) self.arena.alloc(Steal::new(promoted)) 468 (0.0%) } . 816 (0.0%) pub fn mk_adt_def( . self, . did: DefId, . kind: AdtKind, . variants: IndexVec, . repr: ReprOptions, . ) -> ty::AdtDef<'tcx> { 1,224 (0.0%) self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr)) 408 (0.0%) } . . /// Allocates a read-only byte or string literal for `mir::interpret`. . pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId { . // Create an allocation that just contains these bytes. . let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes); . let alloc = self.mk_const_alloc(alloc); . self.create_memory_alloc(alloc) . } . . /// Returns a range of the start/end indices specified with the . /// `rustc_layout_scalar_valid_range` attribute. . // FIXME(eddyb) this is an awkward spot for this method, maybe move it? 3,454 (0.0%) pub fn layout_scalar_valid_range(self, def_id: DefId) -> (Bound, Bound) { 5,024 (0.0%) let get = |name| { 3,140 (0.0%) let Some(attr) = self.get_attr(def_id, name) else { . return Bound::Unbounded; . }; . debug!("layout_scalar_valid_range: attr={:?}", attr); . if let Some( . &[ . ast::NestedMetaItem::Lit(ast::MetaItemLit { . kind: ast::LitKind::Int(a, _), . .. -- line 662 ---------------------------------------- -- line 665 ---------------------------------------- . ) = attr.meta_item_list().as_deref() . { . Bound::Included(a) . } else { . self.sess . .delay_span_bug(attr.span, "invalid rustc_layout_scalar_valid_range attribute"); . Bound::Unbounded . } 5,652 (0.0%) }; 1,884 (0.0%) ( 1,884 (0.0%) get(sym::rustc_layout_scalar_valid_range_start), 942 (0.0%) get(sym::rustc_layout_scalar_valid_range_end), . ) 2,512 (0.0%) } . . pub fn lift>(self, value: T) -> Option { . value.lift_to_tcx(self) . } . . /// Creates a type context. To use the context call `fn enter` which . /// provides a `TyCtxt`. . /// . /// By only providing the `TyCtxt` inside of the closure we enforce that the type . /// context and any interned alue (types, args, etc.) can only be used while `ty::tls` . /// has a valid reference to the context, to allow formatting values that need it. 20 (0.0%) pub fn create_global_ctxt( . s: &'tcx Session, . lint_store: Lrc, . arena: &'tcx WorkerLocal>, . hir_arena: &'tcx WorkerLocal>, . untracked: Untracked, . dep_graph: DepGraph, . query_kinds: &'tcx [DepKindStruct<'tcx>], . query_system: QuerySystem<'tcx>, . ) -> GlobalCtxt<'tcx> { 1 (0.0%) let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| { . s.emit_fatal(err); . }); . let interners = CtxtInterners::new(arena); . let common_types = CommonTypes::new(&interners, s, &untracked); . let common_lifetimes = CommonLifetimes::new(&interners); . let common_consts = CommonConsts::new(&interners, &common_types); . 55 (0.0%) GlobalCtxt { . sess: s, . lint_store, . arena, . hir_arena, 3 (0.0%) interners, . dep_graph, . prof: s.prof.clone(), 2 (0.0%) types: common_types, 8 (0.0%) lifetimes: common_lifetimes, . consts: common_consts, 3 (0.0%) untracked, 3 (0.0%) query_system, . query_kinds, . ty_rcache: Default::default(), . pred_rcache: Default::default(), . selection_cache: Default::default(), . evaluation_cache: Default::default(), . new_solver_evaluation_cache: Default::default(), . new_solver_coherence_evaluation_cache: Default::default(), 6 (0.0%) data_layout, . alloc_map: Lock::new(interpret::AllocMap::new()), . } 9 (0.0%) } . . pub fn consider_optimizing String>(self, msg: T) -> bool { 80 (0.0%) self.sess.consider_optimizing(|| self.crate_name(LOCAL_CRATE), msg) . } . . /// Obtain all lang items of this crate and all dependencies (recursively) 11,366,764 (0.0%) pub fn lang_items(self) -> &'tcx rustc_hir::lang_items::LanguageItems { . self.get_lang_items(()) 17,050,146 (0.0%) } . . /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to . /// compare against another `DefId`, since `is_diagnostic_item` is cheaper. . pub fn get_diagnostic_item(self, name: Symbol) -> Option { . self.all_diagnostic_items(()).name_to_id.get(&name).copied() . } . . /// Obtain the diagnostic item's name 9,058 (0.0%) pub fn get_diagnostic_name(self, id: DefId) -> Option { . self.diagnostic_items(id.krate).id_to_name.get(&id).copied() 10,352 (0.0%) } . . /// Check whether the diagnostic item with the given `name` has the given `DefId`. 5,523 (0.0%) pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool { . self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did) 6,312 (0.0%) } . . /// Returns `true` if the node pointed to by `def_id` is a generator for an async construct. 6 (0.0%) pub fn generator_is_async(self, def_id: DefId) -> bool { 6 (0.0%) matches!(self.generator_kind(def_id), Some(hir::GeneratorKind::Async(_))) 4 (0.0%) } . 26,024 (0.0%) pub fn stability(self) -> &'tcx stability::Index { . self.stability_index(()) 39,036 (0.0%) } . 143,328 (0.0%) pub fn features(self) -> &'tcx rustc_feature::Features { . self.features_query(()) 214,992 (0.0%) } . 4,603,224 (0.0%) pub fn def_key(self, id: impl IntoQueryParam) -> rustc_hir::definitions::DefKey { . let id = id.into_query_param(); . // Accessing the DefKey is ok, since it is part of DefPathHash. 3,069,064 (0.0%) if let Some(id) = id.as_local() { . self.definitions_untracked().def_key(id) . } else { 6,160 (0.0%) self.cstore_untracked().def_key(id) . } 4,603,224 (0.0%) } . . /// Converts a `DefId` into its fully expanded `DefPath` (every . /// `DefId` is really just an interned `DefPath`). . /// . /// Note that if `id` is not local to this crate, the result will . /// be a non-local `DefPath`. . pub fn def_path(self, id: DefId) -> rustc_hir::definitions::DefPath { . // Accessing the DefPath is ok, since it is part of DefPathHash. -- line 787 ---------------------------------------- -- line 788 ---------------------------------------- . if let Some(id) = id.as_local() { . self.definitions_untracked().def_path(id) . } else { . self.cstore_untracked().def_path(id) . } . } . . #[inline] 410 (0.0%) pub fn def_path_hash(self, def_id: DefId) -> rustc_hir::definitions::DefPathHash { . // Accessing the DefPathHash is ok, it is incr. comp. stable. 330 (0.0%) if let Some(def_id) = def_id.as_local() { . self.definitions_untracked().def_path_hash(def_id) . } else { 2 (0.0%) self.cstore_untracked().def_path_hash(def_id) . } 410 (0.0%) } . . #[inline] . pub fn stable_crate_id(self, crate_num: CrateNum) -> StableCrateId { . if crate_num == LOCAL_CRATE { . self.sess.local_stable_crate_id() . } else { . self.cstore_untracked().stable_crate_id(crate_num) . } -- line 811 ---------------------------------------- -- line 863 ---------------------------------------- . stable_crate_id.as_u64() >> (8 * 6), . self.def_path(def_id).to_string_no_crate_verbose() . ) . } . } . . impl<'tcx> TyCtxtAt<'tcx> { . /// Create a new definition within the incr. comp. engine. 1,848 (0.0%) pub fn create_def( . self, . parent: LocalDefId, . data: hir::definitions::DefPathData, . ) -> TyCtxtFeed<'tcx, LocalDefId> { . // This function modifies `self.definitions` using a side-effect. . // We need to ensure that these side effects are re-run by the incr. comp. engine. . // Depending on the forever-red node will tell the graph that the calling query . // needs to be re-evaluated. 336 (0.0%) self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); . . // The following call has the side effect of modifying the tables inside `definitions`. . // These very tables are relied on by the incr. comp. engine to decode DepNodes and to . // decode the on-disk cache. . // . // Any LocalDefId which is used within queries, either as key or result, either: . // - has been created before the construction of the TyCtxt; . // - has been created by this call to `create_def`. . // As a consequence, this LocalDefId is always re-created before it is needed by the incr. . // comp. engine itself. . // . // This call also writes to the value of `source_span` and `expn_that_defined` queries. . // This is fine because: . // - those queries are `eval_always` so we won't miss their result changing; . // - this write will have happened before these queries are called. 1,008 (0.0%) let key = self.untracked.definitions.write().create_def(parent, data); . . let feed = TyCtxtFeed { tcx: self.tcx, key }; 336 (0.0%) feed.def_span(self.span); . feed 1,512 (0.0%) } . } . . impl<'tcx> TyCtxt<'tcx> { . pub fn iter_local_def_id(self) -> impl Iterator + 'tcx { . // Create a dependency to the red node to be sure we re-execute this when the amount of . // definitions change. . self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); . -- line 909 ---------------------------------------- -- line 946 ---------------------------------------- . let definitions = self.untracked.definitions.leak(); . definitions.def_path_hash_to_def_index_map() . } . . /// Note that this is *untracked* and should only be used within the query . /// system if the result is otherwise tracked through queries . #[inline] . pub fn cstore_untracked(self) -> MappedReadGuard<'tcx, CrateStoreDyn> { 3,105 (0.0%) ReadGuard::map(self.untracked.cstore.read(), |c| &**c) . } . . /// Give out access to the untracked data without any sanity checks. . pub fn untracked(self) -> &'tcx Untracked { 41,121 (0.0%) &self.untracked 41,121 (0.0%) } . /// Note that this is *untracked* and should only be used within the query . /// system if the result is otherwise tracked through queries . #[inline] . pub fn definitions_untracked(self) -> ReadGuard<'tcx, Definitions> { 1 (0.0%) self.untracked.definitions.read() . } . . /// Note that this is *untracked* and should only be used within the query . /// system if the result is otherwise tracked through queries . #[inline] . pub fn source_span_untracked(self, def_id: LocalDefId) -> Span { . self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP) . } . . #[inline(always)] . pub fn with_stable_hashing_context( . self, . f: impl FnOnce(StableHashingContext<'_>) -> R, . ) -> R { 5,424 (0.0%) f(StableHashingContext::new(self.sess, &self.untracked)) . } . . pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult { . self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder)) . } . . #[inline] . pub fn local_crate_exports_generics(self) -> bool { -- line 988 ---------------------------------------- -- line 1129 ---------------------------------------- . self, . self.lifetimes.re_static, . self.type_of(self.require_lang_item(LangItem::PanicLocation, None)) . .instantiate(self, self.mk_args(&[self.lifetimes.re_static.into()])), . ) . } . . /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`). 6,710 (0.0%) pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) { 3,050 (0.0%) let kind = self.def_kind(def_id); 10,370 (0.0%) (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id)) 5,490 (0.0%) } . . pub fn type_length_limit(self) -> Limit { . self.limits(()).type_length_limit . } . 86,687,648 (0.0%) pub fn recursion_limit(self) -> Limit { . self.limits(()).recursion_limit 130,031,472 (0.1%) } . . pub fn move_size_limit(self) -> Limit { . self.limits(()).move_size_limit . } . . pub fn all_traits(self) -> impl Iterator + 'tcx { . iter::once(LOCAL_CRATE) . .chain(self.crates(()).iter().copied()) . .flat_map(move |cnum| self.traits(cnum).iter().copied()) . } . . #[inline] . pub fn local_visibility(self, def_id: LocalDefId) -> Visibility { 71,943 (0.0%) self.visibility(def_id).expect_local() . } . . /// Returns the origin of the opaque type `def_id`. . #[instrument(skip(self), level = "trace", ret)] . pub fn opaque_type_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin { . self.hir().expect_item(def_id).expect_opaque_ty().origin . } . } -- line 1170 ---------------------------------------- -- line 1386 ---------------------------------------- . fn into_pointer(&self) -> *const () { . self.0 as *const _ as *const () . } . } . . #[allow(rustc::usage_of_ty_tykind)] . impl<'tcx, T> Borrow for InternedInSet<'tcx, WithCachedTypeInfo> { . fn borrow(&self) -> &T { 4,612,754 (0.0%) &self.0.internee . } . } . . impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, WithCachedTypeInfo> { . fn eq(&self, other: &InternedInSet<'tcx, WithCachedTypeInfo>) -> bool { . // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals . // `x == y`. . self.0.internee == other.0.internee -- line 1402 ---------------------------------------- -- line 1403 ---------------------------------------- . } . } . . impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, WithCachedTypeInfo> {} . . impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, WithCachedTypeInfo> { . fn hash(&self, s: &mut H) { . // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`. 4,128,720 (0.0%) self.0.internee.hash(s) . } . } . . impl<'tcx, T> Borrow<[T]> for InternedInSet<'tcx, List> { . fn borrow(&self) -> &[T] { 57,894,600 (0.0%) &self.0[..] . } . } . . impl<'tcx, T: PartialEq> PartialEq for InternedInSet<'tcx, List> { . fn eq(&self, other: &InternedInSet<'tcx, List>) -> bool { . // The `Borrow` trait requires that `x.borrow() == y.borrow()` equals . // `x == y`. . self.0[..] == other.0[..] -- line 1425 ---------------------------------------- -- line 1426 ---------------------------------------- . } . } . . impl<'tcx, T: Eq> Eq for InternedInSet<'tcx, List> {} . . impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List> { . fn hash(&self, s: &mut H) { . // The `Borrow` trait requires that `x.borrow().hash(s) == x.hash(s)`. 1,900,836 (0.0%) self.0[..].hash(s) . } . } . . macro_rules! direct_interners { . ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => { . $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> { . fn borrow<'a>(&'a self) -> &'a $ty { 9,850 (0.0%) &self.0 . } . } . . impl<'tcx> PartialEq for InternedInSet<'tcx, $ty> { . fn eq(&self, other: &Self) -> bool { . // The `Borrow` trait requires that `x.borrow() == y.borrow()` . // equals `x == y`. . self.0 == other.0 -- line 1450 ---------------------------------------- -- line 1452 ---------------------------------------- . } . . impl<'tcx> Eq for InternedInSet<'tcx, $ty> {} . . impl<'tcx> Hash for InternedInSet<'tcx, $ty> { . fn hash(&self, s: &mut H) { . // The `Borrow` trait requires that `x.borrow().hash(s) == . // x.hash(s)`. 31,332 (0.0%) self.0.hash(s) . } . } . . impl<'tcx> TyCtxt<'tcx> { 51,040 (0.0%) $vis fn $method(self, v: $ty) -> $ret_ty { 46,818 (0.0%) $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| { 7,153 (0.0%) InternedInSet(self.interners.arena.alloc(v)) . }).0)) 60,435 (0.0%) } . })+ . } . } . . // Functions with a `mk_` prefix are intended for use outside this file and . // crate. Functions with an `intern_` prefix are intended for use within this . // crate only, and have a corresponding `mk_` function. . direct_interners! { -- line 1477 ---------------------------------------- -- line 1484 ---------------------------------------- . ExternalConstraints -> ExternalConstraints<'tcx>, . predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<'tcx>): . PredefinedOpaques -> PredefinedOpaques<'tcx>, . } . . macro_rules! slice_interners { . ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => ( . impl<'tcx> TyCtxt<'tcx> { 122,281,383 (0.1%) $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> { 34,965,218 (0.0%) if v.is_empty() { . List::empty() . } else { 14,706,965 (0.0%) self.interners.$field.intern_ref(v, || { . InternedInSet(List::from_arena(&*self.arena, v)) . }).0 . } 157,218,921 (0.1%) })+ . } . ); . } . . // These functions intern slices. They all have a corresponding . // `mk_foo_from_iter` function that interns an iterator. The slice version . // should be used when possible, because it's faster. . slice_interners!( -- line 1508 ---------------------------------------- -- line 1598 ---------------------------------------- . _ => bug!(), . }; . self.mk_fn_sig(params, s.output(), s.c_variadic, unsafety, abi::Abi::Rust) . }) . } . . #[inline] . pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> { 5,179,009 (0.0%) self.interners.intern_predicate( . binder, 4,889,759 (0.0%) self.sess, . // This is only used to create a stable hashing context. 9,707,831 (0.0%) &self.untracked, . ) . } . . #[inline] 24,664,685 (0.0%) pub fn reuse_or_mk_predicate( . self, . pred: Predicate<'tcx>, . binder: Binder<'tcx, PredicateKind<'tcx>>, . ) -> Predicate<'tcx> { 33,824,521 (0.0%) if pred.kind() != binder { self.mk_predicate(binder) } else { pred } 24,664,685 (0.0%) } . . #[inline(always)] . pub(crate) fn check_and_mk_args( . self, . _def_id: DefId, . args: impl IntoIterator>>, . ) -> GenericArgsRef<'tcx> { . let args = args.into_iter().map(Into::into); -- line 1629 ---------------------------------------- -- line 1642 ---------------------------------------- . }; . assert_eq!( . (n, Some(n)), . args.size_hint(), . "wrong number of generic parameters for {_def_id:?}: {:?}", . args.collect::>(), . ); . } 1,613,954 (0.0%) self.mk_args_from_iter(args) . } . . #[inline] . pub fn mk_ct_from_kind(self, kind: ty::ConstKind<'tcx>, ty: Ty<'tcx>) -> Const<'tcx> { 2,912 (0.0%) self.intern_const(ty::ConstData { kind, ty }) . } . . // Avoid this in favour of more specific `Ty::new_*` methods, where possible. . #[allow(rustc::usage_of_ty_tykind)] . #[inline] . pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> { 8,512,566 (0.0%) self.interners.intern_ty( . st, 4,473,602 (0.0%) self.sess, . // This is only used to create a stable hashing context. 8,943,571 (0.0%) &self.untracked, . ) . } . 32,205 (0.0%) pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> { 70,851 (0.0%) match param.kind { . GenericParamDefKind::Lifetime => { . ty::Region::new_early_bound(self, param.to_early_bound_region_data()).into() . } 12,882 (0.0%) GenericParamDefKind::Type { .. } => Ty::new_param(self, param.index, param.name).into(), . GenericParamDefKind::Const { .. } => ty::Const::new_param( . self, . ParamConst { index: param.index, name: param.name }, . self.type_of(param.def_id) . .no_bound_vars() . .expect("const parameter types cannot be generic"), . ) . .into(), . } 32,205 (0.0%) } . . pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> { . self.mk_place_elem(place, PlaceElem::Field(f, ty)) . } . . pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> { . self.mk_place_elem(place, PlaceElem::Deref) . } -- line 1693 ---------------------------------------- -- line 1721 ---------------------------------------- . /// flight. . pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> { . let mut projection = place.projection.to_vec(); . projection.push(elem); . . Place { local: place.local, projection: self.mk_place_elems(&projection) } . } . 4,144 (0.0%) pub fn mk_poly_existential_predicates( . self, . eps: &[PolyExistentialPredicate<'tcx>], . ) -> &'tcx List> { 518 (0.0%) assert!(!eps.is_empty()); . assert!( . eps.array_windows() 27 (0.0%) .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder()) . != Ordering::Greater) . ); . self.intern_poly_existential_predicates(eps) 4,662 (0.0%) } . 96,880 (0.0%) pub fn mk_clauses(self, clauses: &[Clause<'tcx>]) -> &'tcx List> { . // FIXME consider asking the input slice to be sorted to avoid . // re-interning permutations, in which case that would be asserted . // here. . self.intern_clauses(clauses) 124,560 (0.0%) } . . pub fn mk_const_list_from_iter(self, iter: I) -> T::Output . where . I: Iterator, . T: CollectAndApply, &'tcx List>>, . { . T::collect_and_apply(iter, |xs| self.mk_const_list(xs)) . } -- line 1755 ---------------------------------------- -- line 1765 ---------------------------------------- . c_variadic: bool, . unsafety: hir::Unsafety, . abi: abi::Abi, . ) -> T::Output . where . I: IntoIterator, . T: CollectAndApply, ty::FnSig<'tcx>>, . { 3,318 (0.0%) T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig { 885 (0.0%) inputs_and_output: self.mk_type_list(xs), 79 (0.0%) c_variadic, 79 (0.0%) unsafety, 53 (0.0%) abi, . }) . } . . pub fn mk_poly_existential_predicates_from_iter(self, iter: I) -> T::Output . where . I: Iterator, . T: CollectAndApply< . PolyExistentialPredicate<'tcx>, . &'tcx List>, . >, . { 2,530 (0.0%) T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs)) . } . . pub fn mk_clauses_from_iter(self, iter: I) -> T::Output . where . I: Iterator, . T: CollectAndApply, &'tcx List>>, . { 19,128 (0.0%) T::collect_and_apply(iter, |xs| self.mk_clauses(xs)) . } . . pub fn mk_type_list_from_iter(self, iter: I) -> T::Output . where . I: Iterator, . T: CollectAndApply, &'tcx List>>, . { 1,655 (0.0%) T::collect_and_apply(iter, |xs| self.mk_type_list(xs)) . } . . pub fn mk_args_from_iter(self, iter: I) -> T::Output . where . I: Iterator, . T: CollectAndApply, &'tcx List>>, . { 36,320,426 (0.0%) T::collect_and_apply(iter, |xs| self.mk_args(xs)) . } . . pub fn mk_canonical_var_infos_from_iter(self, iter: I) -> T::Output . where . I: Iterator, . T: CollectAndApply, &'tcx List>>, . { . T::collect_and_apply(iter, |xs| self.mk_canonical_var_infos(xs)) -- line 1821 ---------------------------------------- -- line 1854 ---------------------------------------- . ty::AliasTy { def_id, args, _use_mk_alias_ty_instead: () } . } . . pub fn mk_bound_variable_kinds_from_iter(self, iter: I) -> T::Output . where . I: Iterator, . T: CollectAndApply>, . { 76,220 (0.0%) T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs)) . } . . /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`, . /// typically generated by `#[derive(LintDiagnostic)]`). . #[track_caller] 44 (0.0%) pub fn emit_spanned_lint( . self, . lint: &'static Lint, . hir_id: HirId, . span: impl Into, . decorator: impl for<'a> DecorateLint<'a, ()>, . ) { . let msg = decorator.msg(); 34 (0.0%) let (level, src) = self.lint_level_at_node(lint, hir_id); 109 (0.0%) struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| { . decorator.decorate_lint(diag) . }) 21 (0.0%) } . . /// Emit a lint at the appropriate level for a hir node, with an associated span. . /// . /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation. . /// . /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature . #[rustc_lint_diagnostics] . #[track_caller] 384 (0.0%) pub fn struct_span_lint_hir( . self, . lint: &'static Lint, . hir_id: HirId, . span: impl Into, . msg: impl Into, . decorate: impl for<'a, 'b> FnOnce( . &'b mut DiagnosticBuilder<'a, ()>, . ) -> &'b mut DiagnosticBuilder<'a, ()>, . ) { 368 (0.0%) let (level, src) = self.lint_level_at_node(lint, hir_id); 1,267 (0.0%) struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate); 160 (0.0%) } . . /// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically . /// generated by `#[derive(LintDiagnostic)]`). . #[track_caller] . pub fn emit_lint( . self, . lint: &'static Lint, . id: HirId, -- line 1909 ---------------------------------------- -- line 1927 ---------------------------------------- . decorate: impl for<'a, 'b> FnOnce( . &'b mut DiagnosticBuilder<'a, ()>, . ) -> &'b mut DiagnosticBuilder<'a, ()>, . ) { . let (level, src) = self.lint_level_at_node(lint, id); . struct_lint_level(self.sess, lint, level, src, None, msg, decorate); . } . 1,050 (0.0%) pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> { 210 (0.0%) let map = self.in_scope_traits_map(id.owner)?; . let candidates = map.get(&id.local_id)?; 290 (0.0%) Some(candidates) 1,260 (0.0%) } . 85,962 (0.0%) pub fn named_bound_var(self, id: HirId) -> Option { . debug!(?id, "named_region"); . self.named_variable_map(id.owner).and_then(|map| map.get(&id.local_id).cloned()) 114,616 (0.0%) } . 3,810 (0.0%) pub fn is_late_bound(self, id: HirId) -> bool { . self.is_late_bound_map(id.owner).is_some_and(|set| set.contains(&id.local_id)) 4,572 (0.0%) } . 45,409 (0.0%) pub fn late_bound_vars(self, id: HirId) -> &'tcx List { 25,948 (0.0%) self.mk_bound_variable_kinds( . &self . .late_bound_vars_map(id.owner) . .and_then(|map| map.get(&id.local_id).cloned()) . .unwrap_or_else(|| { . bug!("No bound vars found for {}", self.hir().node_to_string(id)) . }), . ) 58,383 (0.0%) } . . /// Whether the `def_id` counts as const fn in the current crate, considering all active . /// feature gates 48 (0.0%) pub fn is_const_fn(self, def_id: DefId) -> bool { 6 (0.0%) if self.is_const_fn_raw(def_id) { . match self.lookup_const_stability(def_id) { . Some(stability) if stability.is_const_unstable() => { . // has a `rustc_const_unstable` attribute, check whether the user enabled the . // corresponding feature gate. . self.features() . .declared_lib_features . .iter() . .any(|&(sym, _)| sym == stability.feature) -- line 1972 ---------------------------------------- -- line 1974 ---------------------------------------- . // functions without const stability are either stable user written . // const fn or the user is using feature gates and we thus don't . // care what they do . _ => true, . } . } else { . false . } 42 (0.0%) } . . /// Whether the trait impl is marked const. This does not consider stability or feature gates. . pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool { . let Some(local_def_id) = def_id.as_local() else { return false }; . let hir_id = self.local_def_id_to_hir_id(local_def_id); . let node = self.hir().get(hir_id); . . matches!( -- line 1990 ---------------------------------------- -- line 1991 ---------------------------------------- . node, . hir::Node::Item(hir::Item { . kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }), . .. . }) . ) . } . 251,000 (0.0%) pub fn local_def_id_to_hir_id(self, local_def_id: LocalDefId) -> HirId { . self.opt_local_def_id_to_hir_id(local_def_id).unwrap() 376,500 (0.0%) } . . pub fn next_trait_solver_globally(self) -> bool { 32,414 (0.0%) self.sess.opts.unstable_opts.trait_solver == rustc_session::config::TraitSolver::Next 32,414 (0.0%) } . . pub fn next_trait_solver_in_coherence(self) -> bool { 282 (0.0%) matches!( 188 (0.0%) self.sess.opts.unstable_opts.trait_solver, . rustc_session::config::TraitSolver::Next . | rustc_session::config::TraitSolver::NextCoherence . ) 94 (0.0%) } . 10,005 (0.0%) pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool { 2,001 (0.0%) self.opt_rpitit_info(def_id).is_some() 4,002 (0.0%) } . . /// Named module children from all kinds of items, including imports. . /// In addition to regular items this list also includes struct and variant constructors, and . /// items inside `extern {}` blocks because all of them introduce names into parent module. . /// . /// Module here is understood in name resolution sense - it can be a `mod` item, . /// or a crate root, or an enum, or a trait. . /// -- line 2025 ---------------------------------------- -- line 2041 ---------------------------------------- . #[derive(Clone, Copy, PartialEq, Debug, Default, TyDecodable, TyEncodable, HashStable)] . pub struct DeducedParamAttrs { . /// The parameter is marked immutable in the function and contains no `UnsafeCell` (i.e. its . /// type is freeze). . pub read_only: bool, . } . . pub fn provide(providers: &mut Providers) { 2 (0.0%) providers.maybe_unused_trait_imports = 1 (0.0%) |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports; 2 (0.0%) providers.names_imported_by_glob_use = |tcx, id| { . tcx.arena.alloc(UnordSet::from( . tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default(), . )) . }; . 2 (0.0%) providers.extern_mod_stmt_cnum = 1 (0.0%) |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned(); 2 (0.0%) providers.is_panic_runtime = . |tcx, LocalCrate| attr::contains_name(tcx.hir().krate_attrs(), sym::panic_runtime); 2 (0.0%) providers.is_compiler_builtins = . |tcx, LocalCrate| attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins); 2 (0.0%) providers.has_panic_handler = |tcx, LocalCrate| { . // We want to check if the panic handler was defined in this crate . tcx.lang_items().panic_impl().is_some_and(|did| did.is_local()) . }; 2 (0.0%) providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP); . } -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_middle/src/ty/generic_args.rs -------------------------------------------------------------------------------- Ir________________ 260,268,898 (0.1%) -- line 42 ---------------------------------------- . } . } . . const TAG_MASK: usize = 0b11; . const TYPE_TAG: usize = 0b00; . const REGION_TAG: usize = 0b01; . const CONST_TAG: usize = 0b10; . 178,073 (0.0%) #[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)] . pub enum GenericArgKind<'tcx> { . Lifetime(ty::Region<'tcx>), . Type(Ty<'tcx>), . Const(ty::Const<'tcx>), . } . . impl<'tcx> GenericArgKind<'tcx> { . #[inline] -- line 58 ---------------------------------------- -- line 70 ---------------------------------------- . } . GenericArgKind::Const(ct) => { . // Ensure we can use the tag bits. . assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0); . (CONST_TAG, ct.0.0 as *const ty::ConstData<'tcx> as usize) . } . }; . 46,000 (0.0%) GenericArg { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData } . } . } . . impl<'tcx> Ord for GenericArg<'tcx> { . fn cmp(&self, other: &GenericArg<'tcx>) -> Ordering { . self.unpack().cmp(&other.unpack()) . } . } -- line 86 ---------------------------------------- -- line 124 ---------------------------------------- . impl<'tcx> GenericArg<'tcx> { . #[inline] . pub fn unpack(self) -> GenericArgKind<'tcx> { . let ptr = self.ptr.get(); . // SAFETY: use of `Interned::new_unchecked` here is ok because these . // pointers were originally created from `Interned` types in `pack()`, . // and this is just going in the other direction. . unsafe { 377,624,518 (0.2%) match ptr & TAG_MASK { . REGION_TAG => GenericArgKind::Lifetime(ty::Region(Interned::new_unchecked( . &*((ptr & !TAG_MASK) as *const ty::RegionKind<'tcx>), . ))), . TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked( . &*((ptr & !TAG_MASK) as *const WithCachedTypeInfo>), . ))), . CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked( . &*((ptr & !TAG_MASK) as *const ty::ConstData<'tcx>), -- line 140 ---------------------------------------- -- line 166 ---------------------------------------- . GenericArgKind::Const(ct) => Some(ct), . _ => None, . } . } . . /// Unpack the `GenericArg` as a region when it is known certainly to be a region. . pub fn expect_region(self) -> ty::Region<'tcx> { . self.as_region().unwrap_or_else(|| bug!("expected a region, but found another kind")) 1,566 (0.0%) } . . /// Unpack the `GenericArg` as a type when it is known certainly to be a type. . /// This is true in cases where `GenericArgs` is used in places where the kinds are known . /// to be limited (e.g. in tuples, where the only parameters are type parameters). . pub fn expect_ty(self) -> Ty<'tcx> { . self.as_type().unwrap_or_else(|| bug!("expected a type, but found another kind")) 134 (0.0%) } . . /// Unpack the `GenericArg` as a const when it is known certainly to be a const. . pub fn expect_const(self) -> ty::Const<'tcx> { . self.as_const().unwrap_or_else(|| bug!("expected a const, but found another kind")) . } . . pub fn is_non_region_infer(self) -> bool { . match self.unpack() { -- line 189 ---------------------------------------- -- line 202 ---------------------------------------- . GenericArgKind::Lifetime(lt) => tcx.lift(lt).map(|lt| lt.into()), . GenericArgKind::Type(ty) => tcx.lift(ty).map(|ty| ty.into()), . GenericArgKind::Const(ct) => tcx.lift(ct).map(|ct| ct.into()), . } . } . } . . impl<'tcx> TypeFoldable> for GenericArg<'tcx> { 59,544 (0.0%) fn try_fold_with>>( . self, . folder: &mut F, . ) -> Result { . match self.unpack() { 145 (0.0%) GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into), 3,942,940 (0.0%) GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into), 2 (0.0%) GenericArgKind::Const(ct) => ct.try_fold_with(folder).map(Into::into), . } 59,062 (0.0%) } . } . . impl<'tcx> TypeVisitable> for GenericArg<'tcx> { 155,479 (0.0%) fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { 955,758 (0.0%) match self.unpack() { . GenericArgKind::Lifetime(lt) => lt.visit_with(visitor), . GenericArgKind::Type(ty) => ty.visit_with(visitor), . GenericArgKind::Const(ct) => ct.visit_with(visitor), . } 34,976 (0.0%) } . } . . impl<'tcx, E: TyEncoder>> Encodable for GenericArg<'tcx> { . fn encode(&self, e: &mut E) { . self.unpack().encode(e) . } . } . . impl<'tcx, D: TyDecoder>> Decodable for GenericArg<'tcx> { . fn decode(d: &mut D) -> GenericArg<'tcx> { 11,751 (0.0%) GenericArgKind::decode(d).pack() . } . } . . /// List of generic arguments that are gonna be used to replace generic parameters. . pub type GenericArgs<'tcx> = List>; . . pub type GenericArgsRef<'tcx> = &'tcx GenericArgs<'tcx>; . -- line 248 ---------------------------------------- -- line 279 ---------------------------------------- . /// Inline const args have a particular structure controlled by the . /// compiler that encodes information like the inferred type; . /// see `ty::InlineConstArgs` struct for more comments. . pub fn as_inline_const(&'tcx self) -> InlineConstArgs<'tcx> { . InlineConstArgs { args: self } . } . . /// Creates an `GenericArgs` that maps each generic parameter to itself. 25,744 (0.0%) pub fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: impl Into) -> GenericArgsRef<'tcx> { 19,444 (0.0%) Self::for_item(tcx, def_id.into(), |param, _| tcx.mk_param_from_def(param)) 16,838 (0.0%) } . . /// Creates an `GenericArgs` for generic parameter definitions, . /// by calling closures to obtain each kind. . /// The closures get to observe the `GenericArgs` as they're . /// being built, which can be used to correctly . /// replace defaults of generic parameters. 3,371,979 (0.0%) pub fn for_item(tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> GenericArgsRef<'tcx> . where . F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>, . { . let defs = tcx.generics_of(def_id); . let count = defs.count(); . let mut args = SmallVec::with_capacity(count); 1,939,124 (0.0%) Self::fill_item(&mut args, tcx, defs, &mut mk_kind); 969,526 (0.0%) tcx.mk_args(&args) 3,368,883 (0.0%) } . 6,475 (0.0%) pub fn extend_to( . &self, . tcx: TyCtxt<'tcx>, . def_id: DefId, . mut mk_kind: F, . ) -> GenericArgsRef<'tcx> . where . F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>, . { . Self::for_item(tcx, def_id, |param, args| { 1,122 (0.0%) self.get(param.index as usize).cloned().unwrap_or_else(|| mk_kind(param, args)) . }) 3,317 (0.0%) } . 4,872,130 (0.0%) pub fn fill_item( . args: &mut SmallVec<[GenericArg<'tcx>; 8]>, . tcx: TyCtxt<'tcx>, . defs: &ty::Generics, . mk_kind: &mut F, . ) where . F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>, . { 1,944,477 (0.0%) if let Some(def_id) = defs.parent { . let parent_defs = tcx.generics_of(def_id); 12,250 (0.0%) Self::fill_item(args, tcx, parent_defs, mk_kind); . } 2,426,828 (0.0%) Self::fill_single(args, defs, mk_kind) 3,897,704 (0.0%) } . . pub fn fill_single( . args: &mut SmallVec<[GenericArg<'tcx>; 8]>, . defs: &ty::Generics, . mk_kind: &mut F, . ) where . F: FnMut(&ty::GenericParamDef, &[GenericArg<'tcx>]) -> GenericArg<'tcx>, . { . args.reserve(defs.params.len()); . for param in &defs.params { 2,953,051 (0.0%) let kind = mk_kind(param, args); 5,924,616 (0.0%) assert_eq!(param.index as usize, args.len(), "{args:#?}, {defs:#?}"); . args.push(kind); . } . } . . // Extend an `original_args` list to the full number of args expected by `def_id`, . // filling in the missing parameters with error ty/ct or 'static regions. . pub fn extend_with_error( . tcx: TyCtxt<'tcx>, -- line 354 ---------------------------------------- -- line 387 ---------------------------------------- . GenericArgKind::Lifetime(_) => None, . generic => Some(generic), . }) . } . . #[inline] . #[track_caller] . pub fn type_at(&self, i: usize) -> Ty<'tcx> { 5,862,540 (0.0%) self[i].as_type().unwrap_or_else(|| bug!("expected type for param #{} in {:?}", i, self)) . } . . #[inline] . #[track_caller] . pub fn region_at(&self, i: usize) -> ty::Region<'tcx> { . self[i] . .as_region() . .unwrap_or_else(|| bug!("expected region for param #{} in {:?}", i, self)) -- line 403 ---------------------------------------- -- line 428 ---------------------------------------- . /// impl X for U { fn f() {} } . /// ``` . /// . /// * If `self` is `[Self, S, T]`: the identity args of `f` in the trait. . /// * If `source_ancestor` is the def_id of the trait. . /// * If `target_args` is `[U]`, the args for the impl. . /// * Then we will return `[U, T]`, the arg for `f` in the impl that . /// are needed for it to match the trait. 2,164,122 (0.0%) pub fn rebase_onto( . &self, . tcx: TyCtxt<'tcx>, . source_ancestor: DefId, . target_args: GenericArgsRef<'tcx>, . ) -> GenericArgsRef<'tcx> { . let defs = tcx.generics_of(source_ancestor); 240,458 (0.0%) tcx.mk_args_from_iter(target_args.iter().chain(self.iter().skip(defs.params.len()))) 1,202,290 (0.0%) } . . pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> GenericArgsRef<'tcx> { 308,207 (0.0%) tcx.mk_args_from_iter(self.iter().take(generics.count())) . } . . pub fn host_effect_param(&'tcx self) -> Option> { . self.consts().rfind(|x| matches!(x.kind(), ty::ConstKind::Param(p) if p.name == sym::host)) . } . } . . impl<'tcx> TypeFoldable> for GenericArgsRef<'tcx> { 204,835,533 (0.1%) fn try_fold_with>>( . self, . folder: &mut F, . ) -> Result { . // This code is hot enough that it's worth specializing for the most . // common length lists, to avoid the overhead of `SmallVec` creation. . // The match arms are in order of frequency. The 1, 2, and 0 cases are . // typically hit in 90--99.99% of cases. When folding doesn't change . // the args, it's faster to reuse the existing args rather than . // calling `mk_args`. 155,044,452 (0.1%) match self.len() { . 1 => { 24,144,047 (0.0%) let param0 = self[0].try_fold_with(folder)?; 90,523,651 (0.0%) if param0 == self[0] { Ok(self) } else { Ok(folder.interner().mk_args(&[param0])) } . } . 2 => { 7,135,051 (0.0%) let param0 = self[0].try_fold_with(folder)?; 21,399,483 (0.0%) let param1 = self[1].try_fold_with(folder)?; 34,817,235 (0.0%) if param0 == self[0] && param1 == self[1] { . Ok(self) . } else { 11,070,977 (0.0%) Ok(folder.interner().mk_args(&[param0, param1])) . } . } . 0 => Ok(self), 16,771,421 (0.0%) _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_args(v)), . } 226,495,869 (0.1%) } . } . . impl<'tcx> TypeFoldable> for &'tcx ty::List> { 2,838,012 (0.0%) fn try_fold_with>>( . self, . folder: &mut F, . ) -> Result { . // This code is fairly hot, though not as hot as `GenericArgsRef`. . // . // When compiling stage 2, I get the following results: . // . // len | total | % -- line 495 ---------------------------------------- -- line 498 ---------------------------------------- . // 3 | 7540067 | 24.0 . // 1 | 5300377 | 16.9 . // 4 | 1351897 | 4.3 . // 0 | 1256849 | 4.0 . // . // I've tried it with some private repositories and got . // close to the same result, with 4 and 0 swapping places . // sometimes. 894,540 (0.0%) match self.len() { . 2 => { 444,090 (0.0%) let param0 = self[0].try_fold_with(folder)?; 1,322,417 (0.0%) let param1 = self[1].try_fold_with(folder)?; 1,485,405 (0.0%) if param0 == self[0] && param1 == self[1] { . Ok(self) . } else { 2,491,213 (0.0%) Ok(folder.interner().mk_type_list(&[param0, param1])) . } . } 26,781 (0.0%) _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_type_list(v)), . } 2,816,506 (0.0%) } . } . . impl<'tcx, T: TypeVisitable>> TypeVisitable> for &'tcx ty::List { . #[inline] . fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { 110,372 (0.0%) self.iter().try_for_each(|t| t.visit_with(visitor)) . } . } . . /// Similar to [`super::Binder`] except that it tracks early bound generics, i.e. `struct Foo(T)` . /// needs `T` instantiated immediately. This type primarily exists to avoid forgetting to call . /// `instantiate`. . /// . /// If you don't have anything to `instantiate`, you may be looking for . /// [`instantiate_identity`](EarlyBinder::instantiate_identity) or [`skip_binder`](EarlyBinder::skip_binder). . #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] 372 (0.0%) #[derive(Encodable, Decodable, HashStable)] . pub struct EarlyBinder { . value: T, . } . . /// For early binders, you should first call `instantiate` before using any visitors. . impl<'tcx, T> !TypeFoldable> for ty::EarlyBinder {} . impl<'tcx, T> !TypeVisitable> for ty::EarlyBinder {} . -- line 543 ---------------------------------------- -- line 584 ---------------------------------------- . /// [`instantiate_identity`](EarlyBinder::instantiate_identity). . /// . /// To skip the binder on `x: &EarlyBinder` to obtain `&T`, leverage . /// [`EarlyBinder::as_ref`](EarlyBinder::as_ref): `x.as_ref().skip_binder()`. . /// . /// See also [`Binder::skip_binder`](super::Binder::skip_binder), which is . /// the analogous operation on [`super::Binder`]. . pub fn skip_binder(self) -> T { 2,330 (0.0%) self.value . } . } . . impl EarlyBinder> { . pub fn transpose(self) -> Option> { . self.value.map(|value| EarlyBinder { value }) . } . } -- line 600 ---------------------------------------- -- line 668 ---------------------------------------- . I::Item: Deref, . ::Target: Copy + TypeFoldable>, . { . pub fn iter_instantiated_copied( . self, . tcx: TyCtxt<'tcx>, . args: &'s [GenericArg<'tcx>], . ) -> IterInstantiatedCopied<'s, 'tcx, I> { 3,013,360 (0.0%) IterInstantiatedCopied { it: self.value.into_iter(), tcx, args } . } . . /// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity), . /// but on an iterator of values that deref to a `TypeFoldable`. . pub fn instantiate_identity_iter_copied( . self, . ) -> impl Iterator::Target> { 570 (0.0%) self.value.into_iter().map(|v| *v) . } . } . . pub struct IterInstantiatedCopied<'a, 'tcx, I: IntoIterator> { . it: I::IntoIter, . tcx: TyCtxt<'tcx>, . args: &'a [GenericArg<'tcx>], . } -- line 692 ---------------------------------------- -- line 694 ---------------------------------------- . impl<'tcx, I: IntoIterator> Iterator for IterInstantiatedCopied<'_, 'tcx, I> . where . I::Item: Deref, . ::Target: Copy + TypeFoldable>, . { . type Item = ::Target; . . fn next(&mut self) -> Option { 6,964,688 (0.0%) self.it.next().map(|value| EarlyBinder { value: *value }.instantiate(self.tcx, self.args)) . } . . fn size_hint(&self) -> (usize, Option) { 683,255 (0.0%) self.it.size_hint() . } . } . . impl<'tcx, I: IntoIterator> DoubleEndedIterator for IterInstantiatedCopied<'_, 'tcx, I> . where . I::IntoIter: DoubleEndedIterator, . I::Item: Deref, . ::Target: Copy + TypeFoldable>, -- line 714 ---------------------------------------- -- line 747 ---------------------------------------- . . fn size_hint(&self) -> (usize, Option) { . self.t.size_hint() . } . } . . impl<'tcx, T: TypeFoldable>> ty::EarlyBinder { . pub fn instantiate(self, tcx: TyCtxt<'tcx>, args: &[GenericArg<'tcx>]) -> T { 14,319,041 (0.0%) let mut folder = ArgFolder { tcx, args, binders_passed: 0 }; . self.value.fold_with(&mut folder) . } . . /// Makes the identity replacement `T0 => T0, ..., TN => TN`. . /// Conceptually, this converts universally bound variables into placeholders . /// when inside of a given item. . /// . /// For example, consider `for fn foo(){ .. }`: . /// - Outside of `foo`, `T` is bound (represented by the presence of `EarlyBinder`). . /// - Inside of the body of `foo`, we treat `T` as a placeholder by calling . /// `instantiate_identity` to discharge the `EarlyBinder`. . pub fn instantiate_identity(self) -> T { 8,334 (0.0%) self.value . } . . /// Returns the inner value, but only if it contains no bound vars. . pub fn no_bound_vars(self) -> Option { . if !self.value.has_param() { Some(self.value) } else { None } . } . } . -- line 776 ---------------------------------------- -- line 790 ---------------------------------------- . fn interner(&self) -> TyCtxt<'tcx> { . self.tcx . } . . fn fold_binder>>( . &mut self, . t: ty::Binder<'tcx, T>, . ) -> ty::Binder<'tcx, T> { 2,363,830 (0.0%) self.binders_passed += 1; . let t = t.super_fold_with(self); 2,350,546 (0.0%) self.binders_passed -= 1; . t . } . 10,660 (0.0%) fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { . #[cold] . #[inline(never)] . fn region_param_out_of_range(data: ty::EarlyBoundRegion, args: &[GenericArg<'_>]) -> ! { . bug!( . "Region parameter out of range when substituting in region {} (index={}, args = {:?})", . data.name, . data.index, . args, -- line 812 ---------------------------------------- -- line 824 ---------------------------------------- . ) . } . . // Note: This routine only handles regions that are bound on . // type declarations and other outer declarations, not those . // bound in *fn types*. Region substitution of the bound . // regions that appear in a function signature is done using . // the specialized routine `ty::replace_late_regions()`. 26,650 (0.0%) match *r { 8,456 (0.0%) ty::ReEarlyBound(data) => { 8,456 (0.0%) let rk = self.args.get(data.index as usize).map(|k| k.unpack()); . match rk { 4,228 (0.0%) Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt), . Some(other) => region_param_invalid(data, other), . None => region_param_out_of_range(data, self.args), . } . } . ty::ReLateBound(..) . | ty::ReFree(_) . | ty::ReStatic . | ty::RePlaceholder(_) . | ty::ReErased . | ty::ReError(_) => r, . ty::ReVar(_) => bug!("unexpected region: {r:?}"), . } 10,660 (0.0%) } . 17,574,506 (0.0%) fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { 8,787,253 (0.0%) if !t.has_param() { . return t; . } . 16,257,234 (0.0%) match *t.kind() { 12,647,600 (0.0%) ty::Param(p) => self.ty_for_param(p, t), . _ => t.super_fold_with(self), . } 13,964,872 (0.0%) } . 1,026 (0.0%) fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> { . if let ty::ConstKind::Param(p) = c.kind() { . self.const_for_param(p, c) . } else { . c.super_fold_with(self) . } 1,026 (0.0%) } . } . . impl<'a, 'tcx> ArgFolder<'a, 'tcx> { . fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> { . // Look up the type in the args. It really should be in there. 12,647,600 (0.0%) let opt_ty = self.args.get(p.index as usize).map(|k| k.unpack()); . let ty = match opt_ty { . Some(GenericArgKind::Type(ty)) => ty, . Some(kind) => self.type_param_expected(p, source_ty, kind), . None => self.type_param_out_of_range(p, source_ty), . }; . . self.shift_vars_through_binders(ty) . } -- line 882 ---------------------------------------- -- line 903 ---------------------------------------- . ty, . p.index, . self.args, . ) . } . . fn const_for_param(&self, p: ParamConst, source_ct: ty::Const<'tcx>) -> ty::Const<'tcx> { . // Look up the const in the args. It really should be in there. 228 (0.0%) let opt_ct = self.args.get(p.index as usize).map(|k| k.unpack()); . let ct = match opt_ct { . Some(GenericArgKind::Const(ct)) => ct, . Some(kind) => self.const_param_expected(p, source_ct, kind), . None => self.const_param_out_of_range(p, source_ct), . }; . . self.shift_vars_through_binders(ct) . } -- line 919 ---------------------------------------- -- line 993 ---------------------------------------- . 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() . ); . 22,451,090 (0.0%) if self.binders_passed == 0 || !val.has_escaping_bound_vars() { . return val; . } . . let result = ty::fold::shift_vars(TypeFolder::interner(self), val, self.binders_passed); . debug!("shift_vars: shifted result = {:?}", result); . . result . } . . fn shift_region_through_binders(&self, region: ty::Region<'tcx>) -> ty::Region<'tcx> { 12,994 (0.0%) if self.binders_passed == 0 || !region.has_escaping_bound_vars() { . return region; . } . ty::fold::shift_region(self.tcx, region, self.binders_passed) . } . } . . /// Stores the user-given args to reach some fully qualified path . /// (e.g., `::Item` or `::Item`). . #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] 5,582 (0.0%) #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub struct UserArgs<'tcx> { . /// The args for the item as given by the user. . pub args: GenericArgsRef<'tcx>, . . /// The self type, in the case of a `::Item` path (when applied . /// to an inherent impl). See `UserSelfTy` below. 91 (0.0%) pub user_self_ty: Option>, . } . . /// Specifies the user-given self type. In the case of a path that . /// refers to a member in an inherent impl, this self type is . /// sometimes needed to constrain the type parameters on the impl. For . /// example, in this code: . /// . /// ```ignore (illustrative) -- line 1037 ---------------------------------------- -- line 1040 ---------------------------------------- . /// ``` . /// . /// when you then have a path like `>::method`, . /// this struct would carry the `DefId` of the impl along with the . /// self type `Foo`. Then we can instantiate the parameters of . /// the impl (with the args from `UserArgs`) and apply those to . /// the self type, giving `Foo`. Finally, we unify that with . /// the self type here, which contains `?A` to be `&'static u32` 213 (0.0%) #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] . #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub struct UserSelfTy<'tcx> { . pub impl_def_id: DefId, 270 (0.0%) pub self_ty: Ty<'tcx>, . } -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_middle/src/ty/mod.rs -------------------------------------------------------------------------------- Ir__________________ 331,246,872 (0.1%) -- line 221 ---------------------------------------- . pub struct MainDefinition { . pub res: Res, . pub is_import: bool, . pub span: Span, . } . . impl MainDefinition { . pub fn opt_fn_def_id(self) -> Option { 7 (0.0%) if let Res::Def(DefKind::Fn, def_id) = self.res { Some(def_id) } else { None } 1 (0.0%) } . } . . /// The "header" of an impl is everything outside the body: a Self type, a trait . /// ref (in the case of a trait impl), and a set of predicates (from the . /// bounds / where-clauses). 1,832 (0.0%) #[derive(Clone, Debug, TypeFoldable, TypeVisitable)] . pub struct ImplHeader<'tcx> { . pub impl_def_id: DefId, . pub self_ty: Ty<'tcx>, . pub trait_ref: Option>, . pub predicates: Vec>, . } . 119 (0.0%) #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)] . pub enum ImplSubject<'tcx> { . Trait(TraitRef<'tcx>), . Inherent(Ty<'tcx>), . } . 587,008,921 (0.2%) #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] . #[derive(TypeFoldable, TypeVisitable)] . pub enum ImplPolarity { . /// `impl Trait for Type` . Positive, . /// `impl !Trait for Type` . Negative, . /// `#[rustc_reservation_impl] impl Trait for Type` . /// -- line 258 ---------------------------------------- -- line 277 ---------------------------------------- . match self { . Self::Positive => f.write_str("positive"), . Self::Negative => f.write_str("negative"), . Self::Reservation => f.write_str("reservation"), . } . } . } . 1,501,829 (0.0%) #[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, Decodable, HashStable)] . pub enum Visibility { . /// Visible everywhere (including in other crates). . Public, . /// Visible only in the given crate-local module. . Restricted(Id), . } . 116,987,385 (0.0%) #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] . pub enum BoundConstness { . /// `T: Trait` . NotConst, . /// `T: ~const Trait` . /// . /// Requires resolving to const only when we are in a const context. . ConstIfConst, . } -- line 301 ---------------------------------------- -- line 329 ---------------------------------------- . pub before_feature_tys: Ty<'tcx>, . /// Tuple containing the types of closure captures after the feature `capture_disjoint_fields` . pub after_feature_tys: Ty<'tcx>, . } . . impl TyCtxt<'_> { . #[inline] . pub fn opt_parent(self, id: DefId) -> Option { 3,755,474 (0.0%) self.def_key(id).parent.map(|index| DefId { index, ..id }) . } . . #[inline] . #[track_caller] 1,920 (0.0%) pub fn parent(self, id: DefId) -> DefId { 610,306 (0.0%) match self.opt_parent(id) { . Some(id) => id, . // not `unwrap_or_else` to avoid breaking caller tracking . None => bug!("{id:?} doesn't have a parent"), . } 960 (0.0%) } . . #[inline] . #[track_caller] . pub fn opt_local_parent(self, id: LocalDefId) -> Option { . self.opt_parent(id.to_def_id()).map(DefId::expect_local) . } . . #[inline] . #[track_caller] . pub fn local_parent(self, id: LocalDefId) -> LocalDefId { 174 (0.0%) self.parent(id.to_def_id()).expect_local() . } . 646,933 (0.0%) pub fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool { 102,572 (0.0%) if descendant.krate != ancestor.krate { . return false; . } . 233,006 (0.0%) while descendant != ancestor { 139,275 (0.0%) match self.opt_parent(descendant) { . Some(parent) => descendant = parent, . None => return false, . } . } . true 739,352 (0.0%) } . } . . impl Visibility { . pub fn is_public(self) -> bool { 48,871 (0.0%) matches!(self, Visibility::Public) . } . . pub fn map_id(self, f: impl FnOnce(Id) -> OutId) -> Visibility { 83,209 (0.0%) match self { . Visibility::Public => Visibility::Public, . Visibility::Restricted(id) => Visibility::Restricted(f(id)), . } . } . } . . impl> Visibility { . pub fn to_def_id(self) -> Visibility { . self.map_id(Into::into) . } . . /// Returns `true` if an item with this visibility is accessible from the given module. . pub fn is_accessible_from(self, module: impl Into, tcx: TyCtxt<'_>) -> bool { 97,026 (0.0%) match self { . // Public items are visible everywhere. . Visibility::Public => true, 520,050 (0.0%) Visibility::Restricted(id) => tcx.is_descendant_of(module.into(), id.into()), . } . } . . /// Returns `true` if this visibility is at least as accessible as the given visibility . pub fn is_at_least(self, vis: Visibility>, tcx: TyCtxt<'_>) -> bool { 336,463 (0.0%) match vis { . Visibility::Public => self.is_public(), . Visibility::Restricted(id) => self.is_accessible_from(id, tcx), . } . } . } . . impl Visibility { 36,844 (0.0%) pub fn expect_local(self) -> Visibility { . self.map_id(|id| id.expect_local()) 110,532 (0.0%) } . . /// Returns `true` if this item is visible anywhere in the local crate. . pub fn is_visible_locally(self) -> bool { . match self { . Visibility::Public => true, . Visibility::Restricted(def_id) => def_id.is_local(), . } . } -- line 424 ---------------------------------------- -- line 442 ---------------------------------------- . // the types of AST nodes. . #[derive(Copy, Clone, PartialEq, Eq, Hash)] . pub struct CReaderCacheKey { . pub cnum: Option, . pub pos: usize, . } . . /// Use this rather than `TyKind`, whenever possible. 2,915 (0.0%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)] . #[rustc_diagnostic_item = "Ty"] . #[rustc_pass_by_value] . pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo>>); . . impl ty::EarlyBoundRegion { . /// Does this early bound region have a name? Early bound regions normally . /// always have names except when using anonymous lifetimes (`'_`). . pub fn has_name(&self) -> bool { -- line 458 ---------------------------------------- -- line 471 ---------------------------------------- . pub struct Predicate<'tcx>( . Interned<'tcx, WithCachedTypeInfo>>>, . ); . . impl<'tcx> Predicate<'tcx> { . /// Gets the inner `Binder<'tcx, PredicateKind<'tcx>>`. . #[inline] . pub fn kind(self) -> Binder<'tcx, PredicateKind<'tcx>> { 145,447,774 (0.1%) self.0.internee . } . . #[inline(always)] . pub fn flags(self) -> TypeFlags { . self.0.flags . } . . #[inline(always)] -- line 487 ---------------------------------------- -- line 508 ---------------------------------------- . . _ => None, . }) . .transpose()?; . . Some(tcx.mk_predicate(kind)) . } . 179,719,518 (0.1%) pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> Self { 179,744,108 (0.1%) if let PredicateKind::Clause(ClauseKind::Trait(TraitPredicate { trait_ref, constness, polarity })) = self.kind().skip_binder() 89,585,480 (0.0%) && constness != BoundConstness::NotConst . { . self = tcx.mk_predicate(self.kind().rebind(PredicateKind::Clause(ClauseKind::Trait(TraitPredicate { . trait_ref, . constness: BoundConstness::NotConst, . polarity, . })))); . } . self 179,719,518 (0.1%) } . . #[instrument(level = "debug", skip(tcx), ret)] . pub fn is_coinductive(self, tcx: TyCtxt<'tcx>) -> bool { . match self.kind().skip_binder() { . ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => { . tcx.trait_is_coinductive(data.def_id()) . } . ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => true, -- line 535 ---------------------------------------- -- line 539 ---------------------------------------- . . /// Whether this projection can be soundly normalized. . /// . /// Wf predicates must not be normalized, as normalization . /// can remove required bounds which would cause us to . /// unsoundly accept some programs. See #91068. . #[inline] . pub fn allow_normalization(self) -> bool { 426,962 (0.0%) match self.kind().skip_binder() { . PredicateKind::Clause(ClauseKind::WellFormed(_)) => false, . PredicateKind::Clause(ClauseKind::Trait(_)) . | PredicateKind::Clause(ClauseKind::RegionOutlives(_)) . | PredicateKind::Clause(ClauseKind::TypeOutlives(_)) . | PredicateKind::Clause(ClauseKind::Projection(_)) . | PredicateKind::Clause(ClauseKind::ConstArgHasType(..)) . | PredicateKind::AliasRelate(..) . | PredicateKind::ObjectSafe(_) -- line 555 ---------------------------------------- -- line 582 ---------------------------------------- . #[rustc_pass_by_value] . pub struct Clause<'tcx>(Interned<'tcx, WithCachedTypeInfo>>>); . . impl<'tcx> Clause<'tcx> { . pub fn as_predicate(self) -> Predicate<'tcx> { . Predicate(self.0) . } . 6,856,779 (0.0%) pub fn kind(self) -> Binder<'tcx, ClauseKind<'tcx>> { 42,161,209 (0.0%) self.0.internee.map_bound(|kind| match kind { 27,436,316 (0.0%) PredicateKind::Clause(clause) => clause, . _ => unreachable!(), . }) 20,570,337 (0.0%) } . 1,585,666 (0.0%) pub fn as_trait_clause(self) -> Option>> { . let clause = self.kind(); 9,263,932 (0.0%) if let ty::ClauseKind::Trait(trait_clause) = clause.skip_binder() { 1,523,150 (0.0%) Some(clause.rebind(trait_clause)) . } else { 62,516 (0.0%) None . } 4,756,998 (0.0%) } . . pub fn as_projection_clause(self) -> Option>> { . let clause = self.kind(); . if let ty::ClauseKind::Projection(projection_clause) = clause.skip_binder() { . Some(clause.rebind(projection_clause)) . } else { . None . } -- line 612 ---------------------------------------- -- line 625 ---------------------------------------- . let clause = self.kind(); . if let ty::ClauseKind::RegionOutlives(o) = clause.skip_binder() { . Some(clause.rebind(o)) . } else { . None . } . } . 24,590 (0.0%) pub fn without_const(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { . self.as_predicate().without_const(tcx).expect_clause() 24,590 (0.0%) } . } . 19,125,372 (0.0%) #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] 76,191,744 (0.0%) #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . /// A clause is something that can appear in where bounds or be inferred . /// by implied bounds. . pub enum ClauseKind<'tcx> { . /// Corresponds to `where Foo: Bar`. `Foo` here would be . /// the `Self` type of the trait reference and `A`, `B`, and `C` . /// would be the type parameters. . Trait(TraitPredicate<'tcx>), . -- line 647 ---------------------------------------- -- line 661 ---------------------------------------- . . /// No syntax: `T` well-formed. . WellFormed(GenericArg<'tcx>), . . /// Constant initializer must evaluate successfully. . ConstEvaluatable(ty::Const<'tcx>), . } . 181,262,587 (0.1%) #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] 256,702,605 (0.1%) #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub enum PredicateKind<'tcx> { . /// Prove a clause . Clause(ClauseKind<'tcx>), . . /// Trait must be object-safe. . ObjectSafe(DefId), . . /// No direct syntax. May be thought of as `where T: FnFoo<...>` . /// for some generic args `...` and `T` being a closure type. . /// Satisfied (or refuted) once we know the closure's kind. 14 (0.0%) ClosureKind(DefId, GenericArgsRef<'tcx>, ClosureKind), . . /// `T1 <: T2` . /// . /// This obligation is created most often when we have two . /// unresolved type variables and hence don't have enough . /// information to process the subtyping obligation yet. . Subtype(SubtypePredicate<'tcx>), . -- line 689 ---------------------------------------- -- line 742 ---------------------------------------- . } . . impl<'tcx> Clause<'tcx> { . /// Performs a substitution suitable for going from a . /// poly-trait-ref to supertraits that must hold if that . /// poly-trait-ref holds. This is slightly different from a normal . /// substitution in terms of what happens with bound regions. See . /// lengthy comment below for details. 13,800 (0.0%) pub fn subst_supertrait( . self, . tcx: TyCtxt<'tcx>, . trait_ref: &ty::PolyTraitRef<'tcx>, . ) -> Clause<'tcx> { . // The interaction between HRTB and supertraits is not entirely . // obvious. Let me walk you (and myself) through an example. . // . // Let's start with an easy case. Consider two traits: -- line 758 ---------------------------------------- -- line 826 ---------------------------------------- . // 3) Finally, to create the final bound vars, we concatenate the bound . // vars of the trait ref with those of the predicate: . // ['x, 'b] . let bound_pred = self.kind(); . let pred_bound_vars = bound_pred.bound_vars(); . let trait_bound_vars = trait_ref.bound_vars(); . // 1) Self: Bar1<'a, '^0.0> -> Self: Bar1<'a, '^0.1> . let shifted_pred = 9,200 (0.0%) tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder()); . // 2) Self: Bar1<'a, '^0.1> -> T: Bar1<'^0.0, '^0.1> 2,300 (0.0%) let new = EarlyBinder::bind(shifted_pred).instantiate(tcx, trait_ref.skip_binder().args); . // 3) ['x] + ['b] -> ['x, 'b] . let bound_vars = 2,300 (0.0%) tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars)); . . // FIXME: Is it really perf sensitive to use reuse_or_mk_predicate here? 11,500 (0.0%) tcx.reuse_or_mk_predicate( . self.as_predicate(), . ty::Binder::bind_with_vars(PredicateKind::Clause(new), bound_vars), . ) . .expect_clause() 16,100 (0.0%) } . } . . #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] 263,743 (0.0%) #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub struct TraitPredicate<'tcx> { . pub trait_ref: TraitRef<'tcx>, . . pub constness: BoundConstness, . . /// If polarity is Positive: we are proving that the trait is implemented. . /// . /// If polarity is Negative: we are proving that a negative impl of this trait . /// exists. (Note that coherence also checks whether negative impls of supertraits . /// exist via a series of predicates.) . /// . /// If polarity is Reserved: that's a bug. 1,920,954,503 (0.8%) pub polarity: ImplPolarity, . } . . pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; . . impl<'tcx> TraitPredicate<'tcx> { 455 (0.0%) pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { 728 (0.0%) Self { trait_ref: self.trait_ref.with_self_ty(tcx, self_ty), ..self } 455 (0.0%) } . . pub fn def_id(self) -> DefId { . self.trait_ref.def_id . } . 983,728 (0.0%) pub fn self_ty(self) -> Ty<'tcx> { . self.trait_ref.self_ty() 1,967,456 (0.0%) } . . #[inline] . pub fn is_const_if_const(self) -> bool { . self.constness == BoundConstness::ConstIfConst . } . . pub fn is_constness_satisfied_by(self, constness: hir::Constness) -> bool { . match (self.constness, constness) { -- line 888 ---------------------------------------- -- line 899 ---------------------------------------- . } . . impl<'tcx> PolyTraitPredicate<'tcx> { . pub fn def_id(self) -> DefId { . // Ok to skip binder since trait `DefId` does not care about regions. . self.skip_binder().def_id() . } . 2,657 (0.0%) pub fn self_ty(self) -> ty::Binder<'tcx, Ty<'tcx>> { 10,628 (0.0%) self.map_bound(|trait_ref| trait_ref.self_ty()) 5,314 (0.0%) } . . #[inline] . pub fn is_const_if_const(self) -> bool { . self.skip_binder().is_const_if_const() . } . . #[inline] . pub fn polarity(self) -> ImplPolarity { . self.skip_binder().polarity . } . } . . /// `A: B` 12 (0.0%) #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] 14,362 (0.0%) #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub struct OutlivesPredicate(pub A, pub B); . pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate, ty::Region<'tcx>>; . pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate, ty::Region<'tcx>>; . pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>; . pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>; . . /// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates . /// whether the `a` type is the type that we should label as "expected" when . /// presenting user diagnostics. . #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] . #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub struct SubtypePredicate<'tcx> { 795 (0.0%) pub a_is_expected: bool, 159 (0.0%) pub a: Ty<'tcx>, . pub b: Ty<'tcx>, . } . pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>; . . /// Encodes that we have to coerce *from* the `a` type to the `b` type. . #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] . #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub struct CoercePredicate<'tcx> { -- line 946 ---------------------------------------- -- line 970 ---------------------------------------- . . impl<'tcx> From> for Term<'tcx> { . fn from(ty: Ty<'tcx>) -> Self { . TermKind::Ty(ty).pack() . } . } . . impl<'tcx> From> for Term<'tcx> { 28 (0.0%) fn from(c: Const<'tcx>) -> Self { . TermKind::Const(c).pack() 28 (0.0%) } . } . . impl<'a, 'tcx> HashStable> for Term<'tcx> { . fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { . self.unpack().hash_stable(hcx, hasher); . } . } . . impl<'tcx> TypeFoldable> for Term<'tcx> { 716,445 (0.0%) fn try_fold_with>>( . self, . folder: &mut F, . ) -> Result { . Ok(self.unpack().try_fold_with(folder)?.pack()) 716,445 (0.0%) } . } . . impl<'tcx> TypeVisitable> for Term<'tcx> { . fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { 239,657 (0.0%) self.unpack().visit_with(visitor) . } . } . . impl<'tcx, E: TyEncoder>> Encodable for Term<'tcx> { . fn encode(&self, e: &mut E) { . self.unpack().encode(e) . } . } . . impl<'tcx, D: TyDecoder>> Decodable for Term<'tcx> { . fn decode(d: &mut D) -> Self { 4 (0.0%) let res: TermKind<'tcx> = Decodable::decode(d); . res.pack() . } . } . . impl<'tcx> Term<'tcx> { . #[inline] . pub fn unpack(self) -> TermKind<'tcx> { . let ptr = self.ptr.get(); . // SAFETY: use of `Interned::new_unchecked` here is ok because these . // pointers were originally created from `Interned` types in `pack()`, . // and this is just going in the other direction. . unsafe { 164 (0.0%) match ptr & TAG_MASK { . TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked( . &*((ptr & !TAG_MASK) as *const WithCachedTypeInfo>), . ))), . CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked( . &*((ptr & !TAG_MASK) as *const ty::ConstData<'tcx>), . ))), . _ => core::intrinsics::unreachable(), . } . } . } . . pub fn ty(&self) -> Option> { 2,364,687 (0.0%) if let TermKind::Ty(ty) = self.unpack() { Some(ty) } else { None } 788,229 (0.0%) } . . pub fn ct(&self) -> Option> { . if let TermKind::Const(c) = self.unpack() { Some(c) } else { None } . } . . pub fn into_arg(self) -> GenericArg<'tcx> { . match self.unpack() { . TermKind::Ty(ty) => ty.into(), -- line 1047 ---------------------------------------- -- line 1070 ---------------------------------------- . } . } . } . . const TAG_MASK: usize = 0b11; . const TYPE_TAG: usize = 0b00; . const CONST_TAG: usize = 0b01; . 30 (0.0%) #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)] 4,129,367 (0.0%) #[derive(HashStable, TypeFoldable, TypeVisitable)] . pub enum TermKind<'tcx> { . Ty(Ty<'tcx>), . Const(Const<'tcx>), . } . . impl<'tcx> TermKind<'tcx> { . #[inline] . fn pack(self) -> Term<'tcx> { -- line 1087 ---------------------------------------- -- line 1093 ---------------------------------------- . } . TermKind::Const(ct) => { . // Ensure we can use the tag bits. . assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0); . (CONST_TAG, ct.0.0 as *const ty::ConstData<'tcx> as usize) . } . }; . 834,947 (0.0%) Term { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData } . } . } . . #[derive(Copy, Clone, PartialEq, Eq, Debug)] . pub enum ParamTerm { . Ty(ParamTy), . Const(ParamConst), . } -- line 1109 ---------------------------------------- -- line 1112 ---------------------------------------- . pub fn index(self) -> usize { . match self { . ParamTerm::Ty(ty) => ty.index as usize, . ParamTerm::Const(ct) => ct.index as usize, . } . } . } . 61,087 (0.0%) #[derive(Copy, Clone, Eq, PartialEq, Debug)] . pub enum TermVid<'tcx> { . Ty(ty::TyVid), . Const(ty::ConstVid<'tcx>), . } . . impl From for TermVid<'_> { . fn from(value: ty::TyVid) -> Self { . TermVid::Ty(value) -- line 1128 ---------------------------------------- -- line 1143 ---------------------------------------- . /// . /// In particular, form #1 is "desugared" to the combination of a . /// normal trait predicate (`T: TraitRef<...>`) and one of these . /// predicates. Form #2 is a broader form in that it also permits . /// equality between arbitrary types. Processing an instance of . /// Form #2 eventually yields one of these `ProjectionPredicate` . /// instances to normalize the LHS. . #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] 1 (0.0%) #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub struct ProjectionPredicate<'tcx> { . pub projection_ty: AliasTy<'tcx>, 76,515 (0.0%) pub term: Term<'tcx>, . } . . impl<'tcx> ProjectionPredicate<'tcx> { 548,193 (0.0%) pub fn self_ty(self) -> Ty<'tcx> { . self.projection_ty.self_ty() . } . . pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ProjectionPredicate<'tcx> { . Self { projection_ty: self.projection_ty.with_self_ty(tcx, self_ty), ..self } . } . . pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { -- line 1166 ---------------------------------------- -- line 1173 ---------------------------------------- . } . . pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>; . . impl<'tcx> PolyProjectionPredicate<'tcx> { . /// Returns the `DefId` of the trait of the associated item being projected. . #[inline] . pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId { 4 (0.0%) self.skip_binder().projection_ty.trait_def_id(tcx) . } . . /// Get the [PolyTraitRef] required for this projection to be well formed. . /// Note that for generic associated types the predicates of the associated . /// type also need to be checked. . #[inline] . pub fn required_poly_trait_ref(&self, tcx: TyCtxt<'tcx>) -> PolyTraitRef<'tcx> { . // Note: unlike with `TraitRef::to_poly_trait_ref()`, -- line 1189 ---------------------------------------- -- line 1208 ---------------------------------------- . } . } . . pub trait ToPolyTraitRef<'tcx> { . fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>; . } . . impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> { 79,060 (0.0%) fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> { . self.map_bound_ref(|trait_pred| trait_pred.trait_ref) 79,060 (0.0%) } . } . . pub trait ToPredicate<'tcx, P = Predicate<'tcx>> { . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> P; . } . . impl<'tcx, T> ToPredicate<'tcx, T> for T { . fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> T { 1,370,405 (0.0%) self 51,760,057 (0.0%) } . } . . impl<'tcx> ToPredicate<'tcx> for PredicateKind<'tcx> { . #[inline(always)] . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { 219 (0.0%) ty::Binder::dummy(self).to_predicate(tcx) . } . } . . impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> { . #[inline(always)] . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { . tcx.mk_predicate(self) . } -- line 1242 ---------------------------------------- -- line 1254 ---------------------------------------- . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { . tcx.mk_predicate(self.map_bound(ty::PredicateKind::Clause)) . } . } . . impl<'tcx> ToPredicate<'tcx> for Clause<'tcx> { . #[inline(always)] . fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { 42,064 (0.0%) self.as_predicate() . } . } . . impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for ClauseKind<'tcx> { . #[inline(always)] . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { . tcx.mk_predicate(Binder::dummy(ty::PredicateKind::Clause(self))).expect_clause() . } . } . . impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for Binder<'tcx, ClauseKind<'tcx>> { . #[inline(always)] . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { 23,220 (0.0%) tcx.mk_predicate(self.map_bound(|clause| ty::PredicateKind::Clause(clause))).expect_clause() . } . } . . impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { . #[inline(always)] . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { 7,681 (0.0%) ty::Binder::dummy(self).to_predicate(tcx) . } . } . . impl<'tcx> ToPredicate<'tcx, TraitPredicate<'tcx>> for TraitRef<'tcx> { . #[inline(always)] . fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> TraitPredicate<'tcx> { . self.without_const() . } . } . . impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for TraitRef<'tcx> { . #[inline(always)] . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { . let p: Predicate<'tcx> = self.to_predicate(tcx); 7,143 (0.0%) p.expect_clause() . } . } . . impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for TraitPredicate<'tcx> { . #[inline(always)] . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { 727 (0.0%) let p: Predicate<'tcx> = self.to_predicate(tcx); 566 (0.0%) p.expect_clause() . } . } . . impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> { . #[inline(always)] . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { 243 (0.0%) let pred: PolyTraitPredicate<'tcx> = self.to_predicate(tcx); 18,299 (0.0%) pred.to_predicate(tcx) . } . } . . impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for Binder<'tcx, TraitRef<'tcx>> { . #[inline(always)] . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { . let pred: PolyTraitPredicate<'tcx> = self.to_predicate(tcx); . pred.to_predicate(tcx) . } . } . . impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef<'tcx>> { . #[inline(always)] . fn to_predicate(self, _: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> { 20 (0.0%) self.map_bound(|trait_ref| TraitPredicate { . trait_ref, . constness: ty::BoundConstness::NotConst, . polarity: ty::ImplPolarity::Positive, . }) . } . } . . impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for TraitRef<'tcx> { -- line 1337 ---------------------------------------- -- line 1342 ---------------------------------------- . . impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for TraitPredicate<'tcx> { . fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> { . ty::Binder::dummy(self) . } . } . . impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> { 67,854 (0.0%) fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { 169,635 (0.0%) self.map_bound(|p| PredicateKind::Clause(ClauseKind::Trait(p))).to_predicate(tcx) 67,854 (0.0%) } . } . . impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyTraitPredicate<'tcx> { . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { 460 (0.0%) let p: Predicate<'tcx> = self.to_predicate(tcx); . p.expect_clause() . } . } . . impl<'tcx> ToPredicate<'tcx> for OutlivesPredicate, ty::Region<'tcx>> { . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { . ty::Binder::dummy(PredicateKind::Clause(ClauseKind::RegionOutlives(self))).to_predicate(tcx) . } -- line 1365 ---------------------------------------- -- line 1385 ---------------------------------------- . . impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { . fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { . self.map_bound(|p| PredicateKind::Clause(ClauseKind::Projection(p))).to_predicate(tcx) . } . } . . impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyProjectionPredicate<'tcx> { 982 (0.0%) fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { 2,455 (0.0%) let p: Predicate<'tcx> = self.to_predicate(tcx); . p.expect_clause() 982 (0.0%) } . } . . impl<'tcx> ToPredicate<'tcx> for TraitPredicate<'tcx> { 876 (0.0%) fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { 876 (0.0%) PredicateKind::Clause(ClauseKind::Trait(self)).to_predicate(tcx) 876 (0.0%) } . } . . impl<'tcx> Predicate<'tcx> { 6,866 (0.0%) pub fn to_opt_poly_trait_pred(self) -> Option> { . let predicate = self.kind(); 13,732 (0.0%) match predicate.skip_binder() { 27,080 (0.0%) PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)), . PredicateKind::Clause(ClauseKind::Projection(..)) . | PredicateKind::Clause(ClauseKind::ConstArgHasType(..)) . | PredicateKind::AliasRelate(..) . | PredicateKind::Subtype(..) . | PredicateKind::Coerce(..) . | PredicateKind::Clause(ClauseKind::RegionOutlives(..)) . | PredicateKind::Clause(ClauseKind::WellFormed(..)) . | PredicateKind::ObjectSafe(..) . | PredicateKind::ClosureKind(..) . | PredicateKind::Clause(ClauseKind::TypeOutlives(..)) . | PredicateKind::Clause(ClauseKind::ConstEvaluatable(..)) . | PredicateKind::ConstEquate(..) 1,450 (0.0%) | PredicateKind::Ambiguous => None, . } 6,866 (0.0%) } . 1 (0.0%) pub fn to_opt_poly_projection_pred(self) -> Option> { . let predicate = self.kind(); 2 (0.0%) match predicate.skip_binder() { . PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)), . PredicateKind::Clause(ClauseKind::Trait(..)) . | PredicateKind::Clause(ClauseKind::ConstArgHasType(..)) . | PredicateKind::AliasRelate(..) . | PredicateKind::Subtype(..) . | PredicateKind::Coerce(..) . | PredicateKind::Clause(ClauseKind::RegionOutlives(..)) . | PredicateKind::Clause(ClauseKind::WellFormed(..)) . | PredicateKind::ObjectSafe(..) . | PredicateKind::ClosureKind(..) . | PredicateKind::Clause(ClauseKind::TypeOutlives(..)) . | PredicateKind::Clause(ClauseKind::ConstEvaluatable(..)) . | PredicateKind::ConstEquate(..) 1 (0.0%) | PredicateKind::Ambiguous => None, . } 1 (0.0%) } . . pub fn to_opt_type_outlives(self) -> Option> { . let predicate = self.kind(); . match predicate.skip_binder() { . PredicateKind::Clause(ClauseKind::TypeOutlives(data)) => Some(predicate.rebind(data)), . PredicateKind::Clause(ClauseKind::Trait(..)) . | PredicateKind::Clause(ClauseKind::ConstArgHasType(..)) . | PredicateKind::Clause(ClauseKind::Projection(..)) -- line 1452 ---------------------------------------- -- line 1467 ---------------------------------------- . pub fn as_clause(self) -> Option> { . match self.kind().skip_binder() { . PredicateKind::Clause(..) => Some(self.expect_clause()), . _ => None, . } . } . . /// Assert that the predicate is a clause. 9,796,282 (0.0%) pub fn expect_clause(self) -> Clause<'tcx> { 14,767,725 (0.0%) match self.kind().skip_binder() { . PredicateKind::Clause(..) => Clause(self.0), . _ => bug!("{self} is not a clause"), . } 14,694,423 (0.0%) } . } . . /// Represents the bounds declared on a particular set of type . /// parameters. Should eventually be generalized into a flag list of . /// where-clauses. You can obtain an `InstantiatedPredicates` list from a . /// `GenericPredicates` by using the `instantiate` method. Note that this method . /// reflects an important semantic invariant of `InstantiatedPredicates`: while . /// the `GenericPredicates` are expressed in terms of the bound type -- line 1488 ---------------------------------------- -- line 1494 ---------------------------------------- . /// Example: . /// ```ignore (illustrative) . /// struct Foo> { ... } . /// ``` . /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like . /// `[[], [U:Bar]]`. Now if there were some particular reference . /// like `Foo`, then the `InstantiatedPredicates` would be `[[], . /// [usize:Bar]]`. 8,138 (0.0%) #[derive(Clone, Debug, TypeFoldable, TypeVisitable)] . pub struct InstantiatedPredicates<'tcx> { . pub predicates: Vec>, . pub spans: Vec, . } . . impl<'tcx> InstantiatedPredicates<'tcx> { . pub fn empty() -> InstantiatedPredicates<'tcx> { 96,378 (0.0%) InstantiatedPredicates { predicates: vec![], spans: vec![] } 85 (0.0%) } . . pub fn is_empty(&self) -> bool { . self.predicates.is_empty() . } . 201 (0.0%) pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter { . (&self).into_iter() . } . } . . impl<'tcx> IntoIterator for InstantiatedPredicates<'tcx> { . type Item = (Clause<'tcx>, Span); . . type IntoIter = std::iter::Zip>, std::vec::IntoIter>; . 12,729 (0.0%) fn into_iter(self) -> Self::IntoIter { . debug_assert_eq!(self.predicates.len(), self.spans.len()); 76,374 (0.0%) std::iter::zip(self.predicates, self.spans) 12,729 (0.0%) } . } . . impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> { . type Item = (Clause<'tcx>, Span); . . type IntoIter = std::iter::Zip< . std::iter::Copied>>, . std::iter::Copied>, . >; . . fn into_iter(self) -> Self::IntoIter { . debug_assert_eq!(self.predicates.len(), self.spans.len()); . std::iter::zip(self.predicates.iter().copied(), self.spans.iter().copied()) 201 (0.0%) } . } . . #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable, Lift)] . #[derive(TypeFoldable, TypeVisitable)] . pub struct OpaqueTypeKey<'tcx> { . pub def_id: LocalDefId, . pub args: GenericArgsRef<'tcx>, . } -- line 1552 ---------------------------------------- -- line 1665 ---------------------------------------- . pub ty: Ty<'tcx>, . } . . pub type PlaceholderConst<'tcx> = Placeholder; . . /// When type checking, we use the `ParamEnv` to track . /// details about the set of where-clauses that are in scope at this . /// particular point. 306,048,583 (0.1%) #[derive(Copy, Clone, Hash, PartialEq, Eq)] . pub struct ParamEnv<'tcx> { . /// This packs both caller bounds and the reveal enum into one pointer. . /// . /// Caller bounds are `Obligation`s that the caller must satisfy. This is . /// basically the set of bounds on the in-scope type parameters, translated . /// into `Obligation`s, and elaborated and normalized. . /// . /// Use the `caller_bounds()` method to access. -- line 1681 ---------------------------------------- -- line 1687 ---------------------------------------- . packed: CopyTaggedPtr<&'tcx List>, ParamTag, true>, . } . . #[derive(Copy, Clone)] . struct ParamTag { . reveal: traits::Reveal, . } . 19,686,232 (0.0%) impl_tag! { . impl Tag for ParamTag; . ParamTag { reveal: traits::Reveal::UserFacing }, . ParamTag { reveal: traits::Reveal::All }, . } . . impl<'tcx> fmt::Debug for ParamEnv<'tcx> { . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { . f.debug_struct("ParamEnv") -- line 1703 ---------------------------------------- -- line 1723 ---------------------------------------- . self.caller_bounds().try_fold_with(folder)?, . self.reveal().try_fold_with(folder)?, . )) . } . } . . impl<'tcx> TypeVisitable> for ParamEnv<'tcx> { . fn visit_with>>(&self, visitor: &mut V) -> ControlFlow { 22,092,257 (0.0%) self.caller_bounds().visit_with(visitor)?; . self.reveal().visit_with(visitor) . } . } . . impl<'tcx> ParamEnv<'tcx> { . /// Construct a trait environment suitable for contexts where . /// there are no where-clauses in scope. Hidden types (like `impl . /// Trait`) are left hidden, so this is suitable for ordinary -- line 1739 ---------------------------------------- -- line 1780 ---------------------------------------- . /// which "reveals" the true results of projections in all cases . /// (even for associated types that are specializable). This is . /// the desired behavior during codegen and certain other special . /// contexts; normally though we want to use `Reveal::UserFacing`, . /// which is the default. . /// All opaque types in the caller_bounds of the `ParamEnv` . /// will be normalized to their underlying types. . /// See PR #65989 and issue #65918 for more details 265 (0.0%) pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> Self { 53 (0.0%) if self.packed.tag().reveal == traits::Reveal::All { . return self; . } . . ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), Reveal::All) 265 (0.0%) } . . /// Returns this same environment but with no caller bounds. . #[inline] . pub fn without_caller_bounds(self) -> Self { . Self::new(List::empty(), self.reveal()) . } . . /// Creates a suitable environment in which to perform trait -- line 1802 ---------------------------------------- -- line 1807 ---------------------------------------- . /// invisible. . /// . /// N.B., we preserve the environment when type-checking because it . /// is possible for the user to have wacky where-clauses like . /// `where Box: Copy`, which are clearly never . /// satisfiable. We generally want to behave as if they were true, . /// although the surrounding function is never reachable. . pub fn and>>(self, value: T) -> ParamEnvAnd<'tcx, T> { 6,282,223 (0.0%) match self.reveal() { . Reveal::UserFacing => ParamEnvAnd { param_env: self, value }, . . Reveal::All => { . if value.is_global() { . ParamEnvAnd { param_env: self.without_caller_bounds(), value } . } else { . ParamEnvAnd { param_env: self, value } . } -- line 1823 ---------------------------------------- -- line 1839 ---------------------------------------- . } . . #[inline] . pub fn without_const(self) -> PolyTraitPredicate<'tcx> { . self.with_constness(BoundConstness::NotConst) . } . } . 4,631 (0.0%) #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)] . #[derive(HashStable, Lift)] . pub struct ParamEnvAnd<'tcx, T> { . pub param_env: ParamEnv<'tcx>, 239,258 (0.0%) pub value: T, . } . . impl<'tcx, T> ParamEnvAnd<'tcx, T> { . pub fn into_parts(self) -> (ParamEnv<'tcx>, T) { . (self.param_env, self.value) . } . } . -- line 1859 ---------------------------------------- -- line 1860 ---------------------------------------- . #[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)] . pub struct Destructor { . /// The `DefId` of the destructor method . pub did: DefId, . /// The constness of the destructor method . pub constness: hir::Constness, . } . 378 (0.0%) bitflags! { . #[derive(HashStable, TyEncodable, TyDecodable)] . pub struct VariantFlags: u8 { . const NO_VARIANT_FLAGS = 0; . /// Indicates whether the field list of this variant is `#[non_exhaustive]`. . const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0; . /// Indicates whether this variant was obtained as part of recovering from . /// a syntactic error. May be incomplete or bogus. . const IS_RECOVERED = 1 << 1; . } . } . . /// Definition of a variant -- a struct's fields or an enum variant. 246,420 (0.0%) #[derive(Debug, HashStable, TyEncodable, TyDecodable)] . pub struct VariantDef { . /// `DefId` that identifies the variant itself. . /// If this variant belongs to a struct or union, then this is a copy of its `DefId`. . pub def_id: DefId, . /// `DefId` that identifies the variant's constructor. . /// If this variant is a struct variant, then this is `None`. . pub ctor: Option<(CtorKind, DefId)>, . /// Variant or struct name. -- line 1889 ---------------------------------------- -- line 1908 ---------------------------------------- . /// `parent_did` is the `DefId` of the `AdtDef` representing the enum or struct that . /// owns this variant. It is used for checking if a struct has `#[non_exhaustive]` w/out having . /// to go through the redirect of checking the ctor's attributes - but compiling a small crate . /// requires loading the `AdtDef`s for all the structs in the universe (e.g., coherence for any . /// built-in trait), and we do not want to load attributes twice. . /// . /// If someone speeds up attribute loading to not be a performance concern, they can . /// remove this hack and use the constructor `DefId` everywhere. 396 (0.0%) pub fn new( . name: Symbol, . variant_did: Option, . ctor: Option<(CtorKind, DefId)>, . discr: VariantDiscr, . fields: IndexVec, . adt_kind: AdtKind, . parent_did: DefId, . recovered: bool, -- line 1924 ---------------------------------------- -- line 1930 ---------------------------------------- . name, variant_did, ctor, discr, fields, adt_kind, parent_did, . ); . . let mut flags = VariantFlags::NO_VARIANT_FLAGS; . if is_field_list_non_exhaustive { . flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; . } . 660 (0.0%) if recovered { . flags |= VariantFlags::IS_RECOVERED; . } . 1,716 (0.0%) VariantDef { def_id: variant_did.unwrap_or(parent_did), ctor, name, discr, fields, flags } 132 (0.0%) } . . /// Is this field list non-exhaustive? . #[inline] . pub fn is_field_list_non_exhaustive(&self) -> bool { 142 (0.0%) self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE) . } . . /// Was this variant obtained as part of recovering from a syntactic error? . #[inline] . pub fn is_recovered(&self) -> bool { . self.flags.intersects(VariantFlags::IS_RECOVERED) . } . . /// Computes the `Ident` of this variant by looking up the `Span` 252 (0.0%) pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident { 108 (0.0%) Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap()) 324 (0.0%) } . . #[inline] . pub fn ctor_kind(&self) -> Option { 44 (0.0%) self.ctor.map(|(kind, _)| kind) . } . . #[inline] . pub fn ctor_def_id(&self) -> Option { 1,524 (0.0%) self.ctor.map(|(_, def_id)| def_id) . } . . /// Returns the one field in this variant. . /// . /// `panic!`s if there are no fields or multiple fields. . #[inline] . pub fn single_field(&self) -> &FieldDef { . assert!(self.fields.len() == 1); -- line 1977 ---------------------------------------- -- line 2037 ---------------------------------------- . // of `VariantDef` changes, a compile-error will be produced, reminding . // us to revisit this assumption. . . let Self { def_id, ctor: _, name: _, discr: _, fields: _, flags: _ } = &self; . def_id.hash(s) . } . } . 50,749 (0.0%) #[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)] . pub enum VariantDiscr { . /// Explicit value for this variant, i.e., `X = 123`. . /// The `DefId` corresponds to the embedded constant. . Explicit(DefId), . . /// The previous variant's discriminant plus one. . /// For efficiency reasons, the distance from the . /// last `Explicit` discriminant is being stored, . /// or `0` for the first variant, if it has none. . Relative(u32), . } . 95,004 (0.0%) #[derive(Debug, HashStable, TyEncodable, TyDecodable)] . pub struct FieldDef { . pub did: DefId, . pub name: Symbol, . pub vis: Visibility, . } . . impl PartialEq for FieldDef { . #[inline] -- line 2066 ---------------------------------------- -- line 2104 ---------------------------------------- . . did.hash(s) . } . } . . impl<'tcx> FieldDef { . /// Returns the type of this field. The resulting type is not normalized. The `arg` is . /// typically obtained via the second field of [`TyKind::Adt`]. 4,985 (0.0%) pub fn ty(&self, tcx: TyCtxt<'tcx>, arg: GenericArgsRef<'tcx>) -> Ty<'tcx> { 2,102 (0.0%) tcx.type_of(self.did).instantiate(tcx, arg) 3,988 (0.0%) } . . /// Computes the `Ident` of this variant by looking up the `Span` 6,251 (0.0%) pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident { 2,679 (0.0%) Ident::new(self.name, tcx.def_ident_span(self.did).unwrap()) 8,037 (0.0%) } . } . . #[derive(Debug, PartialEq, Eq)] . pub enum ImplOverlapKind { . /// These impls are always allowed to overlap. . Permitted { . /// Whether or not the impl is permitted due to the trait being a `#[marker]` trait . marker: bool, -- line 2127 ---------------------------------------- -- line 2165 ---------------------------------------- . /// RPITIT originated from. . #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Encodable, Decodable, HashStable)] . pub enum ImplTraitInTraitData { . Trait { fn_def_id: DefId, opaque_def_id: DefId }, . Impl { fn_def_id: DefId }, . } . . impl<'tcx> TyCtxt<'tcx> { 2,945 (0.0%) pub fn typeck_body(self, body: hir::BodyId) -> &'tcx TypeckResults<'tcx> { 589 (0.0%) self.typeck(self.hir().body_owner_def_id(body)) 3,534 (0.0%) } . . pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator { . self.associated_items(id) . .in_definition_order() . .filter(move |item| item.kind == AssocKind::Fn && item.defaultness(self).has_value()) . } . 1,120 (0.0%) pub fn repr_options_of_def(self, did: DefId) -> ReprOptions { . let mut flags = ReprFlags::empty(); . let mut size = None; . let mut max_align: Option = None; . let mut min_pack: Option = None; . . // Generate a deterministically-derived seed from the item's path hash . // to allow for cross-crate compilation to actually work 320 (0.0%) let mut field_shuffle_seed = self.def_path_hash(did).0.to_smaller_hash(); . . // If the user defined a custom seed for layout randomization, xor the item's . // path hash with the user defined seed, this will allowing determinism while . // still allowing users to further randomize layout generation for e.g. fuzzing 240 (0.0%) if let Some(user_seed) = self.sess.opts.unstable_opts.layout_seed { . field_shuffle_seed ^= user_seed; . } . . for attr in self.get_attrs(did, sym::repr) { . for r in attr::parse_repr_attr(&self.sess, attr) { . flags.insert(match r { . attr::ReprC => ReprFlags::IS_C, . attr::ReprPacked(pack) => { -- line 2204 ---------------------------------------- -- line 2238 ---------------------------------------- . ReprFlags::empty() . } . }); . } . } . . // If `-Z randomize-layout` was enabled for the type definition then we can . // consider performing layout randomization 800 (0.0%) if self.sess.opts.unstable_opts.randomize_layout { . flags.insert(ReprFlags::RANDOMIZE_LAYOUT); . } . . // This is here instead of layout because the choice must make it into metadata. 480 (0.0%) if !self.consider_optimizing(|| format!("Reorder fields of {:?}", self.def_path_str(did))) { . flags.insert(ReprFlags::IS_LINEAR); . } . 1,280 (0.0%) ReprOptions { int: size, align: max_align, pack: min_pack, flags, field_shuffle_seed } 720 (0.0%) } . . /// Look up the name of a definition across crates. This does not look at HIR. 141,400 (0.0%) pub fn opt_item_name(self, def_id: DefId) -> Option { 53,025 (0.0%) if let Some(cnum) = def_id.as_crate_root() { . Some(self.crate_name(cnum)) . } else { 70,672 (0.0%) let def_key = self.def_key(def_id); 88,340 (0.0%) match def_key.disambiguated_data.data { . // The name of a constructor is that of its parent. . rustc_hir::definitions::DefPathData::Ctor => self . .opt_item_name(DefId { krate: def_id.krate, index: def_key.parent.unwrap() }), . // The name of opaque types only exists in HIR. . rustc_hir::definitions::DefPathData::ImplTrait . if let Some(def_id) = def_id.as_local() => . self.hir().opt_name(self.hir().local_def_id_to_hir_id(def_id)), . _ => def_key.get_opt_name(), . } . } 123,725 (0.0%) } . . /// Look up the name of a definition across crates. This does not look at HIR. . /// . /// This method will ICE if the corresponding item does not have a name. In these cases, use . /// [`opt_item_name`] instead. . /// . /// [`opt_item_name`]: Self::opt_item_name 2,824 (0.0%) pub fn item_name(self, id: DefId) -> Symbol { 56,001 (0.0%) self.opt_item_name(id).unwrap_or_else(|| { . bug!("item_name: no name for {:?}", self.def_path(id)); . }) 2,118 (0.0%) } . . /// Look up the name and span of a definition. . /// . /// See [`item_name`][Self::item_name] for more information. . pub fn opt_item_ident(self, def_id: DefId) -> Option { . let def = self.opt_item_name(def_id)?; . let span = self . .def_ident_span(def_id) . .unwrap_or_else(|| bug!("missing ident span for {def_id:?}")); . Some(Ident::new(def, span)) . } . 508,080 (0.0%) pub fn opt_associated_item(self, def_id: DefId) -> Option { 609,696 (0.0%) if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) { . Some(self.associated_item(def_id)) . } else { 49,839 (0.0%) None . } 406,464 (0.0%) } . . /// If the def-id is an associated type that was desugared from a . /// return-position `impl Trait` from a trait, then provide the source info . /// about where that RPITIT came from. 74,750 (0.0%) pub fn opt_rpitit_info(self, def_id: DefId) -> Option { 52,325 (0.0%) if let DefKind::AssocTy = self.def_kind(def_id) { 4,670 (0.0%) self.associated_item(def_id).opt_rpitit_info . } else { 10,280 (0.0%) None . } 59,800 (0.0%) } . . pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option { . variant.fields.iter_enumerated().find_map(|(i, field)| { . self.hygienic_eq(ident, field.ident(self), variant.def_id).then_some(i) . }) . } . . /// Returns `true` if the impls are the same polarity and the trait either . /// has no items or is annotated `#[marker]` and prevents item overrides. 167,520 (0.0%) #[instrument(level = "debug", skip(self), ret)] . pub fn impls_are_allowed_to_overlap( . self, . def_id1: DefId, . def_id2: DefId, . ) -> Option { . let impl_trait_ref1 = self.impl_trait_ref(def_id1); . let impl_trait_ref2 = self.impl_trait_ref(def_id2); . // If either trait impl references an error, they're allowed to overlap, . // as one of them essentially doesn't exist. . if impl_trait_ref1.is_some_and(|tr| tr.instantiate_identity().references_error()) . || impl_trait_ref2.is_some_and(|tr| tr.instantiate_identity().references_error()) . { . return Some(ImplOverlapKind::Permitted { marker: false }); . } . 75,384 (0.0%) match (self.impl_polarity(def_id1), self.impl_polarity(def_id2)) { . (ImplPolarity::Reservation, _) | (_, ImplPolarity::Reservation) => { . // `#[rustc_reservation_impl]` impls don't overlap with anything . return Some(ImplOverlapKind::Permitted { marker: false }); . } . (ImplPolarity::Positive, ImplPolarity::Negative) . | (ImplPolarity::Negative, ImplPolarity::Positive) => { . // `impl AutoTrait for Type` + `impl !AutoTrait for Type` . return None; -- line 2351 ---------------------------------------- -- line 2353 ---------------------------------------- . (ImplPolarity::Positive, ImplPolarity::Positive) . | (ImplPolarity::Negative, ImplPolarity::Negative) => {} . }; . . let is_marker_overlap = { . let is_marker_impl = |trait_ref: Option>>| -> bool { . trait_ref.is_some_and(|tr| self.trait_def(tr.skip_binder().def_id).is_marker) . }; 25,128 (0.0%) is_marker_impl(impl_trait_ref1) && is_marker_impl(impl_trait_ref2) . }; . . if is_marker_overlap { . Some(ImplOverlapKind::Permitted { marker: true }) . } else { 16,752 (0.0%) 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 { . return Some(ImplOverlapKind::Issue33140); . } else { . debug!("found {self_ty1:?} != {self_ty2:?}"); . } . } . } . . None . } . } . . /// Returns `ty::VariantDef` if `res` refers to a struct, . /// or variant or their constructors, panics otherwise. 80 (0.0%) pub fn expect_variant_res(self, res: Res) -> &'tcx VariantDef { 360 (0.0%) match res { . Res::Def(DefKind::Variant, did) => { . let enum_did = self.parent(did); . self.adt_def(enum_did).variant_with_id(did) . } . Res::Def(DefKind::Struct | DefKind::Union, did) => self.adt_def(did).non_enum_variant(), . Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_did) => { . let variant_did = self.parent(variant_ctor_did); . let enum_did = self.parent(variant_did); -- line 2392 ---------------------------------------- -- line 2393 ---------------------------------------- . self.adt_def(enum_did).variant_with_ctor_id(variant_ctor_did) . } . Res::Def(DefKind::Ctor(CtorOf::Struct, ..), ctor_did) => { . let struct_did = self.parent(ctor_did); . self.adt_def(struct_did).non_enum_variant() . } . _ => bug!("expect_variant_res used with unexpected res {:?}", res), . } 100 (0.0%) } . . /// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair. . #[instrument(skip(self), level = "debug")] . pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> { . match instance { . ty::InstanceDef::Item(def) => { . debug!("calling def_kind on def: {:?}", def); . let def_kind = self.def_kind(def); -- line 2409 ---------------------------------------- -- line 2438 ---------------------------------------- . if let Some(did) = did.as_local() { . self.hir().attrs(self.hir().local_def_id_to_hir_id(did)) . } else { . self.item_attrs(did) . } . } . . /// Gets all attributes with the given name. 55,812 (0.0%) pub fn get_attrs( . self, . did: impl Into, . attr: Symbol, . ) -> impl Iterator { . let did: DefId = did.into(); . let filter_fn = move |a: &&ast::Attribute| a.has_name(attr); 47,237 (0.0%) if let Some(did) = did.as_local() { 52,400 (0.0%) self.hir().attrs(self.hir().local_def_id_to_hir_id(did)).iter().filter(filter_fn) . } else if cfg!(debug_assertions) && rustc_feature::is_builtin_only_local(attr) { . bug!("tried to access the `only_local` attribute `{}` from an extern crate", attr); . } else { . self.item_attrs(did).iter().filter(filter_fn) . } 37,384 (0.0%) } . 1,304 (0.0%) pub fn get_attr(self, did: impl Into, attr: Symbol) -> Option<&'tcx ast::Attribute> { . if cfg!(debug_assertions) && !rustc_feature::is_valid_for_get_attr(attr) { . let did: DefId = did.into(); . bug!("get_attr: unexpected called with DefId `{:?}`, attr `{:?}`", did, attr); . } else { 62 (0.0%) self.get_attrs(did, attr).next() . } 990 (0.0%) } . . /// Determines whether an item is annotated with an attribute. 22,750 (0.0%) pub fn has_attr(self, did: impl Into, attr: Symbol) -> bool { . let did: DefId = did.into(); . if cfg!(debug_assertions) && !did.is_local() && rustc_feature::is_builtin_only_local(attr) { . bug!("tried to access the `only_local` attribute `{}` from an extern crate", attr); . } else { 28,730 (0.0%) self.get_attrs(did, attr).next().is_some() . } 18,200 (0.0%) } . . /// Returns `true` if this is an `auto trait`. 432,432 (0.0%) pub fn trait_is_auto(self, trait_def_id: DefId) -> bool { 144,147 (0.0%) self.trait_def(trait_def_id).has_auto_impl 288,288 (0.0%) } . . /// Returns `true` if this is coinductive, either because it is . /// an auto trait or because it has the `#[rustc_coinductive]` attribute. . pub fn trait_is_coinductive(self, trait_def_id: DefId) -> bool { . self.trait_def(trait_def_id).is_coinductive . } . . /// Returns `true` if this is a trait alias. -- line 2492 ---------------------------------------- -- line 2497 ---------------------------------------- . /// Returns layout of a generator. Layout might be unavailable if the . /// generator is tainted by errors. . pub fn generator_layout(self, def_id: DefId) -> Option<&'tcx GeneratorLayout<'tcx>> { . self.optimized_mir(def_id).generator_layout() . } . . /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. . /// If it implements no trait, returns `None`. 2,151,084 (0.0%) pub fn trait_id_of_impl(self, def_id: DefId) -> Option { . self.impl_trait_ref(def_id).map(|tr| tr.skip_binder().def_id) 1,434,056 (0.0%) } . . /// If the given `DefId` describes an item belonging to a trait, . /// returns the `DefId` of the trait that the trait item belongs to; . /// otherwise, returns `None`. 7,200 (0.0%) pub fn trait_of_item(self, def_id: DefId) -> Option { 9,000 (0.0%) if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) { . let parent = self.parent(def_id); 13,425 (0.0%) if let DefKind::Trait | DefKind::TraitAlias = self.def_kind(parent) { . return Some(parent); . } . } . None 7,200 (0.0%) } . . /// If the given `DefId` describes a method belonging to an impl, returns the . /// `DefId` of the impl that the method belongs to; otherwise, returns `None`. 4,515 (0.0%) pub fn impl_of_method(self, def_id: DefId) -> Option { 6,450 (0.0%) if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) { . let parent = self.parent(def_id); 4,515 (0.0%) if let DefKind::Impl { .. } = self.def_kind(parent) { . return Some(parent); . } . } . None 3,870 (0.0%) } . . /// Check if the given `DefId` is `#\[automatically_derived\]`, *and* . /// whether it was produced by expanding a builtin derive macro. . pub fn is_builtin_derived(self, def_id: DefId) -> bool { . if self.is_automatically_derived(def_id) . && let Some(def_id) = def_id.as_local() . && let outer = self.def_span(def_id).ctxt().outer_expn_data() . && matches!(outer.kind, ExpnKind::Macro(MacroKind::Derive, _)) -- line 2540 ---------------------------------------- -- line 2542 ---------------------------------------- . { . true . } else { . false . } . } . . /// Check if the given `DefId` is `#\[automatically_derived\]`. 2,580 (0.0%) pub fn is_automatically_derived(self, def_id: DefId) -> bool { . self.has_attr(def_id, sym::automatically_derived) 1,935 (0.0%) } . . /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err` . /// with the name of the crate containing the impl. 1,967 (0.0%) pub fn span_of_impl(self, impl_def_id: DefId) -> Result { 1,124 (0.0%) if let Some(impl_def_id) = impl_def_id.as_local() { 562 (0.0%) Ok(self.def_span(impl_def_id)) . } else { . Err(self.crate_name(impl_def_id.krate)) . } 1,967 (0.0%) } . . /// Hygienically compares a use-site name (`use_name`) for a field or an associated item with . /// its supposed definition name (`def_name`). The method also needs `DefId` of the supposed . /// definition's parent/scope to perform comparison. 4,356 (0.0%) pub fn hygienic_eq(self, use_name: Ident, def_name: Ident, def_parent_def_id: DefId) -> bool { . // We could use `Ident::eq` here, but we deliberately don't. The name . // comparison fails frequently, and we want to avoid the expensive . // `normalize_to_macros_2_0()` calls required for the span comparison whenever possible. 726 (0.0%) use_name.name == def_name.name 10,470 (0.0%) && use_name . .span . .ctxt() 3,490 (0.0%) .hygienic_eq(def_name.span.ctxt(), self.expn_that_defined(def_parent_def_id)) 224 (0.0%) } . 768 (0.0%) pub fn adjust_ident(self, mut ident: Ident, scope: DefId) -> Ident { 384 (0.0%) ident.span.normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope)); 384 (0.0%) ident 480 (0.0%) } . . // FIXME(vincenzopalazzo): move the HirId to a LocalDefId 11,518 (0.0%) pub fn adjust_ident_and_get_scope( . self, . mut ident: Ident, . scope: DefId, . block: hir::HirId, . ) -> (Ident, DefId) { 3,544 (0.0%) let scope = ident . .span . .normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope)) 260 (0.0%) .and_then(|actual_expansion| actual_expansion.expn_data().parent_module) 4,105 (0.0%) .unwrap_or_else(|| self.parent_module(block).to_def_id()); 5,316 (0.0%) (ident, scope) 7,974 (0.0%) } . . /// Returns `true` if the debuginfo for `span` should be collapsed to the outermost expansion . /// site. Only applies when `Span` is the result of macro expansion. . /// . /// - If the `collapse_debuginfo` feature is enabled then debuginfo is not collapsed by default . /// and only when a macro definition is annotated with `#[collapse_debuginfo]`. . /// - If `collapse_debuginfo` is not enabled, then debuginfo is collapsed by default. . /// -- line 2604 ---------------------------------------- -- line 2608 ---------------------------------------- . && if self.features().collapse_debuginfo { . span.in_macro_expansion_with_collapse_debuginfo() . } else { . span.from_expansion() . } . } . . #[inline] 5,616 (0.0%) pub fn is_const_fn_raw(self, def_id: DefId) -> bool { 1,268 (0.0%) matches!( 5,084 (0.0%) self.def_kind(def_id), . DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Closure . ) && self.constness(def_id) == hir::Constness::Const 4,368 (0.0%) } . . #[inline] . pub fn is_const_default_method(self, def_id: DefId) -> bool { 3,720 (0.0%) matches!(self.trait_of_item(def_id), Some(trait_id) if self.has_attr(trait_id, sym::const_trait)) . } . . /// Returns the `DefId` of the item within which the `impl Trait` is declared. . /// For type-alias-impl-trait this is the `type` alias. . /// For impl-trait-in-assoc-type this is the assoc type. . /// For return-position-impl-trait this is the function. . pub fn impl_trait_parent(self, mut def_id: LocalDefId) -> LocalDefId { . // Find the surrounding item (type alias or assoc type) -- line 2633 ---------------------------------------- -- line 2730 ---------------------------------------- . closure::provide(providers); . context::provide(providers); . erase_regions::provide(providers); . inhabitedness::provide(providers); . util::provide(providers); . print::provide(providers); . super::util::bug::provide(providers); . super::middle::provide(providers); 8 (0.0%) *providers = Providers { . trait_impls_of: trait_def::trait_impls_of_provider, . incoherent_impls: trait_def::incoherent_impls_provider, . const_param_default: consts::const_param_default, . vtable_allocation: vtable::vtable_allocation_provider, . ..*providers . }; 1 (0.0%) } . . /// A map for the local crate mapping each type to a vector of its . /// inherent impls. This is not meant to be used outside of coherence; . /// rather, you should request the vector for a specific type via . /// `tcx.inherent_impls(def_id)` so as to minimize your dependencies . /// (constructing this map requires touching the entire crate). . #[derive(Clone, Debug, Default, HashStable)] . pub struct CrateInherentImpls { -- line 2753 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_middle/src/ty/relate.rs -------------------------------------------------------------------------------- Ir________________ 115,733,822 (0.0%) -- line 26 ---------------------------------------- . . /// Returns a static string we can use for printouts. . fn tag(&self) -> &'static str; . . /// Returns `true` if the value `a` is the "expected" type in the . /// relation. Just affects error messages. . fn a_is_expected(&self) -> bool; . 1,064 (0.0%) fn with_cause(&mut self, _cause: Cause, f: F) -> R . where . F: FnOnce(&mut Self) -> R, . { 304 (0.0%) f(self) 1,064 (0.0%) } . . /// Generic relation routine suitable for most anything. 1,517 (0.0%) fn relate>(&mut self, a: T, b: T) -> RelateResult<'tcx, T> { 42,460,674 (0.0%) Relate::relate(self, a, b) 1,796 (0.0%) } . . /// Relate the two args for the given item. The default . /// is to look up the variance for the item and proceed . /// accordingly. 6,413 (0.0%) fn relate_item_args( . &mut self, . item_def_id: DefId, . a_arg: GenericArgsRef<'tcx>, . b_arg: GenericArgsRef<'tcx>, . ) -> RelateResult<'tcx, GenericArgsRef<'tcx>> { . debug!( . "relate_item_args(item_def_id={:?}, a_arg={:?}, b_arg={:?})", . item_def_id, a_arg, b_arg . ); . . let tcx = self.tcx(); . let opt_variances = tcx.variances_of(item_def_id); 5,313 (0.0%) relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, true) 7,758 (0.0%) } . . /// Switch variance for the purpose of relating `a` and `b`. . fn relate_with_variance>( . &mut self, . variance: ty::Variance, . info: ty::VarianceDiagInfo<'tcx>, . a: T, . b: T, -- line 71 ---------------------------------------- -- line 106 ---------------------------------------- . a: Self, . b: Self, . ) -> RelateResult<'tcx, Self>; . } . . /////////////////////////////////////////////////////////////////////////// . // Relate impls . 28,908 (0.0%) pub fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>( . relation: &mut R, . a: ty::TypeAndMut<'tcx>, . b: ty::TypeAndMut<'tcx>, . base_ty: Ty<'tcx>, . ) -> RelateResult<'tcx, ty::TypeAndMut<'tcx>> { . debug!("{}.mts({:?}, {:?})", relation.tag(), a, b); 5,189 (0.0%) if a.mutbl != b.mutbl { 9 (0.0%) Err(TypeError::Mutability) . } else { . let mutbl = a.mutbl; . let (variance, info) = match mutbl { . hir::Mutability::Not => (ty::Covariant, ty::VarianceDiagInfo::None), . hir::Mutability::Mut => { . (ty::Invariant, ty::VarianceDiagInfo::Invariant { ty: base_ty, param_index: 0 }) . } . }; . let ty = relation.relate_with_variance(variance, info, a.ty, b.ty)?; 15,355 (0.0%) Ok(ty::TypeAndMut { ty, mutbl }) . } 28,908 (0.0%) } . . #[inline] . pub fn relate_args<'tcx, R: TypeRelation<'tcx>>( . relation: &mut R, . a_arg: GenericArgsRef<'tcx>, . b_arg: GenericArgsRef<'tcx>, . ) -> RelateResult<'tcx, GenericArgsRef<'tcx>> { 7,987,309 (0.0%) relation.tcx().mk_args_from_iter(iter::zip(a_arg, b_arg).map(|(a, b)| { . relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b) . })) . } . 5,796 (0.0%) pub fn relate_args_with_variances<'tcx, R: TypeRelation<'tcx>>( . relation: &mut R, . ty_def_id: DefId, . variances: &[ty::Variance], . a_arg: GenericArgsRef<'tcx>, . b_arg: GenericArgsRef<'tcx>, . fetch_ty_for_diag: bool, . ) -> RelateResult<'tcx, GenericArgsRef<'tcx>> { 2,083 (0.0%) let tcx = relation.tcx(); . 2,458 (0.0%) let mut cached_ty = None; . let params = iter::zip(a_arg, b_arg).enumerate().map(|(i, (a, b))| { 10,084 (0.0%) let variance = variances[i]; 2,677 (0.0%) let variance_info = if variance == ty::Invariant && fetch_ty_for_diag { . let ty = 3,308 (0.0%) *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, a_arg)); . ty::VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() } . } else { . ty::VarianceDiagInfo::default() . }; 1,831 (0.0%) relation.relate_with_variance(variance, variance_info, a, b) . }); . 5,175 (0.0%) tcx.mk_args_from_iter(params) 3,381 (0.0%) } . . impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { 1,788 (0.0%) fn relate>( . relation: &mut R, . a: ty::FnSig<'tcx>, . b: ty::FnSig<'tcx>, . ) -> RelateResult<'tcx, ty::FnSig<'tcx>> { 296 (0.0%) let tcx = relation.tcx(); . 1,312 (0.0%) if a.c_variadic != b.c_variadic { . return Err(TypeError::VariadicMismatch(expected_found( . relation, . a.c_variadic, . b.c_variadic, . ))); . } 984 (0.0%) let unsafety = relation.relate(a.unsafety, b.unsafety)?; . let abi = relation.relate(a.abi, b.abi)?; . 1,148 (0.0%) if a.inputs().len() != b.inputs().len() { . return Err(TypeError::ArgCount); . } . 984 (0.0%) let inputs_and_output = iter::zip(a.inputs(), b.inputs()) . .map(|(&a, &b)| ((a, b), false)) 820 (0.0%) .chain(iter::once(((a.output(), b.output()), true))) 164 (0.0%) .map(|((a, b), is_output)| { 164 (0.0%) if is_output { . relation.relate(a, b) . } else { . relation.relate_with_variance( . ty::Contravariant, . ty::VarianceDiagInfo::default(), . a, . b, . ) . } . }) . .enumerate() 2,360 (0.0%) .map(|(i, r)| match r { . Err(TypeError::Sorts(exp_found) | TypeError::ArgumentSorts(exp_found, _)) => { . Err(TypeError::ArgumentSorts(exp_found, i)) . } . Err(TypeError::Mutability | TypeError::ArgumentMutability(_)) => { . Err(TypeError::ArgumentMutability(i)) . } 1,584 (0.0%) r => r, . }); 1,476 (0.0%) Ok(ty::FnSig { 656 (0.0%) inputs_and_output: tcx.mk_type_list_from_iter(inputs_and_output)?, . c_variadic: a.c_variadic, . unsafety, . abi, . }) 1,476 (0.0%) } . } . . impl<'tcx> Relate<'tcx> for ty::BoundConstness { . fn relate>( . relation: &mut R, . a: ty::BoundConstness, . b: ty::BoundConstness, . ) -> RelateResult<'tcx, ty::BoundConstness> { -- line 234 ---------------------------------------- -- line 241 ---------------------------------------- . } . . impl<'tcx> Relate<'tcx> for hir::Unsafety { . fn relate>( . relation: &mut R, . a: hir::Unsafety, . b: hir::Unsafety, . ) -> RelateResult<'tcx, hir::Unsafety> { 164 (0.0%) if a != b { . Err(TypeError::UnsafetyMismatch(expected_found(relation, a, b))) . } else { . Ok(a) . } . } . } . . impl<'tcx> Relate<'tcx> for abi::Abi { 1,512 (0.0%) fn relate>( . relation: &mut R, . a: abi::Abi, . b: abi::Abi, . ) -> RelateResult<'tcx, abi::Abi> { 640 (0.0%) if a == b { Ok(a) } else { Err(TypeError::AbiMismatch(expected_found(relation, a, b))) } 1,052 (0.0%) } . } . . impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> { 32,225 (0.0%) fn relate>( . relation: &mut R, . a: ty::AliasTy<'tcx>, . b: ty::AliasTy<'tcx>, . ) -> RelateResult<'tcx, ty::AliasTy<'tcx>> { 4,285 (0.0%) if a.def_id != b.def_id { 1,897 (0.0%) Err(TypeError::ProjectionMismatched(expected_found(relation, a.def_id, b.def_id))) . } else { 8,570 (0.0%) let args = relation.relate(a.args, b.args)?; 15,570 (0.0%) Ok(relation.tcx().mk_alias_ty(a.def_id, args)) . } 33,932 (0.0%) } . } . . impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> { . fn relate>( . relation: &mut R, . a: ty::ExistentialProjection<'tcx>, . b: ty::ExistentialProjection<'tcx>, . ) -> RelateResult<'tcx, ty::ExistentialProjection<'tcx>> { -- line 287 ---------------------------------------- -- line 301 ---------------------------------------- . b.args, . )?; . Ok(ty::ExistentialProjection { def_id: a.def_id, args, term }) . } . } . } . . impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> { 5,121,036 (0.0%) fn relate>( . relation: &mut R, . a: ty::TraitRef<'tcx>, . b: ty::TraitRef<'tcx>, . ) -> RelateResult<'tcx, ty::TraitRef<'tcx>> { . // Different traits cannot be related. 547,421 (0.0%) if a.def_id != b.def_id { 151,081 (0.0%) Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id))) . } else { 1,094,842 (0.0%) let args = relate_args(relation, a.args, b.args)?; 3,353,679 (0.0%) Ok(ty::TraitRef::new(relation.tcx(), a.def_id, args)) . } 5,121,036 (0.0%) } . } . . impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> { 1,180 (0.0%) fn relate>( . relation: &mut R, . a: ty::ExistentialTraitRef<'tcx>, . b: ty::ExistentialTraitRef<'tcx>, . ) -> RelateResult<'tcx, ty::ExistentialTraitRef<'tcx>> { . // Different traits cannot be related. 236 (0.0%) if a.def_id != b.def_id { . Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id))) . } else { 472 (0.0%) let args = relate_args(relation, a.args, b.args)?; 1,180 (0.0%) Ok(ty::ExistentialTraitRef { def_id: a.def_id, args }) . } 1,416 (0.0%) } . } . . #[derive(PartialEq, Copy, Debug, Clone, TypeFoldable, TypeVisitable)] . struct GeneratorWitness<'tcx>(&'tcx ty::List>); . . impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> { . fn relate>( . relation: &mut R, -- line 345 ---------------------------------------- -- line 356 ---------------------------------------- . . impl<'tcx> Relate<'tcx> for ImplSubject<'tcx> { . #[inline] . fn relate>( . relation: &mut R, . a: ImplSubject<'tcx>, . b: ImplSubject<'tcx>, . ) -> RelateResult<'tcx, ImplSubject<'tcx>> { 35 (0.0%) match (a, b) { 56 (0.0%) (ImplSubject::Trait(trait_ref_a), ImplSubject::Trait(trait_ref_b)) => { 7 (0.0%) let trait_ref = ty::TraitRef::relate(relation, trait_ref_a, trait_ref_b)?; . Ok(ImplSubject::Trait(trait_ref)) . } . (ImplSubject::Inherent(ty_a), ImplSubject::Inherent(ty_b)) => { . let ty = Ty::relate(relation, ty_a, ty_b)?; . Ok(ImplSubject::Inherent(ty)) . } . (ImplSubject::Trait(_), ImplSubject::Inherent(_)) . | (ImplSubject::Inherent(_), ImplSubject::Trait(_)) => { -- line 374 ---------------------------------------- -- line 380 ---------------------------------------- . . impl<'tcx> Relate<'tcx> for Ty<'tcx> { . #[inline] . fn relate>( . relation: &mut R, . a: Ty<'tcx>, . b: Ty<'tcx>, . ) -> RelateResult<'tcx, Ty<'tcx>> { 21,784,046 (0.0%) relation.tys(a, b) . } . } . . /// Relates `a` and `b` structurally, calling the relation for all nested values. . /// Any semantic equality, e.g. of projections, and inference variables have to be . /// handled by the caller. 187,738,236 (0.1%) #[instrument(level = "trace", skip(relation), ret)] . pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>( . relation: &mut R, . a: Ty<'tcx>, . b: Ty<'tcx>, . ) -> RelateResult<'tcx, Ty<'tcx>> { . let tcx = relation.tcx(); 120,700,908 (0.1%) match (a.kind(), b.kind()) { . (&ty::Infer(_), _) | (_, &ty::Infer(_)) => { . // The caller should handle these cases! . bug!("var types encountered in structurally_relate_tys") . } . . (ty::Bound(..), _) | (_, ty::Bound(..)) => { . bug!("bound types encountered in structurally_relate_tys") . } -- line 410 ---------------------------------------- -- line 413 ---------------------------------------- . . (&ty::Never, _) . | (&ty::Char, _) . | (&ty::Bool, _) . | (&ty::Int(_), _) . | (&ty::Uint(_), _) . | (&ty::Float(_), _) . | (&ty::Str, _) 1,980 (0.0%) if a == b => . { . Ok(a) . } . 977,629 (0.0%) (ty::Param(a_p), ty::Param(b_p)) if a_p.index == b_p.index => Ok(a), . . (ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => Ok(a), . 19,021,477 (0.0%) (&ty::Adt(a_def, a_args), &ty::Adt(b_def, b_args)) if a_def == b_def => { 12,680,272 (0.0%) let args = relation.relate_item_args(a_def.did(), a_args, b_args)?; . Ok(Ty::new_adt(tcx, a_def, args)) . } . . (&ty::Foreign(a_id), &ty::Foreign(b_id)) if a_id == b_id => Ok(Ty::new_foreign(tcx, a_id)), . 3,608 (0.0%) (&ty::Dynamic(a_obj, a_region, a_repr), &ty::Dynamic(b_obj, b_region, b_repr)) 500 (0.0%) if a_repr == b_repr => . { 304 (0.0%) let region_bound = relation.with_cause(Cause::ExistentialRegionBound, |relation| { . relation.relate(a_region, b_region) . })?; 416 (0.0%) Ok(Ty::new_dynamic(tcx, relation.relate(a_obj, b_obj)?, region_bound, a_repr)) . } . . (&ty::Generator(a_id, a_args, movability), &ty::Generator(b_id, b_args, _)) . if a_id == b_id => . { . // All Generator types with the same id represent . // the (anonymous) type of the same generator expression. So . // all of their regions should be equated. -- line 451 ---------------------------------------- -- line 468 ---------------------------------------- . { . // All GeneratorWitness types with the same id represent . // the (anonymous) type of the same generator expression. So . // all of their regions should be equated. . let args = relation.relate(a_args, b_args)?; . Ok(Ty::new_generator_witness_mir(tcx, a_id, args)) . } . 64 (0.0%) (&ty::Closure(a_id, a_args), &ty::Closure(b_id, b_args)) 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. 32 (0.0%) let args = relation.relate(a_args, b_args)?; . Ok(Ty::new_closure(tcx, a_id, &args)) . } . . (&ty::RawPtr(a_mt), &ty::RawPtr(b_mt)) => { . let mt = relate_type_and_mut(relation, a_mt, b_mt, a)?; . Ok(Ty::new_ptr(tcx, mt)) . } . 50,152 (0.0%) (&ty::Ref(a_r, a_ty, a_mutbl), &ty::Ref(b_r, b_ty, b_mutbl)) => { 4,368 (0.0%) let r = relation.relate(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 }; 30,742 (0.0%) let mt = relate_type_and_mut(relation, a_mt, b_mt, a)?; . Ok(Ty::new_ref(tcx, r, mt)) . } . 2,625 (0.0%) (&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) => { . let t = relation.relate(a_t, b_t)?; 1,575 (0.0%) match relation.relate(sz_a, sz_b) { 549 (0.0%) Ok(sz) => Ok(Ty::new_array_with_const_len(tcx, t, sz)), . Err(err) => { . // Check whether the lengths are both concrete/known values, . // but are unequal, for better diagnostics. . // . // It might seem dubious to eagerly evaluate these constants here, . // we however cannot end up with errors in `Relate` during both . // `type_of` and `predicates_of`. This means that evaluating the . // constants should not cause cycle errors here. -- line 508 ---------------------------------------- -- line 513 ---------------------------------------- . TypeError::FixedArraySize(expected_found(relation, sz_a_val, sz_b_val)), . ), . _ => Err(err), . } . } . } . } . 1,317 (0.0%) (&ty::Slice(a_t), &ty::Slice(b_t)) => { . let t = relation.relate(a_t, b_t)?; . Ok(Ty::new_slice(tcx, t)) . } . 89,702 (0.0%) (&ty::Tuple(as_), &ty::Tuple(bs)) => { 89,702 (0.0%) if as_.len() == bs.len() { . Ok(Ty::new_tup_from_iter( 44,842 (0.0%) tcx, . iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)), . )?) . } else if !(as_.is_empty() || bs.is_empty()) { . Err(TypeError::TupleSize(expected_found(relation, as_.len(), bs.len()))) . } else { . Err(TypeError::Sorts(expected_found(relation, a, b))) . } . } . 444 (0.0%) (&ty::FnDef(a_def_id, a_args), &ty::FnDef(b_def_id, b_args)) if a_def_id == b_def_id => { 444 (0.0%) let args = relation.relate_item_args(a_def_id, a_args, b_args)?; 467 (0.0%) Ok(Ty::new_fn_def(tcx, a_def_id, args)) . } . 176 (0.0%) (&ty::FnPtr(a_fty), &ty::FnPtr(b_fty)) => { 32 (0.0%) let fty = relation.relate(a_fty, b_fty)?; . Ok(Ty::new_fn_ptr(tcx, fty)) . } . . // The args of opaque types may not all be invariant, so we have . // to treat them separately from other aliases. . ( . &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, args: a_args, .. }), . &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, args: b_args, .. }), -- line 553 ---------------------------------------- -- line 560 ---------------------------------------- . a_args, . b_args, . false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle . )?; . Ok(Ty::new_opaque(tcx, a_def_id, args)) . } . . // Alias tend to mostly already be handled downstream due to normalization. 35,360 (0.0%) (&ty::Alias(a_kind, a_data), &ty::Alias(b_kind, b_data)) => { . let alias_ty = relation.relate(a_data, b_data)?; 1,707 (0.0%) assert_eq!(a_kind, b_kind); . Ok(Ty::new_alias(tcx, a_kind, alias_ty)) . } . . _ => Err(TypeError::Sorts(expected_found(relation, a, b))), . } . } . . /// Relates `a` and `b` structurally, calling the relation for all nested values. . /// Any semantic equality, e.g. of unevaluated consts, and inference variables have . /// to be handled by the caller. . /// . /// FIXME: This is not totally structual, which probably should be fixed. . /// See the HACKs below. 2,470 (0.0%) pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>( . relation: &mut R, . mut a: ty::Const<'tcx>, . mut b: ty::Const<'tcx>, . ) -> RelateResult<'tcx, ty::Const<'tcx>> { . debug!("{}.structurally_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b); . let tcx = relation.tcx(); . 760 (0.0%) if tcx.features().generic_const_exprs { . a = tcx.expand_abstract_consts(a); . b = tcx.expand_abstract_consts(b); . } . . debug!("{}.structurally_relate_consts(normed_a = {:?}, normed_b = {:?})", relation.tag(), a, b); . . // Currently, the values that can be unified are primitive types, . // and those that derive both `PartialEq` and `Eq`, corresponding . // to structural-match types. 1,710 (0.0%) let is_match = match (a.kind(), b.kind()) { . (ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => { . // The caller should handle these cases! . bug!("var types encountered in structurally_relate_consts: {:?} {:?}", a, b) . } . . (ty::ConstKind::Error(_), _) => return Ok(a), . (_, ty::ConstKind::Error(_)) => return Ok(b), . . (ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) => a_p.index == b_p.index, . (ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2, 1,890 (0.0%) (ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => a_val == b_val, . . // While this is slightly incorrect, it shouldn't matter for `min_const_generics` . // and is the better alternative to waiting until `generic_const_exprs` can . // be stabilized. . (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def => { . assert_eq!(a.ty(), b.ty()); . let args = relation.relate_with_variance( . ty::Variance::Invariant, -- line 621 ---------------------------------------- -- line 667 ---------------------------------------- . Expr::FunctionCall(func, related_args) . } . _ => return Err(TypeError::ConstMismatch(expected_found(r, a, b))), . }; . return Ok(ty::Const::new_expr(tcx, expr, a.ty())); . } . _ => false, . }; 190 (0.0%) if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(expected_found(relation, a, b))) } 1,710 (0.0%) } . . impl<'tcx> Relate<'tcx> for &'tcx ty::List> { 3,960 (0.0%) fn relate>( . relation: &mut R, . a: Self, . b: Self, . ) -> RelateResult<'tcx, Self> { 1,000 (0.0%) let tcx = relation.tcx(); . . // FIXME: this is wasteful, but want to do a perf run to see how slow it is. . // We need to perform this deduplication as we sometimes generate duplicate projections . // in `a`. 500 (0.0%) let mut a_v: Vec<_> = a.into_iter().collect(); 500 (0.0%) let mut b_v: Vec<_> = b.into_iter().collect(); . // `skip_binder` here is okay because `stable_cmp` doesn't look at binders . a_v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); . a_v.dedup(); . b_v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); . b_v.dedup(); 1,500 (0.0%) if a_v.len() != b_v.len() { . return Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))); . } . 2,000 (0.0%) let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| { . use crate::ty::ExistentialPredicate::*; 4,000 (0.0%) match (ep_a.skip_binder(), ep_b.skip_binder()) { 3,752 (0.0%) (Trait(a), Trait(b)) => Ok(ep_a 848 (0.0%) .rebind(Trait(relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder()))), . (Projection(a), Projection(b)) => Ok(ep_a.rebind(Projection( . relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), . ))), . (AutoTrait(a), AutoTrait(b)) if a == b => Ok(ep_a.rebind(AutoTrait(a))), . _ => Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))), . } . }); 2,000 (0.0%) tcx.mk_poly_existential_predicates_from_iter(v) 3,564 (0.0%) } . } . . impl<'tcx> Relate<'tcx> for ty::ClosureArgs<'tcx> { . fn relate>( . relation: &mut R, . a: ty::ClosureArgs<'tcx>, . b: ty::ClosureArgs<'tcx>, . ) -> RelateResult<'tcx, ty::ClosureArgs<'tcx>> { -- line 721 ---------------------------------------- -- line 731 ---------------------------------------- . b: ty::GeneratorArgs<'tcx>, . ) -> RelateResult<'tcx, ty::GeneratorArgs<'tcx>> { . let args = relate_args(relation, a.args, b.args)?; . Ok(ty::GeneratorArgs { args }) . } . } . . impl<'tcx> Relate<'tcx> for GenericArgsRef<'tcx> { 33 (0.0%) fn relate>( . relation: &mut R, . a: GenericArgsRef<'tcx>, . b: GenericArgsRef<'tcx>, . ) -> RelateResult<'tcx, GenericArgsRef<'tcx>> { . relate_args(relation, a, b) . } . } . . impl<'tcx> Relate<'tcx> for ty::Region<'tcx> { . fn relate>( . relation: &mut R, . a: ty::Region<'tcx>, . b: ty::Region<'tcx>, . ) -> RelateResult<'tcx, ty::Region<'tcx>> { 10,398 (0.0%) relation.regions(a, b) 15,176 (0.0%) } . } . . impl<'tcx> Relate<'tcx> for ty::Const<'tcx> { . fn relate>( . relation: &mut R, . a: ty::Const<'tcx>, . b: ty::Const<'tcx>, . ) -> RelateResult<'tcx, ty::Const<'tcx>> { 2,120 (0.0%) relation.consts(a, b) . } . } . . impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for ty::Binder<'tcx, T> { . fn relate>( . relation: &mut R, . a: ty::Binder<'tcx, T>, . b: ty::Binder<'tcx, T>, . ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> { 351 (0.0%) relation.binders(a, b) . } . } . . impl<'tcx> Relate<'tcx> for GenericArg<'tcx> { 33,714,780 (0.0%) fn relate>( . relation: &mut R, . a: GenericArg<'tcx>, . b: GenericArg<'tcx>, . ) -> RelateResult<'tcx, GenericArg<'tcx>> { 73,805,996 (0.0%) match (a.unpack(), b.unpack()) { . (GenericArgKind::Lifetime(a_lt), GenericArgKind::Lifetime(b_lt)) => { 1,437 (0.0%) Ok(relation.relate(a_lt, b_lt)?.into()) . } . (GenericArgKind::Type(a_ty), GenericArgKind::Type(b_ty)) => { . Ok(relation.relate(a_ty, b_ty)?.into()) . } . (GenericArgKind::Const(a_ct), GenericArgKind::Const(b_ct)) => { . Ok(relation.relate(a_ct, b_ct)?.into()) . } . (GenericArgKind::Lifetime(unpacked), x) => { -- line 794 ---------------------------------------- -- line 796 ---------------------------------------- . } . (GenericArgKind::Type(unpacked), x) => { . bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x) . } . (GenericArgKind::Const(unpacked), x) => { . bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x) . } . } 42,178,011 (0.0%) } . } . . impl<'tcx> Relate<'tcx> for ty::ImplPolarity { . fn relate>( . relation: &mut R, . a: ty::ImplPolarity, . b: ty::ImplPolarity, . ) -> RelateResult<'tcx, ty::ImplPolarity> { -- line 812 ---------------------------------------- -- line 814 ---------------------------------------- . Err(TypeError::PolarityMismatch(expected_found(relation, a, b))) . } else { . Ok(a) . } . } . } . . impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> { 215,970 (0.0%) fn relate>( . relation: &mut R, . a: ty::TraitPredicate<'tcx>, . b: ty::TraitPredicate<'tcx>, . ) -> RelateResult<'tcx, ty::TraitPredicate<'tcx>> { . Ok(ty::TraitPredicate { 237,567 (0.0%) trait_ref: relation.relate(a.trait_ref, b.trait_ref)?, . constness: relation.relate(a.constness, b.constness)?, . polarity: relation.relate(a.polarity, b.polarity)?, . }) 172,776 (0.0%) } . } . . impl<'tcx> Relate<'tcx> for Term<'tcx> { 328 (0.0%) fn relate>( . relation: &mut R, . a: Self, . b: Self, . ) -> RelateResult<'tcx, Self> { 492 (0.0%) Ok(match (a.unpack(), b.unpack()) { . (TermKind::Ty(a), TermKind::Ty(b)) => relation.relate(a, b)?.into(), . (TermKind::Const(a), TermKind::Const(b)) => relation.relate(a, b)?.into(), . _ => return Err(TypeError::Mismatch), . }) 328 (0.0%) } . } . . impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> { . fn relate>( . relation: &mut R, . a: ty::ProjectionPredicate<'tcx>, . b: ty::ProjectionPredicate<'tcx>, . ) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>> { -- line 854 ---------------------------------------- -- line 861 ---------------------------------------- . . /////////////////////////////////////////////////////////////////////////// . // Error handling . . pub fn expected_found<'tcx, R, T>(relation: &mut R, a: T, b: T) -> ExpectedFound . where . R: TypeRelation<'tcx>, . { 43,166 (0.0%) ExpectedFound::new(relation.a_is_expected(), a, b) . } -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_middle/src/ty/sty.rs -------------------------------------------------------------------------------- Ir__________________ 3,026,517,371 (1.3%) -- line 44 ---------------------------------------- . use super::GenericParamDefKind; . . // Re-export the `TyKind` from `rustc_type_ir` here for convenience . #[rustc_diagnostic_item = "TyKind"] . pub type TyKind<'tcx> = IrTyKind>; . pub type RegionKind<'tcx> = IrRegionKind>; . pub type ConstKind<'tcx> = IrConstKind>; . 154 (0.0%) #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] . #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub struct TypeAndMut<'tcx> { . pub ty: Ty<'tcx>, 18 (0.0%) pub mutbl: hir::Mutability, . } . . #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)] . #[derive(HashStable)] . /// A "free" region `fr` can be interpreted as "some region . /// at least as big as the scope `fr.scope`". . pub struct FreeRegion { 90 (0.0%) pub scope: DefId, 1,716 (0.0%) pub bound_region: BoundRegionKind, . } . 21,360 (0.0%) #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)] . #[derive(HashStable)] . pub enum BoundRegionKind { . /// An anonymous region parameter for a given fn (&T) . BrAnon(Option), . . /// Named region parameters for functions (a in &'a T) . /// . /// The `DefId` is needed to distinguish free regions in . /// the event of shadowing. 880 (0.0%) BrNamed(DefId, Symbol), . . /// Anonymous region for the implicit env pointer parameter . /// to a closure . BrEnv, . } . 876 (0.0%) #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)] . #[derive(HashStable)] . pub struct BoundRegion { 725 (0.0%) pub var: BoundVar, 231 (0.0%) pub kind: BoundRegionKind, . } . . impl BoundRegionKind { . pub fn is_named(&self) -> bool { 338 (0.0%) match *self { 168 (0.0%) BoundRegionKind::BrNamed(_, name) => { . name != kw::UnderscoreLifetime && name != kw::Empty . } . _ => false, . } . } . 169 (0.0%) pub fn get_name(&self) -> Option { 336 (0.0%) if self.is_named() { . match *self { . BoundRegionKind::BrNamed(_, name) => return Some(name), . _ => unreachable!(), . } . } . . None 169 (0.0%) } . . pub fn get_id(&self) -> Option { . match *self { . BoundRegionKind::BrNamed(id, _) => return Some(id), . _ => None, . } . } . } -- line 119 ---------------------------------------- -- line 245 ---------------------------------------- . pub closure_kind_ty: T, . pub closure_sig_as_fn_ptr_ty: T, . pub tupled_upvars_ty: T, . } . . impl<'tcx> ClosureArgs<'tcx> { . /// Construct `ClosureArgs` from `ClosureArgsParts`, containing `Args` . /// for the closure parent, alongside additional closure-specific components. 1 (0.0%) pub fn new(tcx: TyCtxt<'tcx>, parts: ClosureArgsParts<'tcx, Ty<'tcx>>) -> ClosureArgs<'tcx> { . ClosureArgs { 1 (0.0%) args: tcx.mk_args_from_iter( 2 (0.0%) parts.parent_args.iter().copied().chain( 4 (0.0%) [parts.closure_kind_ty, parts.closure_sig_as_fn_ptr_ty, parts.tupled_upvars_ty] . .iter() . .map(|&ty| ty.into()), . ), . ), . } 2 (0.0%) } . . /// Divides the closure args into their respective components. . /// The ordering assumed here must match that used by `ClosureArgs::new` above. 15 (0.0%) fn split(self) -> ClosureArgsParts<'tcx, GenericArg<'tcx>> { . match self.args[..] { 381 (0.0%) [ref parent_args @ .., closure_kind_ty, closure_sig_as_fn_ptr_ty, tupled_upvars_ty] => { 60 (0.0%) ClosureArgsParts { . parent_args, . closure_kind_ty, . closure_sig_as_fn_ptr_ty, . tupled_upvars_ty, . } . } . _ => bug!("closure args missing synthetics"), . } 45 (0.0%) } . . /// Returns `true` only if enough of the synthetic types are known to . /// allow using all of the methods on `ClosureArgs` without panicking. . /// . /// Used primarily by `ty::print::pretty` to be able to handle closure . /// types that haven't had their synthetic types substituted in. . pub fn is_valid(self) -> bool { . self.args.len() >= 3 && matches!(self.split().tupled_upvars_ty.expect_ty().kind(), Tuple(_)) . } . . /// Returns the substitutions of the closure's parent. 1 (0.0%) pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] { . self.split().parent_args 3 (0.0%) } . . /// Returns an iterator over the list of types of captured paths by the closure. . /// In case there was a type error in figuring out the types of the captured path, an . /// empty iterator is returned. . #[inline] 6 (0.0%) pub fn upvar_tys(self) -> impl Iterator> + 'tcx { 3 (0.0%) match self.tupled_upvars_ty().kind() { . TyKind::Error(_) => None, . TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()), . TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), . ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), . } . .into_iter() . .flatten() 4 (0.0%) } . . /// Returns the tuple type representing the upvars for this closure. . #[inline] . pub fn tupled_upvars_ty(self) -> Ty<'tcx> { 69 (0.0%) self.split().tupled_upvars_ty.expect_ty() . } . . /// Returns the closure kind for this closure; may return a type . /// variable during inference. To get the closure kind during . /// inference, use `infcx.closure_kind(args)`. 17 (0.0%) pub fn kind_ty(self) -> Ty<'tcx> { . self.split().closure_kind_ty.expect_ty() 34 (0.0%) } . . /// Returns the `fn` pointer type representing the closure signature for this . /// closure. . // FIXME(eddyb) this should be unnecessary, as the shallowly resolved . // type is known at the time of the creation of `ClosureArgs`, . // see `rustc_hir_analysis::check::closure`. . pub fn sig_as_fn_ptr_ty(self) -> Ty<'tcx> { . self.split().closure_sig_as_fn_ptr_ty.expect_ty() -- line 329 ---------------------------------------- -- line 334 ---------------------------------------- . /// there are no type variables. . /// . /// If you have an inference context, use `infcx.closure_kind()`. . pub fn kind(self) -> ty::ClosureKind { . self.kind_ty().to_opt_closure_kind().unwrap() . } . . /// Extracts the signature from the closure. 22 (0.0%) pub fn sig(self) -> ty::PolyFnSig<'tcx> { . let ty = self.sig_as_fn_ptr_ty(); 44 (0.0%) match ty.kind() { 88 (0.0%) ty::FnPtr(sig) => *sig, . _ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind()), . } 66 (0.0%) } . . pub fn print_as_impl_trait(self) -> ty::print::PrintClosureAsImpl<'tcx> { . ty::print::PrintClosureAsImpl { closure: self } . } . } . . /// Similar to `ClosureArgs`; see the above documentation for more. . #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)] -- line 356 ---------------------------------------- -- line 588 ---------------------------------------- . } . . impl<'tcx> UpvarArgs<'tcx> { . /// Returns an iterator over the list of types of captured paths by the closure/generator. . /// In case there was a type error in figuring out the types of the captured path, an . /// empty iterator is returned. . #[inline] . pub fn upvar_tys(self) -> impl Iterator> + 'tcx { 2 (0.0%) let tupled_tys = match self { 4 (0.0%) UpvarArgs::Closure(args) => args.as_closure().tupled_upvars_ty(), . UpvarArgs::Generator(args) => args.as_generator().tupled_upvars_ty(), . }; . 6 (0.0%) match tupled_tys.kind() { . TyKind::Error(_) => None, . TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()), . TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), . ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), . } . .into_iter() . .flatten() . } . . #[inline] . pub fn tupled_upvars_ty(self) -> Ty<'tcx> { 6 (0.0%) match self { 6 (0.0%) UpvarArgs::Closure(args) => args.as_closure().tupled_upvars_ty(), . UpvarArgs::Generator(args) => args.as_generator().tupled_upvars_ty(), . } . } . } . . /// An inline const is modeled like . /// ```ignore (illustrative) . /// const InlineConst<'l0...'li, T0...Tj, R>: R; -- line 622 ---------------------------------------- -- line 672 ---------------------------------------- . } . . /// Returns the type of this inline const. . pub fn ty(self) -> Ty<'tcx> { . self.split().ty.expect_ty() . } . } . 26,418 (0.0%) #[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, TyEncodable, TyDecodable)] 15,302 (0.0%) #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub enum ExistentialPredicate<'tcx> { . /// E.g., `Iterator`. . Trait(ExistentialTraitRef<'tcx>), . /// E.g., `Iterator::Item = T`. . Projection(ExistentialProjection<'tcx>), . /// E.g., `Send`. . AutoTrait(DefId), . } -- line 689 ---------------------------------------- -- line 695 ---------------------------------------- . ) -> core::fmt::Result { . fmt::Debug::fmt(&this.data, f) . } . } . . impl<'tcx> ExistentialPredicate<'tcx> { . /// Compares via an ordering that will not change if modules are reordered or other changes are . /// made to the tree. In particular, this ordering is preserved across incremental compilations. 24 (0.0%) pub fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering { . use self::ExistentialPredicate::*; 34 (0.0%) match (*self, *other) { . (Trait(_), Trait(_)) => Ordering::Equal, . (Projection(ref a), Projection(ref b)) => { . tcx.def_path_hash(a.def_id).cmp(&tcx.def_path_hash(b.def_id)) . } . (AutoTrait(ref a), AutoTrait(ref b)) => { 10 (0.0%) tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b)) . } . (Trait(_), _) => Ordering::Less, . (Projection(_), Trait(_)) => Ordering::Greater, . (Projection(_), _) => Ordering::Less, . (AutoTrait(_), _) => Ordering::Greater, . } 27 (0.0%) } . } . . pub type PolyExistentialPredicate<'tcx> = Binder<'tcx, ExistentialPredicate<'tcx>>; . . impl<'tcx> PolyExistentialPredicate<'tcx> { . /// Given an existential predicate like `?Self: PartialEq` (e.g., derived from `dyn PartialEq`), . /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self` . /// has been replaced with `self_ty` (e.g., `self_ty: PartialEq`, in our example). 1,035 (0.0%) pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Clause<'tcx> { . use crate::ty::ToPredicate; 1,150 (0.0%) match self.skip_binder() { . ExistentialPredicate::Trait(tr) => { . self.rebind(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx) . } . ExistentialPredicate::Projection(p) => { . self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx) . } . ExistentialPredicate::AutoTrait(did) => { . let generics = tcx.generics_of(did); -- line 737 ---------------------------------------- -- line 741 ---------------------------------------- . // If this is an ill-formed auto trait, then synthesize . // new error args for the missing generics. . let err_args = ty::GenericArgs::extend_with_error(tcx, did, &[self_ty.into()]); . ty::TraitRef::new(tcx, did, err_args) . }; . self.rebind(trait_ref).without_const().to_predicate(tcx) . } . } 920 (0.0%) } . } . . impl<'tcx> List> { . /// Returns the "principal `DefId`" of this set of existential predicates. . /// . /// A Rust trait object type consists (in addition to a lifetime bound) . /// of a set of trait bounds, which are separated into any number . /// of auto-trait bounds, and at most one non-auto-trait bound. The -- line 757 ---------------------------------------- -- line 771 ---------------------------------------- . /// . /// It is also possible to have a "trivial" trait object that . /// consists only of auto traits, with no principal - for example, . /// `dyn Send + Sync`. In that case, the set of auto-trait bounds . /// is `{Send, Sync}`, while there is no principal. These trait objects . /// have a "trivial" vtable consisting of just the size, alignment, . /// and destructor. . pub fn principal(&self) -> Option>> { 339 (0.0%) self[0] 226 (0.0%) .map_bound(|this| match this { 110 (0.0%) ExistentialPredicate::Trait(tr) => Some(tr), . _ => None, . }) . .transpose() . } . 110 (0.0%) pub fn principal_def_id(&self) -> Option { . self.principal().map(|trait_ref| trait_ref.skip_binder().def_id) 220 (0.0%) } . . #[inline] . pub fn projection_bounds<'a>( . &'a self, . ) -> impl Iterator>> + 'a { . self.iter().filter_map(|predicate| { . predicate . .map_bound(|pred| match pred { -- line 797 ---------------------------------------- -- line 799 ---------------------------------------- . _ => None, . }) . .transpose() . }) . } . . #[inline] . pub fn auto_traits<'a>(&'a self) -> impl Iterator + Captures<'tcx> + 'a { 347 (0.0%) self.iter().filter_map(|predicate| match predicate.skip_binder() { . ExistentialPredicate::AutoTrait(did) => Some(did), . _ => None, . }) . } . } . . /// A complete reference to a trait. These take numerous guises in syntax, . /// but perhaps the most recognizable form is in a where-clause: -- line 815 ---------------------------------------- -- line 817 ---------------------------------------- . /// T: Foo . /// ``` . /// This would be represented by a trait-reference where the `DefId` is the . /// `DefId` for the trait `Foo` and the args define `T` as parameter 0, . /// and `U` as parameter 1. . /// . /// Trait references also appear in object types like `Foo`, but in . /// that case the `Self` parameter is absent from the substitutions. 34,695 (0.0%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 74,161,759 (0.0%) #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub struct TraitRef<'tcx> { . pub def_id: DefId, 3,288,112,162 (1.4%) pub args: GenericArgsRef<'tcx>, . /// This field exists to prevent the creation of `TraitRef` without . /// calling [`TraitRef::new`]. . pub(super) _use_trait_ref_new_instead: (), . } . . impl<'tcx> TraitRef<'tcx> { . pub fn new( . tcx: TyCtxt<'tcx>, . trait_def_id: DefId, . args: impl IntoIterator>>, . ) -> Self { . let args = tcx.check_and_mk_args(trait_def_id, args); 930,295 (0.0%) Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () } . } . 1,854 (0.0%) pub fn from_lang_item( . tcx: TyCtxt<'tcx>, . trait_lang_item: LangItem, . span: Span, . args: impl IntoIterator>>, . ) -> Self { 18,617 (0.0%) let trait_def_id = tcx.require_lang_item(trait_lang_item, Some(span)); 254 (0.0%) Self::new(tcx, trait_def_id, args) 1,648 (0.0%) } . 946 (0.0%) pub fn from_method( . tcx: TyCtxt<'tcx>, . trait_id: DefId, . args: GenericArgsRef<'tcx>, . ) -> ty::TraitRef<'tcx> { . let defs = tcx.generics_of(trait_id); 258 (0.0%) ty::TraitRef::new(tcx, trait_id, tcx.mk_args(&args[..defs.params.len()])) 688 (0.0%) } . . /// Returns a `TraitRef` of the form `P0: Foo` where `Pi` . /// are the parameters defined on trait. 3,123 (0.0%) pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> { 1,388 (0.0%) ty::TraitRef::new(tcx, def_id, GenericArgs::identity_for_item(tcx, def_id)) 2,429 (0.0%) } . . pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { . ty::TraitRef::new( . tcx, . self.def_id, . [self_ty.into()].into_iter().chain(self.args.iter().skip(1)), . ) . } -- line 876 ---------------------------------------- -- line 884 ---------------------------------------- . /// Converts this trait ref to a trait predicate without `const` and a positive polarity. . #[inline] . pub fn without_const(self) -> ty::TraitPredicate<'tcx> { . self.with_constness(ty::BoundConstness::NotConst) . } . . #[inline] . pub fn self_ty(&self) -> Ty<'tcx> { 2,955,455 (0.0%) self.args.type_at(0) . } . } . . pub type PolyTraitRef<'tcx> = Binder<'tcx, TraitRef<'tcx>>; . . impl<'tcx> PolyTraitRef<'tcx> { 5 (0.0%) pub fn self_ty(&self) -> Binder<'tcx, Ty<'tcx>> { 20 (0.0%) self.map_bound_ref(|tr| tr.self_ty()) 10 (0.0%) } . . pub fn def_id(&self) -> DefId { . self.skip_binder().def_id . } . } . . impl<'tcx> IntoDiagnosticArg for TraitRef<'tcx> { . fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { -- line 909 ---------------------------------------- -- line 913 ---------------------------------------- . . /// An existential reference to a trait, where `Self` is erased. . /// For example, the trait object `Trait<'a, 'b, X, Y>` is: . /// ```ignore (illustrative) . /// exists T. T: Trait<'a, 'b, X, Y> . /// ``` . /// The substitutions don't include the erased `Self`, only trait . /// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). 72 (0.0%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 10,645 (0.0%) #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub struct ExistentialTraitRef<'tcx> { . pub def_id: DefId, 3,865 (0.0%) pub args: GenericArgsRef<'tcx>, . } . . impl<'tcx> ExistentialTraitRef<'tcx> { 3 (0.0%) pub fn erase_self_ty( . tcx: TyCtxt<'tcx>, . trait_ref: ty::TraitRef<'tcx>, . ) -> ty::ExistentialTraitRef<'tcx> { . // Assert there is a Self. 3 (0.0%) trait_ref.args.type_at(0); . 2 (0.0%) ty::ExistentialTraitRef { 1 (0.0%) def_id: trait_ref.def_id, 3 (0.0%) args: tcx.mk_args(&trait_ref.args[1..]), . } 5 (0.0%) } . . /// Object types don't have a self type specified. Therefore, when . /// we convert the principal trait-ref into a normal trait-ref, . /// you must give *some* self type. A common choice is `mk_err()` . /// or some placeholder type. . pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx> { . // otherwise the escaping vars would be captured by the binder . // debug_assert!(!self_ty.has_escaping_bound_vars()); -- line 948 ---------------------------------------- -- line 968 ---------------------------------------- . /// we convert the principal trait-ref into a normal trait-ref, . /// you must give *some* self type. A common choice is `mk_err()` . /// or some placeholder type. . pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::PolyTraitRef<'tcx> { . self.map_bound(|trait_ref| trait_ref.with_self_ty(tcx, self_ty)) . } . } . 12,061 (0.0%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] . #[derive(HashStable)] . pub enum BoundVariableKind { . Ty(BoundTyKind), . Region(BoundRegionKind), . Const, . } . . impl BoundVariableKind { -- line 984 ---------------------------------------- -- line 1008 ---------------------------------------- . /// compiler's representation for things like `for<'a> Fn(&'a isize)` . /// (which would be represented by the type `PolyTraitRef == . /// Binder<'tcx, TraitRef>`). Note that when we instantiate, . /// erase, or otherwise "discharge" these bound vars, we change the . /// type from `Binder<'tcx, T>` to just `T` (see . /// e.g., `liberate_late_bound_regions`). . /// . /// `Decodable` and `Encodable` are implemented for `Binder` using the `impl_binder_encode_decode!` macro. 5,435,027 (0.0%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] . #[derive(HashStable, Lift)] . pub struct Binder<'tcx, T> { . value: T, 18,452,960 (0.0%) bound_vars: &'tcx List, . } . . impl<'tcx, T> Binder<'tcx, T> . where . T: TypeVisitable>, . { . /// Wraps `value` in a binder, asserting that `value` does not . /// contain any bound vars that would be bound by the . /// binder. This is commonly used to 'inject' a value T into a . /// different binding level. . #[track_caller] 309,113 (0.0%) pub fn dummy(value: T) -> Binder<'tcx, T> { 87,220 (0.0%) assert!( . !value.has_escaping_bound_vars(), . "`{value:?}` has escaping bound vars, so it cannot be wrapped in a dummy binder." . ); 1,604,655 (0.0%) Binder { value, bound_vars: ty::List::empty() } 307,808 (0.0%) } . . pub fn bind_with_vars(value: T, bound_vars: &'tcx List) -> Binder<'tcx, T> { . if cfg!(debug_assertions) { . let mut validator = ValidateBoundVars::new(bound_vars); . value.visit_with(&mut validator); . } 152,645 (0.0%) Binder { value, bound_vars } . } . } . . impl<'tcx, T> Binder<'tcx, T> { . /// Skips the binder and returns the "bound" value. This is a . /// risky thing to do because it's easy to get confused about . /// De Bruijn indices and the like. It is usually better to . /// discharge the binder using `no_bound_vars` or -- line 1053 ---------------------------------------- -- line 1059 ---------------------------------------- . /// accounting. . /// . /// Some examples where `skip_binder` is reasonable: . /// . /// - extracting the `DefId` from a PolyTraitRef; . /// - comparing the self type of a PolyTraitRef to see if it is equal to . /// a type parameter `X`, since the type `X` does not reference any regions . pub fn skip_binder(self) -> T { 22,455,604 (0.0%) self.value . } . . pub fn bound_vars(&self) -> &'tcx List { 2,301 (0.0%) self.bound_vars . } . . pub fn as_ref(&self) -> Binder<'tcx, &T> { 79,702 (0.0%) Binder { value: &self.value, bound_vars: self.bound_vars } . } . . pub fn as_deref(&self) -> Binder<'tcx, &T::Target> . where . T: Deref, . { . Binder { value: &self.value, bound_vars: self.bound_vars } . } . . pub fn map_bound_ref_unchecked(&self, f: F) -> Binder<'tcx, U> . where . F: FnOnce(&T) -> U, . { 495 (0.0%) let value = f(&self.value); . Binder { value, bound_vars: self.bound_vars } . } . 3 (0.0%) pub fn map_bound_ref>>(&self, f: F) -> Binder<'tcx, U> . where . F: FnOnce(&T) -> U, . { . self.as_ref().map_bound(f) 5 (0.0%) } . . pub fn map_bound>>(self, f: F) -> Binder<'tcx, U> . where . F: FnOnce(T) -> U, . { 98 (0.0%) let Binder { value, bound_vars } = self; 2 (0.0%) let value = f(value); . if cfg!(debug_assertions) { . let mut validator = ValidateBoundVars::new(bound_vars); . value.visit_with(&mut validator); . } 14,272,757 (0.0%) Binder { value, bound_vars } . } . . pub fn try_map_bound>, E>( . self, . f: F, . ) -> Result, E> . where . F: FnOnce(T) -> Result, . { 4,050,585 (0.0%) let Binder { value, bound_vars } = self; . let value = f(value)?; . if cfg!(debug_assertions) { . let mut validator = ValidateBoundVars::new(bound_vars); . value.visit_with(&mut validator); . } 7,056 (0.0%) Ok(Binder { value, bound_vars }) . } . . /// Wraps a `value` in a binder, using the same bound variables as the . /// current `Binder`. This should not be used if the new value *changes* . /// the bound variables. Note: the (old or new) value itself does not . /// necessarily need to *name* all the bound variables. . /// . /// This currently doesn't do anything different than `bind`, because we . /// don't actually track bound vars. However, semantically, it is different . /// because bound vars aren't allowed to change here, whereas they are . /// in `bind`. This may be (debug) asserted in the future. . pub fn rebind(&self, value: U) -> Binder<'tcx, U> . where . U: TypeVisitable>, . { 142,278 (0.0%) Binder::bind_with_vars(value, self.bound_vars) . } . . /// Unwraps and returns the value within, but only if it contains . /// no bound vars at all. (In other words, if this binder -- . /// and indeed any enclosing binder -- doesn't bind anything at . /// all.) Otherwise, returns `None`. . /// . /// (One could imagine having a method that just unwraps a single -- line 1150 ---------------------------------------- -- line 1151 ---------------------------------------- . /// binder, but permits late-bound vars bound by enclosing . /// binders, but that would require adjusting the debruijn . /// indices, and given the shallow binding structure we often use, . /// would not be that useful.) . pub fn no_bound_vars(self) -> Option . where . T: TypeVisitable>, . { 470,087 (0.0%) if self.value.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) } . } . . /// Splits the contents into two things that share the same binder . /// level as the original, returning two distinct binders. . /// . /// `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. -- line 1167 ---------------------------------------- -- line 1198 ---------------------------------------- . } . } . . /// Represents the projection of an associated type. . /// . /// * For a projection, this would be `>::N<...>`. . /// * For an inherent projection, this would be `Ty::N<...>`. . /// * For an opaque type, there is no explicit syntax. 69 (0.0%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 9,740,578 (0.0%) #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub struct AliasTy<'tcx> { . /// The parameters of the associated or opaque item. . /// . /// For a projection, these are the substitutions for the trait and the . /// GAT substitutions, if there are any. . /// . /// For an inherent projection, they consist of the self type and the GAT substitutions, . /// if there are any. -- line 1215 ---------------------------------------- -- line 1223 ---------------------------------------- . /// this is an opaque. . /// . /// During codegen, `tcx.type_of(def_id)` can be used to get the type of the . /// underlying type if the type is an opaque. . /// . /// Note that if this is an associated type, this is not the `DefId` of the . /// `TraitRef` containing this associated type, which is in `tcx.associated_item(def_id).container`, . /// aka. `tcx.parent(def_id)`. 4,626,490 (0.0%) pub def_id: DefId, . . /// This field exists to prevent the creation of `AliasTy` without using . /// [TyCtxt::mk_alias_ty]. . pub(super) _use_mk_alias_ty_instead: (), . } . . impl<'tcx> AliasTy<'tcx> { . pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind { -- line 1239 ---------------------------------------- -- line 1249 ---------------------------------------- . pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { . Ty::new_alias(tcx, self.kind(tcx), self) . } . } . . /// The following methods work only with associated type projections. . impl<'tcx> AliasTy<'tcx> { . pub fn self_ty(self) -> Ty<'tcx> { 1,644,579 (0.0%) self.args.type_at(0) 1,096,386 (0.0%) } . . pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { . tcx.mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.args.iter().skip(1))) . } . } . . /// The following methods work only with trait associated type projections. . impl<'tcx> AliasTy<'tcx> { 2,911,565 (0.0%) pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { 10,481,634 (0.0%) match tcx.def_kind(self.def_id) { . DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id), . kind => bug!("expected a projection AliasTy; found {kind:?}"), . } 3,493,878 (0.0%) } . . /// Extracts the underlying trait reference and own args from this projection. . /// For example, if this is a projection of `::Item<'a>`, . /// then this function would return a `T: StreamingIterator` trait reference and `['a]` as the own args 45,600 (0.0%) pub fn trait_ref_and_own_args( . self, . tcx: TyCtxt<'tcx>, . ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { . debug_assert!(matches!(tcx.def_kind(self.def_id), DefKind::AssocTy | DefKind::AssocConst)); 31,920 (0.0%) let trait_def_id = self.trait_def_id(tcx); . let trait_generics = tcx.generics_of(trait_def_id); 27,360 (0.0%) ( 4,560 (0.0%) ty::TraitRef::new(tcx, trait_def_id, self.args.truncate_to(tcx, trait_generics)), . &self.args[trait_generics.count()..], . ) 41,040 (0.0%) } . . /// Extracts the underlying trait reference from this projection. . /// For example, if this is a projection of `::Item`, . /// then this function would return a `T: Iterator` trait reference. . /// . /// WARNING: This will drop the args for generic associated types . /// consider calling [Self::trait_ref_and_own_args] to get those . /// as well. 2,732,823 (0.0%) pub fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> { 2,125,529 (0.0%) let def_id = self.trait_def_id(tcx); 303,647 (0.0%) ty::TraitRef::new(tcx, def_id, self.args.truncate_to(tcx, tcx.generics_of(def_id))) 2,429,176 (0.0%) } . } . . /// The following methods work only with inherent associated type projections. . impl<'tcx> AliasTy<'tcx> { . /// Transform the substitutions to have the given `impl` args as the base and the GAT args on top of that. . /// . /// Does the following transformation: . /// -- line 1308 ---------------------------------------- -- line 1333 ---------------------------------------- . pub type PolyGenSig<'tcx> = Binder<'tcx, GenSig<'tcx>>; . . /// Signature of a function type, which we have arbitrarily . /// decided to use to refer to the input/output types. . /// . /// - `inputs`: is the list of arguments and their modes. . /// - `output`: is the return type. . /// - `c_variadic`: indicates whether this is a C-variadic function. 641 (0.0%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 8,804 (0.0%) #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub struct FnSig<'tcx> { . pub inputs_and_output: &'tcx List>, 2,382 (0.0%) pub c_variadic: bool, 370 (0.0%) pub unsafety: hir::Unsafety, 1,769 (0.0%) pub abi: abi::Abi, . } . . impl<'tcx> FnSig<'tcx> { 4,115 (0.0%) pub fn inputs(&self) -> &'tcx [Ty<'tcx>] { 9,193 (0.0%) &self.inputs_and_output[..self.inputs_and_output.len() - 1] 8,230 (0.0%) } . 2,499 (0.0%) pub fn output(&self) -> Ty<'tcx> { 11,160 (0.0%) self.inputs_and_output[self.inputs_and_output.len() - 1] 4,998 (0.0%) } . . // Creates a minimal `FnSig` to be used when encountering a `TyKind::Error` in a fallible . // method. . fn fake() -> FnSig<'tcx> { . FnSig { . inputs_and_output: List::empty(), . c_variadic: false, . unsafety: hir::Unsafety::Normal, -- line 1365 ---------------------------------------- -- line 1374 ---------------------------------------- . } . } . . pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>; . . impl<'tcx> PolyFnSig<'tcx> { . #[inline] . pub fn inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]> { 1,648 (0.0%) self.map_bound_ref_unchecked(|fn_sig| fn_sig.inputs()) . } . #[inline] . pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> { 1,095 (0.0%) self.map_bound_ref(|fn_sig| fn_sig.inputs()[index]) . } . pub fn inputs_and_output(&self) -> ty::Binder<'tcx, &'tcx List>> { 312 (0.0%) self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output) 156 (0.0%) } . #[inline] . pub fn output(&self) -> ty::Binder<'tcx, Ty<'tcx>> { 611 (0.0%) self.map_bound_ref(|fn_sig| fn_sig.output()) . } . pub fn c_variadic(&self) -> bool { 156 (0.0%) self.skip_binder().c_variadic 156 (0.0%) } . pub fn unsafety(&self) -> hir::Unsafety { 323 (0.0%) self.skip_binder().unsafety 323 (0.0%) } . pub fn abi(&self) -> abi::Abi { 1,742 (0.0%) self.skip_binder().abi 871 (0.0%) } . . pub fn is_fn_trait_compatible(&self) -> bool { . matches!( . self.skip_binder(), . ty::FnSig { . unsafety: rustc_hir::Unsafety::Normal, . abi: Abi::Rust, . c_variadic: false, -- line 1411 ---------------------------------------- -- line 1412 ---------------------------------------- . .. . } . ) . } . } . . pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>; . 4,118 (0.0%) #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] . #[derive(HashStable)] . pub struct ParamTy { . pub index: u32, . pub name: Symbol, . } . . impl<'tcx> ParamTy { . pub fn new(index: u32, name: Symbol) -> ParamTy { . ParamTy { index, name } 3,304 (0.0%) } . . pub fn for_def(def: &ty::GenericParamDef) -> ParamTy { 2,274 (0.0%) ParamTy::new(def.index, def.name) 1,137 (0.0%) } . . #[inline] . pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { . Ty::new_param(tcx, self.index, self.name) . } . . pub fn span_from_generics(&self, tcx: TyCtxt<'tcx>, item_with_generics: DefId) -> Span { . let generics = tcx.generics_of(item_with_generics); . let type_param = generics.type_param(self, tcx); . tcx.def_span(type_param.def_id) . } . } . 86 (0.0%) #[derive(Copy, Clone, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)] . #[derive(HashStable)] . pub struct ParamConst { . pub index: u32, . pub name: Symbol, . } . . impl ParamConst { . pub fn new(index: u32, name: Symbol) -> ParamConst { -- line 1456 ---------------------------------------- -- line 1458 ---------------------------------------- . } . . pub fn for_def(def: &ty::GenericParamDef) -> ParamConst { . ParamConst::new(def.index, def.name) . } . } . . /// Use this rather than `RegionKind`, whenever possible. 3,925 (0.0%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)] . #[rustc_pass_by_value] . pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>); . . impl<'tcx> Region<'tcx> { . #[inline] . pub fn new_early_bound( . tcx: TyCtxt<'tcx>, . early_bound_region: ty::EarlyBoundRegion, . ) -> Region<'tcx> { 2,512 (0.0%) tcx.intern_region(ty::ReEarlyBound(early_bound_region)) . } . . #[inline] . pub fn new_late_bound( . tcx: TyCtxt<'tcx>, . debruijn: ty::DebruijnIndex, . bound_region: ty::BoundRegion, . ) -> Region<'tcx> { . // Use a pre-interned one when possible. 219 (0.0%) if let ty::BoundRegion { var, kind: ty::BrAnon(None) } = bound_region . && let Some(inner) = tcx.lifetimes.re_late_bounds.get(debruijn.as_usize()) . && let Some(re) = inner.get(var.as_usize()).copied() . { . re . } else { 3,577 (0.0%) tcx.intern_region(ty::ReLateBound(debruijn, bound_region)) . } . } . . #[inline] . pub fn new_free( . tcx: TyCtxt<'tcx>, . scope: DefId, . bound_region: ty::BoundRegionKind, . ) -> Region<'tcx> { 7,785 (0.0%) tcx.intern_region(ty::ReFree(ty::FreeRegion { scope, bound_region })) . } . . #[inline] . pub fn new_var(tcx: TyCtxt<'tcx>, v: ty::RegionVid) -> Region<'tcx> { . // Use a pre-interned one when possible. . tcx.lifetimes . .re_vars . .get(v.as_usize()) -- line 1510 ---------------------------------------- -- line 1543 ---------------------------------------- . msg: &'static str, . ) -> Region<'tcx> { . let reported = tcx.sess.delay_span_bug(span, msg); . Region::new_error(tcx, reported) . } . . /// Avoid this in favour of more specific `new_*` methods, where possible, . /// to avoid the cost of the `match`. 1,334 (0.0%) pub fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> { 6,670 (0.0%) match kind { 2,512 (0.0%) ty::ReEarlyBound(region) => Region::new_early_bound(tcx, region), 365 (0.0%) ty::ReLateBound(debruijn, region) => Region::new_late_bound(tcx, debruijn, region), . ty::ReFree(ty::FreeRegion { scope, bound_region }) => { . Region::new_free(tcx, scope, bound_region) . } 5 (0.0%) ty::ReStatic => tcx.lifetimes.re_static, . ty::ReVar(vid) => Region::new_var(tcx, vid), . ty::RePlaceholder(region) => Region::new_placeholder(tcx, region), . ty::ReErased => tcx.lifetimes.re_erased, . ty::ReError(reported) => Region::new_error(tcx, reported), . } 2,668 (0.0%) } . } . . impl<'tcx> Deref for Region<'tcx> { . type Target = RegionKind<'tcx>; . . #[inline] . fn deref(&self) -> &RegionKind<'tcx> { . &self.0.0 . } . } . 7,536 (0.0%) #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)] . #[derive(HashStable)] . pub struct EarlyBoundRegion { . pub def_id: DefId, 298 (0.0%) pub index: u32, 55 (0.0%) pub name: Symbol, . } . . impl fmt::Debug for EarlyBoundRegion { . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { . write!(f, "{:?}, {}, {}", self.def_id, self.index, self.name) . } . } . . /// A **`const`** **v**ariable **ID**. . #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] . #[derive(HashStable, TyEncodable, TyDecodable)] . pub struct ConstVid<'tcx> { 228 (0.0%) pub index: u32, . pub phantom: PhantomData<&'tcx ()>, . } . 230,067 (0.0%) rustc_index::newtype_index! { . /// A **region** (lifetime) **v**ariable **ID**. . #[derive(HashStable)] . #[debug_format = "'?{}"] . pub struct RegionVid {} . } . . impl Atom for RegionVid { . fn index(self) -> usize { . Idx::index(self) . } . } . 27,845 (0.0%) rustc_index::newtype_index! { . #[derive(HashStable)] . #[debug_format = "{}"] . pub struct BoundVar {} . } . . #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] . #[derive(HashStable)] . pub struct BoundTy { -- line 1619 ---------------------------------------- -- line 1624 ---------------------------------------- . #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] . #[derive(HashStable)] . pub enum BoundTyKind { . Anon, . Param(DefId, Symbol), . } . . impl From for BoundTy { 317 (0.0%) fn from(var: BoundVar) -> Self { 634 (0.0%) BoundTy { var, kind: BoundTyKind::Anon } 317 (0.0%) } . } . . /// A `ProjectionPredicate` for an `ExistentialTraitRef`. . #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] . #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] . pub struct ExistentialProjection<'tcx> { . pub def_id: DefId, . pub args: GenericArgsRef<'tcx>, -- line 1642 ---------------------------------------- -- line 1699 ---------------------------------------- . pub fn item_def_id(&self) -> DefId { . self.skip_binder().def_id . } . } . . /// Region utilities . impl<'tcx> Region<'tcx> { . pub fn kind(self) -> RegionKind<'tcx> { 19,379 (0.0%) *self.0.0 . } . . pub fn get_name(self) -> Option { 4 (0.0%) if self.has_name() { . match *self { . ty::ReEarlyBound(ebr) => Some(ebr.name), . ty::ReLateBound(_, br) => br.kind.get_name(), . ty::ReFree(fr) => fr.bound_region.get_name(), . ty::ReStatic => Some(kw::StaticLifetime), . ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(), . _ => None, . } -- line 1719 ---------------------------------------- -- line 1722 ---------------------------------------- . } . } . . pub fn get_name_or_anon(self) -> Symbol { . match self.get_name() { . Some(name) => name, . None => sym::anon, . } 2 (0.0%) } . . /// Is this region named by the user? . pub fn has_name(self) -> bool { 12 (0.0%) match *self { . ty::ReEarlyBound(ebr) => ebr.has_name(), . ty::ReLateBound(_, br) => br.kind.is_named(), . ty::ReFree(fr) => fr.bound_region.is_named(), . ty::ReStatic => true, . ty::ReVar(..) => false, . ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(), . ty::ReErased => false, . ty::ReError(_) => false, -- line 1742 ---------------------------------------- -- line 1755 ---------------------------------------- . . #[inline] . pub fn is_erased(self) -> bool { . matches!(*self, ty::ReErased) . } . . #[inline] . pub fn is_late_bound(self) -> bool { 276 (0.0%) matches!(*self, ty::ReLateBound(..)) . } . . #[inline] . pub fn is_placeholder(self) -> bool { . matches!(*self, ty::RePlaceholder(..)) . } . . #[inline] . pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool { 6,858 (0.0%) match *self { . ty::ReLateBound(debruijn, _) => debruijn >= index, . _ => false, . } . } . . pub fn type_flags(self) -> TypeFlags { . let mut flags = TypeFlags::empty(); . 30,709 (0.0%) match *self { . ty::ReVar(..) => { . flags = flags | TypeFlags::HAS_FREE_REGIONS; . flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; . flags = flags | TypeFlags::HAS_RE_INFER; . } . ty::RePlaceholder(..) => { . flags = flags | TypeFlags::HAS_FREE_REGIONS; . flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; -- line 1790 ---------------------------------------- -- line 1811 ---------------------------------------- . ty::ReError(_) => { . flags = flags | TypeFlags::HAS_FREE_REGIONS; . } . } . . debug!("type_flags({:?}) = {:?}", self, flags); . . flags 1,171 (0.0%) } . . /// Given an early-bound or free region, returns the `DefId` where it was bound. . /// For example, consider the regions in this snippet of code: . /// . /// ```ignore (illustrative) . /// impl<'a> Foo { . /// // ^^ -- early bound, declared on an impl . /// -- line 1827 ---------------------------------------- -- line 1842 ---------------------------------------- . ty::ReEarlyBound(br) => tcx.parent(br.def_id), . ty::ReFree(fr) => fr.scope, . _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self), . } . } . . /// True for free regions other than `'static`. . pub fn is_free(self) -> bool { 720 (0.0%) matches!(*self, ty::ReEarlyBound(_) | ty::ReFree(_)) 360 (0.0%) } . . /// True if `self` is a free region or static. . pub fn is_free_or_static(self) -> bool { 3,240 (0.0%) match *self { . ty::ReStatic => true, . _ => self.is_free(), . } 540 (0.0%) } . . pub fn is_var(self) -> bool { . matches!(self.kind(), ty::ReVar(_)) . } . 38,758 (0.0%) pub fn as_var(self) -> RegionVid { 38,758 (0.0%) match self.kind() { . ty::ReVar(vid) => vid, . _ => bug!("expected region {:?} to be of kind ReVar", self), . } 38,758 (0.0%) } . } . . /// Constructors for `Ty` . impl<'tcx> Ty<'tcx> { . // Avoid this in favour of more specific `new_*` methods, where possible. . #[allow(rustc::usage_of_ty_tykind)] . #[inline] . pub fn new(tcx: TyCtxt<'tcx>, st: TyKind<'tcx>) -> Ty<'tcx> { . tcx.mk_ty_from_kind(st) . } . . #[inline] . pub fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferTy) -> Ty<'tcx> { 44,100 (0.0%) Ty::new(tcx, TyKind::Infer(infer)) . } . . #[inline] 84 (0.0%) pub fn new_var(tcx: TyCtxt<'tcx>, v: ty::TyVid) -> Ty<'tcx> { . // Use a pre-interned one when possible. . tcx.types . .ty_vars . .get(v.as_usize()) . .copied() 4,532,616 (0.0%) .unwrap_or_else(|| Ty::new(tcx, Infer(TyVar(v)))) 168 (0.0%) } . . #[inline] . pub fn new_int_var(tcx: TyCtxt<'tcx>, v: ty::IntVid) -> Ty<'tcx> { . Ty::new_infer(tcx, IntVar(v)) . } . . #[inline] . pub fn new_float_var(tcx: TyCtxt<'tcx>, v: ty::FloatVid) -> Ty<'tcx> { -- line 1903 ---------------------------------------- -- line 1931 ---------------------------------------- . .fresh_float_tys . .get(n as usize) . .copied() . .unwrap_or_else(|| Ty::new_infer(tcx, ty::FreshFloatTy(n))) . } . . #[inline] . pub fn new_param(tcx: TyCtxt<'tcx>, index: u32, name: Symbol) -> Ty<'tcx> { 67,672 (0.0%) tcx.mk_ty_from_kind(Param(ParamTy { index, name })) . } . . #[inline] . pub fn new_bound( . tcx: TyCtxt<'tcx>, . index: ty::DebruijnIndex, . bound_ty: ty::BoundTy, . ) -> Ty<'tcx> { 951 (0.0%) Ty::new(tcx, Bound(index, bound_ty)) . } . . #[inline] . pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderType) -> Ty<'tcx> { . Ty::new(tcx, Placeholder(placeholder)) . } . . #[inline] -- line 1956 ---------------------------------------- -- line 1960 ---------------------------------------- . alias_ty: ty::AliasTy<'tcx>, . ) -> Ty<'tcx> { . debug_assert_matches!( . (kind, tcx.def_kind(alias_ty.def_id)), . (ty::Opaque, DefKind::OpaqueTy) . | (ty::Projection | ty::Inherent, DefKind::AssocTy) . | (ty::Weak, DefKind::TyAlias) . ); 10,705 (0.0%) Ty::new(tcx, Alias(kind, alias_ty)) . } . . #[inline] . pub fn new_opaque(tcx: TyCtxt<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>) -> Ty<'tcx> { . Ty::new_alias(tcx, ty::Opaque, tcx.mk_alias_ty(def_id, args)) . } . . /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed` -- line 1976 ---------------------------------------- -- line 1994 ---------------------------------------- . ) -> Ty<'tcx> { . let reported = tcx.sess.delay_span_bug(span, msg); . Ty::new(tcx, Error(reported)) . } . . #[inline] . pub fn new_int(tcx: TyCtxt<'tcx>, i: ty::IntTy) -> Ty<'tcx> { . use ty::IntTy::*; 96 (0.0%) match i { . Isize => tcx.types.isize, 16 (0.0%) I8 => tcx.types.i8, . I16 => tcx.types.i16, . I32 => tcx.types.i32, . I64 => tcx.types.i64, . I128 => tcx.types.i128, . } . } . . #[inline] . pub fn new_uint(tcx: TyCtxt<'tcx>, ui: ty::UintTy) -> Ty<'tcx> { . use ty::UintTy::*; 8 (0.0%) match ui { 10 (0.0%) Usize => tcx.types.usize, . U8 => tcx.types.u8, . U16 => tcx.types.u16, . U32 => tcx.types.u32, . U64 => tcx.types.u64, . U128 => tcx.types.u128, . } . } . -- line 2024 ---------------------------------------- -- line 2028 ---------------------------------------- . match f { . F32 => tcx.types.f32, . F64 => tcx.types.f64, . } . } . . #[inline] . pub fn new_ref(tcx: TyCtxt<'tcx>, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> { 37,921 (0.0%) Ty::new(tcx, Ref(r, tm.ty, tm.mutbl)) . } . . #[inline] . pub fn new_mut_ref(tcx: TyCtxt<'tcx>, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { . Ty::new_ref(tcx, r, TypeAndMut { ty, mutbl: hir::Mutability::Mut }) . } . . #[inline] -- line 2044 ---------------------------------------- -- line 2058 ---------------------------------------- . . #[inline] . pub fn new_imm_ptr(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { . Ty::new_ptr(tcx, TypeAndMut { ty, mutbl: hir::Mutability::Not }) . } . . #[inline] . pub fn new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> { 25,354,732 (0.0%) Ty::new(tcx, Adt(def, args)) . } . . #[inline] . pub fn new_foreign(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> { . Ty::new(tcx, Foreign(def_id)) . } . . #[inline] . pub fn new_array(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> { 1,232 (0.0%) Ty::new(tcx, Array(ty, ty::Const::from_target_usize(tcx, n))) . } . . #[inline] . pub fn new_array_with_const_len( . tcx: TyCtxt<'tcx>, . ty: Ty<'tcx>, . ct: ty::Const<'tcx>, . ) -> Ty<'tcx> { 2,100 (0.0%) Ty::new(tcx, Array(ty, ct)) . } . . #[inline] . pub fn new_slice(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { 1,332 (0.0%) Ty::new(tcx, Slice(ty)) . } . . #[inline] . pub fn new_tup(tcx: TyCtxt<'tcx>, ts: &[Ty<'tcx>]) -> Ty<'tcx> { 90,223 (0.0%) if ts.is_empty() { tcx.types.unit } else { Ty::new(tcx, Tuple(tcx.mk_type_list(&ts))) } . } . . pub fn new_tup_from_iter(tcx: TyCtxt<'tcx>, iter: I) -> T::Output . where . I: Iterator, . T: CollectAndApply, Ty<'tcx>>, . { 45,051 (0.0%) T::collect_and_apply(iter, |ts| Ty::new_tup(tcx, ts)) . } . . #[inline] 1,682 (0.0%) pub fn new_fn_def( . tcx: TyCtxt<'tcx>, . def_id: DefId, . args: impl IntoIterator>>, . ) -> Ty<'tcx> { . let args = tcx.check_and_mk_args(def_id, args); 1,789 (0.0%) Ty::new(tcx, FnDef(def_id, args)) 1,279 (0.0%) } . . #[inline] . pub fn new_fn_ptr(tcx: TyCtxt<'tcx>, fty: PolyFnSig<'tcx>) -> Ty<'tcx> { 1,177 (0.0%) Ty::new(tcx, FnPtr(fty)) . } . . #[inline] . pub fn new_dynamic( . tcx: TyCtxt<'tcx>, . obj: &'tcx List>, . reg: ty::Region<'tcx>, . repr: DynKind, . ) -> Ty<'tcx> { 2,536 (0.0%) Ty::new(tcx, Dynamic(obj, reg, repr)) . } . . #[inline] 14 (0.0%) pub fn new_projection( . tcx: TyCtxt<'tcx>, . item_def_id: DefId, . args: impl IntoIterator>>, . ) -> Ty<'tcx> { . Ty::new_alias(tcx, ty::Projection, tcx.mk_alias_ty(item_def_id, args)) 10 (0.0%) } . . #[inline] . pub fn new_closure( . tcx: TyCtxt<'tcx>, . def_id: DefId, . closure_args: GenericArgsRef<'tcx>, . ) -> Ty<'tcx> { . debug_assert_eq!( . closure_args.len(), . tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 3, . "closure constructed with incorrect substitutions" . ); 116 (0.0%) Ty::new(tcx, Closure(def_id, closure_args)) . } . . #[inline] . pub fn new_generator( . tcx: TyCtxt<'tcx>, . def_id: DefId, . generator_args: GenericArgsRef<'tcx>, . movability: hir::Movability, -- line 2159 ---------------------------------------- -- line 2182 ---------------------------------------- . ) -> Ty<'tcx> { . Ty::new(tcx, GeneratorWitnessMIR(id, args)) . } . . // misc . . #[inline] . pub fn new_unit(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 75 (0.0%) tcx.types.unit . } . . #[inline] . pub fn new_static_str(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 292 (0.0%) Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, tcx.types.str_) . } . . #[inline] . pub fn new_diverging_default(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { . if tcx.features().never_type_fallback { tcx.types.never } else { tcx.types.unit } . } . . // lang and diagnostic tys -- line 2203 ---------------------------------------- -- line 2261 ---------------------------------------- . . #[inline(always)] . pub fn flags(self) -> TypeFlags { . self.0.0.flags . } . . #[inline] . pub fn is_unit(self) -> bool { 477 (0.0%) match self.kind() { . Tuple(ref tys) => tys.is_empty(), . _ => false, . } . } . . #[inline] . pub fn is_never(self) -> bool { 2,434 (0.0%) matches!(self.kind(), Never) . } . . #[inline] . pub fn is_primitive(self) -> bool { . self.kind().is_primitive() . } . . #[inline] -- line 2285 ---------------------------------------- -- line 2289 ---------------------------------------- . . #[inline] . pub fn is_ref(self) -> bool { . matches!(self.kind(), Ref(..)) . } . . #[inline] . pub fn is_ty_var(self) -> bool { 153,773 (0.0%) matches!(self.kind(), Infer(TyVar(_))) . } . . #[inline] . pub fn ty_vid(self) -> Option { 408,170 (0.0%) match self.kind() { 4 (0.0%) &Infer(TyVar(vid)) => Some(vid), . _ => None, . } . } . . #[inline] . pub fn is_ty_or_numeric_infer(self) -> bool { . matches!(self.kind(), Infer(_)) . } . . #[inline] . pub fn is_phantom_data(self) -> bool { 61 (0.0%) if let Adt(def, _) = self.kind() { def.is_phantom_data() } else { false } . } . . #[inline] . pub fn is_bool(self) -> bool { 208 (0.0%) *self.kind() == Bool . } . . /// Returns `true` if this type is a `str`. . #[inline] . pub fn is_str(self) -> bool { . *self.kind() == Str . } . . #[inline] . pub fn is_param(self, index: u32) -> bool { 338 (0.0%) match self.kind() { . ty::Param(ref data) => data.index == index, . _ => false, . } . } . . #[inline] . pub fn is_slice(self) -> bool { . matches!(self.kind(), Slice(_)) -- line 2339 ---------------------------------------- -- line 2356 ---------------------------------------- . #[inline] . pub fn is_simd(self) -> bool { . match self.kind() { . Adt(def, _) => def.repr().simd(), . _ => false, . } . } . 154 (0.0%) pub fn sequence_element_type(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 539 (0.0%) match self.kind() { 154 (0.0%) Array(ty, _) | Slice(ty) => *ty, . Str => tcx.types.u8, . _ => bug!("`sequence_element_type` called on non-sequence value: {}", self), . } 154 (0.0%) } . . pub fn simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) { . match self.kind() { . Adt(def, args) => { . assert!(def.repr().simd(), "`simd_size_and_type` called on non-SIMD type"); . let variant = def.non_enum_variant(); . let f0_ty = variant.fields[FieldIdx::from_u32(0)].ty(tcx, args); . -- line 2378 ---------------------------------------- -- line 2410 ---------------------------------------- . match self.kind() { . Ref(_, _, mutability) => Some(*mutability), . _ => None, . } . } . . #[inline] . pub fn is_unsafe_ptr(self) -> bool { 3 (0.0%) matches!(self.kind(), RawPtr(_)) . } . . /// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer). . #[inline] . pub fn is_any_ptr(self) -> bool { . self.is_ref() || self.is_unsafe_ptr() || self.is_fn_ptr() . } . . #[inline] . pub fn is_box(self) -> bool { 12,054 (0.0%) match self.kind() { 2,851 (0.0%) Adt(def, _) => def.is_box(), . _ => false, . } . } . . /// Panics if called on any type other than `Box`. . pub fn boxed_ty(self) -> Ty<'tcx> { . match self.kind() { . Adt(def, args) if def.is_box() => args.type_at(0), -- line 2438 ---------------------------------------- -- line 2440 ---------------------------------------- . } . } . . /// A scalar type is one that denotes an atomic datum, with no sub-components. . /// (A RawPtr is scalar because it represents a non-managed pointer, so its . /// contents are abstract to rustc.) . #[inline] . pub fn is_scalar(self) -> bool { 258 (0.0%) matches!( 610 (0.0%) self.kind(), . Bool | Char . | Int(_) . | Float(_) . | Uint(_) . | FnDef(..) . | FnPtr(_) . | RawPtr(_) . | Infer(IntVar(_) | FloatVar(_)) -- line 2457 ---------------------------------------- -- line 2476 ---------------------------------------- . . #[inline] . pub fn is_enum(self) -> bool { . matches!(self.kind(), Adt(adt_def, _) if adt_def.is_enum()) . } . . #[inline] . pub fn is_union(self) -> bool { 1,008 (0.0%) matches!(self.kind(), Adt(adt_def, _) if adt_def.is_union()) . } . . #[inline] . pub fn is_closure(self) -> bool { 179 (0.0%) matches!(self.kind(), Closure(..)) . } . . #[inline] . pub fn is_generator(self) -> bool { . matches!(self.kind(), Generator(..)) . } . . #[inline] . pub fn is_integral(self) -> bool { 728 (0.0%) matches!(self.kind(), Infer(IntVar(_)) | Int(_) | Uint(_)) . } . . #[inline] . pub fn is_fresh_ty(self) -> bool { . matches!(self.kind(), Infer(FreshTy(_))) . } . . #[inline] . pub fn is_fresh(self) -> bool { 210,627 (0.0%) matches!(self.kind(), Infer(FreshTy(_) | FreshIntTy(_) | FreshFloatTy(_))) . } . . #[inline] . pub fn is_char(self) -> bool { 52 (0.0%) matches!(self.kind(), Char) . } . . #[inline] . pub fn is_numeric(self) -> bool { . self.is_integral() || self.is_floating_point() . } . . #[inline] . pub fn is_signed(self) -> bool { . matches!(self.kind(), Int(_)) . } . . #[inline] . pub fn is_ptr_sized_integral(self) -> bool { 56 (0.0%) matches!(self.kind(), Int(ty::IntTy::Isize) | Uint(ty::UintTy::Usize)) . } . . #[inline] . pub fn has_concrete_skeleton(self) -> bool { . !matches!(self.kind(), Param(_) | Infer(_) | Error(_)) . } . . /// Checks whether a type recursively contains another type -- line 2537 ---------------------------------------- -- line 2573 ---------------------------------------- . let cf = self.visit_with(&mut ContainsClosureVisitor); . cf.is_break() . } . . /// Returns the type and mutability of `*ty`. . /// . /// The parameter `explicit` indicates if this is an *explicit* dereference. . /// Some types -- notably unsafe ptrs -- can only be dereferenced explicitly. 1,304 (0.0%) pub fn builtin_deref(self, explicit: bool) -> Option> { 11,417 (0.0%) match self.kind() { 28 (0.0%) Adt(def, _) if def.is_box() => { . Some(TypeAndMut { ty: self.boxed_ty(), mutbl: hir::Mutability::Not }) . } 9,993 (0.0%) Ref(_, ty, mutbl) => Some(TypeAndMut { ty: *ty, mutbl: *mutbl }), . RawPtr(mt) if explicit => Some(*mt), . _ => None, . } 2,608 (0.0%) } . . /// Returns the type of `ty[i]`. . pub fn builtin_index(self) -> Option> { . match self.kind() { . Array(ty, _) | Slice(ty) => Some(*ty), . _ => None, . } . } . 10,736 (0.0%) pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> { 5,368 (0.0%) match self.kind() { 4,026 (0.0%) FnDef(def_id, args) => tcx.fn_sig(*def_id).instantiate(tcx, args), . FnPtr(f) => *f, . Error(_) => { . // ignore errors (#54954) . ty::Binder::dummy(FnSig::fake()) . } . Closure(..) => bug!( . "to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`", . ), . _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self), . } 12,078 (0.0%) } . . #[inline] . pub fn is_fn(self) -> bool { 60 (0.0%) matches!(self.kind(), FnDef(..) | FnPtr(_)) . } . . #[inline] . pub fn is_fn_ptr(self) -> bool { . matches!(self.kind(), FnPtr(_)) . } . . #[inline] . pub fn is_impl_trait(self) -> bool { . matches!(self.kind(), Alias(ty::Opaque, ..)) . } . . #[inline] . pub fn ty_adt_def(self) -> Option> { 658 (0.0%) match self.kind() { 482 (0.0%) Adt(adt, _) => Some(*adt), . _ => None, . } . } . . /// Iterates over tuple fields. . /// Panics when called on anything but a tuple. . #[inline] . pub fn tuple_fields(self) -> &'tcx List> { 6 (0.0%) match self.kind() { 3 (0.0%) Tuple(args) => args, . _ => bug!("tuple_fields called on non-tuple"), . } . } . . /// If the type contains variants, returns the valid range of variant indices. . // . // FIXME: This requires the optimized MIR in the case of generators. . #[inline] -- line 2651 ---------------------------------------- -- line 2676 ---------------------------------------- . TyKind::Generator(def_id, args, _) => { . Some(args.as_generator().discriminant_for_variant(*def_id, tcx, variant_index)) . } . _ => None, . } . } . . /// Returns the type of the discriminant of this type. 1,180 (0.0%) pub fn discriminant_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 590 (0.0%) match self.kind() { 944 (0.0%) ty::Adt(adt, _) if adt.is_enum() => adt.repr().discr_type().to_ty(tcx), . ty::Generator(_, args, _) => args.as_generator().discr_ty(tcx), . . ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => { . let assoc_items = tcx.associated_item_def_ids( . tcx.require_lang_item(hir::LangItem::DiscriminantKind, None), . ); . Ty::new_projection(tcx, assoc_items[0], tcx.mk_args(&[self.into()])) . } -- line 2694 ---------------------------------------- -- line 2717 ---------------------------------------- . | ty::Infer(IntVar(_) | FloatVar(_)) => tcx.types.u8, . . ty::Bound(..) . | ty::Placeholder(_) . | ty::Infer(FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { . bug!("`discriminant_ty` applied to unexpected type: {:?}", self) . } . } 944 (0.0%) } . . /// Returns the type of metadata for (potentially fat) pointers to this type, . /// and a boolean signifying if this is conditional on this type being `Sized`. 14 (0.0%) pub fn ptr_metadata_ty( . self, . tcx: TyCtxt<'tcx>, . normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>, . ) -> (Ty<'tcx>, bool) { 8 (0.0%) let tail = tcx.struct_tail_with_normalize(self, normalize, || {}); 10 (0.0%) match tail.kind() { . // Sized types . ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) . | ty::Uint(_) . | ty::Int(_) . | ty::Bool . | ty::Float(_) . | ty::FnDef(..) . | ty::FnPtr(_) -- line 2743 ---------------------------------------- -- line 2753 ---------------------------------------- . | ty::Error(_) . // Extern types have metadata = (). . | ty::Foreign(..) . // If returned by `struct_tail_without_normalization` this is a unit struct . // without any fields, or not a struct, and therefore is Sized. . | ty::Adt(..) . // If returned by `struct_tail_without_normalization` this is the empty tuple, . // a.k.a. unit type, which is Sized 1 (0.0%) | ty::Tuple(..) => (tcx.types.unit, false), . . ty::Str | ty::Slice(_) => (tcx.types.usize, false), . ty::Dynamic(..) => { 6 (0.0%) let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None); 1 (0.0%) (tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()]), false) . }, . . // type parameters only have unit metadata if they're sized, so return true . // to make sure we double check this during confirmation . ty::Param(_) | ty::Alias(..) => (tcx.types.unit, true), . . ty::Infer(ty::TyVar(_)) . | ty::Bound(..) . | ty::Placeholder(..) . | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { . bug!("`ptr_metadata_ty` applied to unexpected type: {:?} (tail = {:?})", self, tail) . } . } 12 (0.0%) } . . /// When we create a closure, we record its kind (i.e., what trait . /// it implements) into its `ClosureArgs` using a type . /// parameter. This is kind of a phantom type, except that the . /// most convenient thing for us to are the integral types. This . /// function converts such a special type into the closure . /// kind. To go the other way, use `closure_kind.to_ty(tcx)`. . /// . /// Note that during type checking, we use an inference variable . /// to represent the closure kind, because it has not yet been . /// inferred. Once upvar inference (in `rustc_hir_analysis/src/check/upvar.rs`) . /// is complete, that type variable will be unified. 38 (0.0%) pub fn to_opt_closure_kind(self) -> Option { 76 (0.0%) match self.kind() { 76 (0.0%) Int(int_ty) => match int_ty { . ty::IntTy::I8 => Some(ty::ClosureKind::Fn), . ty::IntTy::I16 => Some(ty::ClosureKind::FnMut), . ty::IntTy::I32 => Some(ty::ClosureKind::FnOnce), . _ => bug!("cannot convert type `{:?}` to a closure kind", self), . }, . . // "Bound" types appear in canonical queries when the . // closure type is not yet known . Bound(..) | Infer(_) => None, . . Error(_) => Some(ty::ClosureKind::Fn), . . _ => bug!("cannot convert type `{:?}` to a closure kind", self), . } 38 (0.0%) } . . /// Fast path helper for testing if a type is `Sized`. . /// . /// Returning true means the type is known to be sized. Returning . /// `false` means nothing -- could be sized, might not be. . /// . /// Note that we could never rely on the fact that a type such as `[_]` is . /// trivially `!Sized` because we could be in a type environment with a . /// bound such as `[_]: Copy`. A function with such a bound obviously never . /// can be called, but that doesn't mean it shouldn't typecheck. This is why . /// this method doesn't return `Option`. 30,420 (0.0%) pub fn is_trivially_sized(self, tcx: TyCtxt<'tcx>) -> bool { 20,280 (0.0%) match self.kind() { . ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) . | ty::Uint(_) . | ty::Int(_) . | ty::Bool . | ty::Float(_) . | ty::FnDef(..) . | ty::FnPtr(_) . | ty::RawPtr(..) -- line 2831 ---------------------------------------- -- line 2836 ---------------------------------------- . | ty::GeneratorWitnessMIR(..) . | ty::Array(..) . | ty::Closure(..) . | ty::Never . | ty::Error(_) => true, . . ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => false, . 190 (0.0%) ty::Tuple(tys) => tys.iter().all(|ty| ty.is_trivially_sized(tcx)), . 559 (0.0%) ty::Adt(def, _args) => def.sized_constraint(tcx).skip_binder().is_empty(), . . ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => false, . . ty::Infer(ty::TyVar(_)) => false, . . ty::Bound(..) | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { . bug!("`is_trivially_sized` applied to unexpected type: {:?}", self) . } . } 30,420 (0.0%) } . . /// Fast path helper for primitives which are always `Copy` and which . /// have a side-effect-free `Clone` impl. . /// . /// Returning true means the type is known to be pure and `Copy+Clone`. . /// Returning `false` means nothing -- could be `Copy`, might not be. . /// . /// This is mostly useful for optimizations, as there are the types . /// on which we can replace cloning with dereferencing. 1,750 (0.0%) pub fn is_trivially_pure_clone_copy(self) -> bool { 1,250 (0.0%) match self.kind() { . ty::Bool | ty::Char | ty::Never => true, . . // These aren't even `Clone` . ty::Str | ty::Slice(..) | ty::Foreign(..) | ty::Dynamic(..) => false, . . ty::Infer(ty::InferTy::FloatVar(_) | ty::InferTy::IntVar(_)) . | ty::Int(..) . | ty::Uint(..) -- line 2875 ---------------------------------------- -- line 2877 ---------------------------------------- . . // The voldemort ZSTs are fine. . ty::FnDef(..) => true, . . ty::Array(element_ty, _len) => element_ty.is_trivially_pure_clone_copy(), . . // A 100-tuple isn't "trivial", so doing this only for reasonable sizes. . ty::Tuple(field_tys) => { 96 (0.0%) field_tys.len() <= 3 && field_tys.iter().all(Self::is_trivially_pure_clone_copy) . } . . // Sometimes traits aren't implemented for every ABI or arity, . // because we can't be generic over everything yet. . ty::FnPtr(..) => false, . . // Definitely absolutely not copy. . ty::Ref(_, _, hir::Mutability::Mut) => false, -- line 2893 ---------------------------------------- -- line 2905 ---------------------------------------- . ty::Alias(..) => false, . . ty::Param(..) | ty::Infer(..) | ty::Error(..) => false, . . ty::Bound(..) | ty::Placeholder(..) => { . bug!("`is_trivially_pure_clone_copy` applied to unexpected type: {:?}", self); . } . } 2,000 (0.0%) } . . /// If `self` is a primitive, return its [`Symbol`]. . pub fn primitive_symbol(self) -> Option { . match self.kind() { . ty::Bool => Some(sym::bool), . ty::Char => Some(sym::char), . ty::Float(f) => match f { . ty::FloatTy::F32 => Some(sym::f32), -- line 2921 ---------------------------------------- -- line 2974 ---------------------------------------- . }, . } . . impl<'tcx> VarianceDiagInfo<'tcx> { . /// Mirrors `Variance::xform` - used to 'combine' the existing . /// and new `VarianceDiagInfo`s when our variance changes. . pub fn xform(self, other: VarianceDiagInfo<'tcx>) -> VarianceDiagInfo<'tcx> { . // For now, just use the first `VarianceDiagInfo::Invariant` that we see 2,702 (0.0%) match self { . VarianceDiagInfo::None => other, . VarianceDiagInfo::Invariant { .. } => self, . } 2,702 (0.0%) } . } . . // Some types are used a lot. Make sure they don't unintentionally get bigger. . #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] . mod size_asserts { . use super::*; . use rustc_data_structures::static_assert_size; . // tidy-alphabetical-start -- line 2994 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_query_system/src/cache.rs -------------------------------------------------------------------------------- Ir________________ 42,474,998 (0.0%) -- line 14 ---------------------------------------- . impl Clone for Cache { . fn clone(&self) -> Self { . Self { hashmap: Lock::new(self.hashmap.borrow().clone()) } . } . } . . impl Default for Cache { . fn default() -> Self { 85,136 (0.0%) Self { hashmap: Default::default() } . } . } . . impl Cache { . /// Actually frees the underlying memory in contrast to what stdlib containers do on `clear` . pub fn clear(&self) { . *self.hashmap.borrow_mut() = Default::default(); . } . } . . impl Cache { 152,115,902 (0.1%) pub fn get(&self, key: &Key, tcx: Tcx) -> Option { 46,037,922 (0.0%) Some(self.hashmap.borrow().get(key)?.get(tcx)) 238,149,960 (0.1%) } . 1,061,664 (0.0%) pub fn insert(&self, key: Key, dep_node: DepNodeIndex, value: Value) { 1,833,540 (0.0%) self.hashmap.borrow_mut().insert(key, WithDepNode::new(dep_node, value)); 1,174,057 (0.0%) } . } . . #[derive(Clone, Eq, PartialEq)] . pub struct WithDepNode { . dep_node: DepNodeIndex, . cached_value: T, . } . . impl WithDepNode { . pub fn new(dep_node: DepNodeIndex, cached_value: T) -> Self { 579,588 (0.0%) WithDepNode { dep_node, cached_value } . } . . pub fn get(&self, tcx: Tcx) -> T { 42,277,662 (0.0%) tcx.dep_graph().read_index(self.dep_node); . self.cached_value.clone() . } . } -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_span/src/def_id.rs -------------------------------------------------------------------------------- Ir__________________ 47,850 (0.0%) -- line 7 ---------------------------------------- . use rustc_macros::HashStable_Generic; . use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; . use std::fmt; . use std::hash::{BuildHasherDefault, Hash, Hasher}; . . pub type StableCrateIdMap = . indexmap::IndexMap>; . 2,099,258 (0.0%) rustc_index::newtype_index! { . #[custom_encodable] . #[debug_format = "crate{}"] . pub struct CrateNum {} . } . . /// Item definitions in the currently-compiled crate would have the `CrateNum` . /// `LOCAL_CRATE` in their `DefId`. . pub const LOCAL_CRATE: CrateNum = CrateNum::from_u32(0); -- line 23 ---------------------------------------- -- line 141 ---------------------------------------- . /// see the discussion in [`DefId`]. . #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] . #[derive(Hash, HashStable_Generic, Encodable, Decodable)] . pub struct StableCrateId(pub(crate) Hash64); . . impl StableCrateId { . /// Computes the stable ID for a crate with the given name and . /// `-Cmetadata` arguments. 12 (0.0%) pub fn new( . crate_name: Symbol, . is_exe: bool, . mut metadata: Vec, . cfg_version: &'static str, . ) -> StableCrateId { . let mut hasher = StableHasher::new(); . // We must hash the string text of the crate name, not the id, as the id is not stable . // across builds. -- line 157 ---------------------------------------- -- line 169 ---------------------------------------- . // different values for `-Cmetadata=ab -Cmetadata=c` and . // `-Cmetadata=a -Cmetadata=bc` . hasher.write_usize(s.len()); . hasher.write(s.as_bytes()); . } . . // 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. 5 (0.0%) hasher.write(if is_exe { b"exe" } else { b"lib" }); . . // Also incorporate the rustc version. Otherwise, with -Zsymbol-mangling-version=v0 . // and no -Cmetadata, symbols from the same crate compiled with different versions of . // rustc are named the same. . // . // RUSTC_FORCE_RUSTC_VERSION is used to inject rustc version information . // during testing. 6 (0.0%) if let Some(val) = std::env::var_os("RUSTC_FORCE_RUSTC_VERSION") { . hasher.write(val.to_string_lossy().into_owned().as_bytes()) . } else { . hasher.write(cfg_version.as_bytes()) . } . 18 (0.0%) StableCrateId(hasher.finish()) 8 (0.0%) } . . #[inline] . pub fn as_u64(self) -> u64 { . self.0.as_u64() . } . } . . impl fmt::LowerHex for StableCrateId { . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { . fmt::LowerHex::fmt(&self.0, f) . } . } . 5,271,519,781 (2.2%) rustc_index::newtype_index! { . /// A DefIndex is an index into the hir-map for a crate, identifying a . /// particular definition. It should really be considered an interned . /// shorthand for a particular DefPath. . #[custom_encodable] // (only encodable in metadata) . #[debug_format = "DefIndex({})"] . pub struct DefIndex { . /// The crate root is always assigned index 0 by the AST Map code, . /// thanks to `NodeCollector::new`. -- line 214 ---------------------------------------- -- line 227 ---------------------------------------- . panic!("cannot decode `DefIndex` with `{}`", std::any::type_name::()); . } . } . . /// A `DefId` identifies a particular *definition*, by combining a crate . /// index and a def index. . /// . /// You can create a `DefId` from a `LocalDefId` using `local_def_id.to_def_id()`. 5,335,597,011 (2.2%) #[derive(Clone, PartialEq, Eq, Copy)] . // Don't derive order on 64-bit big-endian, so we can be consistent regardless of field order. . #[cfg_attr(not(all(target_pointer_width = "64", target_endian = "big")), derive(PartialOrd, Ord))] . // On below-64 bit systems we can simply use the derived `Hash` impl . #[cfg_attr(not(target_pointer_width = "64"), derive(Hash))] . #[repr(C)] . #[rustc_pass_by_value] . // We guarantee field order. Note that the order is essential here, see below why. . pub struct DefId { . // cfg-ing the order of fields so that the `DefIndex` which is high entropy always ends up in . // the lower bits no matter the endianness. This allows the compiler to turn that `Hash` impl . // into a direct call to `u64::hash(_)`. . #[cfg(not(all(target_pointer_width = "64", target_endian = "big")))] 92 (0.0%) pub index: DefIndex, 340,545 (0.0%) pub krate: CrateNum, . #[cfg(all(target_pointer_width = "64", target_endian = "big"))] . pub index: DefIndex, . } . . // On 64-bit systems, we can hash the whole `DefId` as one `u64` instead of two `u32`s. This . // improves performance without impairing `FxHash` quality. So the below code gets compiled to a . // noop on little endian systems because the memory layout of `DefId` is as follows: . // -- line 257 ---------------------------------------- -- line 267 ---------------------------------------- . // is used throughout rustc, has problems distributing the entropy from the high bits, so reversing . // the order would lead to a large number of collisions and thus far worse performance. . // . // On 64-bit big-endian systems, this compiles to a 64-bit rotation by 32 bits, which is still . // faster than another `FxHash` round. . #[cfg(target_pointer_width = "64")] . impl Hash for DefId { . fn hash(&self, h: &mut H) { 24,832,797 (0.0%) (((self.krate.as_u32() as u64) << 32) | (self.index.as_u32() as u64)).hash(h) . } . } . . // Implement the same comparison as derived with the other field order. . #[cfg(all(target_pointer_width = "64", target_endian = "big"))] . impl Ord for DefId { . #[inline] . fn cmp(&self, other: &DefId) -> std::cmp::Ordering { -- line 283 ---------------------------------------- -- line 307 ---------------------------------------- . . #[inline] . pub fn as_local(self) -> Option { . self.is_local().then(|| LocalDefId { local_def_index: self.index }) . } . . #[inline] . #[track_caller] 41,736 (0.0%) pub fn expect_local(self) -> LocalDefId { . // NOTE: `match` below is required to apply `#[track_caller]`, . // i.e. don't use closures. 68,338 (0.0%) match self.as_local() { . Some(local_def_id) => local_def_id, . None => panic!("DefId::expect_local: `{self:?}` isn't local"), . } 41,736 (0.0%) } . . #[inline] . pub fn is_crate_root(self) -> bool { . self.index == CRATE_DEF_INDEX . } . . #[inline] . pub fn as_crate_root(self) -> Option { -- line 330 ---------------------------------------- -- line 333 ---------------------------------------- . . #[inline] . pub fn is_top_level_module(self) -> bool { . self.is_local() && self.is_crate_root() . } . } . . impl From for DefId { 165,946 (0.0%) fn from(local: LocalDefId) -> DefId { . local.to_def_id() . } . } . . impl Encodable for DefId { . default fn encode(&self, s: &mut E) { . self.krate.encode(s); . self.index.encode(s); . } . } . . impl Decodable for DefId { 82,460 (0.0%) default fn decode(d: &mut D) -> DefId { 82,460 (0.0%) DefId { krate: Decodable::decode(d), index: Decodable::decode(d) } 82,460 (0.0%) } . } . . pub fn default_def_id_debug(def_id: DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result { . f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish() . } . . pub static DEF_ID_DEBUG: AtomicRef) -> fmt::Result> = . AtomicRef::new(&(default_def_id_debug as fn(_, &mut fmt::Formatter<'_>) -> _)); -- line 364 ---------------------------------------- -- line 372 ---------------------------------------- . rustc_data_structures::define_id_collections!(DefIdMap, DefIdSet, DefIdMapEntry, DefId); . . /// A `LocalDefId` is equivalent to a `DefId` with `krate == LOCAL_CRATE`. Since . /// we encode this information in the type, we can ensure at compile time that . /// no `DefId`s from upstream crates get thrown into the mix. There are quite a . /// few cases where we know that only `DefId`s from the local crate are expected; . /// a `DefId` from a different crate would signify a bug somewhere. This . /// is when `LocalDefId` comes in handy. 312,048,327 (0.1%) #[derive(Clone, Copy, PartialEq, Eq, Hash)] . pub struct LocalDefId { . pub local_def_index: DefIndex, . } . . // To ensure correctness of incremental compilation, . // `LocalDefId` must not implement `Ord` or `PartialOrd`. . // See https://github.com/rust-lang/rust/issues/90317. . impl !Ord for LocalDefId {} -- line 388 ---------------------------------------- -- line 399 ---------------------------------------- . fn index(self) -> usize { . self.local_def_index.index() . } . } . . impl LocalDefId { . #[inline] . pub fn to_def_id(self) -> DefId { 43,498 (0.0%) DefId { krate: LOCAL_CRATE, index: self.local_def_index } . } . . #[inline] . pub fn is_top_level_module(self) -> bool { . self == CRATE_DEF_ID . } . } . -- line 415 ---------------------------------------- -- line 459 ---------------------------------------- . } . } . . impl ToStableHashKey for DefId { . type KeyType = DefPathHash; . . #[inline] . fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash { 1,900 (0.0%) hcx.def_path_hash(*self) . } . } . . impl ToStableHashKey for LocalDefId { . type KeyType = DefPathHash; . . #[inline] . fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash { -- line 475 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_span/src/span_encoding.rs -------------------------------------------------------------------------------- Ir__________________ 1,661,667,290 (0.7%) -- line 66 ---------------------------------------- . /// `ctxt` values depend partly on the crate size and partly on the form of . /// the code. No crates in `rustc-perf` need more than 15 bits for `ctxt_or_tag`, . /// but larger crates might need more than 16 bits. . /// . /// In order to reliably use parented spans in incremental compilation, . /// the dependency to the parent definition's span. This is performed . /// using the callback `SPAN_TRACK` to access the query engine. . /// 8,657,431,432 (3.6%) #[derive(Clone, Copy, Eq, PartialEq, Hash)] . #[rustc_pass_by_value] . pub struct Span { 3 (0.0%) base_or_index: u32, . len_or_tag: u16, 12 (0.0%) ctxt_or_tag: u16, . } . . const LEN_TAG: u16 = 0b1111_1111_1111_1111; . const PARENT_MASK: u16 = 0b1000_0000_0000_0000; . const MAX_LEN: u32 = 0b0111_1111_1111_1111; . const CTXT_TAG: u32 = 0b1111_1111_1111_1111; . const MAX_CTXT: u32 = CTXT_TAG - 1; . . /// Dummy span, both position and length are zero, syntax context is zero as well. . pub const DUMMY_SP: Span = Span { base_or_index: 0, len_or_tag: 0, ctxt_or_tag: 0 }; . . impl Span { . #[inline] 42 (0.0%) pub fn new( . mut lo: BytePos, . mut hi: BytePos, . ctxt: SyntaxContext, . parent: Option, . ) -> Self { . if lo > hi { . std::mem::swap(&mut lo, &mut hi); . } . 59,253 (0.0%) let (base, len, ctxt2) = (lo.0, hi.0 - lo.0, ctxt.as_u32()); . 779,885 (0.0%) if len <= MAX_LEN && ctxt2 <= MAX_CTXT { . let len_or_tag = len as u16; . debug_assert_eq!(len_or_tag & PARENT_MASK, 0); . 274,796 (0.0%) if let Some(parent) = parent { . // Inline format with parent. . let len_or_tag = len_or_tag | PARENT_MASK; . let parent2 = parent.local_def_index.as_u32(); . if ctxt2 == SyntaxContext::root().as_u32() . && parent2 <= MAX_CTXT . && len_or_tag < LEN_TAG . { . debug_assert_ne!(len_or_tag, LEN_TAG); -- line 117 ---------------------------------------- -- line 125 ---------------------------------------- . len_or_tag: len as u16, . ctxt_or_tag: ctxt2 as u16, . }; . } . } . . // Interned format. . let index = 174 (0.0%) with_span_interner(|interner| interner.intern(&SpanData { lo, hi, ctxt, parent })); 72 (0.0%) let ctxt_or_tag = if ctxt2 <= MAX_CTXT { ctxt2 } else { CTXT_TAG } as u16; . Span { base_or_index: index, len_or_tag: LEN_TAG, ctxt_or_tag } 1,172,550 (0.0%) } . . #[inline] . pub fn data(self) -> SpanData { 398 (0.0%) let data = self.data_untracked(); 609 (0.0%) if let Some(parent) = data.parent { . (*SPAN_TRACK)(parent); . } 717,971 (0.0%) data . } . . /// Internal function to translate between an encoded span and the expanded representation. . /// This function must not be used outside the incremental engine. . #[inline] 627 (0.0%) pub fn data_untracked(self) -> SpanData { 853,546 (0.0%) if self.len_or_tag != LEN_TAG { . // Inline format. 944,420 (0.0%) if self.len_or_tag & PARENT_MASK == 0 { . debug_assert!(self.len_or_tag as u32 <= MAX_LEN); 1,088,504 (0.0%) SpanData { . lo: BytePos(self.base_or_index), 541,133 (0.0%) hi: BytePos(self.base_or_index + self.len_or_tag as u32), . ctxt: SyntaxContext::from_u32(self.ctxt_or_tag as u32), . parent: None, . } . } else { . let len = self.len_or_tag & !PARENT_MASK; . debug_assert!(len as u32 <= MAX_LEN); . let parent = . LocalDefId { local_def_index: DefIndex::from_u32(self.ctxt_or_tag as u32) }; -- line 165 ---------------------------------------- -- line 170 ---------------------------------------- . parent: Some(parent), . } . } . } else { . // Interned format. . let index = self.base_or_index; . with_span_interner(|interner| interner.spans[index as usize]) . } 418 (0.0%) } . . /// This function is used as a fast path when decoding the full `SpanData` is not necessary. . #[inline] . pub fn ctxt(self) -> SyntaxContext { . let ctxt_or_tag = self.ctxt_or_tag as u32; . // Check for interned format. 337,786 (0.0%) if self.len_or_tag == LEN_TAG { . if ctxt_or_tag == CTXT_TAG { . // Fully interned format. . let index = self.base_or_index; . with_span_interner(|interner| interner.spans[index as usize].ctxt) . } else { . // Interned format with inline ctxt. . SyntaxContext::from_u32(ctxt_or_tag) . } 114,420 (0.0%) } else if self.len_or_tag & PARENT_MASK == 0 { . // Inline format with inline ctxt. . SyntaxContext::from_u32(ctxt_or_tag) . } else { . // Inline format with inline parent. . // We know that the SyntaxContext is root. . SyntaxContext::root() . } . } -- line 202 ---------------------------------------- -- line 203 ---------------------------------------- . } . . #[derive(Default)] . pub struct SpanInterner { . spans: FxIndexSet, . } . . impl SpanInterner { 17 (0.0%) fn intern(&mut self, span_data: &SpanData) -> u32 { 56 (0.0%) let (index, _) = self.spans.insert_full(*span_data); . index as u32 34 (0.0%) } . } . . // If an interner exists, return it. Otherwise, prepare a fresh one. . #[inline] . fn with_span_interner T>(f: F) -> T { 126 (0.0%) crate::with_session_globals(|session_globals| f(&mut session_globals.span_interner.lock())) . } -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_trait_selection/src/traits/select/confirmation.rs -------------------------------------------------------------------------------- Ir________________ 683,692 (0.0%) -- line 34 ---------------------------------------- . use super::BuiltinImplConditions; . use super::SelectionCandidate::{self, *}; . use super::SelectionContext; . . use std::iter; . use std::ops::ControlFlow; . . impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 6,958,066 (0.0%) #[instrument(level = "debug", skip(self))] . pub(super) fn confirm_candidate( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . candidate: SelectionCandidate<'tcx>, . ) -> Result, SelectionError<'tcx>> { 4,028,354 (0.0%) let mut impl_src = match candidate { 46,923 (0.0%) BuiltinCandidate { has_nested } => { . let data = self.confirm_builtin_candidate(obligation, has_nested); 62,564 (0.0%) ImplSource::Builtin(BuiltinImplSource::Misc, data) . } . . TransmutabilityCandidate => { . let data = self.confirm_transmutability_candidate(obligation)?; . ImplSource::Builtin(BuiltinImplSource::Misc, data) . } . 42,250 (0.0%) ParamCandidate(param) => { . let obligations = . self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref)); 42,250 (0.0%) ImplSource::Param(param.skip_binder().constness, obligations) . } . 2,727,128 (0.0%) ImplCandidate(impl_def_id) => { 4,431,583 (0.0%) ImplSource::UserDefined(self.confirm_impl_candidate(obligation, impl_def_id)) . } . . AutoImplCandidate => { . let data = self.confirm_auto_impl_candidate(obligation)?; . ImplSource::Builtin(BuiltinImplSource::Misc, data) . } . 3,024 (0.0%) ProjectionCandidate(idx, constness) => { . let obligations = self.confirm_projection_candidate(obligation, idx)?; 5,040 (0.0%) ImplSource::Param(constness, obligations) . } . . ObjectCandidate(idx) => self.confirm_object_candidate(obligation, idx)?, . . ClosureCandidate { .. } => { 14 (0.0%) let vtable_closure = self.confirm_closure_candidate(obligation)?; 56 (0.0%) ImplSource::Builtin(BuiltinImplSource::Misc, vtable_closure) . } . . GeneratorCandidate => { . let vtable_generator = self.confirm_generator_candidate(obligation)?; . ImplSource::Builtin(BuiltinImplSource::Misc, vtable_generator) . } . . FutureCandidate => { -- line 91 ---------------------------------------- -- line 105 ---------------------------------------- . . BuiltinObjectCandidate => { . // This indicates something like `Trait + Send: Send`. In this case, we know that . // this holds because that's what the object type is telling us, and there's really . // no additional obligations to prove and no types in particular to unify, etc. . ImplSource::Builtin(BuiltinImplSource::Misc, Vec::new()) . } . 960 (0.0%) BuiltinUnsizeCandidate => self.confirm_builtin_unsize_candidate(obligation)?, . . TraitUpcastingUnsizeCandidate(idx) => { . self.confirm_trait_upcasting_unsize_candidate(obligation, idx)? . } . . ConstDestructCandidate(def_id) => { . let data = self.confirm_const_destruct_candidate(obligation, def_id)?; . ImplSource::Builtin(BuiltinImplSource::Misc, data) . } . }; . . // The obligations returned by confirmation are recursively evaluated . // so we need to make sure they have the correct depth. . for subobligation in impl_src.borrow_nested_obligations_mut() { 592,406 (0.0%) subobligation.set_depth_from_parent(obligation.recursion_depth); . } . 732,328 (0.0%) if !obligation.predicate.is_const_if_const() { . // normalize nested predicates according to parent predicate's constness. 5,858,624 (0.0%) impl_src = impl_src.map(|mut o| { 269,579,277 (0.1%) o.predicate = o.predicate.without_const(self.tcx()); 539,158,554 (0.2%) o . }); . } . 2,196,984 (0.0%) Ok(impl_src) . } . . fn confirm_projection_candidate( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . idx: usize, . ) -> Result>, SelectionError<'tcx>> { . let tcx = self.tcx(); . . let trait_predicate = self.infcx.shallow_resolve(obligation.predicate); . let placeholder_trait_predicate = 6,048 (0.0%) self.infcx.instantiate_binder_with_placeholders(trait_predicate).trait_ref; . let placeholder_self_ty = placeholder_trait_predicate.self_ty(); 2,016 (0.0%) let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate); 5,040 (0.0%) let (def_id, args) = match *placeholder_self_ty.kind() { . // Excluding IATs and type aliases here as they don't have meaningful item bounds. 4,032 (0.0%) ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. }) => { . (def_id, args) . } . _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty), . }; . . let candidate_predicate = 4,032 (0.0%) tcx.item_bounds(def_id).map_bound(|i| i[idx]).instantiate(tcx, args); 2,016 (0.0%) let candidate = candidate_predicate . .as_trait_clause() . .expect("projection candidate is not a trait predicate") . .map_bound(|t| t.trait_ref); . let mut obligations = Vec::new(); 13,104 (0.0%) let candidate = normalize_with_depth_to( . self, 2,016 (0.0%) obligation.param_env, . obligation.cause.clone(), 2,016 (0.0%) obligation.recursion_depth + 1, . candidate, . &mut obligations, . ); . 9,072 (0.0%) obligations.extend(self.infcx.commit_if_ok(|_| { . self.infcx . .at(&obligation.cause, obligation.param_env) . .sup(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate) . .map(|InferOk { obligations, .. }| obligations) . .map_err(|_| Unimplemented) . })?); . 5,040 (0.0%) if let ty::Alias(ty::Projection, ..) = placeholder_self_ty.kind() { 3,024 (0.0%) let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, args); 3,024 (0.0%) for (predicate, _) in predicates { . let normalized = normalize_with_depth_to( . self, . obligation.param_env, . obligation.cause.clone(), . obligation.recursion_depth + 1, . predicate, . &mut obligations, . ); -- line 196 ---------------------------------------- -- line 199 ---------------------------------------- . obligation.cause.clone(), . obligation.recursion_depth + 1, . obligation.param_env, . normalized, . )); . } . } . 3,024 (0.0%) Ok(obligations) . } . . fn confirm_param_candidate( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . param: ty::PolyTraitRef<'tcx>, . ) -> Vec> { . debug!(?obligation, ?param, "confirm_param_candidate"); . . // During evaluation, we already checked that this . // where-clause trait-ref could be unified with the obligation . // trait-ref. Repeat that unification now without any . // transactional boundary; it should not fail. 33,800 (0.0%) match self.match_where_clause_trait_ref(obligation, param) { 16,900 (0.0%) Ok(obligations) => obligations, . Err(()) => { . bug!( . "Where clause `{:?}` was applicable to `{:?}` but now is not", . param, . obligation . ); . } . } -- line 230 ---------------------------------------- -- line 232 ---------------------------------------- . . fn confirm_builtin_candidate( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . has_nested: bool, . ) -> Vec> { . debug!(?obligation, ?has_nested, "confirm_builtin_candidate"); . 15,641 (0.0%) let lang_items = self.tcx().lang_items(); 15,641 (0.0%) let obligations = if has_nested { 30 (0.0%) let trait_def = obligation.predicate.def_id(); 10 (0.0%) let conditions = if Some(trait_def) == lang_items.sized_trait() { 20 (0.0%) self.sized_conditions(obligation) . } else if Some(trait_def) == lang_items.copy_trait() { . self.copy_clone_conditions(obligation) . } else if Some(trait_def) == lang_items.clone_trait() { . self.copy_clone_conditions(obligation) . } else { . bug!("unexpected builtin trait {:?}", trait_def) . }; 35 (0.0%) let BuiltinImplConditions::Where(nested) = conditions else { . bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation); . }; . . let cause = obligation.derived_cause(BuiltinDerivedObligation); 40 (0.0%) self.collect_predicates_for_types( 5 (0.0%) obligation.param_env, 15 (0.0%) cause, 10 (0.0%) obligation.recursion_depth + 1, . trait_def, 25 (0.0%) nested, . ) . } else { . vec![] . }; . . debug!(?obligations); . 93,846 (0.0%) obligations . } . . #[instrument(level = "debug", skip(self))] . fn confirm_transmutability_candidate( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . ) -> Result>, SelectionError<'tcx>> { . use rustc_transmute::{Answer, Condition}; -- line 278 ---------------------------------------- -- line 424 ---------------------------------------- . impl_def_id: DefId, . ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> { . debug!(?obligation, ?impl_def_id, "confirm_impl_candidate"); . . // First, create the substitutions by matching the impl again, . // this time not in a probe. . let args = self.rematch_impl(impl_def_id, obligation); . debug!(?args, "impl args"); 3,068,019 (0.0%) ensure_sufficient_stack(|| { . self.vtable_impl( 681,782 (0.0%) impl_def_id, 1,363,564 (0.0%) args, 340,891 (0.0%) &obligation.cause, 1,022,673 (0.0%) obligation.recursion_depth + 1, 340,891 (0.0%) obligation.param_env, . obligation.predicate, . ) . }) . } . . fn vtable_impl( . &mut self, . impl_def_id: DefId, -- line 446 ---------------------------------------- -- line 447 ---------------------------------------- . args: Normalized<'tcx, GenericArgsRef<'tcx>>, . cause: &ObligationCause<'tcx>, . recursion_depth: usize, . param_env: ty::ParamEnv<'tcx>, . parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, . ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> { . debug!(?impl_def_id, ?args, ?recursion_depth, "vtable_impl"); . 2,727,128 (0.0%) let mut impl_obligations = self.impl_or_trait_obligations( . cause, . recursion_depth, . param_env, . impl_def_id, 340,891 (0.0%) &args.value, . parent_trait_pred, . ); . . debug!(?impl_obligations, "vtable_impl"); . . // Because of RFC447, the impl-trait-ref and obligations . // are sufficient to determine the impl args, without . // relying on projections in the impl-trait-ref. . // . // e.g., `impl> Foo<::T> for V` 1,022,673 (0.0%) impl_obligations.extend(args.obligations); . 3,749,801 (0.0%) ImplSourceUserDefinedData { impl_def_id, args: args.value, nested: impl_obligations } . } . . fn confirm_object_candidate( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . index: usize, . ) -> Result>, SelectionError<'tcx>> { . let tcx = self.tcx(); -- line 481 ---------------------------------------- -- line 510 ---------------------------------------- . obligation.cause.clone(), . obligation.recursion_depth + 1, . unnormalized_upcast_trait_ref, . &mut nested, . ); . . nested.extend(self.infcx.commit_if_ok(|_| { . self.infcx 2,016 (0.0%) .at(&obligation.cause, obligation.param_env) 8,064 (0.0%) .sup(DefineOpaqueTypes::No, obligation_trait_ref, upcast_trait_ref) . .map(|InferOk { obligations, .. }| obligations) . .map_err(|_| Unimplemented) . })?); . . // Check supertraits hold. This is so that their associated type bounds . // will be checked in the code below. . for super_trait in tcx . .super_predicates_of(trait_predicate.def_id()) -- line 527 ---------------------------------------- -- line 785 ---------------------------------------- . Ok(nested) . } . . #[instrument(skip(self), level = "debug")] . fn confirm_closure_candidate( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . ) -> Result>, SelectionError<'tcx>> { 42 (0.0%) let kind = self . .tcx() 28 (0.0%) .fn_trait_kind_from_def_id(obligation.predicate.def_id()) . .unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}", obligation)); . . // Okay to skip binder because the args on closure types never . // touch bound regions, they just capture the in-scope . // type/region parameters. 42 (0.0%) let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); 70 (0.0%) let ty::Closure(closure_def_id, args) = *self_ty.kind() else { . bug!("closure candidate for non-closure {:?}", obligation); . }; . . let trait_ref = self.closure_trait_ref_unnormalized(obligation, args); 140 (0.0%) let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; . . debug!(?closure_def_id, ?trait_ref, ?nested, "confirm closure candidate obligations"); . . nested.push(obligation.with( . self.tcx(), 84 (0.0%) ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, args, kind)), . )); . 14 (0.0%) Ok(nested) . } . . /// In the case of closure types and fn pointers, . /// we currently treat the input type parameters on the trait as . /// outputs. This means that when we have a match we have only . /// considered the self type, so we have to go back and make sure . /// to relate the argument types too. This is kind of wrong, but . /// since we control the full set of impls, also not that wrong, -- line 824 ---------------------------------------- -- line 836 ---------------------------------------- . /// Now imagine our obligation is `Closure: Fn(usize)`. So far . /// we have matched the self type `Closure`. At this point we'll . /// compare the `i32` to `usize` and generate an error. . /// . /// Note that this checking occurs *after* the impl has selected, . /// because these output type parameters should not affect the . /// selection of the impl. Therefore, if there is a mismatch, we . /// report an error to the user. 280 (0.0%) #[instrument(skip(self), level = "trace")] . fn confirm_poly_trait_refs( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . self_ty_trait_ref: ty::PolyTraitRef<'tcx>, . ) -> Result>, SelectionError<'tcx>> { 42 (0.0%) let obligation_trait_ref = obligation.predicate.to_poly_trait_ref(); . // Normalize the obligation and expected trait refs together, because why not 224 (0.0%) let Normalized { obligations: nested, value: (obligation_trait_ref, expected_trait_ref) } = . ensure_sufficient_stack(|| { 56 (0.0%) normalize_with_depth( . self, 14 (0.0%) obligation.param_env, . obligation.cause.clone(), 28 (0.0%) obligation.recursion_depth + 1, 154 (0.0%) (obligation_trait_ref, self_ty_trait_ref), . ) . }); . . // needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs 14 (0.0%) self.infcx 14 (0.0%) .at(&obligation.cause, obligation.param_env) . .sup(DefineOpaqueTypes::Yes, obligation_trait_ref, expected_trait_ref) 56 (0.0%) .map(|InferOk { mut obligations, .. }| { . obligations.extend(nested); 56 (0.0%) obligations . }) . .map_err(|terr| { . OutputTypeParameterMismatch(Box::new(SelectionOutputTypeParameterMismatch { . expected_trait_ref: obligation_trait_ref, . found_trait_ref: expected_trait_ref, . terr, . })) . }) -- line 877 ---------------------------------------- -- line 980 ---------------------------------------- . . Ok(ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { vtable_vptr_slot }, nested)) . } . . fn confirm_builtin_unsize_candidate( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . ) -> Result>, SelectionError<'tcx>> { 210 (0.0%) let tcx = self.tcx(); . . // `assemble_candidates_for_unsizing` should ensure there are no late-bound . // regions here. See the comment there for more details. 630 (0.0%) let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap()); 630 (0.0%) let target = obligation.predicate.skip_binder().trait_ref.args.type_at(1); 210 (0.0%) let target = self.infcx.shallow_resolve(target); . debug!(?source, ?target, "confirm_builtin_unsize_candidate"); . . let mut nested = vec![]; . let src; 2,599 (0.0%) match (source.kind(), target.kind()) { . // Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping). . (&ty::Dynamic(ref data_a, r_a, dyn_a), &ty::Dynamic(ref data_b, r_b, dyn_b)) . if dyn_a == dyn_b => . { . // See `assemble_candidates_for_unsizing` for more info. . // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`. . let iter = data_a . .principal() -- line 1007 ---------------------------------------- -- line 1039 ---------------------------------------- . obligation.param_env, . obligation.predicate.rebind(outlives), . )); . . src = BuiltinImplSource::Misc; . } . . // `T` -> `Trait` 158 (0.0%) (_, &ty::Dynamic(ref data, r, ty::Dyn)) => { 316 (0.0%) let mut object_dids = data.auto_traits().chain(data.principal_def_id()); . if let Some(did) = object_dids.find(|did| !tcx.check_is_object_safe(*did)) { . return Err(TraitNotObjectSafe(did)); . } . 237 (0.0%) let predicate_to_obligation = |predicate| { 316 (0.0%) Obligation::with_depth( 158 (0.0%) tcx, . obligation.cause.clone(), 790 (0.0%) obligation.recursion_depth + 1, 237 (0.0%) obligation.param_env, . predicate, . ) . }; . . // Create obligations: . // - Casting `T` to `Trait` . // - For all the various builtin bounds attached to the object cast. (In other . // words, if the object type is `Foo + Send`, this would create an obligation for . // the `Send` check.) . // - Projection predicates . nested.extend( 79 (0.0%) data.iter().map(|predicate| { 474 (0.0%) predicate_to_obligation(predicate.with_self_ty(tcx, source)) . }), . ); . . // We can only make objects from sized types. 158 (0.0%) let tr = ty::TraitRef::from_lang_item( 158 (0.0%) tcx, . LangItem::Sized, 79 (0.0%) obligation.cause.span, 158 (0.0%) [source], . ); 395 (0.0%) nested.push(predicate_to_obligation(tr.to_predicate(tcx))); . . // If the type is `Foo + 'a`, ensure that the type . // being cast to `Foo + 'a` outlives `'a`: 79 (0.0%) let outlives = ty::OutlivesPredicate(source, r); 158 (0.0%) nested.push(predicate_to_obligation( 632 (0.0%) ty::Binder::dummy(ty::ClauseKind::TypeOutlives(outlives)).to_predicate(tcx), . )); . . src = BuiltinImplSource::Misc; . } . . // `[T; n]` -> `[T]` 243 (0.0%) (&ty::Array(a, _), &ty::Slice(b)) => { 486 (0.0%) let InferOk { obligations, .. } = self . .infcx 162 (0.0%) .at(&obligation.cause, obligation.param_env) . .eq(DefineOpaqueTypes::No, b, a) . .map_err(|_| Unimplemented)?; . nested.extend(obligations); . . src = BuiltinImplSource::Misc; . } . . // `Struct` -> `Struct` 200 (0.0%) (&ty::Adt(def, args_a), &ty::Adt(_, args_b)) => { 50 (0.0%) let unsizing_params = tcx.unsizing_params_for_adt(def.did()); . if unsizing_params.is_empty() { . return Err(Unimplemented); . } . . let tail_field = def.non_enum_variant().tail(); . let tail_field_ty = tcx.type_of(tail_field.did); . . // Extract `TailField` and `TailField` from `Struct` and `Struct`, -- line 1116 ---------------------------------------- -- line 1188 ---------------------------------------- . nested.push(last_unsize_obligation); . . src = BuiltinImplSource::TupleUnsizing; . } . . _ => bug!("source: {source}, target: {target}"), . }; . 646 (0.0%) Ok(ImplSource::Builtin(src, nested)) . } . . fn confirm_const_destruct_candidate( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . impl_def_id: Option, . ) -> Result>, SelectionError<'tcx>> { . // `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop` -- line 1204 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/compiler/rustc_trait_selection/src/traits/select/mod.rs -------------------------------------------------------------------------------- Ir________________ 262,074,331 (0.1%) -- line 194 ---------------------------------------- . /// There is no built-in impl. There may be some other . /// candidate (a where-clause or user-defined impl). . None, . /// It is unknown whether there is an impl. . Ambiguous, . } . . impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 59,778 (0.0%) pub fn new(infcx: &'cx InferCtxt<'tcx>) -> SelectionContext<'cx, 'tcx> { 652,744 (0.0%) SelectionContext { . infcx, 191,149 (0.0%) freshener: infcx.freshener(), . intercrate_ambiguity_causes: None, . query_mode: TraitQueryMode::Standard, . } 49,815 (0.0%) } . 89,056 (0.0%) pub fn with_query_mode( . infcx: &'cx InferCtxt<'tcx>, . query_mode: TraitQueryMode, . ) -> SelectionContext<'cx, 'tcx> { . debug!(?query_mode, "with_query_mode"); 144,716 (0.0%) SelectionContext { query_mode, ..SelectionContext::new(infcx) } 66,792 (0.0%) } . . /// Enables tracking of intercrate ambiguity causes. See . /// the documentation of [`Self::intercrate_ambiguity_causes`] for more. . pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) { . assert!(self.is_intercrate()); . assert!(self.intercrate_ambiguity_causes.is_none()); . self.intercrate_ambiguity_causes = Some(FxIndexSet::default()); . debug!("selcx: enable_tracking_intercrate_ambiguity_causes"); -- line 225 ---------------------------------------- -- line 229 ---------------------------------------- . /// was enabled and disables tracking at the same time. If . /// tracking is not enabled, just returns an empty vector. . pub fn take_intercrate_ambiguity_causes(&mut self) -> FxIndexSet { . assert!(self.is_intercrate()); . self.intercrate_ambiguity_causes.take().unwrap_or_default() . } . . pub fn tcx(&self) -> TyCtxt<'tcx> { 235,288,586 (0.1%) self.infcx.tcx . } . . pub fn is_intercrate(&self) -> bool { 91,355,553 (0.0%) self.infcx.intercrate . } . . /////////////////////////////////////////////////////////////////////////// . // Selection . // . // The selection phase tries to identify *how* an obligation will . // be resolved. For example, it will identify which impl or . // parameter bound is to be used. The process can be inconclusive -- line 249 ---------------------------------------- -- line 253 ---------------------------------------- . // 1. If no applicable impl or parameter bound can be found. . // 2. If the output type parameters in the obligation do not match . // those specified by the impl/bound. For example, if the obligation . // is `Vec: Iterable`, but the impl specifies . // `impl Iterable for Vec`, than an error would result. . . /// Attempts to satisfy the obligation. If successful, this will affect the surrounding . /// type environment by performing unification. 10,536,342 (0.0%) #[instrument(level = "debug", skip(self), ret)] . pub fn poly_select( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . ) -> SelectionResult<'tcx, Selection<'tcx>> { 1,423,830 (0.0%) if self.infcx.next_trait_solver() { . return self.infcx.select_in_new_trait_solver(obligation); . } . 1,388,174 (0.0%) let candidate = match self.select_from_obligation(obligation) { . Err(SelectionError::Overflow(OverflowError::Canonical)) => { . // In standard mode, overflow must have been caught and reported . // earlier. . assert!(self.query_mode == TraitQueryMode::Canonical); . return Err(SelectionError::Overflow(OverflowError::Canonical)); . } . Err(e) => { . return Err(e); . } . Ok(None) => { 52,200 (0.0%) return Ok(None); . } 1,502,364 (0.0%) Ok(Some(candidate)) => candidate, . }; . 1,252,070 (0.0%) match self.confirm_candidate(obligation, candidate) { . Err(SelectionError::Overflow(OverflowError::Canonical)) => { . assert!(self.query_mode == TraitQueryMode::Canonical); . Err(SelectionError::Overflow(OverflowError::Canonical)) . } . Err(e) => Err(e), 1,752,408 (0.0%) Ok(candidate) => Ok(Some(candidate)), . } . } . 2,479,401 (0.0%) pub fn select( . &mut self, . obligation: &TraitObligation<'tcx>, . ) -> SelectionResult<'tcx, Selection<'tcx>> { 4,407,824 (0.0%) self.poly_select(&Obligation { . cause: obligation.cause.clone(), 550,978 (0.0%) param_env: obligation.param_env, 1,101,956 (0.0%) predicate: ty::Binder::dummy(obligation.predicate), 275,489 (0.0%) recursion_depth: obligation.recursion_depth, . }) 2,479,401 (0.0%) } . . fn select_from_obligation( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { . debug_assert!(!obligation.predicate.has_escaping_bound_vars()); . . let pec = &ProvisionalEvaluationCache::default(); . let stack = self.push_stack(TraitObligationStackList::empty(pec), obligation); . 569,532 (0.0%) self.candidate_from_obligation(&stack) . } . 9,535,824 (0.0%) #[instrument(level = "debug", skip(self), ret)] . fn candidate_from_obligation<'o>( . &mut self, . stack: &TraitObligationStack<'o, 'tcx>, . ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { . debug_assert!(!self.infcx.next_trait_solver()); . // Watch out for overflow. This intentionally bypasses (and does . // not update) the cache. 1,986,630 (0.0%) self.check_recursion_limit(&stack.obligation, &stack.obligation)?; . . // Check the cache. Note that we freshen the trait-ref . // separately rather than using `stack.fresh_trait_ref` -- . // this is because we want the unbound variables to be . // replaced with fresh types starting from index 0. 3,575,934 (0.0%) let cache_fresh_trait_pred = self.infcx.freshen(stack.obligation.predicate); . debug!(?cache_fresh_trait_pred); . debug_assert!(!stack.obligation.predicate.has_escaping_bound_vars()); . 3,499,037 (0.0%) if let Some(c) = 1,191,584 (0.0%) self.check_candidate_cache(stack.obligation.param_env, cache_fresh_trait_pred) . { . debug!("CACHE HIT"); . return c; . } . . // If no match, compute result and insert into cache. . // . // FIXME(nikomatsakis) -- this cache is not taking into . // account cycles that may have occurred in forming the . // candidate. I don't know of any specific problems that . // result but it seems awfully suspicious. . let (candidate, dep_node) = 580,376 (0.0%) self.in_task(|this| this.candidate_from_obligation_no_cache(stack)); . . debug!("CACHE MISS"); . self.insert_candidate_cache( 290,188 (0.0%) stack.obligation.param_env, . cache_fresh_trait_pred, . dep_node, . candidate.clone(), . ); 870,564 (0.0%) candidate . } . 1,450,940 (0.0%) fn candidate_from_obligation_no_cache<'o>( . &mut self, . stack: &TraitObligationStack<'o, 'tcx>, . ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { 788 (0.0%) if let Err(conflict) = self.is_knowable(stack) { . debug!("coherence stage: not knowable"); 75 (0.0%) if self.intercrate_ambiguity_causes.is_some() { . debug!("evaluate_stack: intercrate_ambiguity_causes is some"); . // Heuristics: show the diagnostics when there are no candidates in crate. . if let Ok(candidate_set) = self.assemble_candidates(stack) { . let mut no_candidates_apply = true; . . for c in candidate_set.vec.iter() { . if self.evaluate_candidate(stack, &c)?.may_apply() { . no_candidates_apply = false; -- line 378 ---------------------------------------- -- line 401 ---------------------------------------- . IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc } . }; . debug!(?cause, "evaluate_stack: pushing cause"); . self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause); . } . } . } . } 75 (0.0%) return Ok(None); . } . 435,057 (0.0%) let candidate_set = self.assemble_candidates(stack)?; . 290,038 (0.0%) if candidate_set.ambiguous { . debug!("candidate set contains ambig"); 3,389 (0.0%) return Ok(None); . } . . let candidates = candidate_set.vec; . . debug!(?stack, ?candidates, "assembled {} candidates", candidates.len()); . . // At this point, we know that each of the entries in the . // candidate set is *individually* applicable. Now we have to . // figure out if they contain mutual incompatibilities. This . // frequently arises if we have an unconstrained input type -- . // for example, we are looking for `$0: Eq` where `$0` is some . // unconstrained type variable. In that case, we'll get a . // candidate which assumes $0 == int, one that assumes `$0 == . // usize`, etc. This spells an ambiguity. . 281,890 (0.0%) let mut candidates = self.filter_impls(candidates, stack.obligation); . . // If there is more than one candidate, first winnow them down . // by considering extra conditions (nested obligations and so . // forth). We don't winnow if there is exactly one . // candidate. This is a relatively minor distinction but it . // can lead to better inference and error-reporting. An . // example would be if there was an impl: . // . // impl Vec { fn push_clone(...) { ... } } . // . // and we were to see some code `foo.push_clone()` where `boo` . // is a `Vec` and `Bar` does not implement `Clone`. If . // we were to winnow, we'd wind up with zero candidates. . // Instead, we select the right impl now but report "`Bar` does . // not implement `Clone`". 566,520 (0.0%) if candidates.len() == 1 { 262,954 (0.0%) return self.filter_reservation_impls(candidates.pop().unwrap(), stack.obligation); . } . . // Winnow, but record the exact outcome of evaluation, which . // is needed for specialization. Propagate overflow if it occurs. . let mut candidates = candidates . .into_iter() . .map(|c| match self.evaluate_candidate(stack, &c) { 99,664 (0.0%) Ok(eval) if eval.may_apply() => { 94,654 (0.0%) Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval })) . } . Ok(_) => Ok(None), . Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)), . Err(OverflowError::ErrorReporting) => Err(ErrorReporting), . Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))), . }) . .flat_map(Result::transpose) . .collect::, _>>()?; . . debug!(?stack, ?candidates, "winnowed to {} candidates", candidates.len()); . 10,153 (0.0%) let has_non_region_infer = stack.obligation.predicate.has_non_region_infer(); . . // If there are STILL multiple candidates, we can further . // reduce the list by dropping duplicates -- including . // resolving specializations. 30,459 (0.0%) if candidates.len() > 1 { . let mut i = 0; 6,850 (0.0%) while i < candidates.len() { 12,816 (0.0%) let should_drop_i = (0..candidates.len()).filter(|&j| i != j).any(|j| { . self.candidate_should_be_dropped_in_favor_of( . &candidates[i], . &candidates[j], . has_non_region_infer, . ) == DropVictim::Yes . }); . if should_drop_i { . debug!(candidate = ?candidates[i], "Dropping candidate #{}/{}", i, candidates.len()); . candidates.swap_remove(i); . } else { . debug!(candidate = ?candidates[i], "Retaining candidate #{}/{}", i, candidates.len()); . i += 1; . . // If there are *STILL* multiple candidates, give up . // and report ambiguity. 21,000 (0.0%) if i > 1 { . debug!("multiple matches, ambig"); . return Ok(None); . } . } . } . } . . // If there are *NO* candidates, then there are no impls -- -- line 502 ---------------------------------------- -- line 503 ---------------------------------------- . // that we know of, anyway. Note that in the case where there . // are unbound type variables within the obligation, it might . // be the case that you could still satisfy the obligation . // from another crate by instantiating the type variables with . // a type from another crate that does have an impl. This case . // is checked for in `evaluate_stack` (and hence users . // who might care about this case, like coherence, should use . // that function). 16,226 (0.0%) if candidates.is_empty() { . // If there's an error type, 'downgrade' our result from . // `Err(Unimplemented)` to `Ok(None)`. This helps us avoid . // emitting additional spurious errors, since we're guaranteed . // to have emitted at least one. 2,817 (0.0%) if stack.obligation.predicate.references_error() { . debug!(?stack.obligation.predicate, "found error type in predicate, treating as ambiguous"); . return Ok(None); . } 2,817 (0.0%) return Err(Unimplemented); . } . . // Just one candidate left. 28,696 (0.0%) self.filter_reservation_impls(candidates.pop().unwrap().candidate, stack.obligation) 1,381,436 (0.0%) } . . /////////////////////////////////////////////////////////////////////////// . // EVALUATION . // . // Tests whether an obligation can be selected or whether an impl . // can be applied to particular types. It skips the "confirmation" . // step and hence completely ignores output type parameters. . // -- line 533 ---------------------------------------- -- line 534 ---------------------------------------- . // The result is "true" if the obligation *may* hold and "false" if . // we can be sure it does not. . . /// Evaluates whether the obligation `obligation` can be satisfied . /// and returns an `EvaluationResult`. This is meant for the . /// *initial* call. . /// . /// Do not use this directly, use `infcx.evaluate_obligation` instead. 33,396 (0.0%) pub fn evaluate_root_obligation( . &mut self, . obligation: &PredicateObligation<'tcx>, . ) -> Result { . debug_assert!(!self.infcx.next_trait_solver()); . self.evaluation_probe(|this| { . let goal = 45,196 (0.0%) this.infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env)); 56,495 (0.0%) let mut result = this.evaluate_predicate_recursively( . TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()), . obligation.clone(), . )?; . // If the predicate has done any inference, then downgrade the . // result to ambiguous. 11,299 (0.0%) if this.infcx.shallow_resolve(goal) != goal { . result = result.max(EvaluatedToAmbig); . } . Ok(result) . }) 22,264 (0.0%) } . . fn evaluation_probe( . &mut self, . op: impl FnOnce(&mut Self) -> Result, . ) -> Result { 1,736,356 (0.0%) self.infcx.probe(|snapshot| -> Result { 604,444 (0.0%) let outer_universe = self.infcx.universe(); 236,976 (0.0%) let result = op(self)?; . 1,395,304 (0.0%) match self.infcx.leak_check(outer_universe, Some(snapshot)) { . Ok(()) => {} . Err(_) => return Ok(EvaluatedToErr), . } . 988,575 (0.0%) if self.infcx.opaque_types_added_in_snapshot(snapshot) { . return Ok(result.max(EvaluatedToOkModuloOpaqueTypes)); . } . 988,575 (0.0%) if self.infcx.region_constraints_added_in_snapshot(snapshot) { . Ok(result.max(EvaluatedToOkModuloRegions)) . } else { . Ok(result) . } . }) . } . . /// Evaluates the predicates in `predicates` recursively. Note that . /// this applies projections in the predicates, and therefore . /// is run within an inference probe. 2,019,841 (0.0%) #[instrument(skip(self, stack), level = "debug")] . fn evaluate_predicates_recursively<'o, I>( . &mut self, . stack: TraitObligationStackList<'o, 'tcx>, . predicates: I, . ) -> Result . where . I: IntoIterator> + std::fmt::Debug, . { . let mut result = EvaluatedToOk; 231,354,235 (0.1%) for mut obligation in predicates { . obligation.set_depth_from_parent(stack.depth()); 146,915,237 (0.1%) let eval = self.evaluate_predicate_recursively(stack, obligation.clone())?; 41,975,782 (0.0%) if let EvaluatedToErr = eval { . // fast-path - EvaluatedToErr is the top of the lattice, . // so we don't need to look on the other predicates. . return Ok(EvaluatedToErr); . } else { . result = cmp::max(result, eval); . } . } . Ok(result) . } . 356,986,230 (0.1%) #[instrument( . level = "debug", . skip(self, previous_stack), . fields(previous_stack = ?previous_stack.head()) . ret, 209,991,900 (0.1%) )] . fn evaluate_predicate_recursively<'o>( . &mut self, . previous_stack: TraitObligationStackList<'o, 'tcx>, . obligation: PredicateObligation<'tcx>, . ) -> Result { . debug_assert!(!self.infcx.next_trait_solver()); . // `previous_stack` stores a `PolyTraitObligation`, while `obligation` is . // a `PredicateObligation`. These are distinct types, so we can't . // use any `Option` combinator method that would force them to be . // the same. 41,998,380 (0.0%) match previous_stack.head() { 83,951,564 (0.0%) Some(h) => self.check_recursion_limit(&obligation, h.obligation)?, 33,897 (0.0%) None => self.check_recursion_limit(&obligation, &obligation)?, . } . 20,999,190 (0.0%) ensure_sufficient_stack(|| { 20,999,190 (0.0%) let bound_predicate = obligation.predicate.kind(); 209,991,900 (0.1%) match bound_predicate.skip_binder() { . ty::PredicateKind::Clause(ty::ClauseKind::Trait(t)) => { . let t = bound_predicate.rebind(t); . debug_assert!(!t.has_escaping_bound_vars()); 83,996,636 (0.0%) let obligation = obligation.with(self.tcx(), t); 398,984,021 (0.2%) self.evaluate_trait_predicate_recursively(previous_stack, obligation) . } . 4 (0.0%) ty::PredicateKind::Subtype(p) => { . let p = bound_predicate.rebind(p); . // Does this code ever run? 13 (0.0%) match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) { . Ok(Ok(InferOk { obligations, .. })) => { . self.evaluate_predicates_recursively(previous_stack, obligations) . } . Ok(Err(_)) => Ok(EvaluatedToErr), . Err(..) => Ok(EvaluatedToAmbig), . } . } . -- line 657 ---------------------------------------- -- line 775 ---------------------------------------- . ty::PredicateKind::ObjectSafe(trait_def_id) => { . if self.tcx().check_is_object_safe(trait_def_id) { . Ok(EvaluatedToOk) . } else { . Ok(EvaluatedToErr) . } . } . 72 (0.0%) ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { . let data = bound_predicate.rebind(data); . let project_obligation = obligation.with(self.tcx(), data); 270 (0.0%) match project::poly_project_and_unify_type(self, &project_obligation) { 4 (0.0%) ProjectAndUnifyResult::Holds(mut subobligations) => { . 'compute_res: { . // If we've previously marked this projection as 'complete', then . // use the final cached result (either `EvaluatedToOk` or . // `EvaluatedToOkModuloRegions`), and skip re-evaluating the . // sub-obligations. 2 (0.0%) if let Some(key) = 13 (0.0%) ProjectionCacheKey::from_poly_projection_predicate(self, data) . { 8 (0.0%) if let Some(cached_res) = self . .infcx . .inner . .borrow_mut() . .projection_cache() . .is_complete(key) . { . break 'compute_res Ok(cached_res); . } 1 (0.0%) } . . // Need to explicitly set the depth of nested goals here as . // projection obligations can cycle by themselves and in . // `evaluate_predicates_recursively` we only add the depth . // for parent trait goals because only these get added to the . // `TraitObligationStackList`. 1 (0.0%) for subobligation in subobligations.iter_mut() { 1 (0.0%) subobligation.set_depth_from_parent(obligation.recursion_depth); . } 2 (0.0%) let res = self.evaluate_predicates_recursively( 2 (0.0%) previous_stack, 5 (0.0%) subobligations, . ); 4 (0.0%) if let Ok(eval_rslt) = res . && (eval_rslt == EvaluatedToOk || eval_rslt == EvaluatedToOkModuloRegions) 2 (0.0%) && let Some(key) = 13 (0.0%) ProjectionCacheKey::from_poly_projection_predicate( . self, data, . ) . { . // If the result is something that we can cache, then mark this . // entry as 'complete'. This will allow us to skip evaluating the . // subobligations at all the next time we evaluate the projection . // predicate. 7 (0.0%) self.infcx . .inner . .borrow_mut() . .projection_cache() . .complete(key, eval_rslt); . } . res . } . } . ProjectAndUnifyResult::FailedNormalization => Ok(EvaluatedToAmbig), . ProjectAndUnifyResult::Recursive => Ok(EvaluatedToRecur), . ProjectAndUnifyResult::MismatchedProjectionTypes(_) => Ok(EvaluatedToErr), . } . } . . ty::PredicateKind::ClosureKind(_, closure_args, kind) => { 10 (0.0%) match self.infcx.closure_kind(closure_args) { . Some(closure_kind) => { 6 (0.0%) if closure_kind.extends(kind) { . Ok(EvaluatedToOk) . } else { . Ok(EvaluatedToErr) . } . } . None => Ok(EvaluatedToAmbig), . } . } -- line 856 ---------------------------------------- -- line 960 ---------------------------------------- . } . } . } . ty::PredicateKind::AliasRelate(..) => { . bug!("AliasRelate is only used for new solver") . } . ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig), . ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { 70 (0.0%) match self.infcx.at(&obligation.cause, obligation.param_env).eq( . DefineOpaqueTypes::No, . ct.ty(), . ty, . ) { 90 (0.0%) Ok(inf_ok) => self.evaluate_predicates_recursively( 40 (0.0%) previous_stack, 10 (0.0%) inf_ok.into_obligations(), . ), . Err(_) => Ok(EvaluatedToErr), . } . } . } . }) . } . 629,974,770 (0.3%) #[instrument(skip(self, previous_stack), level = "debug", ret)] . fn evaluate_trait_predicate_recursively<'o>( . &mut self, . previous_stack: TraitObligationStackList<'o, 'tcx>, . mut obligation: PolyTraitObligation<'tcx>, . ) -> Result { 20,999,159 (0.0%) if !self.is_intercrate() . && obligation.is_global() 18,838,745 (0.0%) && obligation.param_env.caller_bounds().iter().all(|bound| bound.has_param()) . { . // 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!("in global"); 37,677,490 (0.0%) obligation.param_env = obligation.param_env.without_caller_bounds(); . } . 62,997,477 (0.0%) let stack = self.push_stack(previous_stack, &obligation); 83,996,636 (0.0%) let fresh_trait_pred = stack.fresh_trait_pred; 41,998,318 (0.0%) let param_env = obligation.param_env; . . debug!(?fresh_trait_pred); . . // If a trait predicate is in the (local or global) evaluation cache, . // then we know it holds without cycles. 84,333,818 (0.0%) if let Some(result) = self.check_evaluation_cache(param_env, fresh_trait_pred) { . debug!("CACHE HIT"); . return Ok(result); . } . 675,028 (0.0%) if let Some(result) = stack.cache().get_provisional(fresh_trait_pred) { . debug!("PROVISIONAL CACHE HIT"); . stack.update_reached_depth(result.reached_depth); . return Ok(result.result); . } . . // Check if this is a match for something already on the . // stack. If so, we don't want to insert the result into the . // main cache (it is cycle dependent) nor the provisional . // cache (which is meant for things that have completed but . // for a "backedge" -- this result *is* the backedge). 112,560 (0.0%) if let Some(cycle_result) = self.check_evaluation_cycle(&stack) { . return Ok(cycle_result); . } . 337,680 (0.0%) let (result, dep_node) = self.in_task(|this| { 675,360 (0.0%) let mut result = this.evaluate_stack(&stack)?; . . // fix issue #103563, we don't normalize . // nested obligations which produced by `TraitDef` candidate . // (i.e. using bounds on assoc items as assumptions). . // because we don't have enough information to . // normalize these obligations before evaluating. . // so we will try to normalize the obligation and evaluate again. . // we will replace it with new solver in the future. 112,560 (0.0%) if EvaluationResult::EvaluatedToErr == result . && fresh_trait_pred.has_projections() . && fresh_trait_pred.is_global() . { . let mut nested_obligations = Vec::new(); . let predicate = try_normalize_with_depth_to( . this, . param_env, . obligation.cause.clone(), -- line 1047 ---------------------------------------- -- line 1066 ---------------------------------------- . ); . } . } . } . . Ok::<_, OverflowError>(result) . }); . 225,120 (0.0%) let result = result?; . 562,800 (0.0%) if !result.must_apply_modulo_regions() { 116,529 (0.0%) stack.cache().on_failure(stack.dfn); . } . . let reached_depth = stack.reached_depth.get(); 225,120 (0.0%) if reached_depth >= stack.depth { . debug!("CACHE MISS"); 675,360 (0.0%) self.insert_evaluation_cache(param_env, fresh_trait_pred, dep_node, result); 337,680 (0.0%) stack.cache().on_completion(stack.dfn); . } else { . debug!("PROVISIONAL"); . debug!( . "caching provisionally because {:?} \ . is a cycle participant (at depth {}, reached depth {})", . fresh_trait_pred, stack.depth, reached_depth, . ); . -- line 1092 ---------------------------------------- -- line 1118 ---------------------------------------- . fn check_evaluation_cycle( . &mut self, . stack: &TraitObligationStack<'_, 'tcx>, . ) -> Option { . if let Some(cycle_depth) = stack . .iter() . .skip(1) // Skip top-most frame. . .find(|prev| { 1,242,864 (0.0%) stack.obligation.param_env == prev.obligation.param_env . && stack.fresh_trait_pred == prev.fresh_trait_pred . }) . .map(|stack| stack.depth) . { . debug!("evaluate_stack --> recursive at depth {}", cycle_depth); . . // If we have a stack like `A B C D E A`, where the top of . // the stack is the final `A`, then this will iterate over -- line 1134 ---------------------------------------- -- line 1153 ---------------------------------------- . debug!("evaluate_stack --> recursive, inductive"); . Some(EvaluatedToRecur) . } . } else { . None . } . } . 1,013,040 (0.0%) fn evaluate_stack<'o>( . &mut self, . stack: &TraitObligationStack<'o, 'tcx>, . ) -> Result { . debug_assert!(!self.infcx.next_trait_solver()); . // In intercrate mode, whenever any of the generics are unbound, . // there can always be an impl. Even if there are no impls in . // this crate, perhaps the type would be unified with . // something from another crate that does provide an impl. -- line 1169 ---------------------------------------- -- line 1183 ---------------------------------------- . // imagine, this is just where we started. To avoid that, we . // check for unbound variables and return an ambiguous (hence possible) . // match if we've seen this trait before. . // . // 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 = 112,560 (0.0%) stack.fresh_trait_pred.skip_binder().trait_ref.args.types().any(|ty| ty.is_fresh()); . . if unbound_input_types . && stack.iter().skip(1).any(|prev| { 64,791 (0.0%) stack.obligation.param_env == prev.obligation.param_env . && self.match_fresh_trait_refs( 86,388 (0.0%) stack.fresh_trait_pred, 86,388 (0.0%) prev.fresh_trait_pred, . prev.obligation.param_env, . ) . }) . { . debug!("evaluate_stack --> unbound argument, recursive --> giving up",); . return Ok(EvaluatedToUnknown); . } . 860,017 (0.0%) match self.candidate_from_obligation(stack) { 363,616 (0.0%) Ok(Some(c)) => self.evaluate_candidate(stack, &c), . Ok(None) => Ok(EvaluatedToAmbig), . Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical), . Err(ErrorReporting) => Err(OverflowError::ErrorReporting), . Err(..) => Ok(EvaluatedToErr), . } 1,125,600 (0.0%) } . . /// For defaulted traits, we use a co-inductive strategy to solve, so . /// that recursion is ok. This routine returns `true` if the top of the . /// stack (`cycle[0]`): . /// . /// - is a defaulted trait, . /// - it also appears in the backtrace at some position `X`, . /// - all the predicates at positions `X..` between `X` and the top are -- line 1222 ---------------------------------------- -- line 1237 ---------------------------------------- . fields(depth = stack.obligation.recursion_depth), . ret . )] . fn evaluate_candidate<'o>( . &mut self, . stack: &TraitObligationStack<'o, 'tcx>, . candidate: &SelectionCandidate<'tcx>, . ) -> Result { 140,736 (0.0%) let mut result = self.evaluation_probe(|this| { . let candidate = (*candidate).clone(); 2,720,383 (0.0%) match this.confirm_candidate(stack.obligation, candidate) { 694,920 (0.0%) Ok(selection) => { . debug!(?selection); 579,100 (0.0%) this.evaluate_predicates_recursively( . stack.list(), . selection.nested_obligations().into_iter(), . ) . } . Err(..) => Ok(EvaluatedToErr), . } . })?; . -- line 1258 ---------------------------------------- -- line 1259 ---------------------------------------- . // If we erased any lifetimes, then we want to use . // `EvaluatedToOkModuloRegions` instead of `EvaluatedToOk` . // as your final result. The result will be cached using . // the freshened trait predicate as a key, so we need . // our result to be correct by *any* choice of original lifetimes, . // not just the lifetime choice for this particular (non-erased) . // predicate. . // See issue #80691 149,496 (0.0%) if stack.fresh_trait_pred.has_erased_regions() { . result = result.max(EvaluatedToOkModuloRegions); . } . . Ok(result) . } . . fn check_evaluation_cache( . &self, . param_env: ty::ParamEnv<'tcx>, . trait_pred: ty::PolyTraitPredicate<'tcx>, . ) -> Option { . // Neither the global nor local cache is aware of intercrate . // mode, so don't do any caching. In particular, we might . // re-use the same `InferCtxt` with both an intercrate . // and non-intercrate `SelectionContext` 20,999,159 (0.0%) if self.is_intercrate() { . return None; . } . . let tcx = self.tcx(); 20,998,992 (0.0%) if self.can_use_global_caches(param_env) { 230,988,912 (0.1%) if let Some(res) = tcx.evaluation_cache.get(&(param_env, trait_pred), tcx) { . return Some(res); . } . } 1,123,940 (0.0%) self.infcx.evaluation_cache.get(&(param_env, trait_pred), tcx) . } . . fn insert_evaluation_cache( . &mut self, . param_env: ty::ParamEnv<'tcx>, . trait_pred: ty::PolyTraitPredicate<'tcx>, . dep_node: DepNodeIndex, . result: EvaluationResult, . ) { . // Avoid caching results that depend on more than just the trait-ref . // - the stack can create recursion. 450,240 (0.0%) if result.is_stack_dependent() { . return; . } . . // Neither the global nor local cache is aware of intercrate . // mode, so don't do any caching. In particular, we might . // re-use the same `InferCtxt` with both an intercrate . // and non-intercrate `SelectionContext` 112,560 (0.0%) if self.is_intercrate() { . return; . } . 112,393 (0.0%) if self.can_use_global_caches(param_env) { 224,786 (0.0%) if !trait_pred.has_infer() { . debug!(?trait_pred, ?result, "insert_evaluation_cache global"); . // This may overwrite the cache with the same value . // FIXME: Due to #50507 this overwrites the different values . // This should be changed to use HashMapExt::insert_same . // when that is fixed 1,348,716 (0.0%) self.tcx().evaluation_cache.insert((param_env, trait_pred), dep_node, result); . return; . } . } . . debug!(?trait_pred, ?result, "insert_evaluation_cache"); 1 (0.0%) self.infcx.evaluation_cache.insert((param_env, trait_pred), dep_node, result); . } . . fn check_recursion_depth( . &self, . depth: usize, . error_obligation: &Obligation<'tcx, T>, . ) -> Result<(), OverflowError> . where . T: ToPredicate<'tcx> + Clone, . { 64,189,548 (0.0%) if !self.infcx.tcx.recursion_limit().value_within_limit(depth) { . match self.query_mode { . TraitQueryMode::Standard => { . if let Some(e) = self.infcx.tainted_by_errors() { . return Err(OverflowError::Error(e)); . } . self.infcx.err_ctxt().report_overflow_obligation(error_obligation, true); . } . TraitQueryMode::Canonical => { -- line 1349 ---------------------------------------- -- line 1369 ---------------------------------------- . { . self.check_recursion_depth(obligation.recursion_depth, error_obligation) . } . . fn in_task(&mut self, op: OP) -> (R, DepNodeIndex) . where . OP: FnOnce(&mut Self) -> R, . { 725,470 (0.0%) let (result, dep_node) = 2,558,964 (0.0%) self.tcx().dep_graph.with_anon_task(self.tcx(), DepKind::TraitSelect, || op(self)); 257,654 (0.0%) self.tcx().dep_graph.read_index(dep_node); 580,376 (0.0%) (result, dep_node) . } . . /// filter_impls filters candidates that have a positive impl for a negative . /// goal and a negative impl for a positive goal . #[instrument(level = "debug", skip(self, candidates))] . fn filter_impls( . &mut self, . candidates: Vec>, . obligation: &PolyTraitObligation<'tcx>, . ) -> Vec> { . trace!("{candidates:#?}"); . let tcx = self.tcx(); . let mut result = Vec::with_capacity(candidates.len()); . 938,358 (0.0%) for candidate in candidates { 312,786 (0.0%) if let ImplCandidate(def_id) = candidate { 276,270 (0.0%) if ty::ImplPolarity::Reservation == tcx.impl_polarity(def_id) 276,270 (0.0%) || obligation.polarity() == tcx.impl_polarity(def_id) . { . result.push(candidate); . } . } else { . result.push(candidate); . } . } . . trace!("{result:#?}"); 424,890 (0.0%) result . } . . /// filter_reservation_impls filter reservation impl for any goal as ambiguous 2,357,067 (0.0%) #[instrument(level = "debug", skip(self))] . fn filter_reservation_impls( . &mut self, . candidate: SelectionCandidate<'tcx>, . obligation: &PolyTraitObligation<'tcx>, . ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { . let tcx = self.tcx(); . // Treat reservation impls as ambiguity. 518,308 (0.0%) if let ImplCandidate(def_id) = candidate { 241,006 (0.0%) if let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id) { . if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes { . let value = tcx . .get_attr(def_id, sym::rustc_reservation_impl) . .and_then(|a| a.value_str()); . if let Some(value) = value { . debug!( . "filter_reservation_impls: \ . reservation impl ambiguity on {:?}", -- line 1429 ---------------------------------------- -- line 1434 ---------------------------------------- . message: value.to_string(), . }, . ); . } . } . return Ok(None); . } . } 693,255 (0.0%) Ok(Some(candidate)) . } . . fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> { . debug!("is_knowable(intercrate={:?})", self.is_intercrate()); . 145,094 (0.0%) if !self.is_intercrate() { . return Ok(()); . } . . let obligation = &stack.obligation; 788 (0.0%) 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 . // bound regions. 394 (0.0%) let trait_ref = predicate.skip_binder().trait_ref; . 394 (0.0%) coherence::trait_ref_is_knowable(self.tcx(), trait_ref) . } . . /// Returns `true` if the global caches can be used. . fn can_use_global_caches(&self, param_env: ty::ParamEnv<'tcx>) -> bool { . // If there are any inference variables in the `ParamEnv`, then we . // always use a cache local to this particular scope. Otherwise, we . // switch to a global cache. . if param_env.has_infer() { -- line 1468 ---------------------------------------- -- line 1488 ---------------------------------------- . &mut self, . param_env: ty::ParamEnv<'tcx>, . cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>, . ) -> Option>> { . // Neither the global nor local cache is aware of intercrate . // mode, so don't do any caching. In particular, we might . // re-use the same `InferCtxt` with both an intercrate . // and non-intercrate `SelectionContext` 397,326 (0.0%) if self.is_intercrate() { . return None; . } . let tcx = self.tcx(); . let pred = cache_fresh_trait_pred.skip_binder(); . 397,128 (0.0%) if self.can_use_global_caches(param_env) { 6,026,696 (0.0%) if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) { . return Some(res); . } . } 1,738,764 (0.0%) self.infcx.selection_cache.get(&(param_env, pred), tcx) . } . . /// Determines whether can we safely cache the result . /// of selecting an obligation. This is almost always `true`, . /// except when dealing with certain `ParamCandidate`s. . /// . /// Ordinarily, a `ParamCandidate` will contain no inference variables, . /// since it was usually produced directly from a `DefId`. However, -- line 1515 ---------------------------------------- -- line 1526 ---------------------------------------- . fn can_cache_candidate( . &self, . result: &SelectionResult<'tcx, SelectionCandidate<'tcx>>, . ) -> bool { . // Neither the global nor local cache is aware of intercrate . // mode, so don't do any caching. In particular, we might . // re-use the same `InferCtxt` with both an intercrate . // and non-intercrate `SelectionContext` 145,094 (0.0%) if self.is_intercrate() { . return false; . } 1,417,430 (0.0%) match result { . Ok(Some(SelectionCandidate::ParamCandidate(trait_ref))) => !trait_ref.has_infer(), . _ => true, . } . } . . #[instrument(skip(self, param_env, cache_fresh_trait_pred, dep_node), level = "debug")] . fn insert_candidate_cache( . &mut self, . param_env: ty::ParamEnv<'tcx>, . cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>, . dep_node: DepNodeIndex, . candidate: SelectionResult<'tcx, SelectionCandidate<'tcx>>, . ) { . let tcx = self.tcx(); 580,376 (0.0%) let pred = cache_fresh_trait_pred.skip_binder(); . . if !self.can_cache_candidate(&candidate) { . debug!(?pred, ?candidate, "insert_candidate_cache - candidate is not cacheable"); . return; . } . 144,896 (0.0%) if self.can_use_global_caches(param_env) { 579,584 (0.0%) if let Err(Overflow(OverflowError::Canonical)) = candidate { . // Don't cache overflow globally; we only produce this in certain modes. 289,792 (0.0%) } else if !pred.has_infer() { 289,792 (0.0%) if !candidate.has_infer() { . debug!(?pred, ?candidate, "insert_candidate_cache global"); . // This may overwrite the cache with the same value. 2,318,336 (0.0%) tcx.selection_cache.insert((param_env, pred), dep_node, candidate); . return; . } . } . } . . debug!(?pred, ?candidate, "insert_candidate_cache local"); 16 (0.0%) self.infcx.selection_cache.insert((param_env, pred), dep_node, candidate); . } . . /// Matches a predicate against the bounds of its self type. . /// . /// Given an obligation like `::Bar: Baz` where the self type is . /// a projection, look at the bounds of `T::Bar`, see if we can find a . /// `Baz` bound. We return indexes into the list returned by . /// `tcx.item_bounds` for any applicable bounds. 27,150 (0.0%) #[instrument(level = "debug", skip(self), ret)] . fn match_projection_obligation_against_definition_bounds( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . ) -> smallvec::SmallVec<[(usize, ty::BoundConstness); 2]> { 16,290 (0.0%) let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); . let placeholder_trait_predicate = 3,258 (0.0%) self.infcx.instantiate_binder_with_placeholders(poly_trait_predicate); . debug!(?placeholder_trait_predicate); . 1,086 (0.0%) let tcx = self.infcx.tcx; 5,430 (0.0%) let (def_id, args) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() { 3,258 (0.0%) ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. }) => { . (def_id, args) . } . _ => { . span_bug!( . obligation.cause.span, . "match_projection_obligation_against_definition_bounds() called \ . but self-ty is not a projection: {:?}", . placeholder_trait_predicate.trait_ref.self_ty() -- line 1602 ---------------------------------------- -- line 1609 ---------------------------------------- . // normalization, so try to deduplicate when possible to avoid . // unnecessary ambiguity. . let mut distinct_normalized_bounds = FxHashSet::default(); . . bounds . .iter() . .enumerate() . .filter_map(|(idx, bound)| { 4,344 (0.0%) let bound_predicate = bound.kind(); 13,752 (0.0%) if let ty::ClauseKind::Trait(pred) = bound_predicate.skip_binder() { . let bound = bound_predicate.rebind(pred.trait_ref); 4,332 (0.0%) if self.infcx.probe(|_| { 20,988 (0.0%) match self.match_normalize_trait_ref( . obligation, 4,344 (0.0%) bound, 4,344 (0.0%) placeholder_trait_predicate.trait_ref, . ) { . Ok(None) => true, . Ok(Some(normalized_trait)) 3,600 (0.0%) if distinct_normalized_bounds.insert(normalized_trait) => . { . true . } . _ => false, . } . }) { . return Some((idx, pred.constness)); . } -- line 1636 ---------------------------------------- -- line 1638 ---------------------------------------- . None . }) . .collect() . } . . /// Equates the trait in `obligation` with trait bound. If the two traits . /// can be equated and the normalized trait bound doesn't contain inference . /// variables or placeholders, the normalized bound is returned. 26,064 (0.0%) fn match_normalize_trait_ref( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . trait_bound: ty::PolyTraitRef<'tcx>, . placeholder_trait_ref: ty::TraitRef<'tcx>, . ) -> Result>, ()> { . debug_assert!(!placeholder_trait_ref.has_escaping_bound_vars()); 5,064 (0.0%) if placeholder_trait_ref.def_id != trait_bound.def_id() { . // Avoid unnecessary normalization . return Err(()); . } . 5,760 (0.0%) let Normalized { value: trait_bound, obligations: _ } = ensure_sufficient_stack(|| { . project::normalize_with_depth( . self, 720 (0.0%) obligation.param_env, . obligation.cause.clone(), 1,440 (0.0%) obligation.recursion_depth + 1, 2,880 (0.0%) trait_bound, . ) . }); 2,160 (0.0%) self.infcx 1,440 (0.0%) .at(&obligation.cause, obligation.param_env) 1,440 (0.0%) .sup(DefineOpaqueTypes::No, ty::Binder::dummy(placeholder_trait_ref), trait_bound) . .map(|InferOk { obligations: _, value: () }| { . // This method is called within a probe, so we can't have . // inference variables and placeholders escape. . if !trait_bound.has_infer() && !trait_bound.has_placeholders() { . Some(trait_bound) . } else { . None . } . }) . .map_err(|_| ()) 19,548 (0.0%) } . . fn where_clause_may_apply<'o>( . &mut self, . stack: &TraitObligationStack<'o, 'tcx>, . where_clause_trait_ref: ty::PolyTraitRef<'tcx>, . ) -> Result { . self.evaluation_probe(|this| { 494,172 (0.0%) match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) { 24,012 (0.0%) Ok(obligations) => this.evaluate_predicates_recursively(stack.list(), obligations), . Err(()) => Ok(EvaluatedToErr), . } . }) . } . . /// Return `Yes` if the obligation's predicate type applies to the env_predicate, and . /// `No` if it does not. Return `Ambiguous` in the case that the projection type is a GAT, . /// and applying this env_predicate constrains any of the obligation's GAT substitutions. . /// . /// This behavior is a somewhat of a hack to prevent over-constraining inference variables . /// in cases like #91762. 5,060 (0.0%) pub(super) fn match_projection_projections( . &mut self, . obligation: &ProjectionTyObligation<'tcx>, . env_predicate: PolyProjectionPredicate<'tcx>, . potentially_unnormalized_candidates: bool, . ) -> ProjectionMatchesProjection { . let mut nested_obligations = Vec::new(); 6,072 (0.0%) let infer_predicate = self.infcx.instantiate_binder_with_fresh_vars( 506 (0.0%) obligation.cause.span, . LateBoundRegionConversionTime::HigherRankedType, . env_predicate, . ); 1,012 (0.0%) let infer_projection = if potentially_unnormalized_candidates { . ensure_sufficient_stack(|| { . project::normalize_with_depth_to( . self, . obligation.param_env, . obligation.cause.clone(), . obligation.recursion_depth + 1, . infer_predicate.projection_ty, . &mut nested_obligations, . ) . }) . } else { 1,518 (0.0%) infer_predicate.projection_ty . }; . 506 (0.0%) let is_match = self . .infcx 506 (0.0%) .at(&obligation.cause, obligation.param_env) . .sup(DefineOpaqueTypes::No, obligation.predicate, infer_projection) 2,530 (0.0%) .is_ok_and(|InferOk { obligations, value: () }| { . self.evaluate_predicates_recursively( . TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()), . nested_obligations.into_iter().chain(obligations), . ) 982 (0.0%) .is_ok_and(|res| res.may_apply()) . }); . 982 (0.0%) if is_match { 982 (0.0%) let generics = self.tcx().generics_of(obligation.predicate.def_id); . // FIXME(generic-associated-types): Addresses aggressive inference in #92917. . // If this type is a GAT, and of the GAT args resolve to something new, . // that means that we must have newly inferred something about the GAT. . // We should give up in that case. 491 (0.0%) if !generics.params.is_empty() . && obligation.predicate.args[generics.parent_count..] . .iter() . .any(|&p| p.has_non_region_infer() && self.infcx.shallow_resolve(p) != p) . { . ProjectionMatchesProjection::Ambiguous . } else { . ProjectionMatchesProjection::Yes . } . } else { . ProjectionMatchesProjection::No . } 4,048 (0.0%) } . } . . #[derive(Debug, Copy, Clone, PartialEq, Eq)] . enum DropVictim { . Yes, . No, . } . -- line 1766 ---------------------------------------- -- line 1800 ---------------------------------------- . |cand: &ty::PolyTraitPredicate<'tcx>| cand.is_global() && !cand.has_late_bound_vars(); . . // (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`, . // `DiscriminantKindCandidate`, `ConstDestructCandidate` . // to anything else. . // . // This is a fix for #53123 and prevents winnowing from accidentally extending the . // lifetime of a variable. 220,283 (0.0%) match (&other.candidate, &victim.candidate) { . // FIXME(@jswrenn): this should probably be more sophisticated . (TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => DropVictim::No, . . // (*) . (BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_), _) => { . DropVictim::Yes . } . (_, BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_)) => { -- line 1816 ---------------------------------------- -- line 1885 ---------------------------------------- . | TraitUpcastingUnsizeCandidate(_) . | BuiltinCandidate { has_nested: true } . | TraitAliasCandidate, . ParamCandidate(ref victim_cand), . ) => { . // Prefer these to a global where-clause bound . // (see issue #50825). . DropVictim::drop_if( 30 (0.0%) is_global(victim_cand) && other.evaluation.must_apply_modulo_regions(), . ) . } . . (ProjectionCandidate(i, _), ProjectionCandidate(j, _)) . | (ObjectCandidate(i), ObjectCandidate(j)) => { . // Arbitrarily pick the lower numbered candidate for backwards . // compatibility reasons. Don't let this affect inference. . DropVictim::drop_if(i < j && !has_non_region_infer) -- line 1901 ---------------------------------------- -- line 1902 ---------------------------------------- . } . (ObjectCandidate(_), ProjectionCandidate(..)) . | (ProjectionCandidate(..), ObjectCandidate(_)) => { . bug!("Have both object and projection candidate") . } . . // Arbitrarily give projection and object candidates priority. . ( 16,754 (0.0%) ObjectCandidate(_) | ProjectionCandidate(..), . ImplCandidate(..) . | AutoImplCandidate . | ClosureCandidate { .. } . | GeneratorCandidate . | FutureCandidate . | FnPointerCandidate { .. } . | BuiltinObjectCandidate . | BuiltinUnsizeCandidate -- line 1918 ---------------------------------------- -- line 1928 ---------------------------------------- . | GeneratorCandidate . | FutureCandidate . | FnPointerCandidate { .. } . | BuiltinObjectCandidate . | BuiltinUnsizeCandidate . | TraitUpcastingUnsizeCandidate(_) . | BuiltinCandidate { .. } . | TraitAliasCandidate, 33,508 (0.0%) ObjectCandidate(_) | ProjectionCandidate(..), . ) => DropVictim::No, . 41,885 (0.0%) (&ImplCandidate(other_def), &ImplCandidate(victim_def)) => { . // See if we can toss out `victim` based on specialization. . // While this requires us to know *for sure* that the `other` impl applies . // we still use modulo regions here. . // . // This is fine as specialization currently assumes that specializing . // impls have to be always applicable, meaning that the only allowed . // region constraints may be constraints also present on the default impl. . let tcx = self.tcx(); 50,262 (0.0%) if other.evaluation.must_apply_modulo_regions() { 6,476 (0.0%) if tcx.specializes((other_def, victim_def)) { . return DropVictim::Yes; . } . } . 125,640 (0.0%) match tcx.impls_are_allowed_to_overlap(other_def, victim_def) { . // For #33140 the impl headers must be exactly equal, the trait must not have . // any associated items and there are no where-clauses. . // . // We can just arbitrarily drop one of the impls. . Some(ty::ImplOverlapKind::Issue33140) => { . assert_eq!(other.evaluation, victim.evaluation); . DropVictim::Yes . } -- line 1962 ---------------------------------------- -- line 2050 ---------------------------------------- . | BuiltinCandidate { has_nested: true } . | TraitAliasCandidate, . ) => DropVictim::No, . } . } . } . . impl<'tcx> SelectionContext<'_, 'tcx> { 128,376 (0.0%) fn sized_conditions( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . ) -> BuiltinImplConditions<'tcx> { . use self::BuiltinImplConditions::{Ambiguous, None, Where}; . . // NOTE: binder moved to (*) 48,141 (0.0%) let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty()); . 80,237 (0.0%) match self_ty.kind() { . ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) . | ty::Uint(_) . | ty::Int(_) . | ty::Bool . | ty::Float(_) . | ty::FnDef(..) . | ty::FnPtr(_) . | ty::RawPtr(..) -- line 2075 ---------------------------------------- -- line 2079 ---------------------------------------- . | ty::GeneratorWitness(..) . | ty::GeneratorWitnessMIR(..) . | ty::Array(..) . | ty::Closure(..) . | ty::Never . | ty::Dynamic(_, _, ty::DynStar) . | ty::Error(_) => { . // safe for everything 53 (0.0%) Where(ty::Binder::dummy(Vec::new())) . } . . ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None, . 33 (0.0%) ty::Tuple(tys) => Where( 51 (0.0%) obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])), . ), . . ty::Adt(def, args) => { 29,510 (0.0%) let sized_crit = def.sized_constraint(self.tcx()); . // (*) binder moved here 73,775 (0.0%) Where( . obligation . .predicate 14,755 (0.0%) .rebind(sized_crit.iter_instantiated_copied(self.tcx(), args).collect()), . ) . } . . ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => None, . ty::Infer(ty::TyVar(_)) => Ambiguous, . . // We can make this an ICE if/once we actually instantiate the trait obligation eagerly. . ty::Bound(..) => None, . . ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { . bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); . } . } 96,282 (0.0%) } . 1,050 (0.0%) fn copy_clone_conditions( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . ) -> BuiltinImplConditions<'tcx> { . // NOTE: binder moved to (*) 315 (0.0%) let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty()); . . use self::BuiltinImplConditions::{Ambiguous, None, Where}; . 535 (0.0%) match *self_ty.kind() { . ty::Infer(ty::IntVar(_)) . | ty::Infer(ty::FloatVar(_)) . | ty::FnDef(..) . | ty::FnPtr(_) . | ty::Error(_) => Where(ty::Binder::dummy(Vec::new())), . . ty::Uint(_) . | ty::Int(_) -- line 2135 ---------------------------------------- -- line 2146 ---------------------------------------- . . ty::Dynamic(..) . | ty::Str . | ty::Slice(..) . | ty::Generator(_, _, hir::Movability::Static) . | ty::Foreign(..) . | ty::Ref(_, _, hir::Mutability::Mut) => None, . 2 (0.0%) ty::Tuple(tys) => { . // (*) binder moved here 10 (0.0%) Where(obligation.predicate.rebind(tys.iter().collect())) . } . . ty::Generator(_, args, hir::Movability::Movable) => { . if self.tcx().features().generator_clone { . let resolved_upvars = . self.infcx.shallow_resolve(args.as_generator().tupled_upvars_ty()); . let resolved_witness = . self.infcx.shallow_resolve(args.as_generator().witness()); -- line 2164 ---------------------------------------- -- line 2198 ---------------------------------------- . self.infcx, . def_id, . args, . obligation.predicate.bound_vars(), . ); . Where(hidden_types) . } . 1 (0.0%) ty::Closure(_, args) => { . // (*) binder moved here 3 (0.0%) let ty = self.infcx.shallow_resolve(args.as_closure().tupled_upvars_ty()); 2 (0.0%) if let ty::Infer(ty::TyVar(_)) = ty.kind() { . // Not yet resolved. . Ambiguous . } else { 7 (0.0%) Where(obligation.predicate.rebind(args.as_closure().upvar_tys().collect())) . } . } . . ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => { . // Fallback to whatever user-defined impls exist in this case. . None . } . -- line 2221 ---------------------------------------- -- line 2228 ---------------------------------------- . . // We can make this an ICE if/once we actually instantiate the trait obligation eagerly. . ty::Bound(..) => None, . . ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { . bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); . } . } 840 (0.0%) } . . /// For default impls, we need to break apart a type into its . /// "constituent types" -- meaning, the types that it contains. . /// . /// Here are some (simple) examples: . /// . /// ```ignore (illustrative) . /// (i32, u32) -> [i32, u32] -- line 2244 ---------------------------------------- -- line 2322 ---------------------------------------- . // We can resolve the `impl Trait` to its concrete type, . // which enforces a DAG between the functions requiring . // the auto trait bounds in question. . t.rebind(vec![ty.instantiate(self.tcx(), args)]) . } . }) . } . 60 (0.0%) fn collect_predicates_for_types( . &mut self, . param_env: ty::ParamEnv<'tcx>, . cause: ObligationCause<'tcx>, . recursion_depth: usize, . trait_def_id: DefId, . types: ty::Binder<'tcx, Vec>>, . ) -> Vec> { . // Because the types were potentially derived from -- line 2338 ---------------------------------------- -- line 2349 ---------------------------------------- . // 2. Produce something like `&'0 i32 : Copy` . // 3. Re-bind the regions back to `for<'a> &'a i32 : Copy` . . types . .as_ref() . .skip_binder() // binder moved -\ . .iter() . .flat_map(|ty| { 5 (0.0%) let ty: ty::Binder<'tcx, Ty<'tcx>> = types.rebind(*ty); // <----/ . 25 (0.0%) let placeholder_ty = self.infcx.instantiate_binder_with_placeholders(ty); 20 (0.0%) let Normalized { value: normalized_ty, mut obligations } = 15 (0.0%) ensure_sufficient_stack(|| { . project::normalize_with_depth( . self, 5 (0.0%) param_env, . cause.clone(), 5 (0.0%) recursion_depth, 5 (0.0%) placeholder_ty, . ) . }); . . let obligation = Obligation::new( . self.tcx(), . cause.clone(), 5 (0.0%) param_env, 15 (0.0%) ty::TraitRef::new(self.tcx(), trait_def_id, [normalized_ty]), . ); 30 (0.0%) obligations.push(obligation); 15 (0.0%) obligations . }) . .collect() 30 (0.0%) } . . /////////////////////////////////////////////////////////////////////////// . // Matching . // . // Matching is a common path used for both evaluation and . // confirmation. It basically unifies types that appear in impls . // and traits. This does affect the surrounding environment; . // therefore, when used during evaluation, match routines must be -- line 2389 ---------------------------------------- -- line 2391 ---------------------------------------- . // contained. . . fn rematch_impl( . &mut self, . impl_def_id: DefId, . obligation: &PolyTraitObligation<'tcx>, . ) -> Normalized<'tcx, GenericArgsRef<'tcx>> { . let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap(); 4,090,692 (0.0%) match self.match_impl(impl_def_id, impl_trait_ref, obligation) { 1,363,564 (0.0%) Ok(args) => args, . Err(()) => { . // FIXME: A rematch may fail when a candidate cache hit occurs . // on thefreshened form of the trait predicate, but the match . // fails for some reason that is not captured in the freshened . // cache key. For example, equating an impl trait ref against . // the placeholder trait ref may fail due the Generalizer relation . // raising a CyclicalTy error due to a sub_root_var relation . // for a variable being generalized... -- line 2408 ---------------------------------------- -- line 2420 ---------------------------------------- . lt_op: |l| l, . ct_op: |c| c, . }); . Normalized { value, obligations: vec![] } . } . } . } . 13,422,304 (0.0%) #[instrument(level = "debug", skip(self), ret)] . fn match_impl( . &mut self, . impl_def_id: DefId, . impl_trait_ref: EarlyBinder>, . obligation: &PolyTraitObligation<'tcx>, . ) -> Result>, ()> { . let placeholder_obligation = 4,314,312 (0.0%) self.infcx.instantiate_binder_with_placeholders(obligation.predicate); . let placeholder_obligation_trait_ref = placeholder_obligation.trait_ref; . 4,314,312 (0.0%) let impl_args = self.infcx.fresh_args_for_item(obligation.cause.span, impl_def_id); . . let impl_trait_ref = impl_trait_ref.instantiate(self.tcx(), impl_args); . if impl_trait_ref.references_error() { . return Err(()); . } . . debug!(?impl_trait_ref); . 4,793,680 (0.0%) let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } = . ensure_sufficient_stack(|| { 958,736 (0.0%) project::normalize_with_depth( . self, 479,368 (0.0%) obligation.param_env, . obligation.cause.clone(), 958,736 (0.0%) obligation.recursion_depth + 1, 2,876,208 (0.0%) impl_trait_ref, . ) . }); . . debug!(?impl_trait_ref, ?placeholder_obligation_trait_ref); . . let cause = ObligationCause::new( . obligation.cause.span, . obligation.cause.body_id, . ObligationCauseCode::MatchImpl(obligation.cause.clone(), impl_def_id), . ); . 479,368 (0.0%) let InferOk { obligations, .. } = self . .infcx 479,368 (0.0%) .at(&cause, obligation.param_env) . .eq(DefineOpaqueTypes::No, placeholder_obligation_trait_ref, impl_trait_ref) . .map_err(|e| { . debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx())) . })?; . nested_obligations.extend(obligations); . 958,050 (0.0%) if !self.is_intercrate() . && self.tcx().impl_polarity(impl_def_id) == ty::ImplPolarity::Reservation . { . debug!("reservation impls only apply in intercrate mode"); . return Err(()); . } . 1,916,104 (0.0%) Ok(Normalized { value: impl_args, obligations: nested_obligations }) . } . . /// Normalize `where_clause_trait_ref` and try to match it against . /// `obligation`. If successful, return any predicates that . /// result from the normalization. 635,364 (0.0%) fn match_where_clause_trait_ref( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . where_clause_trait_ref: ty::PolyTraitRef<'tcx>, . ) -> Result>, ()> { . self.match_poly_trait_ref(obligation, where_clause_trait_ref) 564,768 (0.0%) } . . /// Returns `Ok` if `poly_trait_ref` being true implies that the . /// obligation is satisfied. . #[instrument(skip(self), level = "debug")] . fn match_poly_trait_ref( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . poly_trait_ref: ty::PolyTraitRef<'tcx>, . ) -> Result>, ()> { 79,046 (0.0%) self.infcx 237,138 (0.0%) .at(&obligation.cause, obligation.param_env) 158,092 (0.0%) .sup(DefineOpaqueTypes::No, obligation.predicate.to_poly_trait_ref(), poly_trait_ref) . .map(|InferOk { obligations, .. }| obligations) . .map_err(|_| ()) . } . . /////////////////////////////////////////////////////////////////////////// . // Miscellany . . fn match_fresh_trait_refs( . &self, . previous: ty::PolyTraitPredicate<'tcx>, . current: ty::PolyTraitPredicate<'tcx>, . param_env: ty::ParamEnv<'tcx>, . ) -> bool { 64,791 (0.0%) let mut matcher = ty::_match::Match::new(self.tcx(), param_env); . matcher.relate(previous, current).is_ok() . } . . fn push_stack<'o>( . &mut self, . previous_stack: TraitObligationStackList<'o, 'tcx>, . obligation: &'o PolyTraitObligation<'tcx>, . ) -> TraitObligationStack<'o, 'tcx> { 147,278,879 (0.1%) let fresh_trait_pred = obligation.predicate.fold_with(&mut self.freshener); . . let dfn = previous_stack.cache.next_dfn(); 41,975,732 (0.0%) let depth = previous_stack.depth() + 1; 256,261,398 (0.1%) TraitObligationStack { . obligation, . fresh_trait_pred, . reached_depth: Cell::new(depth), . previous: previous_stack, . dfn, . depth, . } . } . . #[instrument(skip(self), level = "debug")] . fn closure_trait_ref_unnormalized( . &mut self, . obligation: &PolyTraitObligation<'tcx>, . args: GenericArgsRef<'tcx>, . ) -> ty::PolyTraitRef<'tcx> { 70 (0.0%) let closure_sig = args.as_closure().sig(); . . debug!(?closure_sig); . . // NOTE: The self-type is an unboxed closure type and hence is . // in fact unparameterized (or at least does not reference any . // regions bound in the obligation). 28 (0.0%) let self_ty = obligation . .predicate . .self_ty() . .no_bound_vars() . .expect("unboxed closure type should not capture bound vars from the predicate"); . . closure_trait_ref_and_return_type( . self.tcx(), 28 (0.0%) obligation.predicate.def_id(), . self_ty, . closure_sig, . util::TupleArgumentsFlag::No, . ) . .map_bound(|(trait_ref, _)| trait_ref) . } . . /// Returns the obligations that are implied by instantiating an . /// impl or trait. The obligations are substituted and fully . /// normalized. This is used when confirming an impl or default . /// impl. 7,840,493 (0.0%) #[instrument(level = "debug", skip(self, cause, param_env))] . fn impl_or_trait_obligations( . &mut self, . cause: &ObligationCause<'tcx>, . recursion_depth: usize, . param_env: ty::ParamEnv<'tcx>, . def_id: DefId, // of impl or trait . args: GenericArgsRef<'tcx>, // for impl or trait . parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, -- line 2585 ---------------------------------------- -- line 2596 ---------------------------------------- . // U: Iterator, U: Sized, . // V: Iterator, V: Sized, . // ::Item: Copy . // When we substitute, say, `V => IntoIter, U => $0`, the last . // obligation will normalize to `<$0 as Iterator>::Item = $1` and . // `$1: Copy`, so we must ensure the obligations are emitted in . // that order. . let predicates = tcx.predicates_of(def_id); 340,891 (0.0%) assert_eq!(predicates.parent, None); 681,782 (0.0%) let predicates = predicates.instantiate_own(tcx, args); . let mut obligations = Vec::with_capacity(predicates.len()); 9,281,668 (0.0%) for (index, (predicate, span)) in predicates.into_iter().enumerate() { . let cause = 27,845,004 (0.0%) if Some(parent_trait_pred.def_id()) == tcx.lang_items().coerce_unsized_trait() { . cause.clone() . } else { 34,794,915 (0.0%) cause.clone().derived_cause(parent_trait_pred, |derived| { . ImplDerivedObligation(Box::new(ImplDerivedObligationCause { . derived, 6,958,983 (0.0%) impl_or_alias_def_id: def_id, 4,639,322 (0.0%) impl_def_predicate_index: Some(index), 4,639,322 (0.0%) span, . })) . }) . }; 11,602,085 (0.0%) let clause = normalize_with_depth_to( . self, . param_env, . cause.clone(), . recursion_depth, . predicate, . &mut obligations, . ); 23,204,170 (0.0%) obligations.push(Obligation { 9,281,668 (0.0%) cause, . recursion_depth, . param_env, 6,961,251 (0.0%) predicate: clause.as_predicate(), . }); . } . 2,386,237 (0.0%) obligations . } . } . . impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> { . fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> { . TraitObligationStackList::with(self) . } . -- line 2645 ---------------------------------------- -- line 2761 ---------------------------------------- . struct ProvisionalEvaluation { . from_dfn: usize, . reached_depth: usize, . result: EvaluationResult, . } . . impl<'tcx> Default for ProvisionalEvaluationCache<'tcx> { . fn default() -> Self { 1,802,916 (0.0%) Self { dfn: Cell::new(0), map: Default::default(), wf_args: Default::default() } . } . } . . impl<'tcx> ProvisionalEvaluationCache<'tcx> { . /// Get the next DFN in sequence (basically a counter). . fn next_dfn(&self) -> usize { . let result = self.dfn.get(); 20,999,159 (0.0%) self.dfn.set(result + 1); . result . } . . /// Check the provisional cache for any result for . /// `fresh_trait_ref`. If there is a hit, then you must consider . /// it an access to the stack slots at depth . /// `reached_depth` (from the returned value). . fn get_provisional( -- line 2785 ---------------------------------------- -- line 2787 ---------------------------------------- . fresh_trait_pred: ty::PolyTraitPredicate<'tcx>, . ) -> Option { . debug!( . ?fresh_trait_pred, . "get_provisional = {:#?}", . self.map.borrow().get(&fresh_trait_pred), . ); . Some(*self.map.borrow().get(&fresh_trait_pred)?) 225,120 (0.0%) } . . /// Insert a provisional result into the cache. The result came . /// from the node with the given DFN. It accessed a minimum depth . /// of `reached_depth` to compute. It evaluated `fresh_trait_pred` . /// and resulted in `result`. . fn insert_provisional( . &self, . from_dfn: usize, -- line 2803 ---------------------------------------- -- line 2908 ---------------------------------------- . } . . impl<'o, 'tcx> TraitObligationStackList<'o, 'tcx> { . fn empty(cache: &'o ProvisionalEvaluationCache<'tcx>) -> TraitObligationStackList<'o, 'tcx> { . TraitObligationStackList { cache, head: None } . } . . fn with(r: &'o TraitObligationStack<'o, 'tcx>) -> TraitObligationStackList<'o, 'tcx> { 121,156 (0.0%) TraitObligationStackList { cache: r.cache(), head: Some(r) } . } . . fn head(&self) -> Option<&'o TraitObligationStack<'o, 'tcx>> { . self.head . } . . fn depth(&self) -> usize { 125,949,857 (0.1%) if let Some(head) = self.head { head.depth } else { 0 } . } . } . . impl<'o, 'tcx> Iterator for TraitObligationStackList<'o, 'tcx> { . type Item = &'o TraitObligationStack<'o, 'tcx>; . . fn next(&mut self) -> Option<&'o TraitObligationStack<'o, 'tcx>> { 776,923 (0.0%) let o = self.head?; 776,923 (0.0%) *self = o.previous; . Some(o) . } . } . . impl<'o, 'tcx> fmt::Debug for TraitObligationStack<'o, 'tcx> { . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { . write!(f, "TraitObligationStack({:?})", self.obligation) . } -- line 2941 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/alloc/src/boxed.rs -------------------------------------------------------------------------------- Ir__________________ 17,202 (0.0%) -- line 209 ---------------------------------------- . /// ``` . #[cfg(all(not(no_global_oom_handling)))] . #[inline(always)] . #[stable(feature = "rust1", since = "1.0.0")] . #[must_use] . #[rustc_diagnostic_item = "box_new"] . pub fn new(x: T) -> Self { . #[rustc_box] 46,378,548 (0.0%) Box::new(x) . } . . /// Constructs a new box with uninitialized contents. . /// . /// # Examples . /// . /// ``` . /// #![feature(new_uninit)] -- line 225 ---------------------------------------- -- line 440 ---------------------------------------- . // #[unstable(feature = "new_uninit", issue = "63291")] . pub fn new_uninit_in(alloc: A) -> Box, A> . where . A: Allocator, . { . let layout = Layout::new::>(); . // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable. . // That would make code size bigger. 15,400 (0.0%) match Box::try_new_uninit_in(alloc) { . Ok(m) => m, . Err(_) => handle_alloc_error(layout), . } . } . . /// Constructs a new box with uninitialized contents in the provided allocator, . /// returning an error if the allocation fails . /// -- line 456 ---------------------------------------- -- line 1226 ---------------------------------------- . #[inline] . fn drop(&mut self) { . // the T in the Box is dropped by the compiler before the destructor is run . . let ptr = self.0; . . unsafe { . let layout = Layout::for_value_raw(ptr.as_ptr()); 24,188 (0.0%) if layout.size() != 0 { . self.1.deallocate(From::from(ptr.cast()), layout); . } . } . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] -- line 1242 ---------------------------------------- -- line 1285 ---------------------------------------- . /// . /// // The value is the same . /// assert_eq!(x, y); . /// . /// // But they are unique objects . /// assert_ne!(&*x as *const i32, &*y as *const i32); . /// ``` . #[inline] 497 (0.0%) fn clone(&self) -> Self { . // Pre-allocate memory to allow writing the cloned value directly. . let mut boxed = Self::new_uninit_in(self.1.clone()); . unsafe { 21 (0.0%) (**self).write_clone_into_raw(boxed.as_mut_ptr()); . boxed.assume_init() . } 568 (0.0%) } . . /// Copies `source`'s contents into `self` without creating a new allocation. . /// . /// # Examples . /// . /// ``` . /// let x = Box::new(5); . /// let mut y = Box::new(10); -- line 1308 ---------------------------------------- -- line 1331 ---------------------------------------- . unsafe { from_boxed_utf8_unchecked(buf) } . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl PartialEq for Box { . #[inline] . fn eq(&self, other: &Self) -> bool { 9,597,542,916 (4.0%) PartialEq::eq(&**self, &**other) . } . #[inline] . fn ne(&self, other: &Self) -> bool { . PartialEq::ne(&**self, &**other) . } . } . #[stable(feature = "rust1", since = "1.0.0")] . impl PartialOrd for Box { -- line 1347 ---------------------------------------- -- line 1374 ---------------------------------------- . } . } . #[stable(feature = "rust1", since = "1.0.0")] . impl Eq for Box {} . . #[stable(feature = "rust1", since = "1.0.0")] . impl Hash for Box { . fn hash(&self, state: &mut H) { 254 (0.0%) (**self).hash(state); . } . } . . #[stable(feature = "indirect_hasher_impl", since = "1.22.0")] . impl Hasher for Box { . fn finish(&self) -> u64 { . (**self).finish() . } -- line 1390 ---------------------------------------- -- line 1729 ---------------------------------------- . /// . /// let my_string = "Hello World".to_string(); . /// print_if_string(Box::new(my_string)); . /// print_if_string(Box::new(0i8)); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn downcast(self) -> Result, Self> { 1 (0.0%) if self.is::() { unsafe { Ok(self.downcast_unchecked::()) } } else { Err(self) } . } . . /// Downcasts the box to a concrete type. . /// . /// For a safe alternative see [`downcast`]. . /// . /// # Examples . /// -- line 1745 ---------------------------------------- -- line 1788 ---------------------------------------- . /// . /// let my_string = "Hello World".to_string(); . /// print_if_string(Box::new(my_string)); . /// print_if_string(Box::new(0i8)); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn downcast(self) -> Result, Self> { 1 (0.0%) if self.is::() { unsafe { Ok(self.downcast_unchecked::()) } } else { Err(self) } . } . . /// Downcasts the box to a concrete type. . /// . /// For a safe alternative see [`downcast`]. . /// . /// # Examples . /// -- line 1804 ---------------------------------------- -- line 1889 ---------------------------------------- . Box::from_raw_in(raw as *mut T, alloc) . } . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl fmt::Display for Box { . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1,632 (0.0%) fmt::Display::fmt(&**self, f) . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl fmt::Debug for Box { . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { . fmt::Debug::fmt(&**self, f) . } -- line 1905 ---------------------------------------- -- line 1933 ---------------------------------------- . . #[unstable(feature = "receiver_trait", issue = "none")] . impl Receiver for Box {} . . #[stable(feature = "rust1", since = "1.0.0")] . impl Iterator for Box { . type Item = I::Item; . fn next(&mut self) -> Option { 54 (0.0%) (**self).next() . } . fn size_hint(&self) -> (usize, Option) { . (**self).size_hint() . } . fn nth(&mut self, n: usize) -> Option { . (**self).nth(n) . } . fn last(self) -> Option { -- line 1949 ---------------------------------------- -- line 1999 ---------------------------------------- . #[stable(feature = "fused", since = "1.26.0")] . impl FusedIterator for Box {} . . #[stable(feature = "boxed_closure_impls", since = "1.35.0")] . impl + ?Sized, A: Allocator> FnOnce for Box { . type Output = >::Output; . . extern "rust-call" fn call_once(self, args: Args) -> Self::Output { 12 (0.0%) >::call_once(*self, args) . } . } . . #[stable(feature = "boxed_closure_impls", since = "1.35.0")] . impl + ?Sized, A: Allocator> FnMut for Box { . extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { 553 (0.0%) >::call_mut(self, args) . } . } . . #[stable(feature = "boxed_closure_impls", since = "1.35.0")] . impl + ?Sized, A: Allocator> Fn for Box { . extern "rust-call" fn call(&self, args: Args) -> Self::Output { 7,248 (0.0%) >::call(self, args) . } . } . . #[unstable(feature = "coerce_unsized", issue = "18598")] . impl, U: ?Sized, A: Allocator> CoerceUnsized> for Box {} . . #[unstable(feature = "dispatch_from_dyn", issue = "none")] . impl, U: ?Sized> DispatchFromDyn> for Box {} . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "boxed_slice_from_iter", since = "1.32.0")] . impl FromIterator for Box<[I]> { 542 (0.0%) fn from_iter>(iter: T) -> Self { 1,643 (0.0%) iter.into_iter().collect::>().into_boxed_slice() 797 (0.0%) } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "box_slice_clone", since = "1.3.0")] . impl Clone for Box<[T], A> { 16,475 (0.0%) fn clone(&self) -> Self { . let alloc = Box::allocator(self).clone(); 9,885 (0.0%) self.to_vec_in(alloc).into_boxed_slice() 19,770 (0.0%) } . 49,568 (0.0%) fn clone_from(&mut self, other: &Self) { 24,784 (0.0%) if self.len() == other.len() { 12,392 (0.0%) self.clone_from_slice(&other); . } else { . *self = other.clone(); . } . } . } . . #[stable(feature = "box_borrow", since = "1.1.0")] . impl borrow::Borrow for Box { . fn borrow(&self) -> &T { 4,818 (0.0%) &**self . } . } . . #[stable(feature = "box_borrow", since = "1.1.0")] . impl borrow::BorrowMut for Box { . fn borrow_mut(&mut self) -> &mut T { 4,775 (0.0%) &mut **self . } . } . . #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")] . impl AsRef for Box { . fn as_ref(&self) -> &T { 2 (0.0%) &**self . } . } . . #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")] . impl AsMut for Box { . fn as_mut(&mut self) -> &mut T { . &mut **self . } -- line 2081 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/alloc/src/rc.rs -------------------------------------------------------------------------------- Ir___________________ 15,960,367,822 (6.6%) -- line 293 ---------------------------------------- . . /// Calculate layout for `RcBox` using the inner value's layout . fn rcbox_layout_for_value_layout(layout: Layout) -> Layout { . // 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). . Layout::new::>().extend(layout).unwrap().0.pad_to_align() 17,818 (0.0%) } . . /// A single-threaded reference-counting pointer. 'Rc' stands for 'Reference . /// Counted'. . /// . /// See the [module-level documentation](./index.html) for more details. . /// . /// The inherent methods of `Rc` are all associated functions, which means . /// that you have to call them as e.g., [`Rc::get_mut(&mut value)`][get_mut] instead of -- line 309 ---------------------------------------- -- line 361 ---------------------------------------- . fn inner(&self) -> &RcBox { . // This unsafety is ok because while this Rc is alive we're guaranteed . // that the inner pointer is valid. . unsafe { self.ptr.as_ref() } . } . . #[inline] . unsafe fn from_inner_in(ptr: NonNull>, alloc: A) -> Self { 3,330 (0.0%) Self { ptr, phantom: PhantomData, alloc } . } . . #[inline] . unsafe fn from_ptr_in(ptr: *mut RcBox, alloc: A) -> Self { . unsafe { Self::from_inner_in(NonNull::new_unchecked(ptr), alloc) } . } . } . -- line 377 ---------------------------------------- -- line 382 ---------------------------------------- . /// . /// ``` . /// use std::rc::Rc; . /// . /// let five = Rc::new(5); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] 3,236 (0.0%) pub fn new(value: T) -> Rc { . // There is an implicit weak pointer owned by all the strong . // pointers, which ensures that the weak destructor never frees . // the allocation while the strong destructor is running, even . // if the weak pointer is stored inside the strong one. . unsafe { . Self::from_inner( 9,130,611 (0.0%) Box::leak(Box::new(RcBox { strong: Cell::new(1), weak: Cell::new(1), value })) . .into(), . ) . } 4,854 (0.0%) } . . /// Constructs a new `Rc` while giving you a `Weak` to the allocation, . /// to allow you to construct a `T` which holds a weak pointer to itself. . /// . /// Generally, a structure circularly referencing itself, either directly or . /// indirectly, should not hold a strong reference to itself to prevent a memory leak. . /// Using this function, you get access to the weak pointer during the . /// initialization of `T`, before the `Rc` is created, such that you can -- line 409 ---------------------------------------- -- line 904 ---------------------------------------- . /// . /// let x = Rc::new(4); . /// let _y = Rc::clone(&x); . /// assert_eq!(*Rc::try_unwrap(x).unwrap_err(), 4); . /// ``` . #[inline] . #[stable(feature = "rc_unique", since = "1.4.0")] . pub fn try_unwrap(this: Self) -> Result { 114 (0.0%) if Rc::strong_count(&this) == 1 { . unsafe { . let val = ptr::read(&*this); // copy the contained object . let alloc = ptr::read(&this.alloc); // copy the allocator . . // Indicate to Weaks that they can't be promoted by decrementing . // the strong count, and then remove the implicit "strong weak" . // pointer while also handling drop logic by just crafting a . // fake Weak. -- line 920 ---------------------------------------- -- line 1553 ---------------------------------------- . /// assert_eq!(*x, 4); . /// . /// let _y = Rc::clone(&x); . /// assert!(Rc::get_mut(&mut x).is_none()); . /// ``` . #[inline] . #[stable(feature = "rc_unique", since = "1.4.0")] . pub fn get_mut(this: &mut Self) -> Option<&mut T> { 213 (0.0%) if Rc::is_unique(this) { unsafe { Some(Rc::get_mut_unchecked(this)) } } else { None } . } . . /// Returns a mutable reference into the given `Rc`, . /// without any check. . /// . /// See also [`get_mut`], which is safe and does appropriate checks. . /// . /// [`get_mut`]: Rc::get_mut -- line 1569 ---------------------------------------- -- line 1621 ---------------------------------------- . /// } . /// println!("{}", &*x); // Use-after-free . /// ``` . #[inline] . #[unstable(feature = "get_mut_unchecked", issue = "63292")] . pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T { . // We are careful to *not* create a reference covering the "count" fields, as . // this would conflict with accesses to the reference counts (e.g. by `Weak`). 2,863,965 (0.0%) unsafe { &mut (*this.ptr.as_ptr()).value } . } . . #[inline] . #[stable(feature = "ptr_eq", since = "1.17.0")] . /// Returns `true` if the two `Rc`s point to the same allocation in a vein similar to . /// [`ptr::eq`]. This function ignores the metadata of `dyn Trait` pointers. . /// . /// # Examples -- line 1637 ---------------------------------------- -- line 1642 ---------------------------------------- . /// let five = Rc::new(5); . /// let same_five = Rc::clone(&five); . /// let other_five = Rc::new(5); . /// . /// assert!(Rc::ptr_eq(&five, &same_five)); . /// assert!(!Rc::ptr_eq(&five, &other_five)); . /// ``` . pub fn ptr_eq(this: &Self, other: &Self) -> bool { 1,836,448,553 (0.8%) this.ptr.as_ptr() as *const () == other.ptr.as_ptr() as *const () . } . } . . impl Rc { . /// Makes a mutable reference into the given `Rc`. . /// . /// If there are other `Rc` pointers to the same allocation, then `make_mut` will . /// [`clone`] the inner value to a new allocation to ensure unique ownership. This is also -- line 1658 ---------------------------------------- -- line 1700 ---------------------------------------- . /// *Rc::make_mut(&mut data) += 1; . /// . /// assert!(76 == *data); . /// assert!(weak.upgrade().is_none()); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[inline] . #[stable(feature = "rc_unique", since = "1.4.0")] 1,631 (0.0%) pub fn make_mut(this: &mut Self) -> &mut T { 36,964 (0.0%) if Rc::strong_count(this) != 1 { . // Gotta clone the data, there are other Rcs. . // Pre-allocate memory to allow writing the cloned value directly. . let mut rc = Self::new_uninit_in(this.alloc.clone()); . unsafe { . let data = Rc::get_mut_unchecked(&mut rc); . (**this).write_clone_into_raw(data.as_mut_ptr()); 40 (0.0%) *this = rc.assume_init(); . } 26,830 (0.0%) } else if Rc::weak_count(this) != 0 { . // Can just steal the data, all that's left is Weaks . let mut rc = Self::new_uninit_in(this.alloc.clone()); . unsafe { . let data = Rc::get_mut_unchecked(&mut rc); . data.as_mut_ptr().copy_from_nonoverlapping(&**this, 1); . . this.inner().dec_strong(); . // Remove implicit strong-weak ref (no need to craft a fake -- line 1726 ---------------------------------------- -- line 1729 ---------------------------------------- . ptr::write(this, rc.assume_init()); . } . } . // This unsafety is ok because we're guaranteed that the pointer . // returned is the *only* pointer that will ever be returned to T. Our . // 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. 1,677 (0.0%) unsafe { &mut this.ptr.as_mut().value } 1,864 (0.0%) } . . /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the . /// clone. . /// . /// Assuming `rc_t` is of type `Rc`, this function is functionally equivalent to . /// `(*rc_t).clone()`, but will avoid cloning the inner value where possible. . /// . /// # Examples -- line 1746 ---------------------------------------- -- line 1852 ---------------------------------------- . /// The function `mem_to_rcbox` is called with the data pointer . /// and must return back a (potentially fat)-pointer for the `RcBox`. . #[cfg(not(no_global_oom_handling))] . unsafe fn allocate_for_layout( . value_layout: Layout, . allocate: impl FnOnce(Layout) -> Result, AllocError>, . mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox, . ) -> *mut RcBox { 46,780 (0.0%) let layout = rcbox_layout_for_value_layout(value_layout); . unsafe { . Rc::try_allocate_for_layout(value_layout, allocate, mem_to_rcbox) . .unwrap_or_else(|_| handle_alloc_error(layout)) . } . } . . /// Allocates an `RcBox` with sufficient space for . /// a possibly-unsized inner value where the value has the layout provided, -- line 1868 ---------------------------------------- -- line 1871 ---------------------------------------- . /// The function `mem_to_rcbox` is called with the data pointer . /// and must return back a (potentially fat)-pointer for the `RcBox`. . #[inline] . unsafe fn try_allocate_for_layout( . value_layout: Layout, . allocate: impl FnOnce(Layout) -> Result, AllocError>, . mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox, . ) -> Result<*mut RcBox, AllocError> { 31,529 (0.0%) let layout = rcbox_layout_for_value_layout(value_layout); . . // Allocate for the layout. 8,909 (0.0%) let ptr = allocate(layout)?; . . // Initialize the RcBox . let inner = mem_to_rcbox(ptr.as_non_null_ptr().as_ptr()); . unsafe { . debug_assert_eq!(Layout::for_value(&*inner), layout); . . ptr::write(&mut (*inner).strong, Cell::new(1)); . ptr::write(&mut (*inner).weak, Cell::new(1)); -- line 1890 ---------------------------------------- -- line 1904 ---------------------------------------- . Layout::for_value(&*ptr), . |layout| alloc.allocate(layout), . |mem| mem.with_metadata_of(ptr as *const RcBox), . ) . } . } . . #[cfg(not(no_global_oom_handling))] 9 (0.0%) fn from_box_in(src: Box) -> Rc { . unsafe { . let value_size = size_of_val(&*src); . let ptr = Self::allocate_for_ptr_in(&*src, Box::allocator(&src)); . . // Copy value as bytes . ptr::copy_nonoverlapping( . &*src as *const T as *const u8, 4 (0.0%) &mut (*ptr).value as *mut _ as *mut u8, . value_size, . ); . . // Free the allocation without dropping its contents . let (bptr, alloc) = Box::into_raw_with_allocator(src); . let src = Box::from_raw(bptr as *mut mem::ManuallyDrop); . drop(src); . . Self::from_ptr_in(ptr, alloc) . } 10 (0.0%) } . } . . impl Rc<[T]> { . /// Allocates an `RcBox<[T]>` with the given length. . #[cfg(not(no_global_oom_handling))] . unsafe fn allocate_for_slice(len: usize) -> *mut RcBox<[T]> { . unsafe { . Self::allocate_for_layout( -- line 1939 ---------------------------------------- -- line 1946 ---------------------------------------- . . /// Copy elements from slice into newly allocated `Rc<[T]>` . /// . /// Unsafe because the caller must either take ownership or bind `T: Copy` . #[cfg(not(no_global_oom_handling))] . unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> { . unsafe { . let ptr = Self::allocate_for_slice(v.len()); 1 (0.0%) ptr::copy_nonoverlapping(v.as_ptr(), &mut (*ptr).value as *mut [T] as *mut T, v.len()); . Self::from_ptr(ptr) . } . } . . /// Constructs an `Rc<[T]>` from an iterator known to be of a certain size. . /// . /// Behavior is undefined should the size be wrong. . #[cfg(not(no_global_oom_handling))] -- line 1962 ---------------------------------------- -- line 2043 ---------------------------------------- . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl Deref for Rc { . type Target = T; . . #[inline(always)] . fn deref(&self) -> &T { 3,204,059,255 (1.3%) &self.inner().value . } . } . . #[unstable(feature = "receiver_trait", issue = "none")] . impl Receiver for Rc {} . . #[stable(feature = "rust1", since = "1.0.0")] . unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Rc { -- line 2059 ---------------------------------------- -- line 2077 ---------------------------------------- . /// } . /// . /// let foo = Rc::new(Foo); . /// let foo2 = Rc::clone(&foo); . /// . /// drop(foo); // Doesn't print anything . /// drop(foo2); // Prints "dropped!" . /// ``` 96,754 (0.0%) fn drop(&mut self) { . unsafe { . self.inner().dec_strong(); 274,135,706 (0.1%) if self.inner().strong() == 0 { . // destroy the contained object 2,846,577 (0.0%) ptr::drop_in_place(Self::get_mut_unchecked(self)); . . // remove the implicit "strong weak" pointer now that we've . // destroyed the contents. . self.inner().dec_weak(); . 2,856,406 (0.0%) if self.inner().weak() == 0 { . self.alloc.deallocate(self.ptr.cast(), Layout::for_value(self.ptr.as_ref())); . } . } . } 119,742 (0.0%) } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl Clone for Rc { . /// Makes a clone of the `Rc` pointer. . /// . /// This creates another pointer to the same allocation, increasing the . /// strong reference count. -- line 2109 ---------------------------------------- -- line 2116 ---------------------------------------- . /// let five = Rc::new(5); . /// . /// let _ = Rc::clone(&five); . /// ``` . #[inline] . fn clone(&self) -> Self { . unsafe { . self.inner().inc_strong(); 51,210 (0.0%) Self::from_inner_in(self.ptr, self.alloc.clone()) . } . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl Default for Rc { . /// Creates a new `Rc`, with the `Default` value for `T`. -- line 2132 ---------------------------------------- -- line 2176 ---------------------------------------- . /// cost to pay off more easily. It's also more likely to have two `Rc` clones, that point to . /// the same value, than two `&T`s. . /// . /// We can only do this when `T: Eq` as a `PartialEq` might be deliberately irreflexive. . #[stable(feature = "rust1", since = "1.0.0")] . impl RcEqIdent for Rc { . #[inline] . fn eq(&self, other: &Rc) -> bool { 3,436,039,039 (1.4%) Rc::ptr_eq(self, other) || **self == **other . } . . #[inline] . fn ne(&self, other: &Rc) -> bool { . !Rc::ptr_eq(self, other) && **self != **other . } . } . -- line 2192 ---------------------------------------- -- line 2473 ---------------------------------------- . /// ``` . /// # use std::rc::Rc; . /// let original: Box = Box::new(1); . /// let shared: Rc = Rc::from(original); . /// assert_eq!(1, *shared); . /// ``` . #[inline] . fn from(v: Box) -> Rc { 3 (0.0%) Rc::from_box_in(v) . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "shared_from_slice", since = "1.21.0")] . impl From> for Rc<[T], A> { . /// Allocate a reference-counted slice and move `v`'s items into it. . /// -- line 2489 ---------------------------------------- -- line 2496 ---------------------------------------- . /// assert_eq!(vec![1, 2, 3], *shared); . /// ``` . #[inline] . fn from(v: Vec) -> Rc<[T], A> { . unsafe { . let (vec_ptr, len, cap, alloc) = v.into_raw_parts_with_alloc(); . . let rc_ptr = Self::allocate_for_slice_in(len, &alloc); 20 (0.0%) ptr::copy_nonoverlapping(vec_ptr, &mut (*rc_ptr).value as *mut [T] as *mut T, len); . . // Create a `Vec` with length 0, to deallocate the buffer . // without dropping its contents or the allocator . let _ = Vec::from_raw_parts_in(vec_ptr, 0, cap, &alloc); . . Self::from_ptr_in(rc_ptr, alloc) . } . } -- line 2512 ---------------------------------------- -- line 2750 ---------------------------------------- . Weak { . ptr: unsafe { NonNull::new_unchecked(ptr::invalid_mut::>(usize::MAX)) }, . alloc, . } . } . } . . pub(crate) fn is_dangling(ptr: *mut T) -> bool { 80 (0.0%) (ptr.cast::<()>()).addr() == usize::MAX . } . . /// Helper type to allow accessing the reference counts without . /// making any assertions about the data field. . struct WeakInner<'a> { . weak: &'a Cell, . strong: &'a Cell, . } -- line 2766 ---------------------------------------- -- line 3149 ---------------------------------------- . /// let other_weak_foo = Weak::clone(&weak_foo); . /// . /// drop(weak_foo); // Doesn't print anything . /// drop(foo); // Prints "dropped!" . /// . /// assert!(other_weak_foo.upgrade().is_none()); . /// ``` . fn drop(&mut self) { 57 (0.0%) let inner = if let Some(inner) = self.inner() { inner } else { return }; . . inner.dec_weak(); . // the weak count starts at 1, and will only go to zero if all . // the strong pointers have disappeared. 57 (0.0%) if inner.weak() == 0 { . unsafe { . self.alloc.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr())); . } . } . } . } . . #[stable(feature = "rc_weak", since = "1.4.0")] -- line 3170 ---------------------------------------- -- line 3232 ---------------------------------------- . . #[inline] . fn strong(&self) -> usize { . self.strong_ref().get() . } . . #[inline] . fn inc_strong(&self) { 405 (0.0%) let strong = self.strong(); . . // We insert an `assume` here to hint LLVM at an otherwise . // missed optimization. . // SAFETY: The reference count will never be zero when this is . // called. . unsafe { . core::intrinsics::assume(strong != 0); . } . . let strong = strong.wrapping_add(1); . self.strong_ref().set(strong); . . // We want to abort on overflow instead of dropping the value. . // Checking for overflow after the store instead of before . // allows for slightly better code generation. 235,036,943 (0.1%) if core::intrinsics::unlikely(strong == 0) { . abort(); . } . } . . #[inline] . fn dec_strong(&self) { . self.strong_ref().set(self.strong() - 1); . } -- line 3264 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/alloc/src/vec/into_iter.rs -------------------------------------------------------------------------------- Ir________________ 2,217,795 (0.0%) -- line 62 ---------------------------------------- . /// let vec = vec!['a', 'b', 'c']; . /// let mut into_iter = vec.into_iter(); . /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']); . /// let _ = into_iter.next().unwrap(); . /// assert_eq!(into_iter.as_slice(), &['b', 'c']); . /// ``` . #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")] . pub fn as_slice(&self) -> &[T] { 13,178 (0.0%) unsafe { slice::from_raw_parts(self.ptr, self.len()) } . } . . /// Returns the remaining items of this iterator as a mutable slice. . /// . /// # Examples . /// . /// ``` . /// let vec = vec!['a', 'b', 'c']; -- line 78 ---------------------------------------- -- line 110 ---------------------------------------- . /// let mut into_iter = std::mem::replace(&mut into_iter, Vec::new().into_iter()); . /// (&mut into_iter).for_each(drop); . /// std::mem::forget(into_iter); . /// ``` . /// . /// This method is used by in-place iteration, refer to the vec::in_place_collect . /// documentation for an overview. . #[cfg(not(no_global_oom_handling))] 1,831,025 (0.0%) pub(super) fn forget_allocation_drop_remaining(&mut self) { 732,700 (0.0%) let remaining = self.as_raw_mut_slice(); . . // overwrite the individual fields instead of creating a new . // struct and then overwriting &mut self. . // this creates less assembly 366,820 (0.0%) self.cap = 0; 366,820 (0.0%) self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) }; 366,820 (0.0%) self.ptr = self.buf.as_ptr(); 366,925 (0.0%) self.end = self.buf.as_ptr(); . . // Dropping the remaining elements can panic, so this needs to be . // done only after updating the other fields. . unsafe { . ptr::drop_in_place(remaining); . } 2,197,230 (0.0%) } . . /// Forgets to Drop the remaining elements while still allowing the backing allocation to be freed. . pub(crate) fn forget_remaining_elements(&mut self) { . // For th ZST case, it is crucial that we mutate `end` here, not `ptr`. . // `ptr` must stay aligned, while `end` may be unaligned. 3,686,016 (0.0%) self.end = self.ptr; . } . . #[cfg(not(no_global_oom_handling))] . #[inline] . pub(crate) fn into_vecdeque(self) -> VecDeque { . // Keep our `Drop` impl from dropping the elements and the allocator . let mut this = ManuallyDrop::new(self); . -- line 148 ---------------------------------------- -- line 181 ---------------------------------------- . unsafe impl Sync for IntoIter {} . . #[stable(feature = "rust1", since = "1.0.0")] . impl Iterator for IntoIter { . type Item = T; . . #[inline] . fn next(&mut self) -> Option { 247,635,797 (0.1%) if self.ptr == self.end { 55,929 (0.0%) None . } else if T::IS_ZST { . // `ptr` has to stay where it is to remain aligned, so we reduce the length by 1 by . // reducing the `end`. . self.end = self.end.wrapping_byte_sub(1); . . // Make up a value of this ZST. . Some(unsafe { mem::zeroed() }) . } else { . let old = self.ptr; 111,693,260 (0.0%) self.ptr = unsafe { self.ptr.add(1) }; . . Some(unsafe { ptr::read(old) }) . } . } . . #[inline] . fn size_hint(&self) -> (usize, Option) { . let exact = if T::IS_ZST { . self.end.addr().wrapping_sub(self.ptr.addr()) . } else { . unsafe { self.end.sub_ptr(self.ptr) } . }; 3 (0.0%) (exact, Some(exact)) . } . . #[inline] . fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { . let step_size = self.len().min(n); . let to_drop = ptr::slice_from_raw_parts_mut(self.ptr as *mut T, step_size); . if T::IS_ZST { . // See `next` for why we sub `end` here. -- line 221 ---------------------------------------- -- line 228 ---------------------------------------- . unsafe { . ptr::drop_in_place(to_drop); . } . NonZeroUsize::new(n - step_size).map_or(Ok(()), Err) . } . . #[inline] . fn count(self) -> usize { 2 (0.0%) self.len() . } . . #[inline] . fn next_chunk(&mut self) -> Result<[T; N], core::array::IntoIter> { . let mut raw_ary = MaybeUninit::uninit_array(); . . let len = self.len(); . -- line 244 ---------------------------------------- -- line 290 ---------------------------------------- . } . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl DoubleEndedIterator for IntoIter { . #[inline] . fn next_back(&mut self) -> Option { 47,871 (0.0%) if self.end == self.ptr { . None . } else if T::IS_ZST { . // See above for why 'ptr.offset' isn't used . self.end = self.end.wrapping_byte_sub(1); . . // Make up a value of this ZST. . Some(unsafe { mem::zeroed() }) . } else { 20,459 (0.0%) self.end = unsafe { self.end.sub(1) }; . . Some(unsafe { ptr::read(self.end) }) . } . } . . #[inline] . fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { . let step_size = self.len().min(n); -- line 315 ---------------------------------------- -- line 391 ---------------------------------------- . #[cfg(test)] . fn clone(&self) -> Self { . crate::slice::to_vec(self.as_slice(), self.alloc.deref().clone()).into_iter() . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter { 13,792,390 (0.0%) fn drop(&mut self) { . struct DropGuard<'a, T, A: Allocator>(&'a mut IntoIter); . . impl Drop for DropGuard<'_, T, A> { . fn drop(&mut self) { . unsafe { . // `IntoIter::alloc` is not used anymore after this and will be dropped by RawVec . let alloc = ManuallyDrop::take(&mut self.0.alloc); . // RawVec handles deallocation 3,078,321 (0.0%) let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc); . } . } . } . . let guard = DropGuard(self); . // destroy the remaining elements . unsafe { 4,684,748 (0.0%) ptr::drop_in_place(guard.0.as_raw_mut_slice()); . } . // now `guard` will be dropped and do the rest 9,702,476 (0.0%) } . } . . // In addition to the SAFETY invariants of the following three unsafe traits . // also refer to the vec::in_place_collect module documentation to get an overview . #[unstable(issue = "none", feature = "inplace_iteration")] . #[doc(hidden)] . unsafe impl InPlaceIterable for IntoIter {} . -- line 427 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/alloc/src/vec/mod.rs -------------------------------------------------------------------------------- Ir________________ 270,617,451 (0.1%) -- line 413 ---------------------------------------- . /// # #![allow(unused_mut)] . /// let mut vec: Vec = Vec::new(); . /// ``` . #[inline] . #[rustc_const_stable(feature = "const_vec_new", since = "1.39.0")] . #[stable(feature = "rust1", since = "1.0.0")] . #[must_use] . pub const fn new() -> Self { 2,378,445 (0.0%) Vec { buf: RawVec::NEW, len: 0 } . } . . /// Constructs a new, empty `Vec` with at least the specified capacity. . /// . /// The vector will be able to hold at least `capacity` elements without . /// reallocating. This method is allowed to allocate for more elements than . /// `capacity`. If `capacity` is 0, the vector will not allocate. . /// -- line 429 ---------------------------------------- -- line 662 ---------------------------------------- . /// // allocation is necessary . /// let vec_units = Vec::<(), System>::with_capacity_in(10, System); . /// assert_eq!(vec_units.capacity(), usize::MAX); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[inline] . #[unstable(feature = "allocator_api", issue = "32838")] . pub fn with_capacity_in(capacity: usize, alloc: A) -> Self { 1,937,623 (0.0%) Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 } . } . . /// Creates a `Vec` directly from a pointer, a capacity, a length, . /// and an allocator. . /// . /// # Safety . /// . /// This is highly unsafe, due to the number of invariants that aren't -- line 678 ---------------------------------------- -- line 776 ---------------------------------------- . /// . /// assert_eq!(vec, &[1_000_000]); . /// assert_eq!(vec.capacity(), 16); . /// } . /// ``` . #[inline] . #[unstable(feature = "allocator_api", issue = "32838")] . pub unsafe fn from_raw_parts_in(ptr: *mut T, length: usize, capacity: usize, alloc: A) -> Self { 53,128 (0.0%) unsafe { Vec { buf: RawVec::from_raw_parts_in(ptr, capacity, alloc), len: length } } . } . . /// Decomposes a `Vec` into its raw components. . /// . /// Returns the raw pointer to the underlying data, the length of . /// the vector (in elements), and the allocated capacity of the . /// data (in elements). These are the same arguments in the same . /// order as the arguments to [`from_raw_parts`]. -- line 792 ---------------------------------------- -- line 901 ---------------------------------------- . /// ``` . /// let mut vec = vec![1]; . /// vec.reserve(10); . /// assert!(vec.capacity() >= 11); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn reserve(&mut self, additional: usize) { 1,704,464 (0.0%) self.buf.reserve(self.len, additional); . } . . /// Reserves the minimum capacity for at least `additional` more elements to . /// be inserted in the given `Vec`. Unlike [`reserve`], this will not . /// deliberately over-allocate to speculatively avoid frequent allocations. . /// After calling `reserve_exact`, capacity will be greater than or equal to . /// `self.len() + additional`. Does nothing if the capacity is already . /// sufficient. -- line 917 ---------------------------------------- -- line 931 ---------------------------------------- . /// ``` . /// let mut vec = vec![1]; . /// vec.reserve_exact(10); . /// assert!(vec.capacity() >= 11); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn reserve_exact(&mut self, additional: usize) { 13 (0.0%) self.buf.reserve_exact(self.len, additional); . } . . /// Tries to reserve capacity for at least `additional` more elements to be inserted . /// in the given `Vec`. The collection may reserve more space to speculatively avoid . /// frequent reallocations. After calling `try_reserve`, capacity will be . /// greater than or equal to `self.len() + additional` if it returns . /// `Ok(())`. Does nothing if capacity is already sufficient. This method . /// preserves the contents even if an error occurs. -- line 947 ---------------------------------------- -- line 1011 ---------------------------------------- . /// })); . /// . /// Ok(output) . /// } . /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?"); . /// ``` . #[stable(feature = "try_reserve", since = "1.57.0")] . pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> { 16,173 (0.0%) self.buf.try_reserve_exact(self.len, additional) . } . . /// Shrinks the capacity of the vector as much as possible. . /// . /// It will drop down as close as possible to the length but the allocator . /// may still inform the vector that there is space for a few more elements. . /// . /// # Examples -- line 1027 ---------------------------------------- -- line 1034 ---------------------------------------- . /// assert!(vec.capacity() >= 3); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn shrink_to_fit(&mut self) { . // The capacity is never less than the length, and there's nothing to do when . // they are equal, so we can avoid the panic case in `RawVec::shrink_to_fit` . // by only calling it with a greater capacity. 18,898 (0.0%) if self.capacity() > self.len { . self.buf.shrink_to_fit(self.len); . } . } . . /// Shrinks the capacity of the vector with a lower bound. . /// . /// The capacity will remain at least as large as both the length . /// and the supplied value. -- line 1050 ---------------------------------------- -- line 1092 ---------------------------------------- . /// vec.extend([1, 2, 3]); . /// . /// assert!(vec.capacity() >= 10); . /// let slice = vec.into_boxed_slice(); . /// assert_eq!(slice.into_vec().capacity(), 3); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] 35,840 (0.0%) pub fn into_boxed_slice(mut self) -> Box<[T], A> { . unsafe { . self.shrink_to_fit(); 11,506 (0.0%) let me = ManuallyDrop::new(self); . let buf = ptr::read(&me.buf); . let len = me.len(); . buf.into_box(len).assume_init() . } 47,794 (0.0%) } . . /// Shortens the vector, keeping the first `len` elements and dropping . /// the rest. . /// . /// If `len` is greater than the vector's current length, this has no . /// effect. . /// . /// The [`drain`] method can emulate `truncate`, but causes the excess -- line 1116 ---------------------------------------- -- line 1157 ---------------------------------------- . // case avoids creating an invalid slice, and . // * the `len` of the vector is shrunk before calling `drop_in_place`, . // such that no value will be dropped twice in case `drop_in_place` . // were to panic once (if it panics twice, the program aborts). . unsafe { . // Note: It's intentional that this is `>` and not `>=`. . // Changing it to `>=` has negative performance . // implications in some cases. See #78884 for more. 10,651 (0.0%) if len > self.len { . return; . } . let remaining_len = self.len - len; . let s = ptr::slice_from_raw_parts_mut(self.as_mut_ptr().add(len), remaining_len); 58,264 (0.0%) self.len = len; 3,397 (0.0%) ptr::drop_in_place(s); . } . } . . /// Extracts a slice containing the entire vector. . /// . /// Equivalent to `&s[..]`. . /// . /// # Examples -- line 1179 ---------------------------------------- -- line 1358 ---------------------------------------- . /// . /// Normally, here, one would use [`clear`] instead to correctly drop . /// the contents and thus not leak memory. . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub unsafe fn set_len(&mut self, new_len: usize) { . debug_assert!(new_len <= self.capacity()); . 822,523 (0.0%) self.len = new_len; . } . . /// Removes an element from the vector and returns it. . /// . /// The removed element is replaced by the last element of the vector. . /// . /// This does not preserve ordering, but is *O*(1). . /// If you need to preserve the element order, use [`remove`] instead. -- line 1374 ---------------------------------------- -- line 1395 ---------------------------------------- . pub fn swap_remove(&mut self, index: usize) -> T { . #[cold] . #[inline(never)] . fn assert_failed(index: usize, len: usize) -> ! { . panic!("swap_remove index (is {index}) should be < len (is {len})"); . } . . let len = self.len(); 534 (0.0%) if index >= len { . assert_failed(index, len); . } . unsafe { . // We replace self[index] with the last element. Note that if the . // bounds check above succeeds there must be a last element (which . // can be self[index] itself). . let value = ptr::read(self.as_ptr().add(index)); . let base_ptr = self.as_mut_ptr(); 387 (0.0%) ptr::copy(base_ptr.add(len - 1), base_ptr.add(index), 1); . self.set_len(len - 1); . value . } . } . . /// Inserts an element at position `index` within the vector, shifting all . /// elements after it to the right. . /// -- line 1420 ---------------------------------------- -- line 1438 ---------------------------------------- . #[inline(never)] . fn assert_failed(index: usize, len: usize) -> ! { . panic!("insertion index (is {index}) should be <= len (is {len})"); . } . . let len = self.len(); . . // space for the new element 4,332 (0.0%) if len == self.buf.capacity() { . self.reserve(1); . } . . unsafe { . // infallible . // The spot to put the new value . { . let p = self.as_mut_ptr().add(index); 6,719 (0.0%) if index < len { . // Shift everything over to make space. (Duplicating the . // `index`th element into two consecutive places.) . ptr::copy(p, p.add(1), len - index); 359 (0.0%) } else if index == len { . // No elements need shifting. . } else { . assert_failed(index, len); . } . // Write it in, overwriting the first copy of the `index`th . // element. . ptr::write(p, element); . } 2,323 (0.0%) self.set_len(len + 1); . } . } . . /// Removes and returns the element at position `index` within the vector, . /// shifting all elements after it to the left. . /// . /// Note: Because this shifts over the remaining elements, it has a . /// worst-case performance of *O*(*n*). If you don't need the order of elements -- line 1476 ---------------------------------------- -- line 1498 ---------------------------------------- . #[cold] . #[inline(never)] . #[track_caller] . fn assert_failed(index: usize, len: usize) -> ! { . panic!("removal index (is {index}) should be < len (is {len})"); . } . . let len = self.len(); 248 (0.0%) if index >= len { . assert_failed(index, len); . } . unsafe { . // infallible . let ret; . { . // the place we are taking from. . let ptr = self.as_mut_ptr().add(index); . // copy it out, unsafely having a copy of the value on . // the stack and in the vector at the same time. . ret = ptr::read(ptr); . . // Shift everything down to fill in that spot. 125 (0.0%) ptr::copy(ptr.add(1), ptr, len - index - 1); . } 2 (0.0%) self.set_len(len - 1); . ret . } . } . . /// Retains only the elements specified by the predicate. . /// . /// In other words, remove all elements `e` for which `f(&e)` returns `false`. . /// This method operates in place, visiting each element exactly once in the -- line 1530 ---------------------------------------- -- line 1544 ---------------------------------------- . /// ``` . /// let mut vec = vec![1, 2, 3, 4, 5]; . /// let keep = [false, true, true, false, true]; . /// let mut iter = keep.iter(); . /// vec.retain(|_| *iter.next().unwrap()); . /// assert_eq!(vec, [2, 3, 5]); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] 2,164,915 (0.0%) pub fn retain(&mut self, mut f: F) . where . F: FnMut(&T) -> bool, . { 2,940 (0.0%) self.retain_mut(|elem| f(elem)); 1,924,511 (0.0%) } . . /// Retains only the elements specified by the predicate, passing a mutable reference to it. . /// . /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`. . /// This method operates in place, visiting each element exactly once in the . /// original order, and preserves the order of the retained elements. . /// . /// # Examples -- line 1565 ---------------------------------------- -- line 1599 ---------------------------------------- . v: &'a mut Vec, . processed_len: usize, . deleted_cnt: usize, . original_len: usize, . } . . impl Drop for BackshiftOnDrop<'_, T, A> { . fn drop(&mut self) { 2 (0.0%) if self.deleted_cnt > 0 { . // SAFETY: Trailing unchecked items must be valid since we never touch them. . unsafe { . ptr::copy( . self.v.as_ptr().add(self.processed_len), . self.v.as_mut_ptr().add(self.processed_len - self.deleted_cnt), . self.original_len - self.processed_len, . ); . } . } . // SAFETY: After filling holes, all items are in contiguous memory. . unsafe { 394,857 (0.0%) self.v.set_len(self.original_len - self.deleted_cnt); . } . } . } . 964,918 (0.0%) let mut g = BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len }; . . fn process_loop( . original_len: usize, . f: &mut F, . g: &mut BackshiftOnDrop<'_, T, A>, . ) where . F: FnMut(&mut T) -> bool, . { 293,599,107 (0.1%) while g.processed_len != original_len { . // SAFETY: Unchecked element must be valid. . let cur = unsafe { &mut *g.v.as_mut_ptr().add(g.processed_len) }; 262,213,984 (0.1%) if !f(cur) { . // Advance early to avoid double drop if `drop_in_place` panicked. 64,024,801 (0.0%) g.processed_len += 1; 64,024,878 (0.0%) g.deleted_cnt += 1; . // SAFETY: We never touch this element again after dropped. 1,162 (0.0%) unsafe { ptr::drop_in_place(cur) }; . // We already advanced the counter. . if DELETED { . continue; . } else { . break; . } . } . if DELETED { . // SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element. . // We use copy for move, and never touch this element again. . unsafe { 73,743,306 (0.0%) let hole_slot = g.v.as_mut_ptr().add(g.processed_len - g.deleted_cnt); . ptr::copy_nonoverlapping(cur, hole_slot, 1); . } . } 36,874,812 (0.0%) g.processed_len += 1; . } . } . . // Stage 1: Nothing was deleted. . process_loop::(original_len, &mut f, &mut g); . . // Stage 2: Some elements were deleted. 286 (0.0%) process_loop::(original_len, &mut f, &mut g); . . // All item are processed. This can be optimized to `set_len` by LLVM. 3 (0.0%) drop(g); . } . . /// Removes all but the first of consecutive elements in the vector that resolve to the same . /// key. . /// . /// If the vector is sorted, this removes all duplicates. . /// . /// # Examples -- line 1676 ---------------------------------------- -- line 1706 ---------------------------------------- . /// ``` . /// let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"]; . /// . /// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b)); . /// . /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]); . /// ``` . #[stable(feature = "dedup_by", since = "1.16.0")] 2,002 (0.0%) pub fn dedup_by(&mut self, mut same_bucket: F) . where . F: FnMut(&mut T, &mut T) -> bool, . { . let len = self.len(); 2,005 (0.0%) if len <= 1 { . return; . } . . /* INVARIANT: vec.len() > read >= write > write-1 >= 0 */ . struct FillGapOnDrop<'a, T, A: core::alloc::Allocator> { . /* Offset of the element we want to check if it is duplicate */ . read: usize, . -- line 1727 ---------------------------------------- -- line 1799 ---------------------------------------- . } . . /* Technically we could let `gap` clean up with its Drop, but . * when `same_bucket` is guaranteed to not panic, this bloats a little . * the codegen, so we just do it manually */ . gap.vec.set_len(gap.write); . mem::forget(gap); . } 3,003 (0.0%) } . . /// Appends an element to the back of a collection. . /// . /// # Panics . /// . /// Panics if the new capacity exceeds `isize::MAX` bytes. . /// . /// # Examples -- line 1815 ---------------------------------------- -- line 1817 ---------------------------------------- . /// ``` . /// let mut vec = vec![1, 2]; . /// vec.push(3); . /// assert_eq!(vec, [1, 2, 3]); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] 205 (0.0%) pub fn push(&mut self, value: T) { . // This will panic or abort if we would allocate > isize::MAX bytes . // or if the length increment would overflow for zero-sized types. 44,333,899 (0.0%) if self.len == self.buf.capacity() { 835,299 (0.0%) self.buf.reserve_for_push(self.len); . } . unsafe { 597,395 (0.0%) let end = self.as_mut_ptr().add(self.len); . ptr::write(end, value); 20,441,666 (0.0%) self.len += 1; . } 164 (0.0%) } . . /// Appends an element if there is sufficient spare capacity, otherwise an error is returned . /// with the element. . /// . /// Unlike [`push`] this method will not reallocate when there's insufficient capacity. . /// The caller should use [`reserve`] or [`try_reserve`] to ensure that there is enough capacity. . /// . /// [`push`]: Vec::push -- line 1844 ---------------------------------------- -- line 1893 ---------------------------------------- . /// ``` . /// let mut vec = vec![1, 2, 3]; . /// assert_eq!(vec.pop(), Some(3)); . /// assert_eq!(vec, [1, 2]); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn pop(&mut self) -> Option { 14,370,000 (0.0%) if self.len == 0 { . None . } else { . unsafe { 27,955,440 (0.0%) self.len -= 1; 89,879 (0.0%) Some(ptr::read(self.as_ptr().add(self.len()))) . } . } . } . . /// Moves all the elements of `other` into `self`, leaving `other` empty. . /// . /// # Panics . /// -- line 1914 ---------------------------------------- -- line 1923 ---------------------------------------- . /// assert_eq!(vec, [1, 2, 3, 4, 5, 6]); . /// assert_eq!(vec2, []); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[inline] . #[stable(feature = "append", since = "1.4.0")] . pub fn append(&mut self, other: &mut Self) { . unsafe { 94 (0.0%) self.append_elements(other.as_slice() as _); . other.set_len(0); . } . } . . /// Appends elements to `self` from other buffer. . #[cfg(not(no_global_oom_handling))] . #[inline] . unsafe fn append_elements(&mut self, other: *const [T]) { . let count = unsafe { (*other).len() }; . self.reserve(count); . let len = self.len(); . unsafe { ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count) }; 3,197,656 (0.0%) self.len += count; . } . . /// Removes the specified range from the vector in bulk, returning all . /// removed elements as an iterator. If the iterator is dropped before . /// being fully consumed, it drops the remaining removed elements. . /// . /// The returned iterator keeps a mutable borrow on the vector to optimize . /// its implementation. -- line 1952 ---------------------------------------- -- line 1991 ---------------------------------------- . // . let len = self.len(); . let Range { start, end } = slice::range(range, ..len); . . unsafe { . // set self.vec length's to start, to be safe in case Drain is leaked . self.set_len(start); . let range_slice = slice::from_raw_parts(self.as_ptr().add(start), end - start); 76 (0.0%) Drain { . tail_start: end, . tail_len: len - end, . iter: range_slice.iter(), . vec: NonNull::from(self), . } . } . } . -- line 2007 ---------------------------------------- -- line 2026 ---------------------------------------- . . // SAFETY: . // - `elems` comes directly from `as_mut_slice` and is therefore valid. . // - Setting `self.len` before calling `drop_in_place` means that, . // if an element's `Drop` impl panics, the vector's `Drop` impl will . // do nothing (leaking the rest of the elements) instead of dropping . // some twice. . unsafe { 63,232 (0.0%) self.len = 0; . ptr::drop_in_place(elems); . } . } . . /// Returns the number of elements in the vector, also referred to . /// as its 'length'. . /// . /// # Examples -- line 2042 ---------------------------------------- -- line 2043 ---------------------------------------- . /// . /// ``` . /// let a = vec![1, 2, 3]; . /// assert_eq!(a.len(), 3); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn len(&self) -> usize { 25,266,712 (0.0%) self.len . } . . /// Returns `true` if the vector contains no elements. . /// . /// # Examples . /// . /// ``` . /// let mut v = Vec::new(); . /// assert!(v.is_empty()); . /// . /// v.push(1); . /// assert!(!v.is_empty()); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . pub fn is_empty(&self) -> bool { 120,147 (0.0%) self.len() == 0 . } . . /// Splits the collection into two at the given index. . /// . /// Returns a newly allocated vector containing the elements in the range . /// `[at, len)`. After the call, the original vector will be left containing . /// the elements `[0, at)` with its previous capacity unchanged. . /// -- line 2075 ---------------------------------------- -- line 2147 ---------------------------------------- . /// . /// let mut vec = vec![]; . /// let mut p = 1; . /// vec.resize_with(4, || { p *= 2; p }); . /// assert_eq!(vec, [2, 4, 8, 16]); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "vec_resize_with", since = "1.33.0")] 1,092 (0.0%) pub fn resize_with(&mut self, new_len: usize, f: F) . where . F: FnMut() -> T, . { . let len = self.len(); 572 (0.0%) if new_len > len { 61,456 (0.0%) self.extend_trusted(iter::repeat_with(f).take(new_len - len)); . } else { . self.truncate(new_len); . } 936 (0.0%) } . . /// Consumes and leaks the `Vec`, returning a mutable reference to the contents, . /// `&'a mut [T]`. Note that the type `T` must outlive the chosen lifetime . /// `'a`. If the type has only static references, or none at all, then this . /// may be chosen to be `'static`. . /// . /// As of Rust 1.57, this method does not reallocate or shrink the `Vec`, . /// so the leaked allocation may include unused capacity that is not part -- line 2173 ---------------------------------------- -- line 2228 ---------------------------------------- . #[stable(feature = "vec_spare_capacity", since = "1.60.0")] . #[inline] . pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit] { . // Note: . // This method is not implemented in terms of `split_at_spare_mut`, . // to prevent invalidation of pointers to the buffer. . unsafe { . slice::from_raw_parts_mut( 4 (0.0%) self.as_mut_ptr().add(self.len) as *mut MaybeUninit, 72 (0.0%) self.buf.capacity() - self.len, . ) . } . } . . /// Returns vector content as a slice of `T`, along with the remaining spare . /// capacity of the vector as a slice of `MaybeUninit`. . /// . /// The returned spare capacity slice can be used to fill the vector with data -- line 2245 ---------------------------------------- -- line 2351 ---------------------------------------- . /// assert_eq!(vec, [1, 2]); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "vec_resize", since = "1.5.0")] . pub fn resize(&mut self, new_len: usize, value: T) { . let len = self.len(); . . if new_len > len { 7 (0.0%) self.extend_with(new_len - len, value) . } else { . self.truncate(new_len); . } . } . . /// Clones and appends all elements in a slice to the `Vec`. . /// . /// Iterates over the slice `other`, clones each element, and then appends -- line 2367 ---------------------------------------- -- line 2379 ---------------------------------------- . /// vec.extend_from_slice(&[2, 3, 4]); . /// assert_eq!(vec, [1, 2, 3, 4]); . /// ``` . /// . /// [`extend`]: Vec::extend . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "vec_extend_from_slice", since = "1.6.0")] . pub fn extend_from_slice(&mut self, other: &[T]) { 309 (0.0%) self.spec_extend(other.iter()) . } . . /// Copies elements from `src` range to the end of the vector. . /// . /// # Panics . /// . /// Panics if the starting point is greater than the end point or if . /// the end point is greater than the length of the vector. -- line 2395 ---------------------------------------- -- line 2468 ---------------------------------------- . // - `len` <= `cap`, so `len * N` <= `cap * N`. . unsafe { Vec::::from_raw_parts_in(ptr.cast(), new_len, new_cap, alloc) } . } . } . . impl Vec { . #[cfg(not(no_global_oom_handling))] . /// Extend the vector by `n` clones of value. 40,404 (0.0%) fn extend_with(&mut self, n: usize, value: T) { . self.reserve(n); . . unsafe { . let mut ptr = self.as_mut_ptr().add(self.len()); . // Use SetLenOnDrop to work around bug where compiler . // might not realize the store through `ptr` through self.set_len() . // don't alias. . let mut local_len = SetLenOnDrop::new(&mut self.len); . . // Write all elements except the last one . for _ in 1..n { 2,720 (0.0%) ptr::write(ptr, value.clone()); . ptr = ptr.add(1); . // Increment the length in every step in case clone() panics . local_len.increment_len(1); . } . 9,879 (0.0%) if n > 0 { . // We can write the last element directly without cloning needlessly . ptr::write(ptr, value); . local_len.increment_len(1); . } . . // len set by scope guard . } 31,068 (0.0%) } . } . . impl Vec { . /// Removes consecutive repeated elements in the vector according to the . /// [`PartialEq`] trait implementation. . /// . /// If the vector is sorted, this removes all duplicates. . /// -- line 2510 ---------------------------------------- -- line 2515 ---------------------------------------- . /// . /// vec.dedup(); . /// . /// assert_eq!(vec, [1, 2, 3, 2]); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[inline] . pub fn dedup(&mut self) { 1,001 (0.0%) self.dedup_by(|a, b| a == b) . } . } . . //////////////////////////////////////////////////////////////////////////////// . // Internal methods and functions . //////////////////////////////////////////////////////////////////////////////// . . #[doc(hidden)] . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn from_elem(elem: T, n: usize) -> Vec { 16,966 (0.0%) ::from_elem(elem, n, Global) . } . . #[doc(hidden)] . #[cfg(not(no_global_oom_handling))] . #[unstable(feature = "allocator_api", issue = "32838")] . pub fn from_elem_in(elem: T, n: usize, alloc: A) -> Vec { . ::from_elem(elem, n, alloc) . } -- line 2543 ---------------------------------------- -- line 2602 ---------------------------------------- . //////////////////////////////////////////////////////////////////////////////// . . #[stable(feature = "rust1", since = "1.0.0")] . impl ops::Deref for Vec { . type Target = [T]; . . #[inline] . fn deref(&self) -> &[T] { 26,399,058 (0.0%) unsafe { slice::from_raw_parts(self.as_ptr(), self.len) } . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl ops::DerefMut for Vec { . #[inline] . fn deref_mut(&mut self) -> &mut [T] { 3,194,029 (0.0%) unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) } . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl Clone for Vec { . #[cfg(not(test))] 4,638,873 (0.0%) fn clone(&self) -> Self { . let alloc = self.allocator().clone(); 10,887 (0.0%) <[T]>::to_vec_in(&**self, alloc) 5,405,451 (0.0%) } . . // HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is . // required for this method definition, is not available. Instead use the . // `slice::to_vec` function which is only available with cfg(test) . // NB see the slice::hack module in slice.rs for more information . #[cfg(test)] . fn clone(&self) -> Self { . let alloc = self.allocator().clone(); -- line 2637 ---------------------------------------- -- line 2653 ---------------------------------------- . /// let v: Vec = vec![0xa8, 0x3c, 0x09]; . /// let s: &[u8] = &[0xa8, 0x3c, 0x09]; . /// assert_eq!(b.hash_one(v), b.hash_one(s)); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . impl Hash for Vec { . #[inline] . fn hash(&self, state: &mut H) { 8 (0.0%) Hash::hash(&**self, state) . } . } . . #[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`" . )] -- line 2669 ---------------------------------------- -- line 2688 ---------------------------------------- . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl FromIterator for Vec { . #[inline] . fn from_iter>(iter: I) -> Vec { 220,094 (0.0%) >::from_iter(iter.into_iter()) . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl IntoIterator for Vec { . type Item = T; . type IntoIter = IntoIter; . -- line 2704 ---------------------------------------- -- line 2725 ---------------------------------------- . let alloc = ManuallyDrop::new(ptr::read(me.allocator())); . let begin = me.as_mut_ptr(); . let end = if T::IS_ZST { . begin.wrapping_byte_add(me.len()) . } else { . begin.add(me.len()) as *const T . }; . let cap = me.buf.capacity(); 7,738,683 (0.0%) IntoIter { . buf: NonNull::new_unchecked(begin), . phantom: PhantomData, . cap, . alloc, . ptr: begin, . end, . } . } -- line 2741 ---------------------------------------- -- line 2744 ---------------------------------------- . . #[stable(feature = "rust1", since = "1.0.0")] . impl<'a, T, A: Allocator> IntoIterator for &'a Vec { . type Item = &'a T; . type IntoIter = slice::Iter<'a, T>; . . fn into_iter(self) -> Self::IntoIter { . self.iter() 3,723 (0.0%) } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl<'a, T, A: Allocator> IntoIterator for &'a mut Vec { . type Item = &'a mut T; . type IntoIter = slice::IterMut<'a, T>; . . fn into_iter(self) -> Self::IntoIter { -- line 2760 ---------------------------------------- -- line 2762 ---------------------------------------- . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl Extend for Vec { . #[inline] . fn extend>(&mut self, iter: I) { 80,289 (0.0%) >::spec_extend(self, iter.into_iter()) . } . . #[inline] . fn extend_one(&mut self, item: T) { . self.push(item); . } . . #[inline] -- line 2778 ---------------------------------------- -- line 2788 ---------------------------------------- . fn extend_desugared>(&mut self, mut iterator: I) { . // This is the case for a general iterator. . // . // This function should be the moral equivalent of: . // . // for item in iterator { . // self.push(item); . // } 424,264 (0.0%) while let Some(element) = iterator.next() { . let len = self.len(); 177,463 (0.0%) if len == self.capacity() { 388 (0.0%) let (lower, _) = iterator.size_hint(); . self.reserve(lower.saturating_add(1)); . } . unsafe { . ptr::write(self.as_mut_ptr().add(len), element); . // Since next() executes user code which can panic we have to bump the length . // after each step. . // NB can't overflow since we would have had to alloc the address space 89,653 (0.0%) self.set_len(len + 1); . } . } 12 (0.0%) } . . // specific extend for `TrustedLen` iterators, called both by the specializations . // and internal places where resolving specialization makes compilation slower . #[cfg(not(no_global_oom_handling))] . fn extend_trusted(&mut self, iterator: impl iter::TrustedLen) { 50,735 (0.0%) let (low, high) = iterator.size_hint(); 1,209 (0.0%) if let Some(additional) = high { . debug_assert_eq!( . low, . additional, . "TrustedLen iterator's size hint is not exact: {:?}", . (low, high) . ); . self.reserve(additional); . unsafe { . let ptr = self.as_mut_ptr(); . let mut local_len = SetLenOnDrop::new(&mut self.len); 382,087 (0.0%) iterator.for_each(move |element| { 196 (0.0%) ptr::write(ptr.add(local_len.current_len()), element); . // Since the loop executes user code which can panic we have to update . // the length every step to correctly drop what we've written. . // NB can't overflow since we would have had to alloc the address space . local_len.increment_len(1); . }); . } . } else { . // Per TrustedLen contract a `None` upper bound means that the iterator length -- line 2837 ---------------------------------------- -- line 2944 ---------------------------------------- . { . let old_len = self.len(); . . // Guard against us getting leaked (leak amplification) . unsafe { . self.set_len(0); . } . 17,628 (0.0%) ExtractIf { vec: self, idx: 0, del: 0, old_len, pred: filter } . } . } . . /// Extend implementation that copies elements out of references before pushing them onto the Vec. . /// . /// This implementation is specialized for slice iterators, where it uses [`copy_from_slice`] to . /// append the entire slice at once. . /// -- line 2960 ---------------------------------------- -- line 3000 ---------------------------------------- . #[inline] . fn cmp(&self, other: &Self) -> Ordering { . Ord::cmp(&**self, &**other) . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec { 159,397 (0.0%) fn drop(&mut self) { . unsafe { . // use drop for [T] . // use a raw slice to refer to the elements of the vector as weakest necessary type; . // could avoid questions of validity in certain cases 737,668 (0.0%) ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.as_mut_ptr(), self.len)) . } . // RawVec handles deallocation 190,100 (0.0%) } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl Default for Vec { . /// Creates an empty `Vec`. . /// . /// The vector will not allocate until elements are pushed onto it. 278 (0.0%) fn default() -> Vec { . Vec::new() . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl fmt::Debug for Vec { . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { . fmt::Debug::fmt(&**self, f) -- line 3032 ---------------------------------------- -- line 3046 ---------------------------------------- . self . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl AsRef<[T]> for Vec { . fn as_ref(&self) -> &[T] { . self 1,337 (0.0%) } . } . . #[stable(feature = "vec_as_mut", since = "1.5.0")] . impl AsMut<[T]> for Vec { . fn as_mut(&mut self) -> &mut [T] { . self . } . } -- line 3062 ---------------------------------------- -- line 3183 ---------------------------------------- . /// Any excess capacity is removed: . /// ``` . /// let mut vec = Vec::with_capacity(10); . /// vec.extend([1, 2, 3]); . /// . /// assert_eq!(Box::from(vec), vec![1, 2, 3].into_boxed_slice()); . /// ``` . fn from(v: Vec) -> Self { 1 (0.0%) v.into_boxed_slice() . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl From<&str> for Vec { . /// Allocate a `Vec` and fill it with a UTF-8 string. . /// -- line 3199 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/../../stdarch/crates/core_arch/src/x86/sse2.rs -------------------------------------------------------------------------------- Ir__________________ 236 (0.0%) -- line 798 ---------------------------------------- . /// Compares packed 8-bit integers in `a` and `b` for equality. . /// . /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpeq_epi8) . #[inline] . #[target_feature(enable = "sse2")] . #[cfg_attr(test, assert_instr(pcmpeqb))] . #[stable(feature = "simd_x86", since = "1.27.0")] . pub unsafe fn _mm_cmpeq_epi8(a: __m128i, b: __m128i) -> __m128i { 801,498 (0.0%) transmute::(simd_eq(a.as_i8x16(), b.as_i8x16())) . } . . /// Compares packed 16-bit integers in `a` and `b` for equality. . /// . /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpeq_epi16) . #[inline] . #[target_feature(enable = "sse2")] . #[cfg_attr(test, assert_instr(pcmpeqw))] -- line 814 ---------------------------------------- -- line 1180 ---------------------------------------- . /// `mem_addr` must be aligned on a 16-byte boundary. . /// . /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_load_si128) . #[inline] . #[target_feature(enable = "sse2")] . #[cfg_attr(test, assert_instr(movaps))] . #[stable(feature = "simd_x86", since = "1.27.0")] . pub unsafe fn _mm_load_si128(mem_addr: *const __m128i) -> __m128i { 6,925,660 (0.0%) *mem_addr . } . . /// Loads 128-bits of integer data from memory into a new vector. . /// . /// `mem_addr` does not need to be aligned on any particular boundary. . /// . /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadu_si128) . #[inline] -- line 1196 ---------------------------------------- -- line 1381 ---------------------------------------- . /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_movemask_epi8) . #[inline] . #[target_feature(enable = "sse2")] . #[cfg_attr(test, assert_instr(pmovmskb))] . #[stable(feature = "simd_x86", since = "1.27.0")] . pub unsafe fn _mm_movemask_epi8(a: __m128i) -> i32 { . let z = i8x16::splat(0); . let m: i8x16 = simd_lt(a.as_i8x16(), z); 1,999,454,293 (0.8%) simd_bitmask::<_, u16>(m) as u32 as i32 . } . . /// Shuffles 32-bit integers in `a` using the control in `IMM8`. . /// . /// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_epi32) . #[inline] . #[target_feature(enable = "sse2")] . #[cfg_attr(test, assert_instr(pshufd, IMM8 = 9))] -- line 1397 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/cmp.rs -------------------------------------------------------------------------------- Ir__________________ 335,631,679 (0.1%) -- line 219 ---------------------------------------- . fn eq(&self, other: &Rhs) -> bool; . . /// This method tests for `!=`. The default implementation is almost always . /// sufficient, and should not be overridden without very good reason. . #[inline] . #[must_use] . #[stable(feature = "rust1", since = "1.0.0")] . fn ne(&self, other: &Rhs) -> bool { 79,107 (0.0%) !self.eq(other) . } . } . . /// Derive macro generating an impl of the trait [`PartialEq`]. . /// The behavior of this macro is described in detail [here](PartialEq#derivable). . #[rustc_builtin_macro] . #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] . #[allow_internal_unstable(core_intrinsics, structural_match)] -- line 235 ---------------------------------------- -- line 322 ---------------------------------------- . /// use std::cmp::Ordering; . /// . /// assert_eq!(1.cmp(&2), Ordering::Less); . /// . /// assert_eq!(1.cmp(&1), Ordering::Equal); . /// . /// assert_eq!(2.cmp(&1), Ordering::Greater); . /// ``` 3 (0.0%) #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] . #[stable(feature = "rust1", since = "1.0.0")] . #[repr(i8)] . pub enum Ordering { . /// An ordering where a compared value is less than another. . #[stable(feature = "rust1", since = "1.0.0")] . Less = -1, . /// An ordering where a compared value is equal to another. . #[stable(feature = "rust1", since = "1.0.0")] -- line 338 ---------------------------------------- -- line 563 ---------------------------------------- . /// let result = x.0.cmp(&y.0).then_with(|| x.1.cmp(&y.1)).then_with(|| x.2.cmp(&y.2)); . /// . /// assert_eq!(result, Ordering::Less); . /// ``` . #[inline] . #[must_use] . #[stable(feature = "ordering_chaining", since = "1.17.0")] . pub fn then_with Ordering>(self, f: F) -> Ordering { 308 (0.0%) match self { . Equal => f(), . _ => self, . } . } . } . . /// A helper struct for reverse ordering. . /// -- line 579 ---------------------------------------- -- line 786 ---------------------------------------- . /// ``` . #[stable(feature = "ord_max_min", since = "1.21.0")] . #[inline] . #[must_use] . fn max(self, other: Self) -> Self . where . Self: Sized, . { 148 (0.0%) max_by(self, other, Ord::cmp) . } . . /// Compares and returns the minimum of two values. . /// . /// Returns the first argument if the comparison determines them to be equal. . /// . /// # Examples . /// -- line 802 ---------------------------------------- -- line 806 ---------------------------------------- . /// ``` . #[stable(feature = "ord_max_min", since = "1.21.0")] . #[inline] . #[must_use] . fn min(self, other: Self) -> Self . where . Self: Sized, . { 24 (0.0%) min_by(self, other, Ord::cmp) . } . . /// Restrict a value to a certain interval. . /// . /// Returns `max` if `self` is greater than `max`, and `min` if `self` is . /// less than `min`. Otherwise this returns `self`. . /// . /// # Panics -- line 822 ---------------------------------------- -- line 1060 ---------------------------------------- . /// assert_eq!(1.0 < 1.0, false); . /// assert_eq!(1.0 < 2.0, true); . /// assert_eq!(2.0 < 1.0, false); . /// ``` . #[inline] . #[must_use] . #[stable(feature = "rust1", since = "1.0.0")] . fn lt(&self, other: &Rhs) -> bool { 28,319 (0.0%) matches!(self.partial_cmp(other), Some(Less)) . } . . /// This method tests less than or equal to (for `self` and `other`) and is used by the `<=` . /// operator. . /// . /// # Examples . /// . /// ``` -- line 1076 ---------------------------------------- -- line 1077 ---------------------------------------- . /// assert_eq!(1.0 <= 1.0, true); . /// assert_eq!(1.0 <= 2.0, true); . /// assert_eq!(2.0 <= 1.0, false); . /// ``` . #[inline] . #[must_use] . #[stable(feature = "rust1", since = "1.0.0")] . fn le(&self, other: &Rhs) -> bool { 23,370,345 (0.0%) matches!(self.partial_cmp(other), Some(Less | Equal)) . } . . /// This method tests greater than (for `self` and `other`) and is used by the `>` operator. . /// . /// # Examples . /// . /// ``` . /// assert_eq!(1.0 > 1.0, false); . /// assert_eq!(1.0 > 2.0, false); . /// assert_eq!(2.0 > 1.0, true); . /// ``` . #[inline] . #[must_use] . #[stable(feature = "rust1", since = "1.0.0")] . fn gt(&self, other: &Rhs) -> bool { 128 (0.0%) matches!(self.partial_cmp(other), Some(Greater)) . } . . /// This method tests greater than or equal to (for `self` and `other`) and is used by the `>=` . /// operator. . /// . /// # Examples . /// . /// ``` -- line 1109 ---------------------------------------- -- line 1110 ---------------------------------------- . /// assert_eq!(1.0 >= 1.0, true); . /// assert_eq!(1.0 >= 2.0, false); . /// assert_eq!(2.0 >= 1.0, true); . /// ``` . #[inline] . #[must_use] . #[stable(feature = "rust1", since = "1.0.0")] . fn ge(&self, other: &Rhs) -> bool { 8,900 (0.0%) matches!(self.partial_cmp(other), Some(Greater | Equal)) . } . } . . /// Derive macro generating an impl of the trait [`PartialOrd`]. . /// The behavior of this macro is described in detail [here](PartialOrd#derivable). . #[rustc_builtin_macro] . #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] . #[allow_internal_unstable(core_intrinsics)] -- line 1126 ---------------------------------------- -- line 1233 ---------------------------------------- . /// . /// let result = cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())) ; . /// assert_eq!(result, 2); . /// ``` . #[inline] . #[must_use] . #[stable(feature = "cmp_min_max_by", since = "1.53.0")] . pub fn max_by Ordering>(v1: T, v2: T, compare: F) -> T { 68 (0.0%) match compare(&v1, &v2) { . Ordering::Less | Ordering::Equal => v2, . Ordering::Greater => v1, . } . } . . /// Returns the element that gives the maximum value from the specified function. . /// . /// Returns the second argument if the comparison determines them to be equal. -- line 1249 ---------------------------------------- -- line 1271 ---------------------------------------- . use crate::cmp::Ordering::{self, Equal, Greater, Less}; . use crate::hint::unreachable_unchecked; . . macro_rules! partial_eq_impl { . ($($t:ty)*) => ($( . #[stable(feature = "rust1", since = "1.0.0")] . impl PartialEq for $t { . #[inline] 21,218 (0.0%) fn eq(&self, other: &$t) -> bool { (*self) == (*other) } . #[inline] . fn ne(&self, other: &$t) -> bool { (*self) != (*other) } . } . )*) . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl PartialEq for () { -- line 1287 ---------------------------------------- -- line 1290 ---------------------------------------- . true . } . #[inline] . fn ne(&self, _other: &()) -> bool { . false . } . } . 345,642,098 (0.1%) partial_eq_impl! { . bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 . } . . macro_rules! eq_impl { . ($($t:ty)*) => ($( . #[stable(feature = "rust1", since = "1.0.0")] . impl Eq for $t {} . )*) -- line 1306 ---------------------------------------- -- line 1355 ---------------------------------------- . ($($t:ty)*) => ($( . #[stable(feature = "rust1", since = "1.0.0")] . impl PartialOrd for $t { . #[inline] . fn partial_cmp(&self, other: &$t) -> Option { . Some(self.cmp(other)) . } . #[inline(always)] 270,085 (0.0%) fn lt(&self, other: &$t) -> bool { (*self) < (*other) } . #[inline(always)] 167,237 (0.0%) fn le(&self, other: &$t) -> bool { (*self) <= (*other) } . #[inline(always)] . fn ge(&self, other: &$t) -> bool { (*self) >= (*other) } . #[inline(always)] . fn gt(&self, other: &$t) -> bool { (*self) > (*other) } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl Ord for $t { . #[inline] . fn cmp(&self, other: &$t) -> Ordering { . // The order here is important to generate more optimal assembly. . // See for more info. 300,570 (0.0%) if *self < *other { Less } . else if *self == *other { Equal } . else { Greater } . } . } . )*) . } . . #[stable(feature = "rust1", since = "1.0.0")] -- line 1386 ---------------------------------------- -- line 1393 ---------------------------------------- . . #[stable(feature = "rust1", since = "1.0.0")] . impl Ord for bool { . #[inline] . fn cmp(&self, other: &bool) -> Ordering { . // Casting to i8's and converting the difference to an Ordering generates . // more optimal assembly. . // See for more info. 288 (0.0%) match (*self as i8) - (*other as i8) { . -1 => Less, . 0 => Equal, . 1 => Greater, . // SAFETY: bool as i8 returns 0 or 1, so the difference can't be anything else . _ => unsafe { unreachable_unchecked() }, . } . } . } . 269,223,122 (0.1%) ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } . . #[unstable(feature = "never_type", issue = "35121")] . impl PartialEq for ! { . #[inline] . fn eq(&self, _: &!) -> bool { . *self . } . } -- line 1419 ---------------------------------------- -- line 1441 ---------------------------------------- . . #[stable(feature = "rust1", since = "1.0.0")] . impl PartialEq<&B> for &A . where . A: PartialEq, . { . #[inline] . fn eq(&self, other: &&B) -> bool { 3,011,664,376 (1.2%) PartialEq::eq(*self, *other) . } . #[inline] . fn ne(&self, other: &&B) -> bool { . PartialEq::ne(*self, *other) . } . } . #[stable(feature = "rust1", since = "1.0.0")] . impl PartialOrd<&B> for &A -- line 1457 ---------------------------------------- -- line 1459 ---------------------------------------- . A: PartialOrd, . { . #[inline] . fn partial_cmp(&self, other: &&B) -> Option { . PartialOrd::partial_cmp(*self, *other) . } . #[inline] . fn lt(&self, other: &&B) -> bool { 1,286 (0.0%) PartialOrd::lt(*self, *other) . } . #[inline] . fn le(&self, other: &&B) -> bool { 4,126 (0.0%) PartialOrd::le(*self, *other) . } . #[inline] . fn gt(&self, other: &&B) -> bool { . PartialOrd::gt(*self, *other) . } . #[inline] . fn ge(&self, other: &&B) -> bool { . PartialOrd::ge(*self, *other) -- line 1479 ---------------------------------------- -- line 1564 ---------------------------------------- . . #[stable(feature = "rust1", since = "1.0.0")] . impl PartialEq<&B> for &mut A . where . A: PartialEq, . { . #[inline] . fn eq(&self, other: &&B) -> bool { 1,933 (0.0%) PartialEq::eq(*self, *other) . } . #[inline] . fn ne(&self, other: &&B) -> bool { . PartialEq::ne(*self, *other) . } . } . } -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/hash/mod.rs -------------------------------------------------------------------------------- Ir__________________ 84 (0.0%) -- line 229 ---------------------------------------- . /// ``` . /// . /// [`VecDeque`]: ../../std/collections/struct.VecDeque.html . /// [`as_slices`]: ../../std/collections/struct.VecDeque.html#method.as_slices . /// [`make_contiguous`]: ../../std/collections/struct.VecDeque.html#method.make_contiguous . /// [`hash`]: Hash::hash . /// [`hash_slice`]: Hash::hash_slice . #[stable(feature = "hash_slice", since = "1.3.0")] 4,009 (0.0%) fn hash_slice(data: &[Self], state: &mut H) . where . Self: Sized, . { . for piece in data { . piece.hash(state) . } 7,249 (0.0%) } . } . . // Separate module to reexport the macro `Hash` from prelude without the trait `Hash`. . pub(crate) mod macros { . /// Derive macro generating an impl of the trait `Hash`. . #[rustc_builtin_macro] . #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] . #[allow_internal_unstable(core_intrinsics)] -- line 252 ---------------------------------------- -- line 691 ---------------------------------------- . /// bh.hash_one(OrderAmbivalentPair(2, 1)) . /// ); . /// assert_eq!( . /// bh.hash_one(OrderAmbivalentPair(10, 2)), . /// bh.hash_one(&OrderAmbivalentPair(2, 10)) . /// ); . /// ``` . #[stable(feature = "build_hasher_simple_hash_one", since = "1.71.0")] 161 (0.0%) fn hash_one(&self, x: T) -> u64 . where . Self: Sized, . Self::Hasher: Hasher, . { 691,953 (0.0%) let mut hasher = self.build_hasher(); . x.hash(&mut hasher); 692,774 (0.0%) hasher.finish() 106 (0.0%) } . } . . /// Used to create a default [`BuildHasher`] instance for types that implement . /// [`Hasher`] and [`Default`]. . /// . /// `BuildHasherDefault` can be used when a type `H` implements [`Hasher`] and . /// [`Default`], and you need a corresponding [`BuildHasher`] instance, but none is . /// defined. -- line 715 ---------------------------------------- -- line 819 ---------------------------------------- . // spans across `data` and is never mutated, and its total size is the . // same as the original `data` so it can't be over `isize::MAX`. . state.write(unsafe { slice::from_raw_parts(ptr, newlen) }) . } . } . )*} . } . 1,163,340,998 (0.5%) impl_write! { . (u8, write_u8), . (u16, write_u16), . (u32, write_u32), . (u64, write_u64), . (usize, write_usize), . (i8, write_i8), . (i16, write_i16), . (i32, write_i32), -- line 835 ---------------------------------------- -- line 838 ---------------------------------------- . (u128, write_u128), . (i128, write_i128), . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl Hash for bool { . #[inline] . fn hash(&self, state: &mut H) { 1,666 (0.0%) state.write_u8(*self as u8) . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl Hash for char { . #[inline] . fn hash(&self, state: &mut H) { . state.write_u32(*self as u32) -- line 854 ---------------------------------------- -- line 883 ---------------------------------------- . ( $($name:ident)+) => ( . maybe_tuple_doc! { . $($name)+ @ . #[stable(feature = "rust1", since = "1.0.0")] . impl<$($name: Hash),+> Hash for ($($name,)+) where last_type!($($name,)+): ?Sized { . #[allow(non_snake_case)] . #[inline] . fn hash(&self, state: &mut S) { 456 (0.0%) let ($(ref $name,)+) = *self; 42,691,968 (0.0%) $($name.hash(state);)+ . } . } . } . ); . } . . macro_rules! maybe_tuple_doc { . ($a:ident @ #[$meta:meta] $item:item) => { -- line 900 ---------------------------------------- -- line 929 ---------------------------------------- . impl_hash_tuple! { T B C D E F G H I J K } . impl_hash_tuple! { T B C D E F G H I J K L } . . #[stable(feature = "rust1", since = "1.0.0")] . impl Hash for [T] { . #[inline] . fn hash(&self, state: &mut H) { . state.write_length_prefix(self.len()); 9,356 (0.0%) Hash::hash_slice(self, state) . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl Hash for &T { . #[inline] . fn hash(&self, state: &mut H) { 46,222,464 (0.0%) (**self).hash(state); . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl Hash for &mut T { . #[inline] . fn hash(&self, state: &mut H) { . (**self).hash(state); -- line 953 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/intrinsics.rs -------------------------------------------------------------------------------- Ir__________________ 8,726 (0.0%) -- line 2658 ---------------------------------------- . assert_unsafe_precondition!( . "ptr::copy_nonoverlapping requires that both pointer arguments are aligned and non-null \ . and the specified memory ranges do not overlap", . [T](src: *const T, dst: *mut T, count: usize) => . is_aligned_and_not_null(src) . && is_aligned_and_not_null(dst) . && is_nonoverlapping(src, dst, count) . ); 1,772,257,796 (0.7%) copy_nonoverlapping(src, dst, count) . } . } . . /// Copies `count * size_of::()` bytes from `src` to `dst`. The source . /// and destination may overlap. . /// . /// If the source and destination will *never* overlap, . /// [`copy_nonoverlapping`] can be used instead. -- line 2674 ---------------------------------------- -- line 2745 ---------------------------------------- . . // SAFETY: the safety contract for `copy` must be upheld by the caller. . unsafe { . assert_unsafe_precondition!( . "ptr::copy requires that both pointer arguments are aligned and non-null", . [T](src: *const T, dst: *mut T) => . is_aligned_and_not_null(src) && is_aligned_and_not_null(dst) . ); 3,146,313 (0.0%) copy(src, dst, count) . } . } . . /// Sets `count * size_of::()` bytes of memory starting at `dst` to . /// `val`. . /// . /// `write_bytes` is similar to C's [`memset`], but sets `count * . /// size_of::()` bytes to `val`. -- line 2761 ---------------------------------------- -- line 2817 ---------------------------------------- . } . . // SAFETY: the safety contract for `write_bytes` must be upheld by the caller. . unsafe { . assert_unsafe_precondition!( . "ptr::write_bytes requires that the destination pointer is aligned and non-null", . [T](dst: *mut T) => is_aligned_and_not_null(dst) . ); 2,985,712 (0.0%) write_bytes(dst, val, count) . } . } -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/iter/adapters/map.rs -------------------------------------------------------------------------------- Ir________________ 149,896 (0.0%) -- line 61 ---------------------------------------- . pub struct Map { . // Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods . pub(crate) iter: I, . f: F, . } . . impl Map { . pub(in crate::iter) fn new(iter: I, f: F) -> Map { 24,569,120 (0.0%) Map { iter, f } . } . } . . #[stable(feature = "core_impl_debug", since = "1.9.0")] . impl fmt::Debug for Map { . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { . f.debug_struct("Map").field("iter", &self.iter).finish() . } . } . . fn map_fold( . mut f: impl FnMut(T) -> B, . mut g: impl FnMut(Acc, B) -> Acc, . ) -> impl FnMut(Acc, T) -> Acc { 169,071 (0.0%) move |acc, elt| g(acc, f(elt)) . } . . fn map_try_fold<'a, T, B, Acc, R>( . f: &'a mut impl FnMut(T) -> B, . mut g: impl FnMut(Acc, B) -> R + 'a, . ) -> impl FnMut(Acc, T) -> R + 'a { 361,354,209 (0.1%) move |acc, elt| g(acc, f(elt)) . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl Iterator for Map . where . F: FnMut(I::Item) -> B, . { . type Item = B; . . #[inline] 12,141 (0.0%) fn next(&mut self) -> Option { 52,016 (0.0%) self.iter.next().map(&mut self.f) 11,878 (0.0%) } . . #[inline] . fn size_hint(&self) -> (usize, Option) { . self.iter.size_hint() . } . 4,996,503 (0.0%) fn try_fold(&mut self, init: Acc, g: G) -> R . where . Self: Sized, . G: FnMut(Acc, Self::Item) -> R, . R: Try, . { 38,473 (0.0%) self.iter.try_fold(init, map_try_fold(&mut self.f, g)) 4,259,780 (0.0%) } . 518,019 (0.0%) fn fold(self, init: Acc, g: G) -> Acc . where . G: FnMut(Acc, Self::Item) -> Acc, . { 236,005 (0.0%) self.iter.fold(init, map_fold(self.f, g)) 586,251 (0.0%) } . . #[inline] . unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B . where . Self: TrustedRandomAccessNoCoerce, . { . // SAFETY: the caller must uphold the contract for . // `Iterator::__iterator_get_unchecked`. -- line 133 ---------------------------------------- -- line 140 ---------------------------------------- . where . F: FnMut(I::Item) -> B, . { . #[inline] . fn next_back(&mut self) -> Option { . self.iter.next_back().map(&mut self.f) . } . 4,999 (0.0%) fn try_rfold(&mut self, init: Acc, g: G) -> R . where . Self: Sized, . G: FnMut(Acc, Self::Item) -> R, . R: Try, . { . self.iter.try_rfold(init, map_try_fold(&mut self.f, g)) 5,464 (0.0%) } . . fn rfold(self, init: Acc, g: G) -> Acc . where . G: FnMut(Acc, Self::Item) -> Acc, . { . self.iter.rfold(init, map_fold(self.f, g)) . } . } -- line 163 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/iter/adapters/take.rs -------------------------------------------------------------------------------- Ir________________ 330,548 (0.0%) -- line 15 ---------------------------------------- . #[stable(feature = "rust1", since = "1.0.0")] . pub struct Take { . iter: I, . n: usize, . } . . impl Take { . pub(in crate::iter) fn new(iter: I, n: usize) -> Take { 1,541,035 (0.0%) Take { iter, n } . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl Iterator for Take . where . I: Iterator, . { . type Item = ::Item; . . #[inline] . fn next(&mut self) -> Option<::Item> { 463,937,733 (0.2%) if self.n != 0 { 819,032 (0.0%) self.n -= 1; . self.iter.next() . } else { . None . } . } . . #[inline] . fn nth(&mut self, n: usize) -> Option { -- line 45 ---------------------------------------- -- line 52 ---------------------------------------- . self.n = 0; . } . None . } . } . . #[inline] . fn size_hint(&self) -> (usize, Option) { 1,395,470 (0.0%) if self.n == 0 { . return (0, Some(0)); . } . . let (lower, upper) = self.iter.size_hint(); . . let lower = cmp::min(lower, self.n); . 2 (0.0%) let upper = match upper { . Some(x) if x < self.n => Some(x), . _ => Some(self.n), . }; . . (lower, upper) . } . . #[inline] -- line 76 ---------------------------------------- -- line 110 ---------------------------------------- . ) -> impl FnMut(usize, Item) -> Option + 'a { . move |more, x| { . action(x); . more.checked_sub(1) . } . } . . let remaining = self.n; 34,902 (0.0%) if remaining > 0 { . self.iter.try_fold(remaining - 1, check(f)); . } . } . . #[inline] . #[rustc_inherit_overflow_checks] . fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { . let min = self.n.min(n); -- line 126 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/iter/traits/iterator.rs -------------------------------------------------------------------------------- Ir__________________ 52,061,726 (0.0%) -- line 216 ---------------------------------------- . /// // and the maximum possible lower bound . /// let iter = 0..; . /// . /// assert_eq!((usize::MAX, None), iter.size_hint()); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_do_not_const_check] 222 (0.0%) fn size_hint(&self) -> (usize, Option) { 444 (0.0%) (0, None) . } . . /// Consumes the iterator, counting the number of iterations and returning it. . /// . /// This method will call [`next`] repeatedly until [`None`] is encountered, . /// returning the number of times it saw [`Some`]. Note that [`next`] has to be . /// called at least once even if the iterator does not have any elements. . /// -- line 233 ---------------------------------------- -- line 258 ---------------------------------------- . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_do_not_const_check] . fn count(self) -> usize . where . Self: Sized, . { 2 (0.0%) self.fold( . 0, . #[rustc_inherit_overflow_checks] 5,435 (0.0%) |count, _| count + 1, . ) . } . . /// Consumes the iterator, returning the last element. . /// . /// This method will evaluate the iterator until it returns [`None`]. While . /// doing so, it keeps track of the current element. After [`None`] is . /// returned, `last()` will then return the last element it saw. -- line 277 ---------------------------------------- -- line 335 ---------------------------------------- . /// assert_eq!(iter.next(), Some(&3)); . /// assert_eq!(iter.advance_by(0), Ok(())); . /// assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(99).unwrap())); // only `&4` was skipped . /// ``` . #[inline] . #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")] . #[rustc_do_not_const_check] . fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { 12 (0.0%) for i in 0..n { 130 (0.0%) if self.next().is_none() { . // SAFETY: `i` is always less than `n`. . return Err(unsafe { NonZeroUsize::new_unchecked(n - i) }); . } . } . Ok(()) . } . . /// Returns the `n`th element of the iterator. -- line 352 ---------------------------------------- -- line 386 ---------------------------------------- . /// . /// ``` . /// let a = [1, 2, 3]; . /// assert_eq!(a.iter().nth(10), None); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_do_not_const_check] 20 (0.0%) fn nth(&mut self, n: usize) -> Option { 1 (0.0%) self.advance_by(n).ok()?; 1,332 (0.0%) self.next() 12 (0.0%) } . . /// Creates an iterator starting at the same point, but stepping by . /// the given amount at each iteration. . /// . /// Note 1: The first element of the iterator will always be returned, . /// regardless of the step given. . /// . /// Note 2: The time at which ignored elements are pulled is not fixed. -- line 405 ---------------------------------------- -- line 516 ---------------------------------------- . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_do_not_const_check] . fn chain(self, other: U) -> Chain . where . Self: Sized, . U: IntoIterator, . { 4,437 (0.0%) Chain::new(self, other.into_iter()) . } . . /// 'Zips up' two iterators into a single iterator of pairs. . /// . /// `zip()` returns a new iterator that will iterate over two other . /// iterators, returning a tuple where the first element comes from the . /// first iterator, and the second element comes from the second iterator. . /// -- line 532 ---------------------------------------- -- line 845 ---------------------------------------- . #[rustc_do_not_const_check] . fn for_each(self, f: F) . where . Self: Sized, . F: FnMut(Self::Item), . { . #[inline] . fn call(mut f: impl FnMut(T)) -> impl FnMut((), T) { 296,681 (0.0%) move |(), item| f(item) . } . 65,535 (0.0%) self.fold((), call(f)); . } . . /// Creates an iterator which uses a closure to determine if an element . /// should be yielded. . /// . /// Given an element the closure must return `true` or `false`. The returned . /// iterator will yield only the elements for which the closure returns . /// true. -- line 864 ---------------------------------------- -- line 1887 ---------------------------------------- . #[stable(feature = "rust1", since = "1.0.0")] . #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] . #[cfg_attr(not(test), rustc_diagnostic_item = "iterator_collect_fn")] . #[rustc_do_not_const_check] . fn collect>(self) -> B . where . Self: Sized, . { 4,600 (0.0%) FromIterator::from_iter(self) . } . . /// Fallibly transforms an iterator into a collection, short circuiting if . /// a failure is encountered. . /// . /// `try_collect()` is a variation of [`collect()`][`collect`] that allows fallible . /// conversions during collection. Its main use case is simplifying conversions from . /// iterators yielding [`Option`][`Option`] into `Option>`, or similarly for other [`Try`] -- line 1903 ---------------------------------------- -- line 1969 ---------------------------------------- . #[rustc_do_not_const_check] . fn try_collect(&mut self) -> ChangeOutputType . where . Self: Sized, . ::Item: Try, . <::Item as Try>::Residual: Residual, . B: FromIterator<::Output>, . { 21 (0.0%) try_process(ByRefSized(self), |i| i.collect()) . } . . /// Collects all the items from an iterator into a collection. . /// . /// This method consumes the iterator and adds all its items to the . /// passed collection. The collection is then returned, so the call chain . /// can be continued. . /// -- line 1985 ---------------------------------------- -- line 2071 ---------------------------------------- . /// .into_iter() . /// .partition(|n| n % 2 == 0); . /// . /// assert_eq!(even, vec![2]); . /// assert_eq!(odd, vec![1, 3]); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_do_not_const_check] 372 (0.0%) fn partition(self, f: F) -> (B, B) . where . Self: Sized, . B: Default + Extend, . F: FnMut(&Self::Item) -> bool, . { . #[inline] . fn extend<'a, T, B: Extend>( . mut f: impl FnMut(&T) -> bool + 'a, . left: &'a mut B, . right: &'a mut B, . ) -> impl FnMut((), T) + 'a { . move |(), x| { 50 (0.0%) if f(&x) { . left.extend_one(x); . } else { 95 (0.0%) right.extend_one(x); . } . } . } . . let mut left: B = Default::default(); . let mut right: B = Default::default(); . 69 (0.0%) self.fold((), extend(f, &mut left, &mut right)); . 607 (0.0%) (left, right) 417 (0.0%) } . . /// Reorders the elements of this iterator *in-place* according to the given predicate, . /// such that all those that return `true` precede all those that return `false`. . /// Returns the number of `true` elements found. . /// . /// The relative order of partitioned items is not maintained. . /// . /// # Current implementation -- line 2114 ---------------------------------------- -- line 2287 ---------------------------------------- . /// ControlFlow::Break(prev) . /// } . /// }); . /// assert_eq!(triangular, ControlFlow::Continue(435)); . /// ``` . #[inline] . #[stable(feature = "iterator_try_fold", since = "1.27.0")] . #[rustc_do_not_const_check] 115,730 (0.0%) fn try_fold(&mut self, init: B, mut f: F) -> R . where . Self: Sized, . F: FnMut(B, Self::Item) -> R, . R: Try, . { 77 (0.0%) let mut accum = init; 1,078,363,210 (0.4%) while let Some(x) = self.next() { 302,421,296 (0.1%) accum = f(accum, x)?; . } 339 (0.0%) try { accum } 53,770 (0.0%) } . . /// An iterator method that applies a fallible function to each item in the . /// iterator, stopping at the first error and returning that error. . /// . /// This can also be thought of as the fallible form of [`for_each()`] . /// or as the stateless version of [`try_fold()`]. . /// . /// [`for_each()`]: Iterator::for_each -- line 2314 ---------------------------------------- -- line 2471 ---------------------------------------- . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_do_not_const_check] . fn fold(mut self, init: B, mut f: F) -> B . where . Self: Sized, . F: FnMut(B, Self::Item) -> B, . { 56 (0.0%) let mut accum = init; 9,899,507 (0.0%) while let Some(x) = self.next() { 835 (0.0%) accum = f(accum, x); . } 56 (0.0%) accum 38 (0.0%) } . . /// Reduces the elements to a single one, by repeatedly applying a reducing . /// operation. . /// . /// If the iterator is empty, returns [`None`]; otherwise, returns the . /// result of the reduction. . /// . /// The reducing function is a closure with two arguments: an 'accumulator', and an element. -- line 2492 ---------------------------------------- -- line 2509 ---------------------------------------- . #[inline] . #[stable(feature = "iterator_fold_self", since = "1.51.0")] . #[rustc_do_not_const_check] . fn reduce(mut self, f: F) -> Option . where . Self: Sized, . F: FnMut(Self::Item, Self::Item) -> Self::Item, . { 697 (0.0%) let first = self.next()?; 277 (0.0%) Some(self.fold(first, f)) . } . . /// Reduces the elements to a single one by repeatedly applying a reducing operation. If the . /// closure returns a failure, the failure is propagated back to the caller immediately. . /// . /// The return type of this method depends on the return type of the closure. If the closure . /// returns `Result`, then this function will return `Result, . /// E>`. If the closure returns `Option`, then this function will return -- line 2526 ---------------------------------------- -- line 2641 ---------------------------------------- . #[rustc_do_not_const_check] . fn all(&mut self, f: F) -> bool . where . Self: Sized, . F: FnMut(Self::Item) -> bool, . { . #[inline] . fn check(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> { 1,631 (0.0%) move |(), x| { . if f(x) { ControlFlow::Continue(()) } else { ControlFlow::Break(()) } . } . } 532 (0.0%) self.try_fold((), check(f)) == ControlFlow::Continue(()) . } . . /// Tests if any element of the iterator matches a predicate. . /// . /// `any()` takes a closure that returns `true` or `false`. It applies . /// this closure to each element of the iterator, and if any of them return . /// `true`, then so does `any()`. If they all return `false`, it . /// returns `false`. -- line 2661 ---------------------------------------- -- line 2700 ---------------------------------------- . { . #[inline] . fn check(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<()> { . move |(), x| { . if f(x) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) } . } . } . 85,130 (0.0%) self.try_fold((), check(f)) == ControlFlow::Break(()) . } . . /// Searches for an element of an iterator that satisfies a predicate. . /// . /// `find()` takes a closure that returns `true` or `false`. It applies . /// this closure to each element of the iterator, and if any of them return . /// `true`, then `find()` returns [`Some(element)`]. If they all return . /// `false`, it returns [`None`]. -- line 2716 ---------------------------------------- -- line 2760 ---------------------------------------- . fn find

(&mut self, predicate: P) -> Option . where . Self: Sized, . P: FnMut(&Self::Item) -> bool, . { . #[inline] . fn check(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow { . move |(), x| { 5,561,799 (0.0%) if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) } . } . } . 143,395 (0.0%) self.try_fold((), check(predicate)).break_value() . } . . /// Applies function to the elements of iterator and returns . /// the first non-none result. . /// . /// `iter.find_map(f)` is equivalent to `iter.filter_map(f).next()`. . /// . /// # Examples -- line 2780 ---------------------------------------- -- line 2791 ---------------------------------------- . #[rustc_do_not_const_check] . fn find_map(&mut self, f: F) -> Option . where . Self: Sized, . F: FnMut(Self::Item) -> Option, . { . #[inline] . fn check(mut f: impl FnMut(T) -> Option) -> impl FnMut((), T) -> ControlFlow { 109,939 (0.0%) move |(), x| match f(x) { 8,955 (0.0%) Some(x) => ControlFlow::Break(x), . None => ControlFlow::Continue(()), . } . } . . self.try_fold((), check(f)).break_value() . } . . /// Applies function to the elements of iterator and returns -- line 2808 ---------------------------------------- -- line 2935 ---------------------------------------- . P: FnMut(Self::Item) -> bool, . { . #[inline] . fn check( . mut predicate: impl FnMut(T) -> bool, . ) -> impl FnMut(usize, T) -> ControlFlow { . #[rustc_inherit_overflow_checks] . move |i, x| { 19 (0.0%) if predicate(x) { ControlFlow::Break(i) } else { ControlFlow::Continue(i + 1) } . } . } . . self.try_fold(0, check(predicate)).break_value() . } . . /// Searches for an element in an iterator from the right, returning its . /// index. -- line 2951 ---------------------------------------- -- line 3103 ---------------------------------------- . #[rustc_do_not_const_check] . fn max_by_key(self, f: F) -> Option . where . Self: Sized, . F: FnMut(&Self::Item) -> B, . { . #[inline] . fn key(mut f: impl FnMut(&T) -> B) -> impl FnMut(T) -> (B, T) { 58 (0.0%) move |x| (f(&x), x) . } . . #[inline] . fn compare((x_p, _): &(B, T), (y_p, _): &(B, T)) -> Ordering { . x_p.cmp(y_p) . } . 34 (0.0%) let (_, x) = self.map(key(f)).max_by(compare)?; . Some(x) . } . . /// Returns the element that gives the maximum value with respect to the . /// specified comparison function. . /// . /// If several elements are equally maximum, the last element is . /// returned. If the iterator is empty, [`None`] is returned. -- line 3127 ---------------------------------------- -- line 3140 ---------------------------------------- . Self: Sized, . F: FnMut(&Self::Item, &Self::Item) -> Ordering, . { . #[inline] . fn fold(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T { . move |x, y| cmp::max_by(x, y, &mut compare) . } . 29 (0.0%) self.reduce(fold(compare)) . } . . /// Returns the element that gives the minimum value from the . /// specified function. . /// . /// If several elements are equally minimum, the first element is . /// returned. If the iterator is empty, [`None`] is returned. . /// -- line 3156 ---------------------------------------- -- line 3202 ---------------------------------------- . Self: Sized, . F: FnMut(&Self::Item, &Self::Item) -> Ordering, . { . #[inline] . fn fold(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T { . move |x, y| cmp::min_by(x, y, &mut compare) . } . 7,992 (0.0%) self.reduce(fold(compare)) . } . . /// Reverses an iterator's direction. . /// . /// Usually, iterators iterate from left to right. After using `rev()`, . /// an iterator will instead iterate from right to left. . /// . /// This is only possible if the iterator has an end, so `rev()` only -- line 3218 ---------------------------------------- -- line 3276 ---------------------------------------- . #[rustc_do_not_const_check] . fn unzip(self) -> (FromA, FromB) . where . FromA: Default + Extend, . FromB: Default + Extend, . Self: Sized + Iterator, . { . let mut unzipped: (FromA, FromB) = Default::default(); 52 (0.0%) unzipped.extend(self); 16,472 (0.0%) unzipped . } . . /// Creates an iterator which copies all of its elements. . /// . /// This is useful when you have an iterator over `&T`, but you need an . /// iterator over `T`. . /// . /// # Examples -- line 3293 ---------------------------------------- -- line 3350 ---------------------------------------- . /// let slower: Vec<_> = a.iter().cloned().filter(|s| s.len() == 1).collect(); . /// assert_eq!(&[vec![23]], &slower[..]); . /// // instead call `cloned` late . /// let faster: Vec<_> = a.iter().filter(|s| s.len() == 1).cloned().collect(); . /// assert_eq!(&[vec![23]], &faster[..]); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_do_not_const_check] 462 (0.0%) fn cloned<'a, T: 'a>(self) -> Cloned . where . Self: Sized + Iterator, . T: Clone, . { . Cloned::new(self) . } . . /// Repeats an iterator endlessly. -- line 3366 ---------------------------------------- -- line 3684 ---------------------------------------- . #[stable(feature = "iter_order", since = "1.5.0")] . #[rustc_do_not_const_check] . fn eq(self, other: I) -> bool . where . I: IntoIterator, . Self::Item: PartialEq, . Self: Sized, . { 503 (0.0%) self.eq_by(other, |x, y| x == y) . } . . /// Determines if the elements of this [`Iterator`] are equal to those of . /// another with respect to the specified equality function. . /// . /// # Examples . /// . /// Basic usage: -- line 3700 ---------------------------------------- -- line 3704 ---------------------------------------- . /// . /// let xs = [1, 2, 3, 4]; . /// let ys = [1, 4, 9, 16]; . /// . /// assert!(xs.iter().eq_by(&ys, |&x, &y| x * x == y)); . /// ``` . #[unstable(feature = "iter_order_by", issue = "64295")] . #[rustc_do_not_const_check] 511 (0.0%) fn eq_by(self, other: I, eq: F) -> bool . where . Self: Sized, . I: IntoIterator, . F: FnMut(Self::Item, I::Item) -> bool, . { . #[inline] . fn compare(mut eq: F) -> impl FnMut(X, Y) -> ControlFlow<()> . where . F: FnMut(X, Y) -> bool, . { . move |x, y| { . if eq(x, y) { ControlFlow::Continue(()) } else { ControlFlow::Break(()) } . } . } . 584 (0.0%) match iter_compare(self, other.into_iter(), compare(eq)) { . ControlFlow::Continue(ord) => ord == Ordering::Equal, . ControlFlow::Break(()) => false, . } 584 (0.0%) } . . /// Determines if the elements of this [`Iterator`] are not equal to those of . /// another. . /// . /// # Examples . /// . /// ``` . /// assert_eq!([1].iter().ne([1].iter()), false); -- line 3740 ---------------------------------------- -- line 3982 ---------------------------------------- . #[inline] . fn compare<'a, B, X, T>( . b: &'a mut B, . mut f: impl FnMut(X, B::Item) -> ControlFlow + 'a, . ) -> impl FnMut(X) -> ControlFlow> + 'a . where . B: Iterator, . { 219 (0.0%) move |x| match b.next() { . None => ControlFlow::Break(ControlFlow::Continue(Ordering::Greater)), 144 (0.0%) Some(y) => f(x, y).map_break(ControlFlow::Break), . } . } . . match a.try_for_each(compare(&mut b, f)) { . ControlFlow::Continue(()) => ControlFlow::Continue(match b.next() { . None => Ordering::Equal, . Some(_) => Ordering::Less, . }), -- line 4000 ---------------------------------------- -- line 4002 ---------------------------------------- . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl Iterator for &mut I { . type Item = I::Item; . #[inline] . fn next(&mut self) -> Option { 5,909 (0.0%) (**self).next() . } . fn size_hint(&self) -> (usize, Option) { 2 (0.0%) (**self).size_hint() 222 (0.0%) } . fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { . (**self).advance_by(n) . } . fn nth(&mut self, n: usize) -> Option { . (**self).nth(n) . } . } -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/mem/maybe_uninit.rs -------------------------------------------------------------------------------- Ir________________ 4 (0.0%) -- line 481 ---------------------------------------- . /// unsafe { Pin::new_unchecked(ref_) } . /// } . /// } . /// ``` . #[stable(feature = "maybe_uninit_write", since = "1.55.0")] . #[rustc_const_unstable(feature = "const_maybe_uninit_write", issue = "63567")] . #[inline(always)] . pub const fn write(&mut self, val: T) -> &mut T { 770,108,392 (0.3%) *self = MaybeUninit::new(val); . // SAFETY: We just initialized this value. . unsafe { self.assume_init_mut() } . } . . /// Gets a pointer to the contained value. Reading from this pointer or turning it . /// into a reference is undefined behavior unless the `MaybeUninit` is initialized. . /// Writing to memory that this pointer (non-transitively) points to is undefined behavior . /// (except inside an `UnsafeCell`). -- line 497 ---------------------------------------- -- line 720 ---------------------------------------- . /// . /// [`assume_init`]: MaybeUninit::assume_init . /// [`Vec`]: ../../std/vec/struct.Vec.html . #[stable(feature = "maybe_uninit_extra", since = "1.60.0")] . pub unsafe fn assume_init_drop(&mut self) { . // SAFETY: the caller must guarantee that `self` is initialized and . // satisfies all invariants of `T`. . // Dropping the value in place is safe if that is the case. 2,181 (0.0%) unsafe { ptr::drop_in_place(self.as_mut_ptr()) } . } . . /// Gets a shared reference to the contained value. . /// . /// This can be useful when we want to access a `MaybeUninit` that has been . /// initialized but don't have ownership of the `MaybeUninit` (preventing the use . /// of `.assume_init()`). . /// -- line 736 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/num/mod.rs -------------------------------------------------------------------------------- Ir__________________ 1,417,625 (0.0%) -- line 351 ---------------------------------------- . be_bytes = "[0x12, 0x34, 0x56, 0x78]", . to_xe_bytes_doc = "", . from_xe_bytes_doc = "", . bound_condition = "", . } . } . . impl i64 { 4 (0.0%) int_impl! { . Self = i64, . ActualT = i64, . UnsignedT = u64, . BITS = 64, . BITS_MINUS_ONE = 63, . Min = -9223372036854775808, . Max = 9223372036854775807, . rot = 12, -- line 367 ---------------------------------------- -- line 448 ---------------------------------------- . to_xe_bytes_doc = usize_isize_to_xe_bytes_doc!(), . from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(), . bound_condition = " on 32-bit targets", . } . } . . #[cfg(target_pointer_width = "64")] . impl isize { 2,111,881,939 (0.9%) int_impl! { . Self = isize, . ActualT = i64, . UnsignedT = usize, . BITS = 64, . BITS_MINUS_ONE = 63, . Min = -9223372036854775808, . Max = 9223372036854775807, . rot = 12, -- line 464 ---------------------------------------- -- line 474 ---------------------------------------- . bound_condition = " on 64-bit targets", . } . } . . /// If 6th bit is set ascii is lower case. . const ASCII_CASE_MASK: u8 = 0b0010_0000; . . impl u8 { 342 (0.0%) uint_impl! { . Self = u8, . ActualT = u8, . SignedT = i8, . NonZeroT = NonZeroU8, . BITS = 8, . MAX = 255, . rot = 2, . rot_op = "0x82", -- line 490 ---------------------------------------- -- line 512 ---------------------------------------- . /// assert!(ascii.is_ascii()); . /// assert!(!non_ascii.is_ascii()); . /// ``` . #[must_use] . #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] . #[rustc_const_stable(feature = "const_u8_is_ascii", since = "1.43.0")] . #[inline] . pub const fn is_ascii(&self) -> bool { 3,738 (0.0%) *self <= 127 . } . . /// If the value of this byte is within the ASCII range, returns it as an . /// [ASCII character](ascii::Char). Otherwise, returns `None`. . #[must_use] . #[unstable(feature = "ascii_char", issue = "110998")] . #[inline] . pub const fn as_ascii(&self) -> Option { -- line 528 ---------------------------------------- -- line 571 ---------------------------------------- . /// . /// [`make_ascii_lowercase`]: Self::make_ascii_lowercase . #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"] . #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] . #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")] . #[inline] . pub const fn to_ascii_lowercase(&self) -> u8 { . // Set the fifth bit if this is an uppercase letter 14,313 (0.0%) *self | (self.is_ascii_uppercase() as u8 * ASCII_CASE_MASK) . } . . /// Assumes self is ascii . #[inline] . pub(crate) const fn ascii_change_case_unchecked(&self) -> u8 { . *self ^ ASCII_CASE_MASK . } . -- line 587 ---------------------------------------- -- line 646 ---------------------------------------- . /// . /// assert_eq!(b'a', byte); . /// ``` . /// . /// [`to_ascii_lowercase`]: Self::to_ascii_lowercase . #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] . #[inline] . pub fn make_ascii_lowercase(&mut self) { 5,695 (0.0%) *self = self.to_ascii_lowercase(); . } . . /// Checks if the value is an ASCII alphabetic character: . /// . /// - U+0041 'A' ..= U+005A 'Z', or . /// - U+0061 'a' ..= U+007A 'z'. . /// . /// # Examples -- line 662 ---------------------------------------- -- line 716 ---------------------------------------- . /// assert!(!lf.is_ascii_uppercase()); . /// assert!(!esc.is_ascii_uppercase()); . /// ``` . #[must_use] . #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")] . #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] . #[inline] . pub const fn is_ascii_uppercase(&self) -> bool { 67,619 (0.0%) matches!(*self, b'A'..=b'Z') . } . . /// Checks if the value is an ASCII lowercase character: . /// U+0061 'a' ..= U+007A 'z'. . /// . /// # Examples . /// . /// ``` -- line 732 ---------------------------------------- -- line 750 ---------------------------------------- . /// assert!(!lf.is_ascii_lowercase()); . /// assert!(!esc.is_ascii_lowercase()); . /// ``` . #[must_use] . #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")] . #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] . #[inline] . pub const fn is_ascii_lowercase(&self) -> bool { 48,010 (0.0%) matches!(*self, b'a'..=b'z') . } . . /// Checks if the value is an ASCII alphanumeric character: . /// . /// - U+0041 'A' ..= U+005A 'Z', or . /// - U+0061 'a' ..= U+007A 'z', or . /// - U+0030 '0' ..= U+0039 '9'. . /// -- line 766 ---------------------------------------- -- line 821 ---------------------------------------- . /// assert!(!lf.is_ascii_digit()); . /// assert!(!esc.is_ascii_digit()); . /// ``` . #[must_use] . #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")] . #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] . #[inline] . pub const fn is_ascii_digit(&self) -> bool { 628 (0.0%) matches!(*self, b'0'..=b'9') . } . . /// Checks if the value is an ASCII octal digit: . /// U+0030 '0' ..= U+0037 '7'. . /// . /// # Examples . /// . /// ``` -- line 837 ---------------------------------------- -- line 1081 ---------------------------------------- . #[inline] . pub fn escape_ascii(self) -> ascii::EscapeDefault { . ascii::escape_default(self) . } . . #[inline] . pub(crate) const fn is_utf8_char_boundary(self) -> bool { . // This is bit magic equivalent to: b < 128 || b >= 192 39,873 (0.0%) (self as i8) >= -0x40 . } . } . . impl u16 { 2,704,819 (0.0%) uint_impl! { . Self = u16, . ActualT = u16, . SignedT = i16, . NonZeroT = NonZeroU16, . BITS = 16, . MAX = 65535, . rot = 4, . rot_op = "0xa003", -- line 1102 ---------------------------------------- -- line 1135 ---------------------------------------- . #[rustc_const_unstable(feature = "utf16_extra_const", issue = "94919")] . #[inline] . pub const fn is_utf16_surrogate(self) -> bool { . matches!(self, 0xD800..=0xDFFF) . } . } . . impl u32 { 810,412 (0.0%) uint_impl! { . Self = u32, . ActualT = u32, . SignedT = i32, . NonZeroT = NonZeroU32, . BITS = 32, . MAX = 4294967295, . rot = 8, . rot_op = "0x10000b3", -- line 1151 ---------------------------------------- -- line 1159 ---------------------------------------- . from_xe_bytes_doc = "", . bound_condition = "", . } . widening_impl! { u32, u64, 32, unsigned } . midpoint_impl! { u32, u64, unsigned } . } . . impl u64 { 448,098 (0.0%) uint_impl! { . Self = u64, . ActualT = u64, . SignedT = i64, . NonZeroT = NonZeroU64, . BITS = 64, . MAX = 18446744073709551615, . rot = 12, . rot_op = "0xaa00000000006e1", -- line 1175 ---------------------------------------- -- line 1183 ---------------------------------------- . from_xe_bytes_doc = "", . bound_condition = "", . } . widening_impl! { u64, u128, 64, unsigned } . midpoint_impl! { u64, u128, unsigned } . } . . impl u128 { 1,247 (0.0%) uint_impl! { . Self = u128, . ActualT = u128, . SignedT = i128, . NonZeroT = NonZeroU128, . BITS = 128, . MAX = 340282366920938463463374607431768211455, . rot = 16, . rot_op = "0x13f40000000000000000000000004f76", -- line 1199 ---------------------------------------- -- line 1259 ---------------------------------------- . bound_condition = " on 32-bit targets", . } . widening_impl! { usize, u64, 32, unsigned } . midpoint_impl! { usize, u64, unsigned } . } . . #[cfg(target_pointer_width = "64")] . impl usize { 1,947,397,420 (0.8%) uint_impl! { . Self = usize, . ActualT = u64, . SignedT = isize, . NonZeroT = NonZeroUsize, . BITS = 64, . MAX = 18446744073709551615, . rot = 12, . rot_op = "0xaa00000000006e1", -- line 1275 ---------------------------------------- -- line 1384 ---------------------------------------- . } . . macro_rules! from_str_radix_int_impl { . ($($t:ty)*) => {$( . #[stable(feature = "rust1", since = "1.0.0")] . impl FromStr for $t { . type Err = ParseIntError; . fn from_str(src: &str) -> Result { 4 (0.0%) from_str_radix(src, 10) 18 (0.0%) } . } . )*} . } . from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 } . . macro_rules! impl_helper_for { . ($($t:ty)*) => ($(impl FromStrRadixHelper for $t { . const MIN: Self = Self::MIN; . #[inline] 33 (0.0%) fn from_u32(u: u32) -> Self { u as Self } . #[inline] . fn checked_mul(&self, other: u32) -> Option { . Self::checked_mul(*self, other as Self) . } . #[inline] . fn checked_sub(&self, other: u32) -> Option { . Self::checked_sub(*self, other as Self) . } -- line 1411 ---------------------------------------- -- line 1420 ---------------------------------------- . /// Determines if a string of text of that length of that radix could be guaranteed to be . /// stored in the given type T. . /// Note that if the radix is known to the compiler, it is just the check of digits.len that . /// is done at runtime. . #[doc(hidden)] . #[inline(always)] . #[unstable(issue = "none", feature = "std_internals")] . pub fn can_not_overflow(radix: u32, is_signed_ty: bool, digits: &[u8]) -> bool { 20 (0.0%) radix <= 16 && digits.len() <= mem::size_of::() * 2 - is_signed_ty as usize . } . 71 (0.0%) fn from_str_radix(src: &str, radix: u32) -> Result { . use self::IntErrorKind::*; . use self::ParseIntError as PIE; . . assert!( . (2..=36).contains(&radix), . "from_str_radix_int: must lie in the range `[2, 36]` - found {}", . radix . ); . 40 (0.0%) if src.is_empty() { . return Err(PIE { kind: Empty }); . } . . let is_signed_ty = T::from_u32(0) > T::MIN; . . // all valid digits are ascii, so we will just iterate over the utf8 bytes . // and cast them to chars. .to_digit() will safely return None for anything . // other than a valid ascii digit for the given radix, including the first-byte . // of multi-byte sequences . let src = src.as_bytes(); . 100 (0.0%) let (is_positive, digits) = match src[0] { 18 (0.0%) b'+' | b'-' if src[1..].is_empty() => { . return Err(PIE { kind: InvalidDigit }); . } . b'+' => (true, &src[1..]), . b'-' if is_signed_ty => (false, &src[1..]), . _ => (true, src), . }; . . let mut result = T::from_u32(0); . 42 (0.0%) if can_not_overflow::(radix, is_signed_ty, digits) { . // If the len of the str is short compared to the range of the type . // we are parsing into, then we can be certain that an overflow will not occur. . // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition . // above is a faster (conservative) approximation of this. . // . // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest: . // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow. . // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow. -- line 1472 ---------------------------------------- -- line 1475 ---------------------------------------- . for &c in digits { . result = result * T::from_u32(radix); . let x = (c as char).to_digit(radix).ok_or(PIE { kind: InvalidDigit })?; . result = $unchecked_additive_op(result, T::from_u32(x)); . } . }; . } . if is_positive { 70 (0.0%) run_unchecked_loop!(::add) . } else { . run_unchecked_loop!(::sub) . }; . } else { . macro_rules! run_checked_loop { . ($checked_additive_op:ident, $overflow_err:expr) => { . for &c in digits { . // When `radix` is passed in as a literal, rather than doing a slow `imul` -- line 1491 ---------------------------------------- -- line 1506 ---------------------------------------- . }; . } . if is_positive { . run_checked_loop!(checked_add, || PIE { kind: PosOverflow }) . } else { . run_checked_loop!(checked_sub, || PIE { kind: NegOverflow }) . }; . } 54 (0.0%) Ok(result) 92 (0.0%) } -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/num/nonzero.rs -------------------------------------------------------------------------------- Ir__________________ 47,142,993 (0.0%) -- line 157 ---------------------------------------- . . impl_nonzero_fmt! { . #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty . } . )+ . } . } . 1,169,849,691 (0.5%) nonzero_integers! { . #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8); . #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16); . #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32); . #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64); . #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128); . #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize); . #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8); . #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16); -- line 173 ---------------------------------------- -- line 246 ---------------------------------------- . unsafe { intrinsics::cttz_nonzero(self.0 as $Uint) as u32 } . } . . } . )+ . } . } . 441 (0.0%) nonzero_leading_trailing_zeros! { . NonZeroU8(u8), u8::MAX; . NonZeroU16(u16), u16::MAX; . NonZeroU32(u32), u32::MAX; . NonZeroU64(u64), u64::MAX; . NonZeroU128(u128), u128::MAX; . NonZeroUsize(usize), usize::MAX; . NonZeroI8(u8), -1i8; . NonZeroI16(u16), -1i16; -- line 262 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/ops/bit.rs -------------------------------------------------------------------------------- Ir________________ 1,165 (0.0%) -- line 60 ---------------------------------------- . #[inline] . fn not(self) -> $t { !self } . } . . forward_ref_unop! { impl Not, not for $t } . )*) . } . 9 (0.0%) not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } . . #[stable(feature = "not_never", since = "1.60.0")] . impl Not for ! { . type Output = !; . . #[inline] . fn not(self) -> ! { . match self {} -- line 76 ---------------------------------------- -- line 170 ---------------------------------------- . #[inline] . fn bitand(self, rhs: $t) -> $t { self & rhs } . } . . forward_ref_binop! { impl BitAnd, bitand for $t, $t } . )*) . } . 2,812 (0.0%) bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } . . /// The bitwise OR operator `|`. . /// . /// Note that `Rhs` is `Self` by default, but this is not mandatory. . /// . /// # Examples . /// . /// An implementation of `BitOr` for a wrapper around `bool`. -- line 186 ---------------------------------------- -- line 270 ---------------------------------------- . #[inline] . fn bitor(self, rhs: $t) -> $t { self | rhs } . } . . forward_ref_binop! { impl BitOr, bitor for $t, $t } . )*) . } . 479 (0.0%) bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } . . /// The bitwise XOR operator `^`. . /// . /// Note that `Rhs` is `Self` by default, but this is not mandatory. . /// . /// # Examples . /// . /// An implementation of `BitXor` that lifts `^` to a wrapper around `bool`. -- line 286 ---------------------------------------- -- line 370 ---------------------------------------- . #[inline] . fn bitxor(self, other: $t) -> $t { self ^ other } . } . . forward_ref_binop! { impl BitXor, bitxor for $t, $t } . )*) . } . 765,796,750 (0.3%) bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } . . /// The left shift operator `<<`. Note that because this trait is implemented . /// for all integer types with multiple right-hand-side types, Rust's type . /// checker has special handling for `_ << _`, setting the result type for . /// integer operations to the type of the left-hand-side operand. This means . /// that though `a << b` and `a.shl(b)` are one and the same from an evaluation . /// standpoint, they are different when it comes to type inference. . /// -- line 386 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/option.rs -------------------------------------------------------------------------------- Ir___________________ 184,546,333 (0.1%) -- line 551 ---------------------------------------- . use crate::pin::Pin; . use crate::{ . cmp, convert, hint, mem, . ops::{self, ControlFlow, Deref, DerefMut}, . slice, . }; . . /// The `Option` type. See [the module level documentation](self) for more. 44,501 (0.0%) #[derive(Copy, PartialOrd, Eq, Ord, Debug, Hash)] . #[rustc_diagnostic_item = "Option"] . #[lang = "Option"] . #[stable(feature = "rust1", since = "1.0.0")] . pub enum Option { . /// No value. . #[lang = "None"] . #[stable(feature = "rust1", since = "1.0.0")] . None, -- line 567 ---------------------------------------- -- line 591 ---------------------------------------- . /// let x: Option = None; . /// assert_eq!(x.is_some(), false); . /// ``` . #[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"] . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_option_basics", since = "1.48.0")] . pub const fn is_some(&self) -> bool { 580,770,974 (0.2%) matches!(*self, Some(_)) . } . . /// Returns `true` if the option is a [`Some`] and the value inside of it matches a predicate. . /// . /// # Examples . /// . /// ``` . /// let x: Option = Some(2); -- line 607 ---------------------------------------- -- line 612 ---------------------------------------- . /// . /// let x: Option = None; . /// assert_eq!(x.is_some_and(|x| x > 1), false); . /// ``` . #[must_use] . #[inline] . #[stable(feature = "is_some_and", since = "1.70.0")] . pub fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool { 124,579 (0.0%) match self { . None => false, 229 (0.0%) Some(x) => f(x), . } . } . . /// Returns `true` if the option is a [`None`] value. . /// . /// # Examples . /// . /// ``` -- line 630 ---------------------------------------- -- line 666 ---------------------------------------- . /// // then consume *that* with `map`, leaving `text` on the stack. . /// let text_length: Option = text.as_ref().map(|s| s.len()); . /// println!("still can print text: {text:?}"); . /// ``` . #[inline] . #[rustc_const_stable(feature = "const_option_basics", since = "1.48.0")] . #[stable(feature = "rust1", since = "1.0.0")] . pub const fn as_ref(&self) -> Option<&T> { 51,251,391 (0.0%) match *self { . Some(ref x) => Some(x), . None => None, . } . } . . /// Converts from `&mut Option` to `Option<&mut T>`. . /// . /// # Examples -- line 682 ---------------------------------------- -- line 688 ---------------------------------------- . /// None => {}, . /// } . /// assert_eq!(x, Some(42)); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_unstable(feature = "const_option", issue = "67441")] . pub const fn as_mut(&mut self) -> Option<&mut T> { 5,207,730 (0.0%) match *self { . Some(ref mut x) => Some(x), . None => None, . } . } . . /// Converts from [Pin]<[&]Option\> to Option<[Pin]<[&]T>>. . /// . /// [&]: reference "shared reference" -- line 704 ---------------------------------------- -- line 888 ---------------------------------------- . /// For more detail on expect message styles and the reasoning behind our . /// recommendation please refer to the section on ["Common Message . /// Styles"](../../std/error/index.html#common-message-styles) in the [`std::error`](../../std/error/index.html) module docs. . #[inline] . #[track_caller] . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_unstable(feature = "const_option", issue = "67441")] . pub const fn expect(self, msg: &str) -> T { 2,794,821 (0.0%) match self { 176,858 (0.0%) Some(val) => val, . None => expect_failed(msg), . } . } . . /// Returns the contained [`Some`] value, consuming the `self` value. . /// . /// Because this function may panic, its use is generally discouraged. . /// Instead, prefer to use pattern matching and handle the [`None`] -- line 905 ---------------------------------------- -- line 925 ---------------------------------------- . /// let x: Option<&str> = None; . /// assert_eq!(x.unwrap(), "air"); // fails . /// ``` . #[inline] . #[track_caller] . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_unstable(feature = "const_option", issue = "67441")] . pub const fn unwrap(self) -> T { 23,785,460 (0.0%) match self { 81,193,926 (0.0%) Some(val) => val, . None => panic("called `Option::unwrap()` on a `None` value"), . } . } . . /// Returns the contained [`Some`] value or a provided default. . /// . /// Arguments passed to `unwrap_or` are eagerly evaluated; if you are passing . /// the result of a function call, it is recommended to use [`unwrap_or_else`], -- line 942 ---------------------------------------- -- line 948 ---------------------------------------- . /// . /// ``` . /// assert_eq!(Some("car").unwrap_or("bike"), "car"); . /// assert_eq!(None.unwrap_or("bike"), "bike"); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn unwrap_or(self, default: T) -> T { 6,086,107 (0.0%) match self { 1,695 (0.0%) Some(x) => x, 10,622 (0.0%) None => default, . } . } . . /// Returns the contained [`Some`] value or computes it from a closure. . /// . /// # Examples . /// . /// ``` -- line 966 ---------------------------------------- -- line 969 ---------------------------------------- . /// assert_eq!(None.unwrap_or_else(|| 2 * k), 20); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn unwrap_or_else(self, f: F) -> T . where . F: FnOnce() -> T, . { 7,345,293 (0.0%) match self { 209,875 (0.0%) Some(x) => x, 828 (0.0%) None => f(), . } . } . . /// Returns the contained [`Some`] value or a default. . /// . /// Consumes the `self` argument then, if [`Some`], returns the contained . /// value, otherwise if [`None`], returns the [default value] for that . /// type. -- line 987 ---------------------------------------- -- line 1000 ---------------------------------------- . /// [`parse`]: str::parse . /// [`FromStr`]: crate::str::FromStr . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn unwrap_or_default(self) -> T . where . T: Default, . { 20,771 (0.0%) match self { 10,258 (0.0%) Some(x) => x, . None => T::default(), . } . } . . /// Returns the contained [`Some`] value, consuming the `self` value, . /// without checking that the value is not [`None`]. . /// . /// # Safety -- line 1017 ---------------------------------------- -- line 1033 ---------------------------------------- . /// ``` . #[inline] . #[track_caller] . #[stable(feature = "option_result_unwrap_unchecked", since = "1.58.0")] . #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] . pub const unsafe fn unwrap_unchecked(self) -> T { . debug_assert!(self.is_some()); . match self { 75 (0.0%) Some(val) => val, . // SAFETY: the safety contract must be upheld by the caller. . None => unsafe { hint::unreachable_unchecked() }, . } . } . . ///////////////////////////////////////////////////////////////////////// . // Transforming contained values . ///////////////////////////////////////////////////////////////////////// -- line 1049 ---------------------------------------- -- line 1066 ---------------------------------------- . /// assert_eq!(x.map(|s| s.len()), None); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn map(self, f: F) -> Option . where . F: FnOnce(T) -> U, . { 62,528,168 (0.0%) match self { 11,242,108 (0.0%) Some(x) => Some(f(x)), 3,837 (0.0%) None => None, . } . } . . /// Calls the provided closure with a reference to the contained value (if [`Some`]). . /// . /// # Examples . /// . /// ``` -- line 1084 ---------------------------------------- -- line 1125 ---------------------------------------- . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . #[must_use = "if you don't need the returned value, use `if let` instead"] . pub fn map_or(self, default: U, f: F) -> U . where . F: FnOnce(T) -> U, . { 146,166 (0.0%) match self { 7,837 (0.0%) Some(t) => f(t), . None => default, . } . } . . /// Computes a default function result (if none), or . /// applies a different function to the contained value (if any). . /// . /// # Basic examples -- line 1142 ---------------------------------------- -- line 1171 ---------------------------------------- . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn map_or_else(self, default: D, f: F) -> U . where . D: FnOnce() -> U, . F: FnOnce(T) -> U, . { 23,432 (0.0%) match self { 18,129 (0.0%) Some(t) => f(t), . None => default(), . } . } . . /// Transforms the `Option` into a [`Result`], mapping [`Some(v)`] to . /// [`Ok(v)`] and [`None`] to [`Err(err)`]. . /// . /// Arguments passed to `ok_or` are eagerly evaluated; if you are passing the -- line 1188 ---------------------------------------- -- line 1201 ---------------------------------------- . /// assert_eq!(x.ok_or(0), Ok("foo")); . /// . /// let x: Option<&str> = None; . /// assert_eq!(x.ok_or(0), Err(0)); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn ok_or(self, err: E) -> Result { 155,758 (0.0%) match self { 920 (0.0%) Some(v) => Ok(v), . None => Err(err), . } 164 (0.0%) } . . /// Transforms the `Option` into a [`Result`], mapping [`Some(v)`] to . /// [`Ok(v)`] and [`None`] to [`Err(err())`]. . /// . /// [`Ok(v)`]: Ok . /// [`Err(err())`]: Err . /// [`Some(v)`]: Some . /// -- line 1221 ---------------------------------------- -- line 1229 ---------------------------------------- . /// assert_eq!(x.ok_or_else(|| 0), Err(0)); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn ok_or_else(self, err: F) -> Result . where . F: FnOnce() -> E, . { 146 (0.0%) match self { 110 (0.0%) Some(v) => Ok(v), . None => Err(err()), . } . } . . /// Converts from `Option` (or `&Option`) to `Option<&T::Target>`. . /// . /// Leaves the original Option in-place, creating a new one with a reference . /// to the original one, additionally coercing the contents via [`Deref`]. -- line 1246 ---------------------------------------- -- line 1255 ---------------------------------------- . /// assert_eq!(x.as_deref(), None); . /// ``` . #[inline] . #[stable(feature = "option_deref", since = "1.40.0")] . pub fn as_deref(&self) -> Option<&T::Target> . where . T: Deref, . { 593,282 (0.0%) match self.as_ref() { . Some(t) => Some(t.deref()), . None => None, . } . } . . /// Converts from `Option` (or `&mut Option`) to `Option<&mut T::Target>`. . /// . /// Leaves the original `Option` in-place, creating a new one containing a mutable reference to -- line 1271 ---------------------------------------- -- line 1405 ---------------------------------------- . /// ``` . #[doc(alias = "flatmap")] . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn and_then(self, f: F) -> Option . where . F: FnOnce(T) -> Option, . { 103,035 (0.0%) match self { 4,027 (0.0%) Some(x) => f(x), 96 (0.0%) None => None, . } . } . . /// Returns [`None`] if the option is [`None`], otherwise calls `predicate` . /// with the wrapped value and returns: . /// . /// - [`Some(t)`] if `predicate` returns `true` (where `t` is the wrapped . /// value), and -- line 1423 ---------------------------------------- -- line 1441 ---------------------------------------- . /// . /// [`Some(t)`]: Some . #[inline] . #[stable(feature = "option_filter", since = "1.27.0")] . pub fn filter

(self, predicate: P) -> Self . where . P: FnOnce(&T) -> bool, . { 40,099 (0.0%) if let Some(x) = self { 3,672 (0.0%) if predicate(&x) { 4,170 (0.0%) return Some(x); . } . } . None . } . . /// Returns the option if it contains a value, otherwise returns `optb`. . /// . /// Arguments passed to `or` are eagerly evaluated; if you are passing the -- line 1459 ---------------------------------------- -- line 1479 ---------------------------------------- . /// . /// let x: Option = None; . /// let y = None; . /// assert_eq!(x.or(y), None); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn or(self, optb: Option) -> Option { 1,082 (0.0%) match self { 348 (0.0%) Some(x) => Some(x), . None => optb, . } . } . . /// Returns the option if it contains a value, otherwise calls `f` and . /// returns the result. . /// . /// # Examples -- line 1496 ---------------------------------------- -- line 1504 ---------------------------------------- . /// assert_eq!(None.or_else(nobody), None); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn or_else(self, f: F) -> Option . where . F: FnOnce() -> Option, . { 11,085 (0.0%) match self { 55,288 (0.0%) Some(x) => Some(x), . None => f(), . } . } . . /// Returns [`Some`] if exactly one of `self`, `optb` is [`Some`], otherwise returns [`None`]. . /// . /// # Examples . /// -- line 1521 ---------------------------------------- -- line 1568 ---------------------------------------- . /// assert_eq!(*val, 2); . /// *val = 3; . /// assert_eq!(opt.unwrap(), 3); . /// ``` . #[must_use = "if you intended to set a value, consider assignment instead"] . #[inline] . #[stable(feature = "option_insert", since = "1.53.0")] . pub fn insert(&mut self, value: T) -> &mut T { 307,718 (0.0%) *self = Some(value); . . // SAFETY: the code above just filled the option . unsafe { self.as_mut().unwrap_unchecked() } . } . . /// Inserts `value` into the option if it is [`None`], then . /// returns a mutable reference to the contained value. . /// -- line 1584 ---------------------------------------- -- line 1597 ---------------------------------------- . /// *y = 7; . /// } . /// . /// assert_eq!(x, Some(7)); . /// ``` . #[inline] . #[stable(feature = "option_entry", since = "1.20.0")] . pub fn get_or_insert(&mut self, value: T) -> &mut T { 9,328 (0.0%) if let None = *self { 32,102 (0.0%) *self = Some(value); . } . . // SAFETY: a `None` variant for `self` would have been replaced by a `Some` . // variant in the code above. . unsafe { self.as_mut().unwrap_unchecked() } . } . . /// Inserts the default value into the option if it is [`None`], then -- line 1614 ---------------------------------------- -- line 1657 ---------------------------------------- . /// assert_eq!(x, Some(7)); . /// ``` . #[inline] . #[stable(feature = "option_entry", since = "1.20.0")] . pub fn get_or_insert_with(&mut self, f: F) -> &mut T . where . F: FnOnce() -> T, . { 178,218 (0.0%) if let None = self { 12,331 (0.0%) *self = Some(f()); . } . . // SAFETY: a `None` variant for `self` would have been replaced by a `Some` . // variant in the code above. . unsafe { self.as_mut().unwrap_unchecked() } . } . . ///////////////////////////////////////////////////////////////////////// -- line 1674 ---------------------------------------- -- line 1798 ---------------------------------------- . /// let y = None::<(u8, u32)>; . /// . /// assert_eq!(x.unzip(), (Some(1), Some("hi"))); . /// assert_eq!(y.unzip(), (None, None)); . /// ``` . #[inline] . #[stable(feature = "unzip_option", since = "1.66.0")] . pub fn unzip(self) -> (Option, Option) { 272 (0.0%) match self { . Some((a, b)) => (Some(a), Some(b)), . None => (None, None), . } . } . } . . impl Option<&T> { . /// Maps an `Option<&T>` to an `Option` by copying the contents of the -- line 1814 ---------------------------------------- -- line 1827 ---------------------------------------- . #[stable(feature = "copied", since = "1.35.0")] . #[rustc_const_unstable(feature = "const_option", issue = "67441")] . pub const fn copied(self) -> Option . where . T: Copy, . { . // FIXME: this implementation, which sidesteps using `Option::map` since it's not const . // ready yet, should be reverted when possible to avoid code repetition 249,894 (0.0%) match self { 15,462,537 (0.0%) Some(&v) => Some(v), 4,226 (0.0%) None => None, . } . } . . /// Maps an `Option<&T>` to an `Option` by cloning the contents of the . /// option. . /// . /// # Examples . /// -- line 1845 ---------------------------------------- -- line 1847 ---------------------------------------- . /// let x = 12; . /// let opt_x = Some(&x); . /// assert_eq!(opt_x, Some(&12)); . /// let cloned = opt_x.cloned(); . /// assert_eq!(cloned, Some(12)); . /// ``` . #[must_use = "`self` will be dropped if the result is not used"] . #[stable(feature = "rust1", since = "1.0.0")] 4,453 (0.0%) pub fn cloned(self) -> Option . where . T: Clone, . { 11,958 (0.0%) match self { 50,533 (0.0%) Some(t) => Some(t.clone()), 3,607 (0.0%) None => None, . } 4,454 (0.0%) } . } . . impl Option<&mut T> { . /// Maps an `Option<&mut T>` to an `Option` by copying the contents of the . /// option. . /// . /// # Examples . /// -- line 1871 ---------------------------------------- -- line 1902 ---------------------------------------- . /// assert_eq!(cloned, Some(12)); . /// ``` . #[must_use = "`self` will be dropped if the result is not used"] . #[stable(since = "1.26.0", feature = "option_ref_mut_cloned")] . pub fn cloned(self) -> Option . where . T: Clone, . { 210 (0.0%) match self { 1,365 (0.0%) Some(t) => Some(t.clone()), . None => None, . } . } . } . . impl Option> { . /// Transposes an `Option` of a [`Result`] into a [`Result`] of an `Option`. . /// -- line 1919 ---------------------------------------- -- line 1959 ---------------------------------------- . . #[stable(feature = "rust1", since = "1.0.0")] . impl Clone for Option . where . T: Clone, . { . #[inline] . fn clone(&self) -> Self { 694,088,256 (0.3%) match self { 3,344,788 (0.0%) Some(x) => Some(x.clone()), 20 (0.0%) None => None, . } . } . . #[inline] . fn clone_from(&mut self, source: &Self) { . match (self, source) { . (Some(to), Some(from)) => to.clone_from(from), . (to, from) => *to = from.clone(), -- line 1977 ---------------------------------------- -- line 2010 ---------------------------------------- . /// assert_eq!(v, ["string"]); . /// . /// let x = None; . /// let v: Vec<&str> = x.into_iter().collect(); . /// assert!(v.is_empty()); . /// ``` . #[inline] . fn into_iter(self) -> IntoIter { 8 (0.0%) IntoIter { inner: Item { opt: self } } . } . } . . #[stable(since = "1.4.0", feature = "option_iter")] . impl<'a, T> IntoIterator for &'a Option { . type Item = &'a T; . type IntoIter = Iter<'a, T>; . -- line 2026 ---------------------------------------- -- line 2105 ---------------------------------------- . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl crate::marker::StructuralPartialEq for Option {} . #[stable(feature = "rust1", since = "1.0.0")] . impl PartialEq for Option { . #[inline] . fn eq(&self, other: &Self) -> bool { 110 (0.0%) SpecOptionPartialEq::eq(self, other) . } . } . . /// This specialization trait is a workaround for LLVM not currently (2023-01) . /// being able to optimize this itself, even though Alive confirms that it would . /// be legal to do so: . /// . /// Once that's fixed, `Option` should go back to deriving `PartialEq`, as -- line 2121 ---------------------------------------- -- line 2125 ---------------------------------------- . pub trait SpecOptionPartialEq: Sized { . fn eq(l: &Option, other: &Option) -> bool; . } . . #[unstable(feature = "spec_option_partial_eq", issue = "none", reason = "exposed only for rustc")] . impl SpecOptionPartialEq for T { . #[inline] . default fn eq(l: &Option, r: &Option) -> bool { 16,796,501,172 (7.0%) match (l, r) { . (Some(l), Some(r)) => *l == *r, . (None, None) => true, . _ => false, . } . } . } . . macro_rules! non_zero_option { -- line 2141 ---------------------------------------- -- line 2198 ---------------------------------------- . . #[inline] . fn next(&mut self) -> Option { . self.opt.take() . } . . #[inline] . fn size_hint(&self) -> (usize, Option) { 5,952 (0.0%) match self.opt { . Some(_) => (1, Some(1)), . None => (0, Some(0)), . } . } . } . . impl DoubleEndedIterator for Item { . #[inline] -- line 2214 ---------------------------------------- -- line 2420 ---------------------------------------- . /// . /// 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) -> Option { . // FIXME(#11084): This could be replaced with Iterator::scan when this . // performance bug is closed. . 52 (0.0%) iter::try_process(iter.into_iter(), |i| i.collect()) . } . } . . #[unstable(feature = "try_trait_v2", issue = "84277")] . impl ops::Try for Option { . type Output = T; . type Residual = Option; . . #[inline] . fn from_output(output: Self::Output) -> Self { . Some(output) . } . . #[inline] . fn branch(self) -> ControlFlow { 1,211,339 (0.0%) match self { 18,389 (0.0%) Some(v) => ControlFlow::Continue(v), . None => ControlFlow::Break(None), . } . } . } . . #[unstable(feature = "try_trait_v2", issue = "84277")] . impl ops::FromResidual for Option { . #[inline] . fn from_residual(residual: Option) -> Self { . match residual { 1,175,409 (0.0%) None => None, . } . } . } . . #[unstable(feature = "try_trait_v2_yeet", issue = "96374")] . impl ops::FromResidual> for Option { . #[inline] . fn from_residual(ops::Yeet(()): ops::Yeet<()>) -> Self { -- line 2464 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/ptr/mod.rs -------------------------------------------------------------------------------- Ir__________________ 16,166,991 (0.0%) -- line 489 ---------------------------------------- . /// assert_eq!(v, &[0.into()]); . /// . /// // Ensure that the last item was dropped. . /// assert!(weak.upgrade().is_none()); . /// ``` . #[stable(feature = "drop_in_place", since = "1.8.0")] . #[lang = "drop_in_place"] . #[allow(unconditional_recursion)] 1,118,464,922 (0.5%) pub unsafe fn drop_in_place(to_drop: *mut T) { . // Code here does not matter - this is replaced by the . // real drop glue by the compiler. . . // SAFETY: see comment above . unsafe { drop_in_place(to_drop) } . } . . /// Creates a null raw pointer. -- line 505 ---------------------------------------- -- line 844 ---------------------------------------- . /// } . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_unstable(feature = "const_swap", issue = "83163")] . pub const unsafe fn swap(x: *mut T, y: *mut T) { . // Give ourselves some scratch space to work with. . // We do not have to worry about drops: `MaybeUninit` does nothing when dropped. 1,374 (0.0%) let mut tmp = MaybeUninit::::uninit(); . . // Perform the swap . // SAFETY: the caller must guarantee that `x` and `y` are . // valid for writes and properly aligned. `tmp` cannot be . // overlapping either `x` or `y` because `tmp` was just allocated . // on the stack as a separate allocated object. . unsafe { . copy_nonoverlapping(x, tmp.as_mut_ptr(), 1); -- line 860 ---------------------------------------- -- line 1171 ---------------------------------------- . // to the previous implementation, rather than using an intrinsic. . . // SAFETY: the caller must guarantee that `src` is valid for reads. . unsafe { . assert_unsafe_precondition!( . "ptr::read requires that the pointer argument is aligned and non-null", . [T](src: *const T) => is_aligned_and_not_null(src) . ); 247,809,286 (0.1%) crate::intrinsics::read_via_copy(src) . } . } . . /// Reads the value from `src` without moving it. This leaves the . /// memory in `src` unchanged. . /// . /// Unlike [`read`], `read_unaligned` works with unaligned pointers. . /// -- line 1187 ---------------------------------------- -- line 1369 ---------------------------------------- . // SAFETY: the caller must guarantee that `dst` is valid for writes. . // `dst` cannot overlap `src` because the caller has mutable access . // to `dst` while `src` is owned by this function. . unsafe { . assert_unsafe_precondition!( . "ptr::write requires that the pointer argument is aligned and non-null", . [T](dst: *mut T) => is_aligned_and_not_null(dst) . ); 1,990,389,726 (0.8%) intrinsics::write_via_move(dst, src) . } . } . . /// Overwrites a memory location with the given value without reading or . /// dropping the old value. . /// . /// Unlike [`write()`], the pointer may be unaligned. . /// -- line 1385 ---------------------------------------- -- line 1535 ---------------------------------------- . #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces . pub unsafe fn read_volatile(src: *const T) -> T { . // SAFETY: the caller must uphold the safety contract for `volatile_load`. . unsafe { . assert_unsafe_precondition!( . "ptr::read_volatile requires that the pointer argument is aligned and non-null", . [T](src: *const T) => is_aligned_and_not_null(src) . ); 14,659,281 (0.0%) intrinsics::volatile_load(src) . } . } . . /// Performs a volatile write of a memory location with the given value without . /// reading or dropping the old value. . /// . /// Volatile operations are intended to act on I/O memory, and are guaranteed . /// to not be elided or reordered by the compiler across other volatile -- line 1551 ---------------------------------------- -- line 1728 ---------------------------------------- . // redistributes operations around the load-bearing, but pessimizing `and` instruction . // sufficiently for LLVM to be able to utilize the various optimizations it knows about. . // . // LLVM handles the branch here particularly nicely. If this branch needs to be evaluated . // at runtime, it will produce a mask `if addr_mod_stride == 0 { 0 } else { usize::MAX }` . // in a branch-free way and then bitwise-OR it with whatever result the `-p mod a` . // computation produces. . 2,702 (0.0%) let aligned_address = wrapping_add(addr, a_minus_one) & wrapping_sub(0, a); 2,808 (0.0%) let byte_offset = wrapping_sub(aligned_address, addr); . // FIXME: Remove the assume after . // SAFETY: Masking by `-a` can only affect the low bits, and thus cannot have reduced . // the value by more than `a-1`, so even though the intermediate values might have . // wrapped, the byte_offset is always in `[0, a)`. . unsafe { assume(byte_offset < a) }; . . // SAFETY: `stride == 0` case has been handled by the special case above. . let addr_mod_stride = unsafe { unchecked_rem(addr, stride) }; -- line 1745 ---------------------------------------- -- line 1853 ---------------------------------------- . /// let a = [1, 2, 3]; . /// assert!(std::ptr::eq(&a[..3], &a[..3])); . /// assert!(!std::ptr::eq(&a[..2], &a[..3])); . /// assert!(!std::ptr::eq(&a[0..2], &a[1..3])); . /// ``` . #[stable(feature = "ptr_eq", since = "1.17.0")] . #[inline(always)] . pub fn eq(a: *const T, b: *const T) -> bool { 1,696,096,474 (0.7%) a == b . } . . /// Hash a raw pointer. . /// . /// This can be used to hash a `&T` reference (which coerces to `*const T` implicitly) . /// by its address rather than the value it points to . /// (which is what the `Hash for &T` implementation does). . /// -- line 1869 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/ptr/mut_ptr.rs -------------------------------------------------------------------------------- Ir__________________ 21,441 (0.0%) -- line 29 ---------------------------------------- . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")] . #[rustc_diagnostic_item = "ptr_is_null"] . #[inline] . pub const fn is_null(self) -> bool { . #[inline] . fn runtime_impl(ptr: *mut u8) -> bool { 37 (0.0%) ptr.addr() == 0 . } . . #[inline] . const fn const_impl(ptr: *mut u8) -> bool { . // Compare via a cast to a thin pointer, so fat pointers are only . // considering their "data" part for null-ness. . match (ptr).guaranteed_eq(null_mut()) { . None => false, -- line 45 ---------------------------------------- -- line 356 ---------------------------------------- . /// } . /// ``` . #[stable(feature = "ptr_as_ref", since = "1.9.0")] . #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] . #[inline] . pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> { . // SAFETY: the caller must guarantee that `self` is valid for a . // reference if it isn't null. 1 (0.0%) if self.is_null() { None } else { unsafe { Some(&*self) } } . } . . /// Returns `None` if the pointer is null, or else returns a shared reference to . /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require . /// that the value has to be initialized. . /// . /// For the mutable counterpart see [`as_uninit_mut`]. . /// -- line 372 ---------------------------------------- -- line 472 ---------------------------------------- . #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces . pub const unsafe fn offset(self, count: isize) -> *mut T . where . T: Sized, . { . // SAFETY: the caller must uphold the safety contract for `offset`. . // The obtained pointer is valid for writes since the caller must . // guarantee that it points to the same allocated object as `self`. 3,945,409,950 (1.6%) unsafe { intrinsics::offset(self, count) } . } . . /// Calculates the offset from a pointer in bytes. . /// . /// `count` is in units of **bytes**. . /// . /// This is purely a convenience for casting to a `u8` pointer and . /// using [offset][pointer::offset] on it. See that method for documentation -- line 488 ---------------------------------------- -- line 551 ---------------------------------------- . #[must_use = "returns a new pointer rather than modifying its argument"] . #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] . #[inline(always)] . pub const fn wrapping_offset(self, count: isize) -> *mut T . where . T: Sized, . { . // SAFETY: the `arith_offset` intrinsic has no prerequisites to be called. 7,113 (0.0%) unsafe { intrinsics::arith_offset(self, count) as *mut T } . } . . /// Calculates the offset from a pointer in bytes using wrapping arithmetic. . /// . /// `count` is in units of **bytes**. . /// . /// This is purely a convenience for casting to a `u8` pointer and . /// using [wrapping_offset][pointer::wrapping_offset] on it. See that method -- line 567 ---------------------------------------- -- line 1013 ---------------------------------------- . #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] . #[inline(always)] . #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces . pub const unsafe fn add(self, count: usize) -> Self . where . T: Sized, . { . // SAFETY: the caller must uphold the safety contract for `offset`. 620,444,822 (0.3%) unsafe { intrinsics::offset(self, count) } . } . . /// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`). . /// . /// `count` is in units of bytes. . /// . /// This is purely a convenience for casting to a `u8` pointer and . /// using [add][pointer::add] on it. See that method for documentation -- line 1029 ---------------------------------------- -- line 1424 ---------------------------------------- . /// . /// See [`ptr::drop_in_place`] for safety concerns and examples. . /// . /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place() . #[stable(feature = "pointer_methods", since = "1.26.0")] . #[inline(always)] . pub unsafe fn drop_in_place(self) { . // SAFETY: the caller must uphold the safety contract for `drop_in_place`. 2,216 (0.0%) unsafe { drop_in_place(self) } . } . . /// Overwrites a memory location with the given value without reading or . /// dropping the old value. . /// . /// See [`ptr::write`] for safety concerns and examples. . /// . /// [`ptr::write`]: crate::ptr::write() -- line 1440 ---------------------------------------- -- line 2151 ---------------------------------------- . } . } . . // Equality for pointers . #[stable(feature = "rust1", since = "1.0.0")] . impl PartialEq for *mut T { . #[inline(always)] . fn eq(&self, other: &*mut T) -> bool { 24,020 (0.0%) *self == *other . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl Eq for *mut T {} . . #[stable(feature = "rust1", since = "1.0.0")] . impl Ord for *mut T { -- line 2167 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/core/src/ptr/non_null.rs -------------------------------------------------------------------------------- Ir________________ 76,490 (0.0%) -- line 369 ---------------------------------------- . #[stable(feature = "nonnull", since = "1.25.0")] . #[rustc_const_stable(feature = "const_nonnull_as_ref", since = "CURRENT_RUSTC_VERSION")] . #[must_use] . #[inline(always)] . pub const unsafe fn as_ref<'a>(&self) -> &'a T { . // SAFETY: the caller must guarantee that `self` meets all the . // requirements for a reference. . // `cast_const` avoids a mutable raw pointer deref. 545,154 (0.0%) unsafe { &*self.as_ptr().cast_const() } . } . . /// Returns a unique reference to the value. If the value may be uninitialized, [`as_uninit_mut`] . /// must be used instead. . /// . /// For the shared counterpart see [`as_ref`]. . /// . /// [`as_uninit_mut`]: NonNull::as_uninit_mut -- line 385 ---------------------------------------- -- line 420 ---------------------------------------- . /// [the module documentation]: crate::ptr#safety . #[stable(feature = "nonnull", since = "1.25.0")] . #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")] . #[must_use] . #[inline(always)] . pub const unsafe fn as_mut<'a>(&mut self) -> &'a mut T { . // SAFETY: the caller must guarantee that `self` meets all the . // requirements for a mutable reference. 467 (0.0%) unsafe { &mut *self.as_ptr() } . } . . /// Casts to a pointer of another type. . /// . /// # Examples . /// . /// ``` . /// use std::ptr::NonNull; -- line 436 ---------------------------------------- -- line 758 ---------------------------------------- . . #[stable(feature = "nonnull", since = "1.25.0")] . impl Eq for NonNull {} . . #[stable(feature = "nonnull", since = "1.25.0")] . impl PartialEq for NonNull { . #[inline] . fn eq(&self, other: &Self) -> bool { 684,884,302 (0.3%) self.as_ptr() == other.as_ptr() . } . } . . #[stable(feature = "nonnull", since = "1.25.0")] . impl Ord for NonNull { . #[inline] . fn cmp(&self, other: &Self) -> Ordering { . self.as_ptr().cmp(&other.as_ptr()) -- line 774 ---------------------------------------- -- line 782 ---------------------------------------- . self.as_ptr().partial_cmp(&other.as_ptr()) . } . } . . #[stable(feature = "nonnull", since = "1.25.0")] . impl hash::Hash for NonNull { . #[inline] . fn hash(&self, state: &mut H) { 261,598,160 (0.1%) self.as_ptr().hash(state) . } . } . . #[unstable(feature = "ptr_internals", issue = "none")] . impl From> for NonNull { . #[inline] . fn from(unique: Unique) -> Self { . // SAFETY: A Unique pointer cannot be null, so the conditions for -- line 798 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: /home/njn/dev/rust0/library/std/src/collections/hash/map.rs -------------------------------------------------------------------------------- Ir________________ 70,406 (0.0%) -- line 277 ---------------------------------------- . /// let s = RandomState::new(); . /// let mut map = HashMap::with_hasher(s); . /// map.insert(1, 2); . /// ``` . #[inline] . #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] . #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")] . pub const fn with_hasher(hash_builder: S) -> HashMap { 1,650,298 (0.0%) HashMap { base: base::HashMap::with_hasher(hash_builder) } . } . . /// Creates an empty `HashMap` with at least the specified capacity, using . /// `hasher` to hash the keys. . /// . /// The hash map will be able to hold at least `capacity` elements without . /// reallocating. This method is allowed to allocate for more elements than . /// `capacity`. If `capacity` is 0, the hash map will not allocate. -- line 293 ---------------------------------------- -- line 509 ---------------------------------------- . /// . /// # Performance . /// . /// In the current implementation, iterating over map takes O(capacity) time . /// instead of O(len) because it internally visits empty buckets too. . #[rustc_lint_query_instability] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn iter(&self) -> Iter<'_, K, V> { 3 (0.0%) Iter { base: self.base.iter() } . } . . /// An iterator visiting all key-value pairs in arbitrary order, . /// with mutable references to the values. . /// The iterator element type is `(&'a K, &'a mut V)`. . /// . /// # Examples . /// -- line 525 ---------------------------------------- -- line 682 ---------------------------------------- . /// instead of O(len) because it internally visits empty buckets too. . #[inline] . #[rustc_lint_query_instability] . #[stable(feature = "retain_hash_collection", since = "1.18.0")] . pub fn retain(&mut self, f: F) . where . F: FnMut(&K, &mut V) -> bool, . { 3,389 (0.0%) self.base.retain(f) . } . . /// Clears the map, removing all key-value pairs. Keeps the allocated memory . /// for reuse. . /// . /// # Examples . /// . /// ``` -- line 698 ---------------------------------------- -- line 846 ---------------------------------------- . /// assert_eq!(letters[&'s'], 2); . /// assert_eq!(letters[&'t'], 3); . /// assert_eq!(letters[&'u'], 1); . /// assert_eq!(letters.get(&'y'), None); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn entry(&mut self, key: K) -> Entry<'_, K, V> { 27,650 (0.0%) map_entry(self.base.rustc_entry(key)) . } . . /// Returns a reference to the value corresponding to the key. . /// . /// The key may be any borrowed form of the map's key type, but . /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for . /// the key type. . /// -- line 862 ---------------------------------------- -- line 1095 ---------------------------------------- . /// . /// map.insert(37, "b"); . /// assert_eq!(map.insert(37, "c"), Some("b")); . /// assert_eq!(map[&37], "c"); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn insert(&mut self, k: K, v: V) -> Option { 542,695,815 (0.2%) self.base.insert(k, v) . } . . /// Tries to insert a key-value pair into the map, and returns . /// a mutable reference to the value in the entry. . /// . /// If the map already had this key present, nothing is updated, and . /// an error containing the occupied entry and the value is returned. . /// -- line 1111 ---------------------------------------- -- line 1258 ---------------------------------------- . impl Clone for HashMap . where . K: Clone, . V: Clone, . S: Clone, . { . #[inline] . fn clone(&self) -> Self { 10 (0.0%) Self { base: self.base.clone() } . } . . #[inline] . fn clone_from(&mut self, other: &Self) { . self.base.clone_from(&other.base); . } . } . -- line 1274 ---------------------------------------- -- line 1330 ---------------------------------------- . type Output = V; . . /// Returns a reference to the value corresponding to the supplied key. . /// . /// # Panics . /// . /// Panics if the key is not present in the `HashMap`. . #[inline] 13,931 (0.0%) fn index(&self, key: &Q) -> &V { . self.get(key).expect("no entry found for key") 27,862 (0.0%) } . } . . #[stable(feature = "std_collections_from_array", since = "1.56.0")] . // Note: as what is currently the most convenient built-in way to construct . // a HashMap, a simple usage of this function must not *require* the user . // to provide a type annotation in order to infer the third type parameter . // (the hasher parameter, conventionally "S"). . // To that end, this impl is defined using RandomState as the concrete -- line 1348 ---------------------------------------- -- line 2212 ---------------------------------------- . /// ]); . /// . /// // Not possible with .iter() . /// let vec: Vec<(&str, i32)> = map.into_iter().collect(); . /// ``` . #[inline] . #[rustc_lint_query_instability] . fn into_iter(self) -> IntoIter { 624 (0.0%) IntoIter { base: self.base.into_iter() } . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl<'a, K, V> Iterator for Iter<'a, K, V> { . type Item = (&'a K, &'a V); . . #[inline] -- line 2228 ---------------------------------------- -- line 2524 ---------------------------------------- . /// assert_eq!(map["poneyland"], 3); . /// . /// *map.entry("poneyland").or_insert(10) *= 2; . /// assert_eq!(map["poneyland"], 6); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn or_insert(self, default: V) -> &'a mut V { 38 (0.0%) match self { . Occupied(entry) => entry.into_mut(), 4 (0.0%) Vacant(entry) => entry.insert(default), . } . } . . /// Ensures a value is in the entry by inserting the result of the default function if empty, . /// and returns a mutable reference to the value in the entry. . /// . /// # Examples . /// -- line 2542 ---------------------------------------- -- line 2550 ---------------------------------------- . /// . /// assert_eq!(map["poneyland"], "hoho"); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn or_insert_with V>(self, default: F) -> &'a mut V { . match self { . Occupied(entry) => entry.into_mut(), 707 (0.0%) Vacant(entry) => entry.insert(default()), . } . } . . /// Ensures a value is in the entry by inserting, if empty, the result of the default function. . /// This method allows for generating key-derived values for insertion by providing the default . /// function a reference to the key that was moved during the `.entry(key)` method call. . /// . /// The reference to the moved key is provided so that cloning or copying the key is -- line 2566 ---------------------------------------- -- line 2683 ---------------------------------------- . /// map.entry("poneyland").or_default(); . /// . /// assert_eq!(map["poneyland"], None); . /// # } . /// ``` . #[inline] . #[stable(feature = "entry_or_default", since = "1.28.0")] . pub fn or_default(self) -> &'a mut V { 18 (0.0%) match self { . Occupied(entry) => entry.into_mut(), 84 (0.0%) Vacant(entry) => entry.insert(Default::default()), . } 9 (0.0%) } . } . . impl<'a, K, V> OccupiedEntry<'a, K, V> { . /// Gets a reference to the key in the entry. . /// . /// # Examples . /// . /// ``` -- line 2703 ---------------------------------------- -- line 2977 ---------------------------------------- . /// if let Entry::Vacant(o) = map.entry("poneyland") { . /// o.insert(37); . /// } . /// assert_eq!(map["poneyland"], 37); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn insert(self, value: V) -> &'a mut V { 539 (0.0%) self.base.insert(value) . } . . /// Sets the value of the entry with the `VacantEntry`'s key, . /// and returns an `OccupiedEntry`. . /// . /// # Examples . /// . /// ``` -- line 2993 ---------------------------------------- -- line 3011 ---------------------------------------- . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl FromIterator<(K, V)> for HashMap . where . K: Eq + Hash, . S: BuildHasher + Default, . { 1,430 (0.0%) fn from_iter>(iter: T) -> HashMap { . let mut map = HashMap::with_hasher(Default::default()); 1,876,784 (0.0%) map.extend(iter); 1,231,353 (0.0%) map 1,900 (0.0%) } . } . . /// Inserts all new key-values from the iterator and replaces values with existing . /// keys with new values returned from the iterator. . #[stable(feature = "rust1", since = "1.0.0")] . impl Extend<(K, V)> for HashMap . where . K: Eq + Hash, . S: BuildHasher, . { . #[inline] . fn extend>(&mut self, iter: T) { 267,915 (0.0%) self.base.extend(iter) . } . . #[inline] . fn extend_one(&mut self, (k, v): (K, V)) { . self.base.insert(k, v); . } . . #[inline] -- line 3044 ---------------------------------------- -- line 3116 ---------------------------------------- . // many hash maps are created on a thread. To solve this performance . // trap we cache the first set of randomly generated keys per-thread. . // . // Later in #36481 it was discovered that exposing a deterministic . // iteration order allows a form of DOS attack. To counter that we . // increment one of the seeds on every RandomState creation, giving . // every corresponding HashMap a different iteration order. . thread_local!(static KEYS: Cell<(u64, u64)> = { 1 (0.0%) Cell::new(sys::hashmap_random_keys()) . }); . . KEYS.with(|keys| { . let (k0, k1) = keys.get(); . keys.set((k0.wrapping_add(1), k1)); . RandomState { k0, k1 } . }) . } -- line 3132 ---------------------------------------- -- line 3158 ---------------------------------------- . /// `DefaultHasher` instances, but is the same as all other `DefaultHasher` . /// instances created through `new` or `default`. . #[stable(feature = "hashmap_default_hasher", since = "1.13.0")] . #[inline] . #[allow(deprecated)] . #[rustc_const_unstable(feature = "const_hash", issue = "104061")] . #[must_use] . pub const fn new() -> DefaultHasher { 11 (0.0%) DefaultHasher(SipHasher13::new_with_keys(0, 0)) . } . } . . #[stable(feature = "hashmap_default_hasher", since = "1.13.0")] . impl Default for DefaultHasher { . /// Creates a new `DefaultHasher` using [`new`]. . /// See its documentation for more. . /// -- line 3174 ---------------------------------------- -- line 3182 ---------------------------------------- . #[stable(feature = "hashmap_default_hasher", since = "1.13.0")] . impl Hasher for DefaultHasher { . // The underlying `SipHasher13` doesn't override the other . // `write_*` methods, so it's ok not to forward them here. . . #[inline] . fn write(&mut self, msg: &[u8]) { . self.0.write(msg) 6 (0.0%) } . . #[inline] . fn write_str(&mut self, s: &str) { . self.0.write_str(s); . } . . #[inline] . fn finish(&self) -> u64 { -- line 3198 ---------------------------------------- -- line 3213 ---------------------------------------- . impl fmt::Debug for RandomState { . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { . f.debug_struct("RandomState").finish_non_exhaustive() . } . } . . #[inline] . fn map_entry<'a, K: 'a, V: 'a>(raw: base::RustcEntry<'a, K, V>) -> Entry<'a, K, V> { 43,624 (0.0%) match raw { 4,180 (0.0%) base::RustcEntry::Occupied(base) => Entry::Occupied(OccupiedEntry { base }), 97,091 (0.0%) base::RustcEntry::Vacant(base) => Entry::Vacant(VacantEntry { base }), . } . } . . #[inline] . pub(super) fn map_try_reserve_error(err: hashbrown::TryReserveError) -> TryReserveError { . match err { . hashbrown::TryReserveError::CapacityOverflow => { . TryReserveErrorKind::CapacityOverflow.into() -- line 3231 ---------------------------------------- -- line 3235 ---------------------------------------- . } . } . } . . #[inline] . fn map_raw_entry<'a, K: 'a, V: 'a, S: 'a>( . raw: base::RawEntryMut<'a, K, V, S>, . ) -> RawEntryMut<'a, K, V, S> { 44,102,772 (0.0%) match raw { . base::RawEntryMut::Occupied(base) => RawEntryMut::Occupied(RawOccupiedEntryMut { base }), . base::RawEntryMut::Vacant(base) => RawEntryMut::Vacant(RawVacantEntryMut { base }), . } . } . . #[allow(dead_code)] . fn assert_covariance() { . fn map_key<'new>(v: HashMap<&'static str, u8>) -> HashMap<&'new str, u8> { -- line 3251 ---------------------------------------- -------------------------------------------------------------------------------- -- Annotated source file: -------------------------------------------------------------------------------- Unannotated because one or more of these original files are unreadable: - -------------------------------------------------------------------------------- -- Annotation summary -------------------------------------------------------------------------------- Ir_____________________ 185,888,316,524 (77.1%) annotated: files known & above threshold & readable, line numbers known 36,854,842,194 (15.3%) annotated: files known & above threshold & readable, line numbers unknown 0 unannotated: files known & above threshold & two or more non-identical 8,066,318,832 (3.3%) unannotated: files known & above threshold & unreadable 10,415,601,246 (4.3%) unannotated: files known & below threshold 23,473,003 (0.0%) unannotated: files unknown