-------------------------------------------------------------------------------- I1 cache: 65536 B, 64 B, 4-way associative D1 cache: 32768 B, 64 B, 8-way associative LL cache: 67108864 B, 64 B, 64-way associative Command: /usr/home/liquid/.rustup/toolchains/w-profiling/bin/rustc --crate-name sentry_types --edition=2018 src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type lib --emit=dep-info,metadata,link -C opt-level=3 -C embed-bitcode=no --cfg feature="default" --cfg feature="protocol" -C metadata=3f9efb5d4ad26fb2 -C extra-filename=-3f9efb5d4ad26fb2 --out-dir /usr/home/liquid/tmp/.tmprwBCr3/target/release/deps -L dependency=/usr/home/liquid/tmp/.tmprwBCr3/target/release/deps --extern debugid=/usr/home/liquid/tmp/.tmprwBCr3/target/release/deps/libdebugid-91cea7a256291e34.rmeta --extern getrandom=/usr/home/liquid/tmp/.tmprwBCr3/target/release/deps/libgetrandom-9059d26502f14346.rmeta --extern hex=/usr/home/liquid/tmp/.tmprwBCr3/target/release/deps/libhex-d179b7ce5a42ad9e.rmeta --extern serde=/usr/home/liquid/tmp/.tmprwBCr3/target/release/deps/libserde-fc05f8c3c891b92a.rmeta --extern serde_json=/usr/home/liquid/tmp/.tmprwBCr3/target/release/deps/libserde_json-8a3c2629cc7d15ff.rmeta --extern thiserror=/usr/home/liquid/tmp/.tmprwBCr3/target/release/deps/libthiserror-6ca5817dd6293fe5.rmeta --extern time=/usr/home/liquid/tmp/.tmprwBCr3/target/release/deps/libtime-895afc73ec82228e.rmeta --extern url=/usr/home/liquid/tmp/.tmprwBCr3/target/release/deps/liburl-113bf2ac77a1aabe.rmeta --extern uuid=/usr/home/liquid/tmp/.tmprwBCr3/target/release/deps/libuuid-df52a25fd10c2dcc.rmeta -Adeprecated -Aunknown-lints -Zincremental-verify-ich Data file: results/cgout-w-profiling-sentry-types-0.24.2-Opt-Full Events recorded: Ir Events shown: Ir Event sort order: Ir Thresholds: 0.1 Include dirs: User annotated: Auto-annotation: on -------------------------------------------------------------------------------- Ir -------------------------------------------------------------------------------- 27,241,100,693 (100.0%) PROGRAM TOTALS -------------------------------------------------------------------------------- Ir file:function -------------------------------------------------------------------------------- 853,342,994 ( 3.13%) ./malloc/malloc.c:_int_free 739,367,273 ( 2.71%) ./malloc/malloc.c:_int_malloc 528,876,187 ( 1.94%) ./malloc/malloc.c:malloc 396,932,367 ( 1.46%) ???:llvm::FPPassManager::runOnFunction(llvm::Function&) 390,910,673 ( 1.44%) ???:llvm::InstCombinerImpl::run() 283,789,256 ( 1.04%) ./string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:__memcpy_avx_unaligned_erms 272,284,793 ( 1.00%) ./malloc/malloc.c:free 263,912,048 ( 0.97%) ???:combineInstructionsOverFunction(llvm::Function&, llvm::InstCombineWorklist&, llvm::AAResults*, llvm::AssumptionCache&, llvm::TargetLibraryInfo&, llvm::TargetTransformInfo&, llvm::DominatorTree&, llvm::OptimizationRemarkEmitter&, llvm::BlockFrequencyInfo*, llvm::ProfileSummaryInfo*, unsigned int, llvm::LoopInfo*) 243,609,112 ( 0.89%) ???:llvm::isNonEscapingLocalObject(llvm::Value const*, llvm::SmallDenseMap, llvm::detail::DenseMapPair >*) 241,334,724 ( 0.89%) ???:llvm::SelectionDAG::Combine(llvm::CombineLevel, llvm::AAResults*, llvm::CodeGenOpt::Level) 237,568,147 ( 0.87%) ???:llvm::AnalysisManager::getResultImpl(llvm::AnalysisKey*, llvm::Function&) 223,272,626 ( 0.82%) ???:llvm::AnalysisManager::invalidate(llvm::Function&, llvm::PreservedAnalyses const&) 198,474,106 ( 0.73%) ???:llvm::BasicAAResult::alias(llvm::MemoryLocation const&, llvm::MemoryLocation const&, llvm::AAQueryInfo&) 166,465,904 ( 0.61%) ???:llvm::BitstreamCursor::readRecord(unsigned int, llvm::SmallVectorImpl&, llvm::StringRef*) 141,275,662 ( 0.52%) ???:llvm::DomTreeBuilder::SemiNCAInfo >::CalculateFromScratch(llvm::DominatorTreeBase&, llvm::DomTreeBuilder::SemiNCAInfo >::BatchUpdateInfo*) 134,707,670 ( 0.49%) ???:runCVP(llvm::Module&) [clone .llvm.11785992503873176614] 133,914,569 ( 0.49%) ???:llvm::ValueHandleBase::AddToUseList() 133,664,332 ( 0.49%) ???:computeKnownBits(llvm::Value const*, llvm::KnownBits&, unsigned int, (anonymous namespace)::Query const&) [clone .llvm.15619146473165121143] 132,542,673 ( 0.49%) ./string/../sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S:__memcmp_avx2_movbe 129,974,100 ( 0.48%) ???:llvm::TargetLibraryInfoImpl::getLibFunc(llvm::Function const&, llvm::LibFunc&) const 126,634,970 ( 0.46%) ???:llvm::AttributeList::addAttributes(llvm::LLVMContext&, unsigned int, llvm::AttrBuilder const&) const 122,619,677 ( 0.45%) ???:llvm::DataLayout::getAlignment(llvm::Type*, bool) const 116,757,793 ( 0.43%) ./malloc/malloc.c:malloc_consolidate 116,455,446 ( 0.43%) ???:bool llvm::DenseMapBase*, llvm::DenseMapInfo<(anonymous namespace)::SimpleValue>, llvm::detail::DenseMapPair<(anonymous namespace)::SimpleValue, llvm::ScopedHashTableVal<(anonymous namespace)::SimpleValue, llvm::Value*>*> >, (anonymous namespace)::SimpleValue, llvm::ScopedHashTableVal<(anonymous namespace)::SimpleValue, llvm::Value*>*, llvm::DenseMapInfo<(anonymous namespace)::SimpleValue>, llvm::detail::DenseMapPair<(anonymous namespace)::SimpleValue, llvm::ScopedHashTableVal<(anonymous namespace)::SimpleValue, llvm::Value*>*> >::LookupBucketFor<(anonymous namespace)::SimpleValue>((anonymous namespace)::SimpleValue const&, llvm::detail::DenseMapPair<(anonymous namespace)::SimpleValue, llvm::ScopedHashTableVal<(anonymous namespace)::SimpleValue, llvm::Value*>*> const*&) const 105,462,047 ( 0.39%) ???:(anonymous namespace)::LazyValueInfoImpl::solve() [clone .llvm.4316243980339171764] 105,296,194 ( 0.39%) ???:SimplifyICmpInst(unsigned int, llvm::Value*, llvm::Value*, llvm::SimplifyQuery const&, unsigned int) [clone .llvm.1619516508949622737] 104,372,206 ( 0.38%) ???:llvm::DataLayout::getTypeSizeInBits(llvm::Type*) const 104,221,399 ( 0.38%) ???:llvm::InstCombinerImpl::visitCallInst(llvm::CallInst&) 100,089,341 ( 0.37%) ???:llvm::removeUnreachableBlocks(llvm::Function&, llvm::DomTreeUpdater*, llvm::MemorySSAUpdater*) 97,513,512 ( 0.36%) ???:computeKnownBitsFromOperator(llvm::Operator const*, llvm::APInt const&, llvm::KnownBits&, unsigned int, (anonymous namespace)::Query const&) 94,572,520 ( 0.35%) ???:llvm::SimplifyInstruction(llvm::Instruction*, llvm::SimplifyQuery const&, llvm::OptimizationRemarkEmitter*) 85,944,792 ( 0.32%) ???:llvm::LiveVariables::runOnBlock(llvm::MachineBasicBlock*, unsigned int) 81,890,625 ( 0.30%) ???:(anonymous namespace)::LazyValueInfoImpl::getEdgeValue(llvm::Value*, llvm::BasicBlock*, llvm::BasicBlock*, llvm::Instruction*) [clone .llvm.4316243980339171764] 76,329,276 ( 0.28%) ./malloc/malloc.c:unlink_chunk.constprop.0 76,156,193 ( 0.28%) ???:llvm::AttributeList::get(llvm::LLVMContext&, llvm::ArrayRef) 73,776,728 ( 0.27%) ???:isKnownNonZero(llvm::Value const*, llvm::APInt const&, unsigned int, (anonymous namespace)::Query const&) [clone .llvm.15619146473165121143] 72,650,700 ( 0.27%) /usr/home/liquid/rust/worktree-benchmarking/library/core/src/hash/sip.rs:::write 71,411,940 ( 0.26%) ???:llvm::InstCombinerImpl::visitICmpInst(llvm::ICmpInst&) 71,305,300 ( 0.26%) ???:(anonymous namespace)::MachineCopyPropagation::runOnMachineFunction(llvm::MachineFunction&) 70,373,406 ( 0.26%) ???:computeKnownBits(llvm::Value const*, llvm::APInt const&, llvm::KnownBits&, unsigned int, (anonymous namespace)::Query const&) 69,486,527 ( 0.26%) ???:llvm::InlineFunction(llvm::CallBase&, llvm::InlineFunctionInfo&, llvm::AAResults*, bool, llvm::Function*) 69,242,323 ( 0.25%) ???:llvm::DomTreeBuilder::SemiNCAInfo >::runSemiNCA(llvm::DominatorTreeBase&, unsigned int) 68,917,947 ( 0.25%) ???:llvm::coro::declaresIntrinsics(llvm::Module const&, std::initializer_list) 68,450,558 ( 0.25%) /tmp/gcc-build/x86_64-unknown-linux-gnu/libstdc++-v3/libsupc++/../../../../gcc-5.5.0/libstdc++-v3/libsupc++/new_op.cc:operator new(unsigned long) 66,746,270 ( 0.25%) ???:llvm::PMDataManager::verifyPreservedAnalysis(llvm::Pass*) 66,086,785 ( 0.24%) ???:llvm::AttributeSetNode::get(llvm::LLVMContext&, llvm::AttrBuilder const&) 66,073,810 ( 0.24%) ./string/../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:__memset_avx2_erms 65,682,270 ( 0.24%) ???:(anonymous namespace)::DAGCombiner::combine(llvm::SDNode*) 65,005,363 ( 0.24%) /usr/home/liquid/rust/worktree-benchmarking/library/proc_macro/src/bridge/server.rs:> as proc_macro::bridge::server::DispatcherTrait>::dispatch 63,483,469 ( 0.23%) ???:computeKnownBitsFromAssume(llvm::Value const*, llvm::KnownBits&, unsigned int, (anonymous namespace)::Query const&) 63,267,102 ( 0.23%) ???:llvm::simplifyCFG(llvm::BasicBlock*, llvm::TargetTransformInfo const&, llvm::DomTreeUpdater*, llvm::SimplifyCFGOptions const&, llvm::ArrayRef) 62,706,266 ( 0.23%) ./string/../sysdeps/x86_64/multiarch/strcmp-avx2.S:__strncmp_avx2 62,258,258 ( 0.23%) ???:llvm::FindFunctionBackedges(llvm::Function const&, llvm::SmallVectorImpl >&) 62,197,674 ( 0.23%) ./elf/../elf/dl-tls.c:_dl_update_slotinfo 60,859,195 ( 0.22%) /usr/home/liquid/.cargo/registry/src/github.com-1ecc6299db9ec823/hashbrown-0.12.0/src/raw/mod.rs:, (), core::hash::BuildHasherDefault>>::from_hash::>::{closure#0}> 59,699,119 ( 0.22%) ???:(anonymous namespace)::EarlyCSE::run() [clone .llvm.7062997131228810369] 58,249,347 ( 0.21%) ???:llvm::MemorySSA::buildMemorySSA(llvm::BatchAAResults&) 57,955,354 ( 0.21%) ???:llvm::SelectionDAGISel::SelectCodeCommon(llvm::SDNode*, unsigned char const*, unsigned int) 56,858,461 ( 0.21%) ???:llvm::detail::PassModel>, llvm::PreservedAnalyses, llvm::AnalysisManager>::run(llvm::Function&, llvm::AnalysisManager&) 54,923,353 ( 0.20%) ???:llvm::SimplifyGEPInst(llvm::Type*, llvm::ArrayRef, llvm::SimplifyQuery const&) 53,676,791 ( 0.20%) ???:llvm::LiveVariables::HandleRegMask(llvm::MachineOperand const&) 51,249,330 ( 0.19%) ???:(anonymous namespace)::eliminateDeadStores(llvm::Function&, llvm::AAResults&, llvm::MemorySSA&, llvm::DominatorTree&, llvm::PostDominatorTree&, llvm::TargetLibraryInfo const&, llvm::LoopInfo const&) [clone .llvm.5769264623867638418] 50,713,515 ( 0.19%) ???:llvm::BasicAAResult::getModRefInfo(llvm::CallBase const*, llvm::MemoryLocation const&, llvm::AAQueryInfo&) 50,664,832 ( 0.19%) ???:llvm::Type::isSizedDerivedType(llvm::SmallPtrSetImpl*) const 50,013,253 ( 0.18%) ???:(anonymous namespace)::DeadMachineInstructionElim::eliminateDeadMI(llvm::MachineFunction&) 49,486,415 ( 0.18%) ???:llvm::GVN::processBlock(llvm::BasicBlock*) 48,695,904 ( 0.18%) ???:llvm::ScalarEvolution::getAddExpr(llvm::SmallVectorImpl&, llvm::SCEV::NoWrapFlags, unsigned int) 48,130,621 ( 0.18%) ???:llvm::SROA::runOnAlloca(llvm::AllocaInst&) 46,636,843 ( 0.17%) ???:llvm::Value::stripAndAccumulateConstantOffsets(llvm::DataLayout const&, llvm::APInt&, bool, llvm::function_ref) const 46,040,800 ( 0.17%) ???:llvm::DomTreeBuilder::SemiNCAInfo >::CalculateFromScratch(llvm::DominatorTreeBase&, llvm::DomTreeBuilder::SemiNCAInfo >::BatchUpdateInfo*) 45,049,319 ( 0.17%) ???:(anonymous namespace)::PruningFunctionCloner::CloneBlock(llvm::BasicBlock const*, llvm::ilist_iterator, false, true>, std::vector >&) 44,551,573 ( 0.16%) ???:llvm::DomTreeBuilder::SemiNCAInfo >::FindRoots(llvm::DominatorTreeBase const&, llvm::DomTreeBuilder::SemiNCAInfo >::BatchUpdateInfo*) 44,413,943 ( 0.16%) /usr/home/liquid/rust/worktree-benchmarking/library/core/src/num/uint_macros.rs:::short_write_process_buffer:: 43,181,244 ( 0.16%) ???:llvm::InstCombinerImpl::visitLoadInst(llvm::LoadInst&) 42,825,081 ( 0.16%) ???:llvm::LivePhysRegs::stepBackward(llvm::MachineInstr const&) 42,759,628 ( 0.16%) /usr/home/liquid/rust/worktree-benchmarking/library/proc_macro/src/bridge/client.rs:proc_macro::bridge::scoped_cell::ScopedCell::replace 42,297,647 ( 0.16%) ./string/../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:__memset_avx2_unaligned_erms 41,445,771 ( 0.15%) ./malloc/malloc.c:realloc 41,036,276 ( 0.15%) ???:llvm::InstCombinerImpl::visitBitCast(llvm::BitCastInst&) 40,905,520 ( 0.15%) ???:(anonymous namespace)::SimplifyCFGOpt::simplifyCondBranch(llvm::BranchInst*, llvm::IRBuilder&) 40,834,756 ( 0.15%) ???:llvm::MD5::final(llvm::MD5::MD5Result&) 40,495,570 ( 0.15%) ???:(anonymous namespace)::AggressiveDeadCodeElimination::performDeadCodeElimination() 40,303,695 ( 0.15%) ???:llvm::TargetLoweringBase::getTypeConversion(llvm::LLVMContext&, llvm::EVT) const 40,273,650 ( 0.15%) ???:??? 39,895,592 ( 0.15%) /usr/home/liquid/rust/worktree-benchmarking/library/alloc/src/string.rs:alloc::string::String::push 38,667,484 ( 0.14%) ???:llvm::DemandedBits::isInstructionDead(llvm::Instruction*) 38,535,913 ( 0.14%) ???:llvm::ConstantRange::makeExactICmpRegion(llvm::CmpInst::Predicate, llvm::APInt const&) 38,229,238 ( 0.14%) ???:llvm::MemoryDependenceResults::getNonLocalPointerDepFromBB(llvm::Instruction*, llvm::PHITransAddr const&, llvm::MemoryLocation const&, bool, llvm::BasicBlock*, llvm::SmallVectorImpl&, llvm::DenseMap, llvm::detail::DenseMapPair >&, bool, bool) 38,062,425 ( 0.14%) ???:llvm::ScheduleDAGSDNodes::BuildSchedUnits() 37,835,604 ( 0.14%) ???:llvm::MD5::update(llvm::StringRef) 37,525,282 ( 0.14%) ???:(anonymous namespace)::Verifier::visitInstruction(llvm::Instruction&) 37,514,854 ( 0.14%) ???:llvm::InstCombinerImpl::SimplifyDemandedUseBits(llvm::Value*, llvm::APInt, llvm::KnownBits&, unsigned int, llvm::Instruction*) 36,708,756 ( 0.13%) ???:llvm::SmallPtrSetImplBase::insert_imp_big(void const*) 35,532,251 ( 0.13%) ???:llvm::AttributeList::addAttribute(llvm::LLVMContext&, unsigned int, llvm::Attribute::AttrKind) const 35,502,527 ( 0.13%) ???:llvm::IDFCalculatorBase::calculate(llvm::SmallVectorImpl&) 35,245,803 ( 0.13%) ???:llvm::LoopBase::verifyLoop() const 35,185,510 ( 0.13%) ???:updateCGAndAnalysisManagerForPass(llvm::LazyCallGraph&, llvm::LazyCallGraph::SCC&, llvm::LazyCallGraph::Node&, llvm::AnalysisManager&, llvm::CGSCCUpdateResult&, llvm::AnalysisManager&, bool) [clone .llvm.5426518467876156712] 35,132,933 ( 0.13%) ???:llvm::LoopInfoBase::analyze(llvm::DominatorTreeBase const&) 34,963,513 ( 0.13%) ???:llvm::PopulateLoopsDFS::traverse(llvm::BasicBlock*) 34,853,723 ( 0.13%) ???:(anonymous namespace)::CVPLatticeFunc::ComputeInstructionState(llvm::Instruction&, llvm::DenseMap, llvm::PointerIntPairInfo > >, (anonymous namespace)::CVPLatticeVal, llvm::DenseMapInfo, llvm::PointerIntPairInfo > > >, llvm::detail::DenseMapPair, llvm::PointerIntPairInfo > >, (anonymous namespace)::CVPLatticeVal> >&, llvm::SparseSolver, llvm::PointerIntPairInfo > >, (anonymous namespace)::CVPLatticeVal, llvm::LatticeKeyInfo, llvm::PointerIntPairInfo > > > >&) 34,816,453 ( 0.13%) ???:llvm::AAResults::getModRefInfo(llvm::Instruction const*, llvm::Optional const&, llvm::AAQueryInfo&) 34,566,661 ( 0.13%) ???:(anonymous namespace)::LazyValueInfoImpl::getValueInBlock(llvm::Value*, llvm::BasicBlock*, llvm::Instruction*) [clone .llvm.4316243980339171764] 34,542,031 ( 0.13%) /usr/home/liquid/rust/worktree-benchmarking/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs:rustc_mir_dataflow::drop_flag_effects::on_all_children_bits::is_terminal_path 33,864,615 ( 0.12%) ???:llvm::MachineInstr::addOperand(llvm::MachineFunction&, llvm::MachineOperand const&) 33,846,690 ( 0.12%) ???:llvm::AAResults::Model::getModRefBehavior(llvm::CallBase const*) 33,608,113 ( 0.12%) ???:llvm::FoldingSetBase::FindNodeOrInsertPos(llvm::FoldingSetNodeID const&, void*&, llvm::FoldingSetBase::FoldingSetInfo const&) 33,486,488 ( 0.12%) ???:(anonymous namespace)::BitcodeReader::parseModule(unsigned long, bool, llvm::function_ref, std::allocator > > (llvm::StringRef)>) 33,256,110 ( 0.12%) ???:llvm::BlockFrequencyInfoImpl::initializeRPOT() 32,641,848 ( 0.12%) /usr/home/liquid/rust/worktree-benchmarking/library/alloc/src/vec/mod.rs:alloc::string::String::push 32,253,629 ( 0.12%) ???:runImpl(llvm::Function&, llvm::LazyValueInfo*, llvm::DominatorTree*, llvm::SimplifyQuery const&) [clone .llvm.16011871802505272439] 32,099,755 ( 0.12%) ???:llvm::getObjectSize(llvm::Value const*, unsigned long&, llvm::DataLayout const&, llvm::TargetLibraryInfo const*, llvm::ObjectSizeOpts) 32,019,688 ( 0.12%) /usr/home/liquid/rust/worktree-benchmarking/compiler/rustc_middle/src/ty/sty.rs:::eq 31,802,612 ( 0.12%) ???:llvm::ScalarEvolution::getRangeRef(llvm::SCEV const*, llvm::ScalarEvolution::RangeSignHint) 31,764,169 ( 0.12%) ???:llvm::MemorySSA::OptimizeUses::optimizeUses() 31,278,902 ( 0.11%) ???:llvm::InstCombinerImpl::visitStoreInst(llvm::StoreInst&) 30,570,044 ( 0.11%) /usr/home/liquid/rust/worktree-benchmarking/library/std/src/sys/unix/alloc.rs:__rdl_alloc 29,793,204 ( 0.11%) /usr/home/liquid/rust/worktree-benchmarking/compiler/rustc_data_structures/src/sip128.rs:::short_write_process_buffer:: 29,785,170 ( 0.11%) ./string/../sysdeps/x86_64/multiarch/strlen-avx2.S:__strlen_avx2 29,725,272 ( 0.11%) ???:llvm::SCCPInstVisitor::solve() 29,687,047 ( 0.11%) ???:llvm::JumpThreadingPass::processBlock(llvm::BasicBlock*) 29,638,300 ( 0.11%) /usr/home/liquid/rust/worktree-benchmarking/compiler/rustc_infer/src/infer/mod.rs:::shallow_resolve_ty 29,574,554 ( 0.11%) ???:llvm::ReassociatePass::BuildRankMap(llvm::Function&, llvm::ReversePostOrderTraversal >&) 29,037,185 ( 0.11%) ???:llvm::AAResults::Model::pointsToConstantMemory(llvm::MemoryLocation const&, llvm::AAQueryInfo&, bool) 28,838,896 ( 0.11%) ./malloc/malloc.c:_int_realloc 28,150,856 ( 0.10%) ???:llvm::Intrinsic::getDeclaration(llvm::Module*, unsigned int, llvm::ArrayRef) 28,025,928 ( 0.10%) /usr/home/liquid/rust/worktree-benchmarking/library/proc_macro/src/bridge/rpc.rs:>::decode 27,964,830 ( 0.10%) ???:llvm::ScalarEvolution::getSCEV(llvm::Value*) 27,816,091 ( 0.10%) ???:llvm::PMDataManager::removeNotPreservedAnalysis(llvm::Pass*) 27,689,643 ( 0.10%) /usr/home/liquid/.cargo/registry/src/github.com-1ecc6299db9ec823/hashbrown-0.12.0/src/map.rs:, (), core::hash::BuildHasherDefault>>::from_hash::>::{closure#0}> -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/library/core/src/num/uint_macros.rs -------------------------------------------------------------------------------- Ir -- line 57 ---------------------------------------- . /// # Examples . /// . /// Basic usage: . /// . /// ``` . #[doc = concat!("assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));")] . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] 1,422 ( 0.00%) pub fn from_str_radix(src: &str, radix: u32) -> Result { 711 ( 0.00%) from_str_radix(src, radix) 2,133 ( 0.00%) } . . /// Returns the number of ones in the binary representation of `self`. . /// . /// # Examples . /// . /// Basic usage: . /// . /// ``` -- line 75 ---------------------------------------- -- line 80 ---------------------------------------- . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_math", since = "1.32.0")] . #[doc(alias = "popcount")] . #[doc(alias = "popcnt")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline(always)] . pub const fn count_ones(self) -> u32 { 872,280 ( 0.00%) intrinsics::ctpop(self as $ActualT) as u32 . } . . /// Returns the number of zeros in the binary representation of `self`. . /// . /// # Examples . /// . /// Basic usage: . /// -- line 96 ---------------------------------------- -- line 118 ---------------------------------------- . /// assert_eq!(n.leading_zeros(), 2); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_math", since = "1.32.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline(always)] . pub const fn leading_zeros(self) -> u32 { 1,511,796 ( 0.01%) intrinsics::ctlz(self as $ActualT) as u32 . } . . /// Returns the number of trailing zeros in the binary representation . /// of `self`. . /// . /// # Examples . /// . /// Basic usage: -- line 134 ---------------------------------------- -- line 139 ---------------------------------------- . /// assert_eq!(n.trailing_zeros(), 3); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_math", since = "1.32.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline(always)] . pub const fn trailing_zeros(self) -> u32 { 1,410,200 ( 0.01%) intrinsics::cttz(self) as u32 . } . . /// Returns the number of leading ones in the binary representation of `self`. . /// . /// # Examples . /// . /// Basic usage: . /// -- line 155 ---------------------------------------- -- line 204 ---------------------------------------- . #[doc = concat!("assert_eq!(n.rotate_left(", $rot, "), m);")] . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_math", since = "1.32.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline(always)] . pub const fn rotate_left(self, n: u32) -> Self { 63,909,408 ( 0.23%) intrinsics::rotate_left(self, n as $SelfT) . } . . /// Shifts the bits to the right by a specified amount, `n`, . /// wrapping the truncated bits to the beginning of the resulting . /// integer. . /// . /// Please note this isn't the same operation as the `>>` shifting operator! . /// -- line 220 ---------------------------------------- -- line 430 ---------------------------------------- . #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(3), None);")] . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline] . pub const fn checked_add(self, rhs: Self) -> Option { 1,312 ( 0.00%) let (a, b) = self.overflowing_add(rhs); . if unlikely!(b) {None} else {Some(a)} . } . . /// Unchecked integer addition. Computes `self + rhs`, assuming overflow . /// cannot occur. . /// . /// # Safety . /// -- line 446 ---------------------------------------- -- line 456 ---------------------------------------- . )] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")] . #[inline(always)] . pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { . // SAFETY: the caller must uphold the safety contract for . // `unchecked_add`. 3,980,280 ( 0.01%) unsafe { intrinsics::unchecked_add(self, rhs) } . } . . /// Checked addition with a signed integer. Computes `self + rhs`, . /// returning `None` if overflow occurred. . /// . /// # Examples . /// . /// Basic usage: -- line 472 ---------------------------------------- -- line 525 ---------------------------------------- . )] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[rustc_const_unstable(feature = "const_inherent_unchecked_arith", issue = "85122")] . #[inline(always)] . pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { . // SAFETY: the caller must uphold the safety contract for . // `unchecked_sub`. 914,028 ( 0.00%) unsafe { intrinsics::unchecked_sub(self, rhs) } . } . . /// Checked integer multiplication. Computes `self * rhs`, returning . /// `None` if overflow occurred. . /// . /// # Examples . /// . /// Basic usage: -- line 541 ---------------------------------------- -- line 596 ---------------------------------------- . without modifying the original"] . #[inline] . pub const fn checked_div(self, rhs: Self) -> Option { . if unlikely!(rhs == 0) { . None . } else { . // SAFETY: div by zero has been checked above and unsigned types have no other . // failure modes for division 1,184 ( 0.00%) Some(unsafe { intrinsics::unchecked_div(self, rhs) }) . } . } . . /// Checked Euclidean division. Computes `self.div_euclid(rhs)`, returning `None` . /// if `rhs == 0`. . /// . /// # Examples . /// -- line 612 ---------------------------------------- -- line 1035 ---------------------------------------- . #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.saturating_add(127), ", stringify!($SelfT), "::MAX);")] . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")] . #[inline(always)] . pub const fn saturating_add(self, rhs: Self) -> Self { 1,417,744 ( 0.01%) intrinsics::saturating_add(self, rhs) . } . . /// Saturating addition with a signed integer. Computes `self + rhs`, . /// saturating at the numeric bounds instead of overflowing. . /// . /// # Examples . /// . /// Basic usage: -- line 1051 ---------------------------------------- -- line 1084 ---------------------------------------- . #[doc = concat!("assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);")] . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")] . #[inline(always)] . pub const fn saturating_sub(self, rhs: Self) -> Self { 46,373 ( 0.00%) intrinsics::saturating_sub(self, rhs) . } . . /// Saturating integer multiplication. Computes `self * rhs`, . /// saturating at the numeric bounds instead of overflowing. . /// . /// # Examples . /// . /// Basic usage: -- line 1100 ---------------------------------------- -- line 1175 ---------------------------------------- . #[doc = concat!("assert_eq!(200", stringify!($SelfT), ".wrapping_add(", stringify!($SelfT), "::MAX), 199);")] . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline(always)] . pub const fn wrapping_add(self, rhs: Self) -> Self { 32,873,341 ( 0.12%) intrinsics::wrapping_add(self, rhs) . } . . /// Wrapping (modular) addition with a signed integer. Computes . /// `self + rhs`, wrapping around at the boundary of the type. . /// . /// # Examples . /// . /// Basic usage: -- line 1191 ---------------------------------------- -- line 1217 ---------------------------------------- . #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_sub(", stringify!($SelfT), "::MAX), 101);")] . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline(always)] . pub const fn wrapping_sub(self, rhs: Self) -> Self { 10,614,985 ( 0.04%) intrinsics::wrapping_sub(self, rhs) . } . . /// Wrapping (modular) multiplication. Computes `self * . /// rhs`, wrapping around at the boundary of the type. . /// . /// # Examples . /// . /// Basic usage: -- line 1233 ---------------------------------------- -- line 1240 ---------------------------------------- . /// assert_eq!(25u8.wrapping_mul(12), 44); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline(always)] . pub const fn wrapping_mul(self, rhs: Self) -> Self { 30,899,284 ( 0.11%) intrinsics::wrapping_mul(self, rhs) . } . . /// Wrapping (modular) division. Computes `self / rhs`. . /// Wrapped division on unsigned types is just normal division. . /// There's no way wrapping could ever happen. . /// This function exists, so that all operations . /// are accounted for in the wrapping operations. . /// -- line 1256 ---------------------------------------- -- line 1397 ---------------------------------------- . #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline(always)] . pub const fn wrapping_shl(self, rhs: u32) -> Self { . // SAFETY: the masking by the bitsize of the type ensures that we do not shift . // out of bounds . unsafe { 39 ( 0.00%) intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT) . } . } . . /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, . /// where `mask` removes any high-order bits of `rhs` that . /// would cause the shift to exceed the bitwidth of the type. . /// . /// Note that this is *not* the same as a rotate-right; the -- line 1413 ---------------------------------------- -- line 1491 ---------------------------------------- . #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false));")] . #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (0, true));")] . /// ``` . #[stable(feature = "wrapping", since = "1.7.0")] . #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline(always)] 271 ( 0.00%) pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) { 3,577,002 ( 0.01%) let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT); . (a as Self, b) 542 ( 0.00%) } . . /// Calculates `self + rhs + carry` without the ability to overflow. . /// . /// Performs "ternary addition" which takes in an extra bit to add, and may return an . /// additional bit of overflow. This allows for chaining together multiple additions . /// to create "big integers" which represent larger values. . /// . #[doc = concat!("This can be thought of as a ", stringify!($BITS), "-bit \"full adder\", in the electronics sense.")] -- line 1510 ---------------------------------------- -- line 1587 ---------------------------------------- . #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_sub(2), (3, false));")] . #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".overflowing_sub(1), (", stringify!($SelfT), "::MAX, true));")] . /// ``` . #[stable(feature = "wrapping", since = "1.7.0")] . #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline(always)] 9 ( 0.00%) pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) { 1,069,676 ( 0.00%) let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT); . (a as Self, b) 18 ( 0.00%) } . . /// Calculates `self - rhs - borrow` without the ability to overflow. . /// . /// Performs "ternary subtraction" which takes in an extra bit to subtract, and may return . /// an additional bit of overflow. This allows for chaining together multiple subtractions . /// to create "big integers" which represent larger values. . /// . /// # Examples -- line 1606 ---------------------------------------- -- line 1673 ---------------------------------------- . /// assert_eq!(5u32.overflowing_mul(2), (10, false)); . /// assert_eq!(1_000_000_000u32.overflowing_mul(10), (1410065408, true)); . /// ``` . #[stable(feature = "wrapping", since = "1.7.0")] . #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline(always)] 4 ( 0.00%) pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) { 7,309,366 ( 0.03%) let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT); . (a as Self, b) 2 ( 0.00%) } . . /// Calculates the divisor when `self` is divided by `rhs`. . /// . /// Returns a tuple of the divisor along with a boolean indicating . /// whether an arithmetic overflow would occur. Note that for unsigned . /// integers overflow never occurs, so the second value is always . /// `false`. . /// -- line 1692 ---------------------------------------- -- line 1838 ---------------------------------------- . #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(132), (0x10, true));")] . /// ``` . #[stable(feature = "wrapping", since = "1.7.0")] . #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline(always)] . pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) { 9 ( 0.00%) (self.wrapping_shl(rhs), (rhs > ($BITS - 1))) . } . . /// Shifts self right by `rhs` bits. . /// . /// Returns a tuple of the shifted version of self along with a boolean . /// indicating whether the shift value was larger than or equal to the . /// number of bits. If the shift value is too large, then value is . /// masked (N-1) where N is the number of bits, and this value is then -- line 1854 ---------------------------------------- -- line 2132 ---------------------------------------- . #[doc = concat!("assert!(16", stringify!($SelfT), ".is_power_of_two());")] . #[doc = concat!("assert!(!10", stringify!($SelfT), ".is_power_of_two());")] . /// ``` . #[must_use] . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_is_power_of_two", since = "1.32.0")] . #[inline(always)] . pub const fn is_power_of_two(self) -> bool { 312 ( 0.00%) self.count_ones() == 1 . } . . // Returns one less than next power of two. . // (For 8u8 next power of two is 8u8 and for 6u8 it is 8u8) . // . // 8u8.one_less_than_next_power_of_two() == 7 . // 6u8.one_less_than_next_power_of_two() == 7 . // . // This method cannot overflow, as in the `next_power_of_two` . // overflow cases it instead ends up returning the maximum value . // of the type, and can return 0 for 0. . #[inline] . #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")] . const fn one_less_than_next_power_of_two(self) -> Self { 169,956 ( 0.00%) if self <= 1 { return 0; } . 169,095 ( 0.00%) let p = self - 1; . // SAFETY: Because `p > 0`, it cannot consist entirely of leading zeros. . // That means the shift is always in-bounds, and some processors . // (such as intel pre-haswell) have more efficient ctlz . // intrinsics when the argument is non-zero. 507,104 ( 0.00%) let z = unsafe { intrinsics::ctlz_nonzero(p) }; 169,060 ( 0.00%) <$SelfT>::MAX >> z . } . . /// Returns the smallest power of two greater than or equal to `self`. . /// . /// When return value overflows (i.e., `self > (1 << (N-1))` for type . /// `uN`), it panics in debug mode and the return value is wrapped to 0 in . /// release mode (the only situation in which method can return 0). . /// -- line 2171 ---------------------------------------- -- line 2179 ---------------------------------------- . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")] . #[must_use = "this returns the result of the operation, \ . without modifying the original"] . #[inline] . #[rustc_inherit_overflow_checks] . pub const fn next_power_of_two(self) -> Self { 168,128 ( 0.00%) self.one_less_than_next_power_of_two() + 1 . } . . /// Returns the smallest power of two greater than or equal to `n`. If . /// the next power of two is greater than the type's maximum value, . /// `None` is returned, otherwise the power of two is wrapped in `Some`. . /// . /// # Examples . /// -- line 2195 ---------------------------------------- 489,559 ( 0.00%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/.cargo/registry/src/github.com-1ecc6299db9ec823/hashbrown-0.12.0/src/map.rs -------------------------------------------------------------------------------- Ir -- line 186 ---------------------------------------- . /// // use the values stored in map . /// ``` . pub struct HashMap { . pub(crate) hash_builder: S, . pub(crate) table: RawTable<(K, V), A>, . } . . impl Clone for HashMap { 1,080 ( 0.00%) fn clone(&self) -> Self { 15,383 ( 0.00%) HashMap { . hash_builder: self.hash_builder.clone(), 3,218 ( 0.00%) table: self.table.clone(), . } 1,215 ( 0.00%) } . . 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 207 ---------------------------------------- -- line 210 ---------------------------------------- . /// instances of any functions like RawTable::reserve from being generated . #[cfg_attr(feature = "inline-more", inline)] . pub(crate) fn make_hasher(hash_builder: &S) -> impl Fn(&(Q, V)) -> u64 + '_ . where . K: Borrow, . Q: Hash, . S: BuildHasher, . { 670,734 ( 0.00%) move |val| make_hash::(hash_builder, &val.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_key(k: &Q) -> impl Fn(&(K, V)) -> bool + '_ . where . K: Borrow, . Q: ?Sized + Eq, . { 1,607,422 ( 0.01%) move |x| k.eq(x.0.borrow()) . } . . /// 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 . K: Borrow, . Q: ?Sized + Eq, . { 1,957,738 ( 0.01%) move |x| k.eq(x.borrow()) . } . . #[cfg(not(feature = "nightly"))] . #[cfg_attr(feature = "inline-more", inline)] . pub(crate) fn make_hash(hash_builder: &S, val: &Q) -> u64 . where . K: Borrow, . Q: Hash + ?Sized, -- line 248 ---------------------------------------- -- line 251 ---------------------------------------- . use core::hash::Hasher; . let mut state = hash_builder.build_hasher(); . val.hash(&mut state); . state.finish() . } . . #[cfg(feature = "nightly")] . #[cfg_attr(feature = "inline-more", inline)] 2 ( 0.00%) pub(crate) fn make_hash(hash_builder: &S, val: &Q) -> u64 . where . K: Borrow, . Q: Hash + ?Sized, . S: BuildHasher, . { 49,546 ( 0.00%) hash_builder.hash_one(val) 4 ( 0.00%) } . . #[cfg(not(feature = "nightly"))] . #[cfg_attr(feature = "inline-more", inline)] . pub(crate) fn make_insert_hash(hash_builder: &S, val: &K) -> u64 . where . K: Hash, . S: BuildHasher, . { -- line 274 ---------------------------------------- -- line 280 ---------------------------------------- . . #[cfg(feature = "nightly")] . #[cfg_attr(feature = "inline-more", inline)] . pub(crate) fn make_insert_hash(hash_builder: &S, val: &K) -> u64 . where . K: Hash, . S: BuildHasher, . { 1,168,251 ( 0.00%) 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 296 ---------------------------------------- -- line 367 ---------------------------------------- . /// let s = DefaultHashBuilder::default(); . /// let mut map = HashMap::with_hasher(s); . /// map.insert(1, 2); . /// ``` . /// . /// [`BuildHasher`]: ../../std/hash/trait.BuildHasher.html . #[cfg_attr(feature = "inline-more", inline)] . pub const fn with_hasher(hash_builder: S) -> Self { 864,319 ( 0.00%) Self { . hash_builder, . table: RawTable::new(), . } . } . . /// Creates an empty `HashMap` with the specified capacity, using `hash_builder` . /// to hash the keys. . /// -- line 383 ---------------------------------------- -- line 437 ---------------------------------------- . /// 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 fn with_hasher_in(hash_builder: S, alloc: A) -> Self { 133 ( 0.00%) 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 453 ---------------------------------------- -- line 527 ---------------------------------------- . /// map.insert("c", 3); . /// . /// for key in map.keys() { . /// println!("{}", key); . /// } . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . pub fn keys(&self) -> Keys<'_, K, V> { 6 ( 0.00%) Keys { inner: self.iter() } . } . . /// An iterator visiting all values in arbitrary order. . /// The iterator element type is `&'a V`. . /// . /// # Examples . /// . /// ``` -- line 543 ---------------------------------------- -- line 663 ---------------------------------------- . /// . /// let mut a = HashMap::new(); . /// assert_eq!(a.len(), 0); . /// a.insert(1, "a"); . /// assert_eq!(a.len(), 1); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . pub fn len(&self) -> usize { 155,723 ( 0.00%) self.table.len() . } . . /// Returns `true` if the map contains no elements. . /// . /// # Examples . /// . /// ``` . /// use hashbrown::HashMap; -- line 679 ---------------------------------------- -- line 680 ---------------------------------------- . /// . /// 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 { 385,765 ( 0.00%) self.len() == 0 . } . . /// Clears the map, returning all key-value pairs as an iterator. Keeps the . /// allocated memory for reuse. . /// . /// # Examples . /// . /// ``` -- line 696 ---------------------------------------- -- line 790 ---------------------------------------- . /// use hashbrown::HashMap; . /// . /// let mut a = HashMap::new(); . /// a.insert(1, "a"); . /// a.clear(); . /// assert!(a.is_empty()); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] 6 ( 0.00%) pub fn clear(&mut self) { . self.table.clear(); 6 ( 0.00%) } . . /// Creates a consuming iterator visiting all the keys in arbitrary order. . /// The map cannot be used after calling this. . /// The iterator element type is `K`. . /// . /// # Examples . /// . /// ``` -- line 808 ---------------------------------------- -- line 963 ---------------------------------------- . /// } . /// . /// assert_eq!(letters[&'s'], 2); . /// assert_eq!(letters[&'t'], 3); . /// assert_eq!(letters[&'u'], 1); . /// assert_eq!(letters.get(&'y'), None); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] 2,624 ( 0.00%) pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S, A> { . let hash = make_insert_hash::(&self.hash_builder, &key); . if let Some(elem) = self.table.find(hash, equivalent_key(&key)) { 775 ( 0.00%) Entry::Occupied(OccupiedEntry { . hash, . key: Some(key), . elem, . table: self, . }) . } else { 2,505 ( 0.00%) Entry::Vacant(VacantEntry { . hash, . key, . table: self, . }) . } 3,280 ( 0.00%) } . . /// Gets the given key's corresponding entry by reference in the map for in-place manipulation. . /// . /// # Examples . /// . /// ``` . /// use hashbrown::HashMap; . /// -- line 995 ---------------------------------------- -- line 1047 ---------------------------------------- . /// ``` . #[inline] . pub fn get(&self, k: &Q) -> Option<&V> . where . K: Borrow, . Q: Hash + Eq, . { . // Avoid `Option::map` because it bloats LLVM IR. 3,383,257 ( 0.01%) match self.get_inner(k) { . Some(&(_, ref 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 1063 ---------------------------------------- -- line 1091 ---------------------------------------- . } . . #[inline] . fn get_inner(&self, k: &Q) -> Option<&(K, V)> . where . K: Borrow, . Q: Hash + Eq, . { 4,481,530 ( 0.02%) if self.table.is_empty() { . None . } else { 1 ( 0.00%) let hash = make_hash::(&self.hash_builder, k); . self.table.get(hash, equivalent_key(k)) . } . } . . /// 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 -- line 1110 ---------------------------------------- -- line 1155 ---------------------------------------- . /// use hashbrown::HashMap; . /// . /// let mut map = HashMap::new(); . /// map.insert(1, "a"); . /// assert_eq!(map.contains_key(&1), true); . /// assert_eq!(map.contains_key(&2), false); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] 1,563,049 ( 0.01%) pub fn contains_key(&self, k: &Q) -> bool . where . K: Borrow, . Q: Hash + Eq, . { . self.get_inner(k).is_some() 2,107,370 ( 0.01%) } . . /// Returns a mutable 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. . /// . /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html -- line 1177 ---------------------------------------- -- line 1185 ---------------------------------------- . /// let mut map = HashMap::new(); . /// map.insert(1, "a"); . /// if let Some(x) = map.get_mut(&1) { . /// *x = "b"; . /// } . /// assert_eq!(map[&1], "b"); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] 427 ( 0.00%) pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> . where . K: Borrow, . Q: Hash + Eq, . { . // Avoid `Option::map` because it bloats LLVM IR. 6,144 ( 0.00%) match self.get_inner_mut(k) { . Some(&mut (_, ref mut v)) => Some(v), . None => None, . } 854 ( 0.00%) } . . #[inline] . fn get_inner_mut(&mut self, k: &Q) -> Option<&mut (K, V)> . where . K: Borrow, . Q: Hash + Eq, . { 2,048 ( 0.00%) if self.table.is_empty() { . None . } else { . let hash = make_hash::(&self.hash_builder, k); 3,242 ( 0.00%) 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 1223 ---------------------------------------- -- line 1495 ---------------------------------------- . /// 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)] 10,888,631 ( 0.04%) pub fn insert(&mut self, k: K, v: V) -> Option { . let hash = make_insert_hash::(&self.hash_builder, &k); 14,841 ( 0.00%) if let Some((_, item)) = self.table.get_mut(hash, equivalent_key(&k)) { . Some(mem::replace(item, v)) . } else { 4,389,631 ( 0.02%) self.table 4,437,092 ( 0.02%) .insert(hash, (k, v), make_hasher::(&self.hash_builder)); 538,438 ( 0.00%) None . } 10,276,241 ( 0.04%) } . . /// 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 1520 ---------------------------------------- -- line 1592 ---------------------------------------- . /// use hashbrown::HashMap; . /// . /// let mut map = HashMap::new(); . /// map.insert(1, "a"); . /// assert_eq!(map.remove(&1), Some("a")); . /// assert_eq!(map.remove(&1), None); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] 334,591 ( 0.00%) pub fn remove(&mut self, k: &Q) -> Option . where . K: Borrow, . Q: Hash + Eq, . { . // Avoid `Option::map` because it bloats LLVM IR. 2,057,030 ( 0.01%) match self.remove_entry(k) { 117,912 ( 0.00%) Some((_, v)) => Some(v), 292,912 ( 0.00%) None => None, . } 753,849 ( 0.00%) } . . /// Removes a key from the map, returning the stored key and value if the . /// key was previously in the map. . /// . /// 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 1618 ---------------------------------------- -- line 1631 ---------------------------------------- . /// ``` . #[cfg_attr(feature = "inline-more", inline)] . pub fn remove_entry(&mut self, k: &Q) -> Option<(K, V)> . where . K: Borrow, . Q: Hash + Eq, . { . let hash = make_hash::(&self.hash_builder, k); 824,630 ( 0.00%) 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 1647 ---------------------------------------- -- line 2069 ---------------------------------------- . where . F: FnMut(&K, &mut V) -> bool, . A: Allocator + Clone, . { . type Item = (K, V); . . #[cfg_attr(feature = "inline-more", inline)] . fn next(&mut self) -> Option { 12 ( 0.00%) self.inner.next(&mut self.f) . } . . #[inline] . fn size_hint(&self) -> (usize, Option) { . (0, self.inner.iter.size_hint().1) . } . } . -- line 2085 ---------------------------------------- -- line 2095 ---------------------------------------- . #[cfg_attr(feature = "inline-more", inline)] . pub(super) fn next(&mut self, f: &mut F) -> Option<(K, V)> . where . F: FnMut(&K, &mut V) -> bool, . { . unsafe { . for item in &mut self.iter { . let &mut (ref key, ref mut value) = item.as_mut(); 12 ( 0.00%) if f(key, value) { 4 ( 0.00%) return Some(self.table.remove(item)); . } . } . } . None . } . } . . /// A mutable iterator over the values of a `HashMap`. -- line 2112 ---------------------------------------- -- line 2209 ---------------------------------------- . /// Creates a `RawEntryMut` from the given key and its hash. . #[inline] . #[allow(clippy::wrong_self_convention)] . pub fn from_key_hashed_nocheck(self, hash: u64, k: &Q) -> RawEntryMut<'a, K, V, S, A> . where . K: Borrow, . Q: Eq, . { 9,876,954 ( 0.04%) self.from_hash(hash, equivalent(k)) . } . } . . impl<'a, K, V, S, A: Allocator + Clone> RawEntryBuilderMut<'a, K, V, S, A> { . /// Creates a `RawEntryMut` from the given hash. . #[cfg_attr(feature = "inline-more", inline)] . #[allow(clippy::wrong_self_convention)] 24,702,108 ( 0.09%) pub fn from_hash(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S, A> . where . for<'b> F: FnMut(&'b K) -> bool, . { . self.search(hash, is_match) 26,702,329 ( 0.10%) } . . #[cfg_attr(feature = "inline-more", inline)] . fn search(self, hash: u64, mut is_match: F) -> RawEntryMut<'a, K, V, S, A> . where . for<'b> F: FnMut(&'b K) -> bool, . { 3,034,370 ( 0.01%) match self.map.table.find(hash, |(k, _)| is_match(k)) { 16,155,687 ( 0.06%) Some(elem) => RawEntryMut::Occupied(RawOccupiedEntryMut { . elem, . table: &mut self.map.table, . hash_builder: &self.map.hash_builder, . }), 1,050,375 ( 0.00%) None => RawEntryMut::Vacant(RawVacantEntryMut { . table: &mut self.map.table, . hash_builder: &self.map.hash_builder, . }), . } . } . } . . impl<'a, K, V, S, A: Allocator + Clone> RawEntryBuilder<'a, K, V, S, A> { -- line 2251 ---------------------------------------- -- line 2260 ---------------------------------------- . { . let hash = make_hash::(&self.map.hash_builder, k); . self.from_key_hashed_nocheck(hash, k) . } . . /// Access an entry by a key and its hash. . #[cfg_attr(feature = "inline-more", inline)] . #[allow(clippy::wrong_self_convention)] 5,772,797 ( 0.02%) pub fn from_key_hashed_nocheck(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)> . where . K: Borrow, . Q: Eq, . { 6,466,467 ( 0.02%) self.from_hash(hash, equivalent(k)) 10,481,702 ( 0.04%) } . . #[cfg_attr(feature = "inline-more", inline)] . fn search(self, hash: u64, mut is_match: F) -> Option<(&'a K, &'a V)> . where . F: FnMut(&K) -> bool, . { 9,328,657 ( 0.03%) match self.map.table.get(hash, |(k, _)| is_match(k)) { . Some(&(ref key, ref value)) => Some((key, value)), . None => None, . } . } . . /// Access an entry by hash. . #[cfg_attr(feature = "inline-more", inline)] . #[allow(clippy::wrong_self_convention)] -- line 2289 ---------------------------------------- -- line 2624 ---------------------------------------- . /// and returns a mutable reference to it. . #[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, . { 1,738,885 ( 0.01%) let &mut (ref mut k, ref mut v) = self.table.insert_entry( . hash, . (key, value), . make_hasher::(self.hash_builder), . ); . (k, v) . } . . /// Set the value of an entry with a custom hasher function. -- line 2640 ---------------------------------------- -- line 2974 ---------------------------------------- . /// map.insert("a", 1); . /// map.insert("b", 2); . /// map.insert("c", 3); . /// . /// // Not possible with .iter() . /// let vec: Vec<(&str, i32)> = map.into_iter().collect(); . /// ``` . #[cfg_attr(feature = "inline-more", inline)] 5,466 ( 0.00%) fn into_iter(self) -> IntoIter { 99,041 ( 0.00%) IntoIter { 49,255 ( 0.00%) inner: self.table.into_iter(), . } 16,398 ( 0.00%) } . } . . 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. 860,232 ( 0.00%) match self.inner.next() { . Some(x) => unsafe { . let r = x.as_ref(); 4,331 ( 0.00%) Some((&r.0, &r.1)) . }, . None => None, . } . } . #[cfg_attr(feature = "inline-more", inline)] . fn size_hint(&self) -> (usize, Option) { 353 ( 0.00%) self.inner.size_hint() . } . } . impl ExactSizeIterator for Iter<'_, K, V> { . #[cfg_attr(feature = "inline-more", inline)] . fn len(&self) -> usize { . self.inner.len() . } . } -- line 3013 ---------------------------------------- -- line 3051 ---------------------------------------- . } . } . . impl Iterator for IntoIter { . type Item = (K, V); . . #[cfg_attr(feature = "inline-more", inline)] . fn next(&mut self) -> Option<(K, V)> { 24,643 ( 0.00%) self.inner.next() . } . #[cfg_attr(feature = "inline-more", inline)] . fn size_hint(&self) -> (usize, Option) { . self.inner.size_hint() . } . } . impl ExactSizeIterator for IntoIter { . #[cfg_attr(feature = "inline-more", inline)] -- line 3067 ---------------------------------------- -- line 3076 ---------------------------------------- . f.debug_list().entries(self.iter()).finish() . } . } . . impl<'a, K, V> Iterator for Keys<'a, K, V> { . type Item = &'a K; . . #[cfg_attr(feature = "inline-more", inline)] 227 ( 0.00%) fn next(&mut self) -> Option<&'a K> { . // Avoid `Option::map` because it bloats LLVM IR. . match self.inner.next() { . Some((k, _)) => Some(k), . None => None, . } 454 ( 0.00%) } . #[cfg_attr(feature = "inline-more", inline)] . fn size_hint(&self) -> (usize, Option) { . self.inner.size_hint() . } . } . impl ExactSizeIterator for Keys<'_, K, V> { . #[cfg_attr(feature = "inline-more", inline)] . fn len(&self) -> usize { -- line 3098 ---------------------------------------- -- line 3819 ---------------------------------------- . /// ``` . #[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; 100 ( 0.00%) let entry = table.insert_entry( . self.hash, . (self.key, value), . make_hasher::(&self.table.hash_builder), . ); . &mut entry.1 . } . . #[cfg_attr(feature = "inline-more", inline)] -- line 3835 ---------------------------------------- -- line 4557 ---------------------------------------- . /// keys with new values returned from the iterator. . impl Extend<(K, V)> for HashMap . where . K: Eq + Hash, . S: BuildHasher, . A: Allocator + Clone, . { . #[cfg_attr(feature = "inline-more", inline)] 85,591 ( 0.00%) 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. 71,330 ( 0.00%) let iter = iter.into_iter(); 88,903 ( 0.00%) let reserve = if self.is_empty() { . iter.size_hint().0 . } else { 4,835 ( 0.00%) (iter.size_hint().0 + 1) / 2 . }; . self.reserve(reserve); . iter.for_each(move |(k, v)| { 282,477 ( 0.00%) self.insert(k, v); . }); 53,653 ( 0.00%) } . . #[inline] . #[cfg(feature = "nightly")] . fn extend_one(&mut self, (k, v): (K, V)) { . self.insert(k, v); . } . . #[inline] -- line 4588 ---------------------------------------- 10,713,998 ( 0.04%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/library/alloc/src/vec/mod.rs -------------------------------------------------------------------------------- Ir -- line 417 ---------------------------------------- . /// # #![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 { 14,645,848 ( 0.05%) Vec { buf: RawVec::NEW, len: 0 } 1,821 ( 0.00%) } . . /// Constructs a new, empty `Vec` with the specified capacity. . /// . /// The vector will be able to hold exactly `capacity` elements without . /// reallocating. If `capacity` is 0, the vector will not allocate. . /// . /// It is important to note that although the returned vector has the . /// *capacity* specified, the vector will have a zero *length*. For an -- line 434 ---------------------------------------- -- line 601 ---------------------------------------- . /// vec.push(11); . /// assert_eq!(vec.len(), 11); . /// assert!(vec.capacity() >= 11); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[inline] . #[unstable(feature = "allocator_api", issue = "32838")] . pub fn with_capacity_in(capacity: usize, alloc: A) -> Self { 4,623,634 ( 0.02%) Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 } . } . . /// Creates a `Vec` directly from the raw components of another vector. . /// . /// # Safety . /// . /// This is highly unsafe, due to the number of invariants that aren't . /// checked: -- line 617 ---------------------------------------- -- line 677 ---------------------------------------- . /// // Put everything back together into a Vec . /// let rebuilt = Vec::from_raw_parts_in(p, len, cap, alloc.clone()); . /// assert_eq!(rebuilt, [4, 5, 6]); . /// } . /// ``` . #[inline] . #[unstable(feature = "allocator_api", issue = "32838")] . pub unsafe fn from_raw_parts_in(ptr: *mut T, length: usize, capacity: usize, alloc: A) -> Self { 674,939 ( 0.00%) 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 693 ---------------------------------------- -- line 778 ---------------------------------------- . /// . /// ``` . /// let vec: Vec = Vec::with_capacity(10); . /// assert_eq!(vec.capacity(), 10); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn capacity(&self) -> usize { 1,828,305 ( 0.01%) self.buf.capacity() . } . . /// Reserves capacity for at least `additional` more elements to be inserted . /// in the given `Vec`. The collection may reserve more space to avoid . /// frequent reallocations. After calling `reserve`, capacity will be . /// greater than or equal to `self.len() + additional`. Does nothing if . /// capacity is already sufficient. . /// -- line 794 ---------------------------------------- -- line 801 ---------------------------------------- . /// ``` . /// 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) { 2,382,464 ( 0.01%) self.buf.reserve(self.len, additional); . } . . /// Reserves the minimum capacity for exactly `additional` more elements to . /// be inserted in the given `Vec`. After calling `reserve_exact`, . /// capacity will be greater than or equal to `self.len() + additional`. . /// Does nothing if the capacity is already sufficient. . /// . /// Note that the allocator may give the collection more space than it -- line 817 ---------------------------------------- -- line 829 ---------------------------------------- . /// ``` . /// 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) { 43,949 ( 0.00%) 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 avoid . /// frequent reallocations. After calling `try_reserve`, capacity will be . /// greater than or equal to `self.len() + additional`. Does nothing if . /// capacity is already sufficient. . /// -- line 845 ---------------------------------------- -- line 930 ---------------------------------------- . /// 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. 81,826 ( 0.00%) if self.capacity() > self.len { 46,792 ( 0.00%) 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 947 ---------------------------------------- -- line 990 ---------------------------------------- . /// 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")] . pub fn into_boxed_slice(mut self) -> Box<[T], A> { . unsafe { . self.shrink_to_fit(); 28,187 ( 0.00%) let me = ManuallyDrop::new(self); . let buf = ptr::read(&me.buf); . let len = me.len(); . buf.into_box(len).assume_init() . } . } . . /// Shortens the vector, keeping the first `len` elements and dropping . /// the rest. -- line 1006 ---------------------------------------- -- line 1040 ---------------------------------------- . /// let mut vec = vec![1, 2, 3]; . /// vec.truncate(0); . /// assert_eq!(vec, []); . /// ``` . /// . /// [`clear`]: Vec::clear . /// [`drain`]: Vec::drain . #[stable(feature = "rust1", since = "1.0.0")] 1,093,027 ( 0.00%) pub fn truncate(&mut self, len: usize) { . // This is safe because: . // . // * the slice passed to `drop_in_place` is valid; the `len > self.len` . // 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. 889,855 ( 0.00%) 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); 1,201,835 ( 0.00%) self.len = len; 24,843 ( 0.00%) ptr::drop_in_place(s); . } 1,311,600 ( 0.00%) } . . /// Extracts a slice containing the entire vector. . /// . /// Equivalent to `&s[..]`. . /// . /// # Examples . /// . /// ``` -- line 1076 ---------------------------------------- -- line 1126 ---------------------------------------- . /// ``` . /// . /// [`as_mut_ptr`]: Vec::as_mut_ptr . #[stable(feature = "vec_as_ptr", since = "1.37.0")] . #[inline] . pub fn as_ptr(&self) -> *const T { . // We shadow the slice method of the same name to avoid going through . // `deref`, which creates an intermediate reference. 27,290,760 ( 0.10%) let ptr = self.buf.ptr(); . unsafe { . assume(!ptr.is_null()); . } . ptr . } . . /// Returns an unsafe mutable pointer to the vector's buffer. . /// -- line 1142 ---------------------------------------- -- line 1162 ---------------------------------------- . /// } . /// assert_eq!(&*x, &[0, 1, 2, 3]); . /// ``` . #[stable(feature = "vec_as_ptr", since = "1.37.0")] . #[inline] . pub fn as_mut_ptr(&mut self) -> *mut T { . // We shadow the slice method of the same name to avoid going through . // `deref_mut`, which creates an intermediate reference. 21,686,038 ( 0.08%) let ptr = self.buf.ptr(); . unsafe { . assume(!ptr.is_null()); . } . ptr . } . . /// Returns a reference to the underlying allocator. . #[unstable(feature = "allocator_api", issue = "32838")] -- line 1178 ---------------------------------------- -- line 1259 ---------------------------------------- . /// . /// 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()); . 3,891,405 ( 0.01%) self.len = new_len; 117,142 ( 0.00%) } . . /// 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 1276 ---------------------------------------- -- line 1305 ---------------------------------------- . 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(); 15 ( 0.00%) 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 1321 ---------------------------------------- -- line 1329 ---------------------------------------- . /// let mut vec = vec![1, 2, 3]; . /// vec.insert(1, 4); . /// assert_eq!(vec, [1, 4, 2, 3]); . /// vec.insert(4, 5); . /// assert_eq!(vec, [1, 4, 2, 3, 5]); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] 31,717 ( 0.00%) pub fn insert(&mut self, index: usize, element: T) { . #[cold] . #[inline(never)] . fn assert_failed(index: usize, len: usize) -> ! { . panic!("insertion index (is {}) should be <= len (is {})", index, len); . } . 5,028 ( 0.00%) let len = self.len(); 11,574 ( 0.00%) if index > len { . assert_failed(index, len); . } . . // space for the new element 16,154 ( 0.00%) 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); . // Shift everything over to make space. (Duplicating the . // `index`th element into two consecutive places.) 22,740 ( 0.00%) ptr::copy(p, p.offset(1), len - index); . // Write it in, overwriting the first copy of the `index`th . // element. . ptr::write(p, element); . } 16,154 ( 0.00%) self.set_len(len + 1); . } 27,186 ( 0.00%) } . . /// 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 . /// to be preserved, use [`swap_remove`] instead. If you'd like to remove . /// elements from the beginning of the `Vec`, consider using -- line 1376 ---------------------------------------- -- line 1387 ---------------------------------------- . /// . /// ``` . /// let mut v = vec![1, 2, 3]; . /// assert_eq!(v.remove(1), 2); . /// assert_eq!(v, [1, 3]); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[track_caller] 76,059 ( 0.00%) pub fn remove(&mut self, index: usize) -> T { . #[cold] . #[inline(never)] . #[track_caller] . fn assert_failed(index: usize, len: usize) -> ! { . panic!("removal index (is {}) should be < len (is {})", index, len); . } . 27,223 ( 0.00%) let len = self.len(); 83,226 ( 0.00%) 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. 157,126 ( 0.00%) ret = ptr::read(ptr); . . // Shift everything down to fill in that spot. 54,720 ( 0.00%) ptr::copy(ptr.offset(1), ptr, len - index - 1); . } 28,086 ( 0.00%) self.set_len(len - 1); . ret . } 126,765 ( 0.00%) } . . /// Retains only the elements specified by the predicate. . /// . /// In other words, remove all elements `e` such that `f(&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 1431 ---------------------------------------- -- line 1442 ---------------------------------------- . /// ``` . /// 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,423,983 ( 0.01%) pub fn retain(&mut self, mut f: F) . where . F: FnMut(&T) -> bool, . { 26,033 ( 0.00%) self.retain_mut(|elem| f(elem)); 2,383,152 ( 0.01%) } . . /// 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 1463 ---------------------------------------- -- line 1474 ---------------------------------------- . /// }); . /// assert_eq!(vec, [2, 3, 4]); . /// ``` . #[unstable(feature = "vec_retain_mut", issue = "90829")] . pub fn retain_mut(&mut self, mut f: F) . where . F: FnMut(&mut T) -> bool, . { 305,052 ( 0.00%) let original_len = self.len(); . // Avoid double drop if the drop guard is not executed, . // since we may make some holes during the process. . unsafe { self.set_len(0) }; . . // Vec: [Kept, Kept, Hole, Hole, Hole, Hole, Unchecked, Unchecked] . // |<- processed len ->| ^- next to check . // |<- deleted cnt ->| . // |<- original_len ->| -- line 1490 ---------------------------------------- -- line 1499 ---------------------------------------- . v: &'a mut Vec, . processed_len: usize, . deleted_cnt: usize, . original_len: usize, . } . . impl Drop for BackshiftOnDrop<'_, T, A> { . fn drop(&mut self) { 257,600 ( 0.00%) 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), 240,206 ( 0.00%) 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 { 2 ( 0.00%) self.v.set_len(self.original_len - self.deleted_cnt); . } . } . } . . 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, . { 3,443,321 ( 0.01%) 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) }; 727,398 ( 0.00%) if !f(cur) { . // Advance early to avoid double drop if `drop_in_place` panicked. 34,089 ( 0.00%) g.processed_len += 1; 13,178 ( 0.00%) g.deleted_cnt += 1; . // SAFETY: We never touch this element again after dropped. 1,201 ( 0.00%) 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 { 113,517 ( 0.00%) let hole_slot = g.v.as_mut_ptr().add(g.processed_len - g.deleted_cnt); . ptr::copy_nonoverlapping(cur, hole_slot, 1); . } . } 91,493 ( 0.00%) g.processed_len += 1; . } . } . . // Stage 1: Nothing was deleted. . process_loop::(original_len, &mut f, &mut g); . . // Stage 2: Some elements were deleted. . process_loop::(original_len, &mut f, &mut g); -- line 1565 ---------------------------------------- -- line 1606 ---------------------------------------- . /// ``` . /// 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")] 26,495 ( 0.00%) pub fn dedup_by(&mut self, mut same_bucket: F) . where . F: FnMut(&mut T, &mut T) -> bool, . { 8,739 ( 0.00%) let len = self.len(); 23,076 ( 0.00%) 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 1627 ---------------------------------------- -- line 1670 ---------------------------------------- . let ptr = gap.vec.as_mut_ptr(); . . /* Drop items while going through Vec, it should be more efficient than . * doing slice partition_dedup + truncate */ . . /* SAFETY: Because of the invariant, read_ptr, prev_ptr and write_ptr . * are always in-bounds and read_ptr never aliases prev_ptr */ . unsafe { 36,223 ( 0.00%) while gap.read < len { . let read_ptr = ptr.add(gap.read); . let prev_ptr = ptr.add(gap.write.wrapping_sub(1)); . 3,752 ( 0.00%) if same_bucket(&mut *read_ptr, &mut *prev_ptr) { . // Increase `gap.read` now since the drop may panic. . gap.read += 1; . /* We have found duplicate, drop it in-place */ . ptr::drop_in_place(read_ptr); . } else { . let write_ptr = ptr.add(gap.write); . . /* Because `read_ptr` can be equal to `write_ptr`, we either . * have to use `copy` or conditional `copy_nonoverlapping`. . * Looks like the first option is faster. */ . ptr::copy(read_ptr, write_ptr, 1); . . /* We have filled that place, so go further */ 19,853 ( 0.00%) gap.write += 1; . gap.read += 1; . } . } . . /* 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); . } 30,280 ( 0.00%) } . . /// Appends an element to the back of a collection. . /// . /// # Panics . /// . /// Panics if the new capacity exceeds `isize::MAX` bytes. . /// . /// # Examples -- line 1715 ---------------------------------------- -- line 1717 ---------------------------------------- . /// ``` . /// 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")] 13,620 ( 0.00%) 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. 29,232,829 ( 0.11%) if self.len == self.buf.capacity() { 1,619,041 ( 0.01%) self.buf.reserve_for_push(self.len); . } . unsafe { 756,118 ( 0.00%) let end = self.as_mut_ptr().add(self.len); . ptr::write(end, value); 45,291,494 ( 0.17%) self.len += 1; . } 10,896 ( 0.00%) } . . /// Removes the last element from a vector and returns it, or [`None`] if it . /// is empty. . /// . /// If you'd like to pop the first element, consider using . /// [`VecDeque::pop_front`] instead. . /// . /// [`VecDeque::pop_front`]: crate::collections::VecDeque::pop_front -- line 1744 ---------------------------------------- -- line 1748 ---------------------------------------- . /// ``` . /// 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 { 8,143,313 ( 0.03%) if self.len == 0 { 189 ( 0.00%) None . } else { . unsafe { 5,390,430 ( 0.02%) self.len -= 1; 1,672,646 ( 0.01%) Some(ptr::read(self.as_ptr().add(self.len()))) . } . } . } . . /// Moves all the elements of `other` into `Self`, leaving `other` empty. . /// . /// # Panics . /// -- line 1769 ---------------------------------------- -- line 1776 ---------------------------------------- . /// let mut vec2 = vec![4, 5, 6]; . /// vec.append(&mut vec2); . /// 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")] 2,926 ( 0.00%) pub fn append(&mut self, other: &mut Self) { . unsafe { . self.append_elements(other.as_slice() as _); . other.set_len(0); . } 2,508 ( 0.00%) } . . /// 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); 419,333 ( 0.00%) let len = self.len(); . unsafe { ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count) }; 2,731,851 ( 0.01%) self.len += count; . } . . /// Creates a draining iterator that removes the specified range in the vector . /// and yields the removed items. . /// . /// When the iterator **is** dropped, all elements in the range are removed . /// from the vector, even if the iterator was not fully consumed. If the . /// iterator **is not** dropped (with [`mem::forget`] for example), it is -- line 1807 ---------------------------------------- -- line 1834 ---------------------------------------- . // When the Drain is first created, it shortens the length of . // the source vector to make sure no uninitialized or moved-from elements . // are accessible at all if the Drain's destructor never gets to run. . // . // Drain will ptr::read out the values to remove. . // When finished, remaining tail of the vec is copied back to cover . // the hole, and the vector length is restored to the new length. . // 101,237 ( 0.00%) 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); . // Use the borrow in the IterMut to indicate borrowing behavior of the . // whole Drain iterator (like &mut T). 9,911 ( 0.00%) let range_slice = slice::from_raw_parts_mut(self.as_mut_ptr().add(start), end - start); 1,901 ( 0.00%) Drain { . tail_start: end, 6,656 ( 0.00%) tail_len: len - end, . iter: range_slice.iter(), . vec: NonNull::from(self), . } . } . } . . /// Clears the vector, removing all values. . /// -- line 1861 ---------------------------------------- -- line 1869 ---------------------------------------- . /// . /// v.clear(); . /// . /// assert!(v.is_empty()); . /// ``` . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn clear(&mut self) { 1,954,444 ( 0.01%) self.truncate(0) . } . . /// Returns the number of elements in the vector, also referred to . /// as its 'length'. . /// . /// # Examples . /// . /// ``` -- line 1885 ---------------------------------------- -- line 1900 ---------------------------------------- . /// 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 { 2,112,623 ( 0.01%) 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 1916 ---------------------------------------- -- line 1935 ---------------------------------------- . A: Clone, . { . #[cold] . #[inline(never)] . fn assert_failed(at: usize, len: usize) -> ! { . panic!("`at` split index (is {}) should be <= len (is {})", at, len); . } . 6,087 ( 0.00%) if at > self.len() { . assert_failed(at, self.len()); . } . 4,611 ( 0.00%) if at == 0 { . // the new vector can take over the original buffer and avoid the copy . return mem::replace( . self, . Vec::with_capacity_in(self.capacity(), self.allocator().clone()), . ); . } . . let other_len = self.len - at; -- line 1955 ---------------------------------------- -- line 1988 ---------------------------------------- . /// . /// 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")] 151,657 ( 0.00%) pub fn resize_with(&mut self, new_len: usize, f: F) . where . F: FnMut() -> T, . { 19,943 ( 0.00%) let len = self.len(); 39,886 ( 0.00%) if new_len > len { 120,535 ( 0.00%) self.extend_with(new_len - len, ExtendFunc(f)); . } else { . self.truncate(new_len); . } 131,714 ( 0.00%) } . . /// 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 2014 ---------------------------------------- -- line 2070 ---------------------------------------- . #[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( 6 ( 0.00%) self.as_mut_ptr().add(self.len) as *mut MaybeUninit, 113 ( 0.00%) 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 2087 ---------------------------------------- -- line 2189 ---------------------------------------- . /// assert_eq!(vec, ["hello", "world", "world"]); . /// . /// let mut vec = vec![1, 2, 3, 4]; . /// vec.resize(2, 0); . /// assert_eq!(vec, [1, 2]); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "vec_resize", since = "1.5.0")] 218,270 ( 0.00%) pub fn resize(&mut self, new_len: usize, value: T) { 21,827 ( 0.00%) let len = self.len(); . 65,481 ( 0.00%) if new_len > len { 32,394 ( 0.00%) self.extend_with(new_len - len, ExtendElement(value)) . } else { . self.truncate(new_len); . } 45,435 ( 0.00%) } . . /// Clones and appends all elements in a slice to the `Vec`. . /// . /// Iterates over the slice `other`, clones each element, and then appends . /// it to this `Vec`. The `other` slice is traversed in-order. . /// . /// Note that this function is same as [`extend`] except that it is . /// specialized to work with slices instead. If and when Rust gets -- line 2213 ---------------------------------------- -- line 2271 ---------------------------------------- . trait ExtendWith { . fn next(&mut self) -> T; . fn last(self) -> T; . } . . struct ExtendElement(T); . impl ExtendWith for ExtendElement { . fn next(&mut self) -> T { 4,804 ( 0.00%) self.0.clone() . } . fn last(self) -> T { . self.0 . } . } . . struct ExtendFunc(F); . impl T> ExtendWith for ExtendFunc { -- line 2287 ---------------------------------------- -- line 2291 ---------------------------------------- . fn last(mut self) -> T { . (self.0)() . } . } . . impl Vec { . #[cfg(not(no_global_oom_handling))] . /// Extend the vector by `n` values, using the given generator. 1,629,911 ( 0.01%) fn extend_with>(&mut self, n: usize, mut value: E) { . self.reserve(n); . . unsafe { 29,583 ( 0.00%) 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 { . ptr::write(ptr, value.next()); . ptr = ptr.offset(1); . // Increment the length in every step in case next() panics . local_len.increment_len(1); . } . 1,185,280 ( 0.00%) if n > 0 { . // We can write the last element directly without cloning needlessly . ptr::write(ptr, value.last()); . local_len.increment_len(1); . } . . // len set by scope guard . } 1,300,361 ( 0.00%) } . } . . 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 2333 ---------------------------------------- -- line 2338 ---------------------------------------- . /// . /// vec.dedup(); . /// . /// assert_eq!(vec, [1, 2, 3, 2]); . /// ``` . #[stable(feature = "rust1", since = "1.0.0")] . #[inline] . pub fn dedup(&mut self) { 3,786 ( 0.00%) 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")] 190,896 ( 0.00%) pub fn from_elem(elem: T, n: usize) -> Vec { 1,871,194 ( 0.01%) ::from_elem(elem, n, Global) 234,337 ( 0.00%) } . . #[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 2367 ---------------------------------------- -- line 2424 ---------------------------------------- . // Common trait implementations for Vec . //////////////////////////////////////////////////////////////////////////////// . . #[stable(feature = "rust1", since = "1.0.0")] . impl ops::Deref for Vec { . type Target = [T]; . . fn deref(&self) -> &[T] { 40,517,006 ( 0.15%) unsafe { slice::from_raw_parts(self.as_ptr(), self.len) } 72 ( 0.00%) } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl ops::DerefMut for Vec { . fn deref_mut(&mut self) -> &mut [T] { 13,318,568 ( 0.05%) unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) } . } . } . . #[cfg(not(no_global_oom_handling))] . trait SpecCloneFrom { . fn clone_from(this: &mut Self, other: &Self); . } . -- line 2447 ---------------------------------------- -- line 2468 ---------------------------------------- . this.extend_from_slice(other); . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl Clone for Vec { . #[cfg(not(test))] 1,233,918 ( 0.00%) fn clone(&self) -> Self { . let alloc = self.allocator().clone(); 2 ( 0.00%) <[T]>::to_vec_in(&**self, alloc) 1,523,594 ( 0.01%) } . . // 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 2487 ---------------------------------------- -- line 2518 ---------------------------------------- . message = "vector indices are of type `usize` or ranges of `usize`", . label = "vector indices are of type `usize` or ranges of `usize`" . )] . impl, A: Allocator> Index for Vec { . type Output = I::Output; . . #[inline] . fn index(&self, index: I) -> &Self::Output { 1,154,607 ( 0.00%) Index::index(&**self, index) . } . } . . #[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`" . )] . impl, A: Allocator> IndexMut for Vec { . #[inline] . fn index_mut(&mut self, index: I) -> &mut Self::Output { 4,520 ( 0.00%) IndexMut::index_mut(&mut **self, index) . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl FromIterator for Vec { . #[inline] . fn from_iter>(iter: I) -> Vec { 6,978,634 ( 0.03%) >::from_iter(iter.into_iter()) . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl IntoIterator for Vec { . type Item = T; . type IntoIter = IntoIter; . -- line 2555 ---------------------------------------- -- line 2564 ---------------------------------------- . /// for s in v.into_iter() { . /// // s has type String, not &String . /// println!("{}", s); . /// } . /// ``` . #[inline] . fn into_iter(self) -> IntoIter { . unsafe { 2,838,635 ( 0.01%) let mut me = ManuallyDrop::new(self); . let alloc = ptr::read(me.allocator()); . let begin = me.as_mut_ptr(); . let end = if mem::size_of::() == 0 { . arith_offset(begin as *const i8, me.len() as isize) as *const T . } else { . begin.add(me.len()) as *const T . }; . let cap = me.buf.capacity(); 1,070,615 ( 0.00%) IntoIter { . buf: NonNull::new_unchecked(begin), . phantom: PhantomData, . cap, . alloc, . ptr: begin, . end, . } . } -- line 2589 ---------------------------------------- -- line 2591 ---------------------------------------- . } . . #[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) -> slice::Iter<'a, T> { 338 ( 0.00%) self.iter() . } . } . . #[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) -> slice::IterMut<'a, T> { 1,322 ( 0.00%) self.iter_mut() . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl Extend for Vec { . #[inline] 37,304 ( 0.00%) fn extend>(&mut self, iter: I) { 3,383,891 ( 0.01%) >::spec_extend(self, iter.into_iter()) 37,304 ( 0.00%) } . . #[inline] . fn extend_one(&mut self, item: T) { 16 ( 0.00%) self.push(item); . } . . #[inline] . fn extend_reserve(&mut self, additional: usize) { . self.reserve(additional); . } . } . -- line 2631 ---------------------------------------- -- line 2636 ---------------------------------------- . 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); . // } 637,192 ( 0.00%) while let Some(element) = iterator.next() { 130,181 ( 0.00%) let len = self.len(); 2,150,677 ( 0.01%) if len == self.capacity() { 3,972 ( 0.00%) 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 1,482,846 ( 0.01%) self.set_len(len + 1); . } . } 20,067 ( 0.00%) } . . /// Creates a splicing iterator that replaces the specified range in the vector . /// with the given `replace_with` iterator and yields the removed items. . /// `replace_with` does not need to be the same length as `range`. . /// . /// `range` is removed even if the iterator is not consumed until the end. . /// . /// It is unspecified how many elements are removed from the vector -- line 2666 ---------------------------------------- -- line 2693 ---------------------------------------- . #[cfg(not(no_global_oom_handling))] . #[inline] . #[stable(feature = "vec_splice", since = "1.21.0")] . pub fn splice(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter, A> . where . R: RangeBounds, . I: IntoIterator, . { 35,832 ( 0.00%) Splice { drain: self.drain(range), replace_with: replace_with.into_iter() } . } . . /// Creates an iterator which uses a closure to determine if an element should be removed. . /// . /// If the closure returns true, then the element is removed and yielded. . /// If the closure returns false, the element will remain in the vector and will not be yielded . /// by the iterator. . /// -- line 2709 ---------------------------------------- -- line 2745 ---------------------------------------- . /// assert_eq!(evens, vec![2, 4, 6, 8, 14]); . /// assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]); . /// ``` . #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] . pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F, A> . where . F: FnMut(&mut T) -> bool, . { 7,657 ( 0.00%) let old_len = self.len(); . . // Guard against us getting leaked (leak amplification) . unsafe { . self.set_len(0); . } . 23,736 ( 0.00%) DrainFilter { vec: self, idx: 0, del: 0, old_len, pred: filter, panic_flag: false } . } . } . . /// 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 2768 ---------------------------------------- -- line 2803 ---------------------------------------- . #[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 { 3,364,783 ( 0.01%) 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 1,875,622 ( 0.01%) ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.as_mut_ptr(), self.len)) . } . // RawVec handles deallocation 3,972,920 ( 0.01%) } . } . . #[stable(feature = "rust1", since = "1.0.0")] . #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] . impl const Default for Vec { . /// Creates an empty `Vec`. . fn default() -> Vec { . Vec::new() -- line 2827 ---------------------------------------- -- line 2976 ---------------------------------------- . /// newly-allocated buffer with exactly the right capacity. . /// . /// # Examples . /// . /// ``` . /// assert_eq!(Box::from(vec![1, 2, 3]), vec![1, 2, 3].into_boxed_slice()); . /// ``` . fn from(v: Vec) -> Self { 4 ( 0.00%) 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 2992 ---------------------------------------- 10,011,656 ( 0.04%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/library/proc_macro/src/bridge/rpc.rs -------------------------------------------------------------------------------- Ir -- line 21 ---------------------------------------- . . pub(super) trait DecodeMut<'a, 's, S>: Sized { . fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self; . } . . macro_rules! rpc_encode_decode { . (le $ty:ty) => { . impl Encode for $ty { 6,256,332 ( 0.02%) fn encode(self, w: &mut Writer, _: &mut S) { . w.extend_from_array(&self.to_le_bytes()); 7,820,415 ( 0.03%) } . } . . impl DecodeMut<'_, '_, S> for $ty { . fn decode(r: &mut Reader<'_>, _: &mut S) -> Self { . const N: usize = ::std::mem::size_of::<$ty>(); . . let mut bytes = [0; N]; 1,000,940 ( 0.00%) bytes.copy_from_slice(&r[..N]); 4,115,745 ( 0.02%) *r = &r[N..]; . . Self::from_le_bytes(bytes) . } . } . }; . (struct $name:ident { $($field:ident),* $(,)? }) => { . impl Encode for $name { . fn encode(self, w: &mut Writer, s: &mut S) { -- line 48 ---------------------------------------- -- line 55 ---------------------------------------- . $name { . $($field: DecodeMut::decode(r, s)),* . } . } . } . }; . (enum $name:ident $(<$($T:ident),+>)? { $($variant:ident $(($field:ident))*),* $(,)? }) => { . impl),+)?> Encode for $name $(<$($T),+>)? { 17,444,660 ( 0.06%) fn encode(self, w: &mut Writer, s: &mut S) { . // HACK(eddyb): `Tag` enum duplicated between the . // two impls as there's no other place to stash it. . #[allow(non_upper_case_globals)] . mod tag { . #[repr(u8)] enum Tag { $($variant),* } . . $(pub const $variant: u8 = Tag::$variant as u8;)* . } . 9,551,775 ( 0.04%) match self { 2,037,071 ( 0.01%) $($name::$variant $(($field))* => { 132,924 ( 0.00%) tag::$variant.encode(w, s); 2,358,491 ( 0.01%) $($field.encode(w, s);)* . })* . } 13,627,236 ( 0.05%) } . } . . impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S> . for $name $(<$($T),+>)? . { 4,492,565 ( 0.02%) fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { . // HACK(eddyb): `Tag` enum duplicated between the . // two impls as there's no other place to stash it. . #[allow(non_upper_case_globals)] . mod tag { . #[repr(u8)] enum Tag { $($variant),* } . . $(pub const $variant: u8 = Tag::$variant as u8;)* . } . 4,319,515 ( 0.02%) match u8::decode(r, s) { . $(tag::$variant => { 121,866 ( 0.00%) $(let $field = DecodeMut::decode(r, s);)* 3,100,335 ( 0.01%) $name::$variant $(($field))* 60,786 ( 0.00%) })* . _ => unreachable!(), . } 7,819,715 ( 0.03%) } . } . } . } . . impl Encode for () { . fn encode(self, _: &mut Writer, _: &mut S) {} . } . . impl DecodeMut<'_, '_, S> for () { . fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {} . } . . impl Encode for u8 { 826,926 ( 0.00%) fn encode(self, w: &mut Writer, _: &mut S) { . w.push(self); 689,105 ( 0.00%) } . } . . impl DecodeMut<'_, '_, S> for u8 { . fn decode(r: &mut Reader<'_>, _: &mut S) -> Self { 17,377,759 ( 0.06%) let x = r[0]; 9,659,035 ( 0.04%) *r = &r[1..]; . x . } . } . . rpc_encode_decode!(le u32); . rpc_encode_decode!(le usize); . . impl Encode for bool { . fn encode(self, w: &mut Writer, s: &mut S) { 139,404 ( 0.00%) (self as u8).encode(w, s); . } . } . . impl DecodeMut<'_, '_, S> for bool { . fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { 93,088 ( 0.00%) match u8::decode(r, s) { . 0 => false, . 1 => true, . _ => unreachable!(), . } . } . } . . impl Encode for char { . fn encode(self, w: &mut Writer, s: &mut S) { 154,992 ( 0.00%) (self as u32).encode(w, s); . } . } . . impl DecodeMut<'_, '_, S> for char { . fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { . char::from_u32(u32::decode(r, s)).unwrap() . } . } . . impl Encode for NonZeroU32 { . fn encode(self, w: &mut Writer, s: &mut S) { 4,373,345 ( 0.02%) self.get().encode(w, s); . } . } . . impl DecodeMut<'_, '_, S> for NonZeroU32 { . fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { . Self::new(u32::decode(r, s)).unwrap() . } . } -- line 170 ---------------------------------------- -- line 204 ---------------------------------------- . Ok(x), . Err(e), . } . ); . . impl Encode for &[u8] { . fn encode(self, w: &mut Writer, s: &mut S) { . self.len().encode(w, s); 168,204 ( 0.00%) w.write_all(self).unwrap(); . } . } . . impl<'a, S> DecodeMut<'a, '_, S> for &'a [u8] { . fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { . let len = usize::decode(r, s); . let xs = &r[..len]; 274,528 ( 0.00%) *r = &r[len..]; . xs . } . } . . impl Encode for &str { 168,204 ( 0.00%) fn encode(self, w: &mut Writer, s: &mut S) { . self.as_bytes().encode(w, s); 210,255 ( 0.00%) } . } . . impl<'a, S> DecodeMut<'a, '_, S> for &'a str { 91,334 ( 0.00%) fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { 182,668 ( 0.00%) str::from_utf8(<&[u8]>::decode(r, s)).unwrap() 182,668 ( 0.00%) } . } . . impl Encode for String { . fn encode(self, w: &mut Writer, s: &mut S) { 168,204 ( 0.00%) self[..].encode(w, s); . } . } . . impl DecodeMut<'_, '_, S> for String { . fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { 210,255 ( 0.00%) <&str>::decode(r, s).to_string() . } . } . . /// Simplified version of panic payloads, ignoring . /// types other than `&'static str` and `String`. . pub enum PanicMessage { . StaticStr(&'static str), . String(String), -- line 253 ---------------------------------------- 16,326,950 ( 0.06%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs -------------------------------------------------------------------------------- Ir -- line 10 ---------------------------------------- . pub fn move_path_children_matching<'tcx, F>( . move_data: &MoveData<'tcx>, . path: MovePathIndex, . mut cond: F, . ) -> Option . where . F: FnMut(mir::PlaceElem<'tcx>) -> bool, . { 11,364 ( 0.00%) let mut next_child = move_data.move_paths[path].first_child; 31,148 ( 0.00%) while let Some(child_index) = next_child { . let move_path_children = &move_data.move_paths[child_index]; 26,972 ( 0.00%) if let Some(&elem) = move_path_children.place.projection.last() { 45,144 ( 0.00%) if cond(elem) { . return Some(child_index); . } . } . next_child = move_path_children.next_sibling; . } . . None . } -- line 30 ---------------------------------------- -- line 48 ---------------------------------------- . // . // FIXME: we have to do something for moving slice patterns. . fn place_contents_drop_state_cannot_differ<'tcx>( . tcx: TyCtxt<'tcx>, . body: &Body<'tcx>, . place: mir::Place<'tcx>, . ) -> bool { . let ty = place.ty(body, tcx).ty; 5,823,788 ( 0.02%) match ty.kind() { . ty::Array(..) => { . debug!( . "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} => false", . place, ty . ); . false . } . ty::Slice(..) | ty::Ref(..) | ty::RawPtr(..) => { . debug!( . "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} refd => true", . place, ty . ); . true . } 4,145,634 ( 0.02%) ty::Adt(def, _) if (def.has_dtor(tcx) && !def.is_box()) || def.is_union() => { . debug!( . "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} Drop => true", . place, ty . ); . true . } . _ => false, . } -- line 79 ---------------------------------------- -- line 83 ---------------------------------------- . tcx: TyCtxt<'tcx>, . body: &Body<'tcx>, . move_data: &MoveData<'tcx>, . lookup_result: LookupResult, . each_child: F, . ) where . F: FnMut(MovePathIndex), . { 87,702 ( 0.00%) match lookup_result { . LookupResult::Parent(..) => { . // access to untracked value - do not touch children . } . LookupResult::Exact(e) => on_all_children_bits(tcx, body, move_data, e, each_child), . } . } . . pub fn on_all_children_bits<'tcx, F>( -- line 99 ---------------------------------------- -- line 100 ---------------------------------------- . tcx: TyCtxt<'tcx>, . body: &Body<'tcx>, . move_data: &MoveData<'tcx>, . move_path_index: MovePathIndex, . mut each_child: F, . ) where . F: FnMut(MovePathIndex), . { 8,352,840 ( 0.03%) fn is_terminal_path<'tcx>( . tcx: TyCtxt<'tcx>, . body: &Body<'tcx>, . move_data: &MoveData<'tcx>, . path: MovePathIndex, . ) -> bool { 2,088,210 ( 0.01%) place_contents_drop_state_cannot_differ(tcx, body, move_data.move_paths[path].place) 8,352,840 ( 0.03%) } . 9,929,194 ( 0.04%) fn on_all_children_bits<'tcx, F>( . tcx: TyCtxt<'tcx>, . body: &Body<'tcx>, . move_data: &MoveData<'tcx>, . move_path_index: MovePathIndex, . each_child: &mut F, . ) where . F: FnMut(MovePathIndex), . { 250,138 ( 0.00%) each_child(move_path_index); . 7,332,499 ( 0.03%) if is_terminal_path(tcx, body, move_data, move_path_index) { . return; . } . 799,421 ( 0.00%) let mut next_child_index = move_data.move_paths[move_path_index].first_child; 2,409,192 ( 0.01%) while let Some(child_index) = next_child_index { 1,177,536 ( 0.00%) on_all_children_bits(tcx, body, move_data, child_index, each_child); 196,256 ( 0.00%) next_child_index = move_data.move_paths[child_index].next_sibling; . } 8,161,466 ( 0.03%) } 4,993,990 ( 0.02%) on_all_children_bits(tcx, body, move_data, move_path_index, &mut each_child); . } . . pub fn on_all_drop_children_bits<'tcx, F>( . tcx: TyCtxt<'tcx>, . body: &Body<'tcx>, . ctxt: &MoveDataParamEnv<'tcx>, . path: MovePathIndex, . mut each_child: F, . ) where . F: FnMut(MovePathIndex), . { 379,696 ( 0.00%) on_all_children_bits(tcx, body, &ctxt.move_data, path, |child| { 292,284 ( 0.00%) let place = &ctxt.move_data.move_paths[path].place; 73,071 ( 0.00%) let ty = place.ty(body, tcx).ty; . debug!("on_all_drop_children_bits({:?}, {:?} : {:?})", path, place, ty); . 44,343 ( 0.00%) let erased_ty = tcx.erase_regions(ty); 452,893 ( 0.00%) if erased_ty.needs_drop(tcx, ctxt.param_env) { 72,934 ( 0.00%) each_child(child); . } else { . debug!("on_all_drop_children_bits - skipping") . } . }) . } . 92,852 ( 0.00%) pub fn drop_flag_effects_for_function_entry<'tcx, F>( . tcx: TyCtxt<'tcx>, . body: &Body<'tcx>, . ctxt: &MoveDataParamEnv<'tcx>, . mut callback: F, . ) where . F: FnMut(MovePathIndex, DropFlagState), . { . let move_data = &ctxt.move_data; 8,308 ( 0.00%) for arg in body.args_iter() { 21,036 ( 0.00%) let place = mir::Place::from(arg); 31,554 ( 0.00%) let lookup_result = move_data.rev_lookup.find(place.as_ref()); . on_lookup_result_bits(tcx, body, move_data, lookup_result, |mpi| { 10,722 ( 0.00%) callback(mpi, DropFlagState::Present) . }); . } 66,464 ( 0.00%) } . 9,494,043 ( 0.03%) pub fn drop_flag_effects_for_location<'tcx, F>( . tcx: TyCtxt<'tcx>, . body: &Body<'tcx>, . ctxt: &MoveDataParamEnv<'tcx>, . loc: Location, . mut callback: F, . ) where . F: FnMut(MovePathIndex, DropFlagState), . { . let move_data = &ctxt.move_data; . debug!("drop_flag_effects_for_location({:?})", loc); . . // first, move out of the RHS 384,869 ( 0.00%) for mi in &move_data.loc_map[loc] { 1,983,223 ( 0.01%) let path = mi.move_path_index(move_data); . debug!("moving out of path {:?}", move_data.move_paths[path]); . 635,837 ( 0.00%) on_all_children_bits(tcx, body, move_data, path, |mpi| callback(mpi, DropFlagState::Absent)) . } . . debug!("drop_flag_effects: assignment for location({:?})", loc); . 247,918 ( 0.00%) for_location_inits(tcx, body, move_data, loc, |mpi| callback(mpi, DropFlagState::Present)); 7,412,832 ( 0.03%) } . . pub fn for_location_inits<'tcx, F>( . tcx: TyCtxt<'tcx>, . body: &Body<'tcx>, . move_data: &MoveData<'tcx>, . loc: Location, . mut callback: F, . ) where . F: FnMut(MovePathIndex), . { 384,869 ( 0.00%) for ii in &move_data.init_loc_map[loc] { 1,103,004 ( 0.00%) let init = move_data.inits[*ii]; 624,140 ( 0.00%) match init.kind { . InitKind::Deep => { . let path = init.path; . . on_all_children_bits(tcx, body, move_data, path, &mut callback) . } . InitKind::Shallow => { . let mpi = init.path; . callback(mpi); -- line 226 ---------------------------------------- -- line 230 ---------------------------------------- . } . } . . /// Calls `handle_inactive_variant` for each descendant move path of `enum_place` that contains a . /// `Downcast` to a variant besides the `active_variant`. . /// . /// NOTE: If there are no move paths corresponding to an inactive variant, . /// `handle_inactive_variant` will not be called for that variant. 224,544 ( 0.00%) pub(crate) fn on_all_inactive_variants<'tcx>( . tcx: TyCtxt<'tcx>, . body: &mir::Body<'tcx>, . move_data: &MoveData<'tcx>, . enum_place: mir::Place<'tcx>, . active_variant: VariantIdx, . mut handle_inactive_variant: impl FnMut(MovePathIndex), . ) { 93,560 ( 0.00%) let enum_mpi = match move_data.rev_lookup.find(enum_place.as_ref()) { . LookupResult::Exact(mpi) => mpi, . LookupResult::Parent(_) => return, . }; . . let enum_path = &move_data.move_paths[enum_mpi]; 108,099 ( 0.00%) for (variant_mpi, variant_path) in enum_path.children(&move_data.move_paths) { . // Because of the way we build the `MoveData` tree, each child should have exactly one more . // projection than `enum_place`. This additional projection must be a downcast since the . // base is an enum. 18,678 ( 0.00%) let (downcast, base_proj) = variant_path.place.projection.split_last().unwrap(); 74,712 ( 0.00%) assert_eq!(enum_place.projection.len(), base_proj.len()); . 56,034 ( 0.00%) let variant_idx = match *downcast { . mir::ProjectionElem::Downcast(_, idx) => idx, . _ => unreachable!(), . }; . 18,678 ( 0.00%) if variant_idx != active_variant { . on_all_children_bits(tcx, body, move_data, variant_mpi, |mpi| { 18,642 ( 0.00%) handle_inactive_variant(mpi) . }); . } . } 149,696 ( 0.00%) } 7,525,269 ( 0.03%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/.cargo/registry/src/github.com-1ecc6299db9ec823/hashbrown-0.12.0/src/raw/mod.rs -------------------------------------------------------------------------------- Ir -- line 111 ---------------------------------------- . 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 { 7,050,862 ( 0.03%) 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)); 501,884 ( 0.00%) 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 140 ---------------------------------------- -- line 143 ---------------------------------------- . /// 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. . let hash_len = usize::min(mem::size_of::(), mem::size_of::()); 163,856,737 ( 0.60%) let top7 = hash >> (hash_len * 8 - 7); . (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 -- line 159 ---------------------------------------- -- line 170 ---------------------------------------- . #[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" . ); . 1,054,678 ( 0.00%) self.stride += Group::WIDTH; 1,054,678 ( 0.00%) self.pos += self.stride; 905,266 ( 0.00%) 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. 514,078 ( 0.00%) 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. 1,100,550 ( 0.00%) 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. 221,574 ( 0.00%) 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 { 1,405,022 ( 0.01%) 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. 321,054 ( 0.00%) ((bucket_mask + 1) / 8) * 7 . } . } . . /// Helper which allows the max calculation for ctrl_align to be statically computed for each T . /// while keeping the rest of `calculate_layout_for` independent of `T` . #[derive(Copy, Clone)] . struct TableLayout { . size: usize, -- line 233 ---------------------------------------- -- line 246 ---------------------------------------- . . #[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,034,180 ( 0.00%) size.checked_mul(buckets)?.checked_add(ctrl_align - 1)? & !(ctrl_align - 1); 1,392,523 ( 0.01%) let len = ctrl_offset.checked_add(buckets + Group::WIDTH)?; . . Some(( . unsafe { Layout::from_size_align_unchecked(len, ctrl_align) }, . ctrl_offset, . )) . } . } . -- line 263 ---------------------------------------- -- line 337 ---------------------------------------- . } . } . #[cfg_attr(feature = "inline-more", inline)] . pub unsafe fn drop(&self) { . self.as_ptr().drop_in_place(); . } . #[inline] . pub unsafe fn read(&self) -> T { 6,816 ( 0.00%) self.as_ptr().read() . } . #[inline] . pub unsafe fn write(&self, val: T) { . self.as_ptr().write(val); . } . #[inline] . pub unsafe fn as_ref<'a>(&self) -> &'a T { . &*self.as_ptr() -- line 353 ---------------------------------------- -- line 422 ---------------------------------------- . /// 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 fn new_in(alloc: A) -> Self { 9,651 ( 0.00%) 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 438 ---------------------------------------- -- line 440 ---------------------------------------- . unsafe fn new_uninitialized( . alloc: A, . buckets: usize, . fallibility: Fallibility, . ) -> Result { . debug_assert!(buckets.is_power_of_two()); . . Ok(Self { 655 ( 0.00%) table: RawTableInner::new_uninitialized( . alloc, . TableLayout::new::(), . buckets, . fallibility, . )?, . marker: PhantomData, . }) . } -- line 456 ---------------------------------------- -- line 458 ---------------------------------------- . /// Attempts to allocate a new hash table with at least enough capacity . /// for inserting the given number of elements without reallocating. . fn fallible_with_capacity( . alloc: A, . capacity: usize, . fallibility: Fallibility, . ) -> Result { . Ok(Self { 29,991 ( 0.00%) table: RawTableInner::fallible_with_capacity( . alloc, . TableLayout::new::(), . capacity, . fallibility, . )?, . marker: PhantomData, . }) . } -- line 474 ---------------------------------------- -- line 527 ---------------------------------------- . debug_assert_ne!(self.table.bucket_mask, 0); . debug_assert!(index < self.buckets()); . Bucket::from_base_index(self.data_end(), index) . } . . /// Erases an element from the table without dropping it. . #[cfg_attr(feature = "inline-more", inline)] . #[deprecated(since = "0.8.1", note = "use erase or remove instead")] 95,894 ( 0.00%) pub unsafe fn erase_no_drop(&mut self, item: &Bucket) { 95,894 ( 0.00%) let index = self.bucket_index(item); . self.table.erase(index); 191,788 ( 0.00%) } . . /// Erases an element from the table, dropping it in place. . #[cfg_attr(feature = "inline-more", inline)] . #[allow(clippy::needless_pass_by_value)] . #[allow(deprecated)] . pub unsafe fn erase(&mut self, item: Bucket) { . // Erase the element from the table first since drop might panic. 75,260 ( 0.00%) self.erase_no_drop(&item); . item.drop(); . } . . /// Finds and erases an element from the table, dropping it in place. . /// Returns true if an element was found. . #[cfg(feature = "raw")] . #[cfg_attr(feature = "inline-more", inline)] . pub fn erase_entry(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> bool { -- line 554 ---------------------------------------- -- line 563 ---------------------------------------- . } . } . . /// Removes an element from the table, returning it. . #[cfg_attr(feature = "inline-more", inline)] . #[allow(clippy::needless_pass_by_value)] . #[allow(deprecated)] . pub unsafe fn remove(&mut self, item: Bucket) -> T { 116,528 ( 0.00%) self.erase_no_drop(&item); 893 ( 0.00%) item.read() . } . . /// Finds and removes an element from the table, returning it. . #[cfg_attr(feature = "inline-more", inline)] 2,604,538 ( 0.01%) pub fn remove_entry(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option { . // Avoid `Option::map` because it bloats LLVM IR. 7,724 ( 0.00%) match self.find(hash, eq) { 25,328 ( 0.00%) Some(bucket) => Some(unsafe { self.remove(bucket) }), 646,037 ( 0.00%) None => None, . } 3,556,149 ( 0.01%) } . . /// 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) { . // Ensure that the table is reset even if one of the drops panic . let mut self_ = guard(self, |self_| self_.clear_no_drop()); . unsafe { 1 ( 0.00%) self_.drop_elements(); . } . } . 7 ( 0.00%) unsafe fn drop_elements(&mut self) { 56,524 ( 0.00%) if mem::needs_drop::() && !self.is_empty() { . for item in self.iter() { . item.drop(); . } . } 8 ( 0.00%) } . . /// Shrinks the table to fit `max(self.len(), min_size)` elements. . #[cfg_attr(feature = "inline-more", inline)] . pub fn shrink_to(&mut self, min_size: usize, hasher: impl Fn(&T) -> u64) { . // Calculate the minimal number of elements that we need to reserve . // space for. . let min_size = usize::max(self.table.items, min_size); . if min_size == 0 { -- line 615 ---------------------------------------- -- line 642 ---------------------------------------- . } . } . } . . /// 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) { 1,416,474 ( 0.01%) if additional > self.table.growth_left { . // Avoid `Result::unwrap_or_else` because it bloats LLVM IR. 901,771 ( 0.00%) if self . .reserve_rehash(additional, hasher, Fallibility::Infallible) . .is_err() . { . unsafe { hint::unreachable_unchecked() } . } . } . } . -- line 660 ---------------------------------------- -- line 671 ---------------------------------------- . } else { . Ok(()) . } . } . . /// Out-of-line slow path for `reserve` and `try_reserve`. . #[cold] . #[inline(never)] 2,054,635 ( 0.01%) fn reserve_rehash( . &mut self, . additional: usize, . hasher: impl Fn(&T) -> u64, . fallibility: Fallibility, . ) -> Result<(), TryReserveError> { . unsafe { . self.table.reserve_rehash_inner( . additional, -- line 687 ---------------------------------------- -- line 690 ---------------------------------------- . TableLayout::new::(), . if mem::needs_drop::() { . Some(mem::transmute(ptr::drop_in_place:: as unsafe fn(*mut T))) . } else { . None . }, . ) . } 1,484,624 ( 0.01%) } . . /// 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 706 ---------------------------------------- -- line 714 ---------------------------------------- . ) . } . } . . /// 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)] 9,180,114 ( 0.03%) pub fn insert(&mut self, hash: u64, value: T, hasher: impl Fn(&T) -> u64) -> Bucket { . unsafe { . let mut index = 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. 20,826 ( 0.00%) let old_ctrl = *self.table.ctrl(index); 6,666,909 ( 0.02%) if unlikely(self.table.growth_left == 0 && special_is_empty(old_ctrl)) { . self.reserve(1, hasher); . index = self.table.find_insert_slot(hash); . } . . self.table.record_item_insert_at(index, old_ctrl, hash); . . let bucket = self.bucket(index); 4 ( 0.00%) bucket.write(value); . bucket . } 6,792,385 ( 0.02%) } . . /// 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 749 ---------------------------------------- -- line 760 ---------------------------------------- . } . } . } . . /// 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)] 2,482,528 ( 0.01%) pub fn insert_entry(&mut self, hash: u64, value: T, hasher: impl Fn(&T) -> u64) -> &mut T { 981 ( 0.00%) unsafe { self.insert(hash, value, hasher).as_mut() } 1,861,896 ( 0.01%) } . . /// 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"))] 53,719 ( 0.00%) pub unsafe fn insert_no_grow(&mut self, hash: u64, value: T) -> Bucket { 1,326,600 ( 0.00%) let (index, old_ctrl) = self.table.prepare_insert_slot(hash); 57,198 ( 0.00%) let bucket = self.table.bucket(index); . . // If we are replacing a DELETED entry then we don't need to update . // the load counter. 2,854,756 ( 0.01%) self.table.growth_left -= special_is_empty(old_ctrl) as usize; . . bucket.write(value); 2,272,808 ( 0.01%) self.table.items += 1; . bucket 80,633 ( 0.00%) } . . /// 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 . /// . /// This does not check if the given bucket is actually occupied. . #[cfg_attr(feature = "inline-more", inline)] -- line 798 ---------------------------------------- -- line 813 ---------------------------------------- . true . } else { . false . } . } . . /// Searches for an element in the table. . #[inline] 150,226 ( 0.00%) pub fn find(&self, hash: u64, mut eq: impl FnMut(&T) -> bool) -> Option> { 36,603 ( 0.00%) let result = self.table.find_inner(hash, &mut |index| unsafe { 159,724 ( 0.00%) eq(self.bucket(index).as_ref()) 17,020 ( 0.00%) }); . . // Avoid `Option::map` because it bloats LLVM IR. . match result { 5,324 ( 0.00%) Some(index) => Some(unsafe { self.bucket(index) }), . None => None, . } 170,144 ( 0.00%) } . . /// 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. 123,604 ( 0.00%) 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] 11,347 ( 0.00%) pub fn get_mut(&mut self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&mut T> { . // Avoid `Option::map` because it bloats LLVM IR. 71,255 ( 0.00%) match self.find(hash, eq) { . Some(bucket) => Some(unsafe { bucket.as_mut() }), . None => None, . } 12,968 ( 0.00%) } . . /// Attempts to get mutable references to `N` entries in the table at once. . /// . /// Returns an array of length `N` with the results of each query. . /// . /// At most one mutable reference will be returned to any entry. `None` will be returned if any . /// of the hashes are duplicates. `None` will be returned if the hash is not found. . /// -- line 859 ---------------------------------------- -- line 920 ---------------------------------------- . #[inline] . pub fn len(&self) -> usize { . self.table.items . } . . /// Returns `true` if the table contains no elements. . #[inline] . pub fn is_empty(&self) -> bool { 4,499,415 ( 0.02%) self.len() == 0 . } . . /// Returns the number of buckets in the table. . #[inline] . pub fn buckets(&self) -> usize { . self.table.bucket_mask + 1 . } . . /// 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 { 2 ( 0.00%) let data = Bucket::from_base_index(self.data_end(), 0); . RawIter { . iter: RawIterRange::new(self.table.ctrl.as_ptr(), data, self.table.buckets()), 518,384 ( 0.00%) 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 954 ---------------------------------------- -- line 995 ---------------------------------------- . /// 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. . pub unsafe fn into_iter_from(self, iter: RawIter) -> RawIntoIter { . debug_assert_eq!(iter.len(), self.len()); . . let alloc = self.table.alloc.clone(); 22,360 ( 0.00%) let allocation = self.into_allocation(); 16,770 ( 0.00%) RawIntoIter { 27,950 ( 0.00%) iter, . allocation, . marker: PhantomData, . 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)> { 11,056 ( 0.00%) 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 calculate_layout::(self.table.buckets()) { . Some(lco) => lco, . None => unsafe { hint::unreachable_unchecked() }, . }; . Some(( 1,699 ( 0.00%) unsafe { NonNull::new_unchecked(self.table.ctrl.as_ptr().sub(ctrl_offset)) }, . layout, . )) . }; . mem::forget(self); . alloc . } . } . -- line 1033 ---------------------------------------- -- line 1042 ---------------------------------------- . T: Sync, . A: Sync, . { . } . . impl RawTableInner { . #[inline] . const fn new_in(alloc: A) -> Self { 3,062,413 ( 0.01%) Self { . // Be careful to cast the entire slice to a raw pointer. . ctrl: unsafe { NonNull::new_unchecked(Group::static_empty() as *const _ as *mut u8) }, . bucket_mask: 0, . items: 0, . growth_left: 0, . alloc, . } . } . } . . impl RawTableInner { . #[cfg_attr(feature = "inline-more", inline)] 1,840,660 ( 0.01%) unsafe fn new_uninitialized( . alloc: A, . table_layout: TableLayout, . buckets: usize, . fallibility: Fallibility, . ) -> Result { . debug_assert!(buckets.is_power_of_two()); . . // Avoid `Option::ok_or_else` because it bloats LLVM IR. -- line 1071 ---------------------------------------- -- line 1078 ---------------------------------------- . // exceed `isize::MAX`. We can skip this check on 64-bit systems since . // such allocations will never succeed anyways. . // . // This mirrors what Vec does in the standard library. . if mem::size_of::() < 8 && layout.size() > isize::MAX as usize { . return Err(fallibility.capacity_overflow()); . } . 431,490 ( 0.00%) let ptr: NonNull = match do_alloc(&alloc, layout) { . Ok(block) => block.cast(), . Err(_) => return Err(fallibility.alloc_err(layout)), . }; . . let ctrl = NonNull::new_unchecked(ptr.as_ptr().add(ctrl_offset)); 1,016,472 ( 0.00%) Ok(Self { . ctrl, 426,582 ( 0.00%) bucket_mask: buckets - 1, . items: 0, . growth_left: bucket_mask_to_capacity(buckets - 1), . alloc, . }) 1,340,048 ( 0.00%) } . . #[inline] 100,077 ( 0.00%) fn fallible_with_capacity( . alloc: A, . table_layout: TableLayout, . capacity: usize, . fallibility: Fallibility, . ) -> Result { 25,908 ( 0.00%) if capacity == 0 { 12,491 ( 0.00%) Ok(Self::new_in(alloc)) . } else { . unsafe { . let buckets = . capacity_to_buckets(capacity).ok_or_else(|| fallibility.capacity_overflow())?; . 833,126 ( 0.00%) let result = Self::new_uninitialized(alloc, table_layout, buckets, fallibility)?; . result.ctrl(0).write_bytes(EMPTY, result.num_ctrl_bytes()); . 61,313 ( 0.00%) Ok(result) . } . } 100,077 ( 0.00%) } . . /// 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] 468,270 ( 0.00%) unsafe fn prepare_insert_slot(&self, hash: u64) -> (usize, u8) { . let index = self.find_insert_slot(hash); 468,270 ( 0.00%) let old_ctrl = *self.ctrl(index); . self.set_ctrl_h2(index, hash); . (index, old_ctrl) 936,540 ( 0.00%) } . . /// Searches for an empty or deleted bucket which is suitable for inserting . /// a new element. . /// . /// There must be at least 1 empty bucket in the table. . #[inline] . fn find_insert_slot(&self, hash: u64) -> usize { . let mut probe_seq = self.probe_seq(hash); . loop { . unsafe { . let group = Group::load(self.ctrl(probe_seq.pos)); 4,556,630 ( 0.02%) if let Some(bit) = group.match_empty_or_deleted().lowest_set_bit() { 13,307,576 ( 0.05%) let result = (probe_seq.pos + bit) & self.bucket_mask; . . // In tables smaller than the group width, trailing control . // 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). 6,100,716 ( 0.02%) if unlikely(is_full(*self.ctrl(result))) { . debug_assert!(self.bucket_mask < Group::WIDTH); . debug_assert_ne!(probe_seq.pos, 0); . return Group::load_aligned(self.ctrl(0)) . .match_empty_or_deleted() . .lowest_set_bit_nonzero(); . } . . return result; -- line 1165 ---------------------------------------- -- line 1171 ---------------------------------------- . . /// Searches for an element in the table. This uses dynamic dispatch to reduce the amount of . /// code generated, but it is eliminated by LLVM optimizations. . #[inline] . fn find_inner(&self, hash: u64, eq: &mut dyn FnMut(usize) -> bool) -> Option { . let h2_hash = h2(hash); . let mut probe_seq = self.probe_seq(hash); . 577,752 ( 0.00%) loop { . let group = unsafe { Group::load(self.ctrl(probe_seq.pos)) }; . 17,675,796 ( 0.06%) for bit in group.match_byte(h2_hash) { 35,445,883 ( 0.13%) let index = (probe_seq.pos + bit) & self.bucket_mask; . 23,008,897 ( 0.08%) if likely(eq(index)) { . return Some(index); . } . } . 4,943,865 ( 0.02%) if likely(group.match_empty().any_bit_set()) { . return None; . } . . probe_seq.move_next(self.bucket_mask); . } . } . . #[allow(clippy::mut_mut)] . #[inline] . unsafe fn prepare_rehash_in_place(&mut self) { . // Bulk convert all full control bytes to DELETED, and all DELETED . // control bytes to EMPTY. This effectively frees up all buckets . // containing a DELETED entry. 11 ( 0.00%) for i in (0..self.buckets()).step_by(Group::WIDTH) { . let group = Group::load_aligned(self.ctrl(i)); . let group = group.convert_special_to_empty_and_full_to_deleted(); . group.store_aligned(self.ctrl(i)); . } . . // Fix up the trailing control bytes. See the comments in set_ctrl . // for the handling of tables smaller than the group width. 9 ( 0.00%) if self.buckets() < Group::WIDTH { . self.ctrl(0) . .copy_to(self.ctrl(Group::WIDTH), self.buckets()); . } else { . self.ctrl(0) . .copy_to(self.ctrl(self.buckets()), Group::WIDTH); . } . } . -- line 1220 ---------------------------------------- -- line 1225 ---------------------------------------- . 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(); 16,890,200 ( 0.06%) 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 { 93,416,827 ( 0.34%) 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 1257 ---------------------------------------- -- line 1263 ---------------------------------------- . } 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) { 8,328,362 ( 0.03%) self.growth_left -= special_is_empty(old_ctrl) as usize; . self.set_ctrl_h2(index, hash); 6,662,644 ( 0.02%) 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; 123 ( 0.00%) probe_index(i) == probe_index(new_i) . } . . /// Sets a control byte to the hash, and possibly also the replicated control byte at . /// the end of the array. . #[inline] . unsafe fn set_ctrl_h2(&self, index: usize, hash: u64) { . self.set_ctrl(index, h2(hash)); . } -- line 1289 ---------------------------------------- -- line 1312 ---------------------------------------- . // replicate the buckets at the end of the trailing group. For example . // with 2 buckets and a group size of 4, the control bytes will look . // like this: . // . // Real | Replicated . // --------------------------------------------- . // | [A] | [B] | [EMPTY] | [EMPTY] | [A] | [B] | . // --------------------------------------------- 12,842,768 ( 0.05%) let index2 = ((index.wrapping_sub(Group::WIDTH)) & self.bucket_mask) + Group::WIDTH; . 4,278,820 ( 0.02%) *self.ctrl(index) = ctrl; 4,284,178 ( 0.02%) *self.ctrl(index2) = ctrl; . } . . /// Returns a pointer to a control byte. . #[inline] . unsafe fn ctrl(&self, index: usize) -> *mut u8 { . debug_assert!(index < self.num_ctrl_bytes()); . self.ctrl.as_ptr().add(index) . } . . #[inline] . fn buckets(&self) -> usize { 1,500,558 ( 0.01%) self.bucket_mask + 1 . } . . #[inline] . fn num_ctrl_bytes(&self) -> usize { 1,151,916 ( 0.00%) self.bucket_mask + 1 + Group::WIDTH . } . . #[inline] . fn is_empty_singleton(&self) -> bool { 5,497,203 ( 0.02%) self.bucket_mask == 0 . } . . #[allow(clippy::mut_mut)] . #[inline] . unsafe fn prepare_resize( . &self, . table_layout: TableLayout, . capacity: usize, . fallibility: Fallibility, . ) -> Result, TryReserveError> { . debug_assert!(self.items <= capacity); . . // Allocate and initialize the new table. 15,480 ( 0.00%) let mut new_table = RawTableInner::fallible_with_capacity( . self.alloc.clone(), . table_layout, . capacity, . fallibility, . )?; 574,848 ( 0.00%) 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_| { 251,980 ( 0.00%) 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 1383 ---------------------------------------- -- line 1388 ---------------------------------------- . &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. 503,978 ( 0.00%) let new_items = match self.items.checked_add(additional) { . Some(new_items) => new_items, . None => return Err(fallibility.capacity_overflow()), . }; 503,966 ( 0.00%) let full_capacity = bucket_mask_to_capacity(self.bucket_mask); 1,074,446 ( 0.00%) 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); 6 ( 0.00%) Ok(()) . } else { . // Otherwise, conservatively resize to at least the next size up . // to avoid churning deletes into frequent rehashes. . self.resize_inner( 251,980 ( 0.00%) 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 1418 ---------------------------------------- -- line 1424 ---------------------------------------- . #[inline(always)] . unsafe fn resize_inner( . &mut self, . capacity: usize, . hasher: &dyn Fn(&mut Self, usize) -> u64, . fallibility: Fallibility, . layout: TableLayout, . ) -> Result<(), TryReserveError> { 38,572 ( 0.00%) let mut new_table = self.prepare_resize(layout, capacity, fallibility)?; . . // Copy all elements to the new table. . for i in 0..self.buckets() { 2,615,807 ( 0.01%) if !is_full(*self.ctrl(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 1444 ---------------------------------------- -- line 1454 ---------------------------------------- . } . . // We successfully copied all elements without panicking. Now replace . // self with the new table. The old table will have its memory freed but . // the items will not be dropped (since they have been moved into the . // new table). . mem::swap(self, &mut new_table); . 251,980 ( 0.00%) Ok(()) . } . . /// Rehashes the contents of the table in place (i.e. without changing the . /// allocation). . /// . /// If `hasher` panics then some the table's contents may be lost. . /// . /// This uses dynamic dispatch to reduce the amount of -- line 1470 ---------------------------------------- -- line 1496 ---------------------------------------- . } . self_.growth_left = bucket_mask_to_capacity(self_.bucket_mask) - self_.items; . }); . . // At this point, DELETED elements are elements that we haven't . // rehashed yet. Find them and re-insert them at their ideal . // position. . 'outer: for i in 0..guard.buckets() { 256 ( 0.00%) if *guard.ctrl(i) != DELETED { . continue; . } . . let i_p = guard.bucket_ptr(i, size_of); . . 'inner: loop { . // Hash the current item . let hash = hasher(*guard, i); -- line 1512 ---------------------------------------- -- line 1515 ---------------------------------------- . let new_i = guard.find_insert_slot(hash); . let new_i_p = guard.bucket_ptr(new_i, size_of); . . // Probing works by scanning through all of the control . // bytes in groups, which may not be aligned to the group . // size. If both the new and old position fall within the . // same unaligned group, then there is no benefit in moving . // it and we can just continue to the next item. 41 ( 0.00%) if likely(guard.is_in_same_group(i, new_i, hash)) { . guard.set_ctrl_h2(i, hash); . continue 'outer; . } . . // We are moving the current item to a new position. Write . // our H2 to the control byte of the new position. . let prev_ctrl = guard.replace_ctrl_h2(new_i, hash); . if prev_ctrl == EMPTY { -- line 1531 ---------------------------------------- -- line 1541 ---------------------------------------- . // swapped into the old slot. . debug_assert_eq!(prev_ctrl, DELETED); . ptr::swap_nonoverlapping(i_p, new_i_p, size_of); . continue 'inner; . } . } . } . 9 ( 0.00%) guard.growth_left = bucket_mask_to_capacity(guard.bucket_mask) - guard.items; . . mem::forget(guard); . } . . #[inline] . unsafe fn free_buckets(&mut self, table_layout: TableLayout) { . // Avoid `Option::unwrap_or_else` because it bloats LLVM IR. . let (layout, ctrl_offset) = match table_layout.calculate_layout_for(self.buckets()) { . Some(lco) => lco, . None => hint::unreachable_unchecked(), . }; . self.alloc.deallocate( 175,543 ( 0.00%) NonNull::new_unchecked(self.ctrl.as_ptr().sub(ctrl_offset)), . layout, . ); . } . . /// Marks all table buckets as empty without dropping their contents. . #[inline] . fn clear_no_drop(&mut self) { 62,984 ( 0.00%) if !self.is_empty_singleton() { . unsafe { . self.ctrl(0).write_bytes(EMPTY, self.num_ctrl_bytes()); . } . } 75,442 ( 0.00%) self.items = 0; 63,034 ( 0.00%) self.growth_left = bucket_mask_to_capacity(self.bucket_mask); . } . . #[inline] . unsafe fn erase(&mut self, index: usize) { . debug_assert!(is_full(*self.ctrl(index))); 369,639 ( 0.00%) let index_before = index.wrapping_sub(Group::WIDTH) & self.bucket_mask; . let empty_before = Group::load(self.ctrl(index_before)).match_empty(); . let empty_after = Group::load(self.ctrl(index)).match_empty(); . . // If we are inside a continuous block of Group::WIDTH full or deleted . // cells then a probe window may have seen a full block when trying to . // insert. We therefore need to keep that block non-empty so that . // lookups will continue searching to the next probe window. . // . // 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,478,556 ( 0.01%) let ctrl = if empty_before.leading_zeros() + empty_after.trailing_zeros() >= Group::WIDTH { . DELETED . } else { 1,792,575 ( 0.01%) self.growth_left += 1; . EMPTY . }; . self.set_ctrl(index, ctrl); 1,478,556 ( 0.01%) self.items -= 1; . } . } . . impl Clone for RawTable { 25,752 ( 0.00%) fn clone(&self) -> Self { 3,354 ( 0.00%) if self.table.is_empty_singleton() { . Self::new_in(self.table.alloc.clone()) . } else { . unsafe { . let mut new_table = ManuallyDrop::new( . // Avoid `Result::ok_or_else` because it bloats LLVM IR. . match Self::new_uninitialized( . self.table.alloc.clone(), . self.table.buckets(), -- line 1615 ---------------------------------------- -- line 1624 ---------------------------------------- . // We need to free the memory allocated for the new table. . new_table.free_buckets(); . }); . . // Return the newly created table. . ManuallyDrop::into_inner(new_table) . } . } 28,971 ( 0.00%) } . . fn clone_from(&mut self, source: &Self) { . if source.table.is_empty_singleton() { . *self = Self::new_in(self.table.alloc.clone()); . } else { . unsafe { . // First, drop all our elements without clearing the control bytes. . self.drop_elements(); -- line 1640 ---------------------------------------- -- line 1687 ---------------------------------------- . .table . .ctrl(0) . .copy_to_nonoverlapping(self.table.ctrl(0), self.table.num_ctrl_bytes()); . source . .data_start() . .copy_to_nonoverlapping(self.data_start(), self.table.buckets()); . . self.table.items = source.table.items; 262 ( 0.00%) self.table.growth_left = source.table.growth_left; . } . } . . impl RawTable { . /// Common code for clone and clone_from. Assumes `self.buckets() == source.buckets()`. . #[cfg_attr(feature = "inline-more", inline)] . unsafe fn clone_from_impl(&mut self, source: &Self, mut on_panic: impl FnMut(&mut Self)) { . // Copy the control bytes unchanged. We do this in a single pass -- line 1703 ---------------------------------------- -- line 1790 ---------------------------------------- . 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)] 2,417,089 ( 0.01%) fn drop(&mut self) { 2,385,434 ( 0.01%) if !self.table.is_empty_singleton() { . unsafe { . self.drop_elements(); . self.free_buckets(); . } . } 2,570,594 ( 0.01%) } . } . #[cfg(not(feature = "nightly"))] . impl Drop for RawTable { . #[cfg_attr(feature = "inline-more", inline)] . fn drop(&mut self) { . if !self.table.is_empty_singleton() { . unsafe { . self.drop_elements(); -- line 1813 ---------------------------------------- -- line 1817 ---------------------------------------- . } . } . . impl IntoIterator for RawTable { . type Item = T; . type IntoIter = RawIntoIter; . . #[cfg_attr(feature = "inline-more", inline)] 22,360 ( 0.00%) fn into_iter(self) -> RawIntoIter { . unsafe { . let iter = self.iter(); . self.into_iter_from(iter) . } 27,950 ( 0.00%) } . } . . /// Iterator over a sub-range of a table. Unlike `RawIter` this iterator does . /// not track an item count. . pub(crate) struct RawIterRange { . // Mask of full buckets in the current group. Bits are cleared from this . // mask as each element is processed. . current_group: BitMask, -- line 1838 ---------------------------------------- -- line 1934 ---------------------------------------- . . impl Iterator for RawIterRange { . type Item = Bucket; . . #[cfg_attr(feature = "inline-more", inline)] . fn next(&mut self) -> Option> { . unsafe { . loop { 1,297,571 ( 0.00%) if let Some(index) = self.current_group.lowest_set_bit() { 209,199 ( 0.00%) self.current_group = self.current_group.remove_lowest_bit(); 338,205 ( 0.00%) return Some(self.data.next_n(index)); . } . 1,239,929 ( 0.00%) if self.next_ctrl >= self.end { . return None; . } . . // We might read past self.end up to the next group boundary, . // but this is fine because it only occurs on tables smaller . // than the group size where the trailing control bytes are all . // EMPTY. On larger tables self.end is guaranteed to be aligned . // to the group size (since tables are power-of-two sized). 30,452 ( 0.00%) self.current_group = Group::load_aligned(self.next_ctrl).match_full(); 34,152 ( 0.00%) self.data = self.data.next_n(Group::WIDTH); 52,882 ( 0.00%) self.next_ctrl = self.next_ctrl.add(Group::WIDTH); . } . } . } . . #[inline] . fn size_hint(&self) -> (usize, Option) { . // We don't have an item count, so just guess based on the range size. . ( -- line 1966 ---------------------------------------- -- line 2102 ---------------------------------------- . } . } else { . // We must have already iterated past the removed item. . } . } . } . . unsafe fn drop_elements(&mut self) { 6,748 ( 0.00%) if mem::needs_drop::() && self.len() != 0 { . for item in self { . item.drop(); . } . } . } . } . . impl Clone for RawIter { -- line 2118 ---------------------------------------- -- line 2124 ---------------------------------------- . } . } . } . . impl Iterator for RawIter { . type Item = Bucket; . . #[cfg_attr(feature = "inline-more", inline)] 264,536 ( 0.00%) fn next(&mut self) -> Option> { 604,534 ( 0.00%) if let Some(b) = self.iter.next() { 2,061,364 ( 0.01%) self.items -= 1; . Some(b) . } else { . // We don't check against items == 0 here to allow the . // compiler to optimize away the item count entirely if the . // iterator length is never queried. . debug_assert_eq!(self.items, 0); . None . } 529,072 ( 0.00%) } . . #[inline] . fn size_hint(&self) -> (usize, Option) { . (self.items, Some(self.items)) . } . } . . impl ExactSizeIterator for RawIter {} -- line 2151 ---------------------------------------- -- line 2177 ---------------------------------------- . T: Sync, . A: Sync, . { . } . . #[cfg(feature = "nightly")] . unsafe impl<#[may_dangle] T, A: Allocator + Clone> Drop for RawIntoIter { . #[cfg_attr(feature = "inline-more", inline)] 8,752 ( 0.00%) fn drop(&mut self) { . unsafe { . // Drop all remaining elements . self.iter.drop_elements(); . . // Free the table 51,974 ( 0.00%) if let Some((ptr, layout)) = self.allocation { . self.alloc.deallocate(ptr, layout); . } . } 1,338 ( 0.00%) } . } . #[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 2203 ---------------------------------------- -- line 2209 ---------------------------------------- . } . } . } . . impl Iterator for RawIntoIter { . type Item = T; . . #[cfg_attr(feature = "inline-more", inline)] 10,436 ( 0.00%) fn next(&mut self) -> Option { 9,468 ( 0.00%) unsafe { Some(self.iter.next()?.read()) } 24,647 ( 0.00%) } . . #[inline] . fn size_hint(&self) -> (usize, Option) { 4 ( 0.00%) self.iter.size_hint() . } . } . . impl ExactSizeIterator for RawIntoIter {} . impl FusedIterator for RawIntoIter {} . . /// Iterator which consumes elements without freeing the table storage. . pub struct RawDrain<'a, T, A: Allocator + Clone = Global> { -- line 2231 ---------------------------------------- -- line 2259 ---------------------------------------- . where . T: Sync, . A: Sync, . { . } . . impl Drop for RawDrain<'_, T, A> { . #[cfg_attr(feature = "inline-more", inline)] 8,896 ( 0.00%) 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. . self.table.clear_no_drop(); . . // Move the now empty table back to its original location. 1,112 ( 0.00%) self.orig_table . .as_ptr() . .copy_from_nonoverlapping(&*self.table, 1); . } 8,896 ( 0.00%) } . } . . impl Iterator for RawDrain<'_, T, A> { . type Item = T; . . #[cfg_attr(feature = "inline-more", inline)] . fn next(&mut self) -> Option { . unsafe { -- line 2289 ---------------------------------------- 51,417,114 ( 0.19%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/library/proc_macro/src/bridge/client.rs -------------------------------------------------------------------------------- Ir -- line 18 ---------------------------------------- . // FIXME(eddyb) use a reference to the `static COUNTERS`, instead of . // a wrapper `fn` pointer, once `const fn` can reference `static`s. . extern "C" fn get() -> &'static Self { . static COUNTERS: HandleCounters = HandleCounters { . $($oty: AtomicUsize::new(1),)* . $($ity: AtomicUsize::new(1),)* . }; . &COUNTERS 196 ( 0.00%) } . } . . // FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`. . #[repr(C)] . #[allow(non_snake_case)] . pub(super) struct HandleStore { . $($oty: handle::OwnedStore,)* . $($ity: handle::InternedStore,)* . } . . impl HandleStore { 588 ( 0.00%) pub(super) fn new(handle_counters: &'static HandleCounters) -> Self { 5,782 ( 0.00%) HandleStore { . $($oty: handle::OwnedStore::new(&handle_counters.$oty),)* . $($ity: handle::InternedStore::new(&handle_counters.$ity),)* . } 784 ( 0.00%) } . } . . $( . #[repr(C)] . pub(crate) struct $oty(handle::Handle); . impl !Send for $oty {} . impl !Sync for $oty {} . . // Forward `Drop::drop` to the inherent `drop` method. . impl Drop for $oty { 17,752 ( 0.00%) fn drop(&mut self) { 106,120 ( 0.00%) $oty(self.0).drop(); 26,628 ( 0.00%) } . } . . impl Encode for $oty { . fn encode(self, w: &mut Writer, s: &mut S) { . let handle = self.0; . mem::forget(self); . handle.encode(w, s); . } . } . . impl DecodeMut<'_, '_, HandleStore>> . for Marked . { 891,432 ( 0.00%) fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { . s.$oty.take(handle::Handle::decode(r, &mut ())) 1,188,576 ( 0.00%) } . } . . impl Encode for &$oty { . fn encode(self, w: &mut Writer, s: &mut S) { 192,192 ( 0.00%) self.0.encode(w, s); . } . } . . impl<'s, S: server::Types> Decode<'_, 's, HandleStore>> . for &'s Marked . { 64,064 ( 0.00%) fn decode(r: &mut Reader<'_>, s: &'s HandleStore>) -> Self { . &s.$oty[handle::Handle::decode(r, &mut ())] 128,128 ( 0.00%) } . } . . impl Encode for &mut $oty { . fn encode(self, w: &mut Writer, s: &mut S) { 705,102 ( 0.00%) self.0.encode(w, s); . } . } . . impl<'s, S: server::Types> DecodeMut<'_, 's, HandleStore>> . for &'s mut Marked . { 235,034 ( 0.00%) fn decode( . r: &mut Reader<'_>, . s: &'s mut HandleStore> . ) -> Self { . &mut s.$oty[handle::Handle::decode(r, &mut ())] 470,068 ( 0.00%) } . } . . impl Encode>> . for Marked . { 1,767,730 ( 0.01%) fn encode(self, w: &mut Writer, s: &mut HandleStore>) { 299,890 ( 0.00%) s.$oty.alloc(self).encode(w, s); . } . } . . impl DecodeMut<'_, '_, S> for $oty { . fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { . $oty(handle::Handle::decode(r, s)) . } . } -- line 118 ---------------------------------------- -- line 129 ---------------------------------------- . fn encode(self, w: &mut Writer, s: &mut S) { . self.0.encode(w, s); . } . } . . impl DecodeMut<'_, '_, HandleStore>> . for Marked . { 263,506 ( 0.00%) fn decode(r: &mut Reader<'_>, s: &mut HandleStore>) -> Self { . s.$ity.copy(handle::Handle::decode(r, &mut ())) 527,012 ( 0.00%) } . } . . impl Encode>> . for Marked . { . fn encode(self, w: &mut Writer, s: &mut HandleStore>) { 2,134,673 ( 0.01%) s.$ity.alloc(self).encode(w, s); . } . } . . impl DecodeMut<'_, '_, S> for $ity { . fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { . $ity(handle::Handle::decode(r, s)) . } . } -- line 154 ---------------------------------------- -- line 175 ---------------------------------------- . . // FIXME(eddyb) generate these impls by pattern-matching on the . // names of methods - also could use the presence of `fn drop` . // to distinguish between 'owned and 'interned, above. . // Alternatively, special 'modes" could be listed of types in with_api . // instead of pattern matching on methods, here and in server decl. . . impl Clone for TokenStream { 30,078 ( 0.00%) fn clone(&self) -> Self { . self.clone() 30,078 ( 0.00%) } . } . . impl Clone for TokenStreamIter { . fn clone(&self) -> Self { . self.clone() . } . } . . impl Clone for Group { 15,840 ( 0.00%) fn clone(&self) -> Self { . self.clone() 15,840 ( 0.00%) } . } . . impl Clone for Literal { 4,773 ( 0.00%) fn clone(&self) -> Self { . self.clone() 4,773 ( 0.00%) } . } . . impl fmt::Debug for Literal { . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { . f.debug_struct("Literal") . // format the kind without quotes, as in `kind: Float` . .field("kind", &format_args!("{}", &self.debug_kind())) . .field("symbol", &self.symbol()) -- line 211 ---------------------------------------- -- line 219 ---------------------------------------- . impl Clone for SourceFile { . fn clone(&self) -> Self { . self.clone() . } . } . . impl fmt::Debug for Span { . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 49,020 ( 0.00%) f.write_str(&self.debug()) . } . } . . macro_rules! define_client_side { . ($($name:ident { . $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)* . }),* $(,)?) => { . $(impl $name { 1,184,172 ( 0.00%) $(pub(crate) fn $method($($arg: $arg_ty),*) $(-> $ret_ty)* { 605,943 ( 0.00%) Bridge::with(|bridge| { . let mut b = bridge.cached_buffer.take(); . . b.clear(); 3,386,706 ( 0.01%) api_tags::Method::$name(api_tags::$name::$method).encode(&mut b, &mut ()); 902,752 ( 0.00%) reverse_encode!(b; $($arg),*); . 6,773,412 ( 0.02%) b = bridge.dispatch.call(b); . 4,755,040 ( 0.02%) let r = Result::<_, PanicMessage>::decode(&mut &b[..], &mut ()); . 13,546,824 ( 0.05%) bridge.cached_buffer = b; . 1,699,887 ( 0.01%) r.unwrap_or_else(|e| panic::resume_unwind(e.into())) . }) 986,810 ( 0.00%) })* . })* . } . } . with_api!(self, self, define_client_side); . . enum BridgeState<'a> { . /// No server is currently connected to this client. . NotConnected, -- line 260 ---------------------------------------- -- line 281 ---------------------------------------- . impl BridgeState<'_> { . /// Take exclusive control of the thread-local . /// `BridgeState`, and pass it to `f`, mutably. . /// The state will be restored after `f` exits, even . /// by panic, including modifications made to it by `f`. . /// . /// N.B., while `f` is running, the thread-local state . /// is `BridgeState::InUse`. 605,755 ( 0.00%) fn with(f: impl FnOnce(&mut BridgeState<'_>) -> R) -> R { 589,108 ( 0.00%) BRIDGE_STATE.with(|state| { 6,109,249 ( 0.02%) state.replace(BridgeState::InUse, |mut state| { . // FIXME(#52812) pass `f` directly to `replace` when `RefMutL` is gone . f(&mut *state) . }) . }) 517,387 ( 0.00%) } . } . . impl Bridge<'_> { . pub(crate) fn is_available() -> bool { 6 ( 0.00%) BridgeState::with(|state| match state { . BridgeState::Connected(_) | BridgeState::InUse => true, . BridgeState::NotConnected => false, . }) . } . . fn enter(self, f: impl FnOnce() -> R) -> R { . let force_show_panics = self.force_show_panics; . // Hide the default panic output within `proc_macro` expansions. -- line 309 ---------------------------------------- -- line 320 ---------------------------------------- . } . }); . }); . . BRIDGE_STATE.with(|state| state.set(BridgeState::Connected(self), f)) . } . . fn with(f: impl FnOnce(&mut Bridge<'_>) -> R) -> R { 7,990,682 ( 0.03%) BridgeState::with(|state| match state { . BridgeState::NotConnected => { . panic!("procedural macro API is used outside of a procedural macro"); . } . BridgeState::InUse => { . panic!("procedural macro API is used while it's already in use"); . } . BridgeState::Connected(bridge) => f(bridge), . }) -- line 336 ---------------------------------------- -- line 396 ---------------------------------------- . b.clear(); . Err::<(), _>(e).encode(&mut b, &mut ()); . }); . b . } . . impl Client crate::TokenStream> { . #[rustc_allow_const_fn_unstable(const_fn)] 1 ( 0.00%) pub const fn expand1(f: fn(crate::TokenStream) -> crate::TokenStream) -> Self { . extern "C" fn run( . bridge: Bridge<'_>, . f: impl FnOnce(crate::TokenStream) -> crate::TokenStream, . ) -> Buffer { . run_client(bridge, |input| f(crate::TokenStream(input)).0) . } 5 ( 0.00%) Client { get_handle_counters: HandleCounters::get, run, f } 1 ( 0.00%) } . } . . impl Client crate::TokenStream> { . #[rustc_allow_const_fn_unstable(const_fn)] . pub const fn expand2( . f: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream, . ) -> Self { . extern "C" fn run( -- line 420 ---------------------------------------- 2,937,311 ( 0.01%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/compiler/rustc_infer/src/infer/mod.rs -------------------------------------------------------------------------------- Ir -- line 108 ---------------------------------------- . suppress_errors: bool, . }, . } . . impl RegionckMode { . /// Indicates that the MIR borrowck will repeat these region . /// checks, so we should ignore errors if NLL is (unconditionally) . /// enabled. 1,185 ( 0.00%) pub fn for_item_body(tcx: TyCtxt<'_>) -> Self { . // FIXME(Centril): Once we actually remove `::Migrate` also make . // this always `true` and then proceed to eliminate the dead code. 1,185 ( 0.00%) match tcx.borrowck_mode() { . // If we're on Migrate mode, report AST region errors . BorrowckMode::Migrate => RegionckMode::Erase { suppress_errors: false }, . . // If we're on MIR, don't report AST region errors as they should be reported by NLL . BorrowckMode::Mir => RegionckMode::Erase { suppress_errors: true }, . } 2,370 ( 0.00%) } . } . . /// This type contains all the things within `InferCtxt` that sit within a . /// `RefCell` and are involved with taking/rolling back snapshots. Snapshot . /// operations are hot enough that we want only one call to `borrow_mut` per . /// call to `start_snapshot` and `rollback_to`. . pub struct InferCtxtInner<'tcx> { . /// Cache for projections. This cache is snapshotted along with the infcx. -- line 134 ---------------------------------------- -- line 202 ---------------------------------------- . /// type instantiations (`ty::Infer`) to the actual opaque . /// type (`ty::Opaque`). Used during fallback to map unconstrained . /// opaque type inference variables to their corresponding . /// opaque type. . pub opaque_types_vars: FxHashMap, Ty<'tcx>>, . } . . impl<'tcx> InferCtxtInner<'tcx> { 228,245 ( 0.00%) fn new() -> InferCtxtInner<'tcx> { 1,552,066 ( 0.01%) InferCtxtInner { . projection_cache: Default::default(), . type_variable_storage: type_variable::TypeVariableStorage::new(), . undo_log: InferCtxtUndoLogs::default(), . const_unification_storage: ut::UnificationTableStorage::new(), . int_unification_storage: ut::UnificationTableStorage::new(), . float_unification_storage: ut::UnificationTableStorage::new(), 136,947 ( 0.00%) region_constraint_storage: Some(RegionConstraintStorage::new()), . region_obligations: vec![], . opaque_types: Default::default(), . opaque_types_vars: Default::default(), . } 273,894 ( 0.00%) } . . #[inline] . pub fn region_obligations(&self) -> &[(hir::HirId, RegionObligation<'tcx>)] { . &self.region_obligations . } . . #[inline] . pub fn projection_cache(&mut self) -> traits::ProjectionCache<'_, 'tcx> { 43,189 ( 0.00%) self.projection_cache.with_log(&mut self.undo_log) . } . . #[inline] . fn type_variables(&mut self) -> type_variable::TypeVariableTable<'_, 'tcx> { 2,291,891 ( 0.01%) self.type_variable_storage.with_log(&mut self.undo_log) . } . . #[inline] . fn int_unification_table( . &mut self, . ) -> ut::UnificationTable< . ut::InPlace< . ty::IntVid, . &mut ut::UnificationStorage, . &mut InferCtxtUndoLogs<'tcx>, . >, . > { 12,943 ( 0.00%) self.int_unification_storage.with_log(&mut self.undo_log) . } . . #[inline] . fn float_unification_table( . &mut self, . ) -> ut::UnificationTable< . ut::InPlace< . ty::FloatVid, -- line 258 ---------------------------------------- -- line 268 ---------------------------------------- . &mut self, . ) -> ut::UnificationTable< . ut::InPlace< . ty::ConstVid<'tcx>, . &mut ut::UnificationStorage>, . &mut InferCtxtUndoLogs<'tcx>, . >, . > { 7,912 ( 0.00%) self.const_unification_storage.with_log(&mut self.undo_log) . } . . #[inline] . pub fn unwrap_region_constraints(&mut self) -> RegionConstraintCollector<'_, 'tcx> { 290,340 ( 0.00%) self.region_constraint_storage . .as_mut() . .expect("region constraints already solved") 371,594 ( 0.00%) .with_log(&mut self.undo_log) . } . } . . pub struct InferCtxt<'a, 'tcx> { . pub tcx: TyCtxt<'tcx>, . . /// The `DefId` of the item in whose context we are performing inference or typeck. . /// It is used to check whether an opaque type use is a defining use. -- line 292 ---------------------------------------- -- line 361 ---------------------------------------- . /// item we are type-checking, and just consider those names as . /// part of the root universe. So this would only get incremented . /// when we enter into a higher-ranked (`for<..>`) type or trait . /// bound. . universe: Cell, . } . . /// See the `error_reporting` module for more details. 610,544 ( 0.00%) #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable)] . pub enum ValuePairs<'tcx> { . Types(ExpectedFound>), . Regions(ExpectedFound>), . Consts(ExpectedFound<&'tcx ty::Const<'tcx>>), . TraitRefs(ExpectedFound>), . PolyTraitRefs(ExpectedFound>), . } . -- line 377 ---------------------------------------- -- line 383 ---------------------------------------- . pub struct TypeTrace<'tcx> { . cause: ObligationCause<'tcx>, . values: ValuePairs<'tcx>, . } . . /// The origin of a `r1 <= r2` constraint. . /// . /// See `error_reporting` module for more details 539,414 ( 0.00%) #[derive(Clone, Debug)] . pub enum SubregionOrigin<'tcx> { . /// Arose from a subtyping relation 31,125 ( 0.00%) Subtype(Box>), . . /// When casting `&'a T` to an `&'b Trait` object, . /// relating `'a` to `'b` . RelateObjectBound(Span), . . /// Some type parameter was instantiated with the given type, . /// and that type must outlive some region. 4,103 ( 0.00%) RelateParamBound(Span, Ty<'tcx>, Option), . . /// The given region parameter was instantiated with a region . /// that must outlive some other region. . RelateRegionParamBound(Span), . . /// Creating a pointer `b` to contents of another reference . Reborrow(Span), . . /// Creating a pointer `b` to contents of an upvar . ReborrowUpvar(Span, ty::UpvarId), . . /// Data with type `Ty<'tcx>` was borrowed 4,521 ( 0.00%) DataBorrowed(Ty<'tcx>, Span), . . /// (&'a &'b T) where a >= b 3,036 ( 0.00%) ReferenceOutlivesReferent(Ty<'tcx>, Span), . . /// Comparing the signature and requirements of an impl method against . /// the containing trait. . CompareImplMethodObligation { span: Span, impl_item_def_id: DefId, trait_item_def_id: DefId }, . . /// Comparing the signature and requirements of an impl associated type . /// against the containing trait . CompareImplTypeObligation { span: Span, impl_item_def_id: DefId, trait_item_def_id: DefId }, -- line 426 ---------------------------------------- -- line 554 ---------------------------------------- . defining_use_anchor: Option, . } . . pub trait TyCtxtInferExt<'tcx> { . fn infer_ctxt(self) -> InferCtxtBuilder<'tcx>; . } . . impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> { 45,649 ( 0.00%) fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> { 136,947 ( 0.00%) InferCtxtBuilder { tcx: self, defining_use_anchor: None, fresh_typeck_results: None } 45,649 ( 0.00%) } . } . . impl<'tcx> InferCtxtBuilder<'tcx> { . /// Used only by `rustc_typeck` during body type-checking/inference, . /// will initialize `in_progress_typeck_results` with fresh `TypeckResults`. . /// Will also change the scope for opaque type defining use checks to the given owner. 30,924 ( 0.00%) pub fn with_fresh_in_progress_typeck_results(mut self, table_owner: LocalDefId) -> Self { 37,796 ( 0.00%) self.fresh_typeck_results = Some(RefCell::new(ty::TypeckResults::new(table_owner))); 17,180 ( 0.00%) self.with_opaque_type_inference(table_owner) 24,052 ( 0.00%) } . . /// Whenever the `InferCtxt` should be able to handle defining uses of opaque types, . /// you need to call this function. Otherwise the opaque type will be treated opaquely. . /// . /// It is only meant to be called in two places, for typeck . /// (via `with_fresh_in_progress_typeck_results`) and for the inference context used . /// in mir borrowck. 2,452 ( 0.00%) pub fn with_opaque_type_inference(mut self, defining_use_anchor: LocalDefId) -> Self { 1,226 ( 0.00%) self.defining_use_anchor = Some(defining_use_anchor); 9,324 ( 0.00%) self 3,678 ( 0.00%) } . . /// Given a canonical value `C` as a starting point, create an . /// inference context that contains each of the bound values . /// within instantiated as a fresh variable. The `f` closure is . /// invoked with the new infcx, along with the instantiated value . /// `V` and a substitution `S`. This substitution `S` maps from . /// the bound values in `C` to their instantiated values in `V` . /// (in other words, `S(C) = V`). 76,857 ( 0.00%) pub fn enter_with_canonical( . &mut self, . span: Span, . canonical: &Canonical<'tcx, T>, . f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>, T, CanonicalVarValues<'tcx>) -> R, . ) -> R . where . T: TypeFoldable<'tcx>, . { . self.enter(|infcx| { 105,158 ( 0.00%) let (value, subst) = 6,421 ( 0.00%) infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical); 151,760 ( 0.00%) f(infcx, value, subst) . }) 83,556 ( 0.00%) } . 250,353 ( 0.00%) pub fn enter(&mut self, f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>) -> R) -> R { 129,709 ( 0.00%) let InferCtxtBuilder { tcx, defining_use_anchor, ref fresh_typeck_results } = *self; . let in_progress_typeck_results = fresh_typeck_results.as_ref(); 1,921,103 ( 0.01%) f(InferCtxt { . tcx, . defining_use_anchor, . in_progress_typeck_results, 45,649 ( 0.00%) inner: RefCell::new(InferCtxtInner::new()), . lexical_region_resolutions: RefCell::new(None), . selection_cache: Default::default(), . evaluation_cache: Default::default(), . reported_trait_errors: Default::default(), . reported_closure_mismatch: Default::default(), . tainted_by_errors_flag: Cell::new(false), 45,649 ( 0.00%) err_count_on_creation: tcx.sess.err_count(), . in_snapshot: Cell::new(false), . skip_leak_check: Cell::new(false), . universe: Cell::new(ty::UniverseIndex::ROOT), . }) 271,477 ( 0.00%) } . } . . impl<'tcx, T> InferOk<'tcx, T> { . pub fn unit(self) -> InferOk<'tcx, ()> { . InferOk { value: (), obligations: self.obligations } . } . . /// Extracts `value`, registering any obligations into `fulfill_cx`. . pub fn into_value_registering_obligations( . self, . infcx: &InferCtxt<'_, 'tcx>, . fulfill_cx: &mut dyn TraitEngine<'tcx>, . ) -> T { 3,285 ( 0.00%) let InferOk { value, obligations } = self; 11,834 ( 0.00%) for obligation in obligations { . fulfill_cx.register_predicate_obligation(infcx, obligation); . } . value . } . } . . impl<'tcx> InferOk<'tcx, ()> { 59,215 ( 0.00%) pub fn into_obligations(self) -> PredicateObligations<'tcx> { 236,860 ( 0.00%) self.obligations 59,215 ( 0.00%) } . } . . #[must_use = "once you start a snapshot, you should always consume it"] . pub struct CombinedSnapshot<'a, 'tcx> { . undo_snapshot: Snapshot<'tcx>, . region_constraints_snapshot: RegionSnapshot, . universe: ty::UniverseIndex, . was_in_snapshot: bool, -- line 662 ---------------------------------------- -- line 674 ---------------------------------------- . let canonical = self.canonicalize_query((a, b), &mut OriginalQueryValues::default()); . debug!("canonical consts: {:?}", &canonical.value); . . self.tcx.try_unify_abstract_consts(canonical.value) . } . . pub fn is_in_snapshot(&self) -> bool { . self.in_snapshot.get() 95,709 ( 0.00%) } . 699,680 ( 0.00%) pub fn freshen>(&self, t: T) -> T { 787,140 ( 0.00%) t.fold_with(&mut self.freshener()) 787,140 ( 0.00%) } . . /// Returns the origin of the type variable identified by `vid`, or `None` . /// if this is not a type variable. . /// . /// No attempt is made to resolve `ty`. 2,124 ( 0.00%) pub fn type_var_origin(&'a self, ty: Ty<'tcx>) -> Option { 4,248 ( 0.00%) match *ty.kind() { 1,062 ( 0.00%) ty::Infer(ty::TyVar(vid)) => { 4,248 ( 0.00%) Some(*self.inner.borrow_mut().type_variables().var_origin(vid)) . } . _ => None, . } 4,248 ( 0.00%) } . 87,460 ( 0.00%) pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx> { . freshen::TypeFreshener::new(self, false) 87,460 ( 0.00%) } . . /// Like `freshener`, but does not replace `'static` regions. 288,036 ( 0.00%) pub fn freshener_keep_static<'b>(&'b self) -> TypeFreshener<'b, 'tcx> { . freshen::TypeFreshener::new(self, true) 288,036 ( 0.00%) } . 5,280 ( 0.00%) pub fn unsolved_variables(&self) -> Vec> { 2,640 ( 0.00%) let mut inner = self.inner.borrow_mut(); 2,640 ( 0.00%) let mut vars: Vec> = inner . .type_variables() . .unsolved_variables() . .into_iter() 2,124 ( 0.00%) .map(|t| self.tcx.mk_ty_var(t)) . .collect(); . vars.extend( . (0..inner.int_unification_table().len()) . .map(|i| ty::IntVid { index: i as u32 }) 1,338 ( 0.00%) .filter(|&vid| inner.int_unification_table().probe_value(vid).is_none()) . .map(|v| self.tcx.mk_int_var(v)), . ); . vars.extend( . (0..inner.float_unification_table().len()) . .map(|i| ty::FloatVid { index: i as u32 }) . .filter(|&vid| inner.float_unification_table().probe_value(vid).is_none()) . .map(|v| self.tcx.mk_float_var(v)), . ); . vars 9,240 ( 0.00%) } . 161,980 ( 0.00%) fn combine_fields( . &'a self, . trace: TypeTrace<'tcx>, . param_env: ty::ParamEnv<'tcx>, . ) -> CombineFields<'a, 'tcx> { 649,800 ( 0.00%) CombineFields { . infcx: self, 1,624,500 ( 0.01%) trace, . cause: None, . param_env, . obligations: PredicateObligations::new(), . } 161,980 ( 0.00%) } . . /// Clear the "currently in a snapshot" flag, invoke the closure, . /// then restore the flag to its original value. This flag is a . /// debugging measure designed to detect cases where we start a . /// snapshot, create type variables, and register obligations . /// which may involve those type variables in the fulfillment cx, . /// potentially leaving "dangling type variables" behind. . /// In such cases, an assertion will fail when attempting to -- line 753 ---------------------------------------- -- line 755 ---------------------------------------- . /// better than grovelling through megabytes of `RUSTC_LOG` output. . /// . /// HOWEVER, in some cases the flag is unhelpful. In particular, we . /// sometimes create a "mini-fulfilment-cx" in which we enroll . /// obligations. As long as this fulfillment cx is fully drained . /// before we return, this is not a problem, as there won't be any . /// escaping obligations in the main cx. In those cases, you can . /// use this function. 168 ( 0.00%) pub fn save_and_restore_in_snapshot_flag(&self, func: F) -> R . where . F: FnOnce(&Self) -> R, . { . let flag = self.in_snapshot.replace(false); 41,427 ( 0.00%) let result = func(self); . self.in_snapshot.set(flag); . result 189 ( 0.00%) } . 861,074 ( 0.00%) fn start_snapshot(&self) -> CombinedSnapshot<'a, 'tcx> { . debug!("start_snapshot()"); . . let in_snapshot = self.in_snapshot.replace(true); . . let mut inner = self.inner.borrow_mut(); . 2,583,222 ( 0.01%) CombinedSnapshot { . undo_snapshot: inner.undo_log.start_snapshot(), . region_constraints_snapshot: inner.unwrap_region_constraints().start_snapshot(), . universe: self.universe(), . was_in_snapshot: in_snapshot, . // Borrow typeck results "in progress" (i.e., during typeck) . // to ban writes from within a snapshot to them. 430,537 ( 0.00%) _in_progress_typeck_results: self . .in_progress_typeck_results . .map(|typeck_results| typeck_results.borrow()), . } 1,722,148 ( 0.01%) } . 1,250,282 ( 0.00%) #[instrument(skip(self, snapshot), level = "debug")] . fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot<'a, 'tcx>) { . let CombinedSnapshot { 113,662 ( 0.00%) undo_snapshot, 113,662 ( 0.00%) region_constraints_snapshot, 113,662 ( 0.00%) universe, 113,662 ( 0.00%) was_in_snapshot, 227,324 ( 0.00%) _in_progress_typeck_results, . } = snapshot; . . self.in_snapshot.set(was_in_snapshot); . self.universe.set(universe); . . let mut inner = self.inner.borrow_mut(); 113,662 ( 0.00%) inner.rollback_to(undo_snapshot); . inner.unwrap_region_constraints().rollback_to(region_constraints_snapshot); . } . 4,753,125 ( 0.02%) #[instrument(skip(self, snapshot), level = "debug")] . fn commit_from(&self, snapshot: CombinedSnapshot<'a, 'tcx>) { . let CombinedSnapshot { 316,875 ( 0.00%) undo_snapshot, . region_constraints_snapshot: _, . universe: _, 316,875 ( 0.00%) was_in_snapshot, 633,750 ( 0.00%) _in_progress_typeck_results, . } = snapshot; . . self.in_snapshot.set(was_in_snapshot); . . self.inner.borrow_mut().commit(undo_snapshot); . } . . /// Executes `f` and commit the bindings. 245,771 ( 0.00%) #[instrument(skip(self, f), level = "debug")] 313,333 ( 0.00%) pub fn commit_unconditionally(&self, f: F) -> R . where . F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R, . { 28,487 ( 0.00%) let snapshot = self.start_snapshot(); 117,250 ( 0.00%) let r = f(&snapshot); 199,393 ( 0.00%) self.commit_from(snapshot); 220,014 ( 0.00%) r . } . . /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`. 1,949,520 ( 0.01%) #[instrument(skip(self, f), level = "debug")] 2,401,074 ( 0.01%) pub fn commit_if_ok(&self, f: F) -> Result . where . F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> Result, . { 373,153 ( 0.00%) let snapshot = self.start_snapshot(); 1,106,807 ( 0.00%) let r = f(&snapshot); . debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok()); 340,840 ( 0.00%) match r { . Ok(_) => { 2,093,598 ( 0.01%) self.commit_from(snapshot); . } . Err(_) => { 405,233 ( 0.00%) self.rollback_to("commit_if_ok -- error", snapshot); . } . } 1,968,792 ( 0.01%) r . } . . /// Execute `f` then unroll any bindings it creates. 470,427 ( 0.00%) #[instrument(skip(self, f), level = "debug")] 540,764 ( 0.00%) pub fn probe(&self, f: F) -> R . where . F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R, . { 142,640 ( 0.00%) let snapshot = self.start_snapshot(); 205,751 ( 0.00%) let r = f(&snapshot); 663,509 ( 0.00%) self.rollback_to("probe", snapshot); 134,960 ( 0.00%) r . } . . /// If `should_skip` is true, then execute `f` then unroll any bindings it creates. 846 ( 0.00%) #[instrument(skip(self, f), level = "debug")] 1,128 ( 0.00%) pub fn probe_maybe_skip_leak_check(&self, should_skip: bool, f: F) -> R . where . F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R, . { 188 ( 0.00%) let snapshot = self.start_snapshot(); 94 ( 0.00%) let was_skip_leak_check = self.skip_leak_check.get(); 188 ( 0.00%) if should_skip { . self.skip_leak_check.set(true); . } 376 ( 0.00%) let r = f(&snapshot); 846 ( 0.00%) self.rollback_to("probe", snapshot); . self.skip_leak_check.set(was_skip_leak_check); 1,128 ( 0.00%) r . } . . /// Scan the constraints produced since `snapshot` began and returns: . /// . /// - `None` -- if none of them involve "region outlives" constraints . /// - `Some(true)` -- if there are `'a: 'b` constraints where `'a` or `'b` is a placeholder . /// - `Some(false)` -- if there are `'a: 'b` constraints but none involve placeholders 49,764 ( 0.00%) pub fn region_constraints_added_in_snapshot( . &self, . snapshot: &CombinedSnapshot<'a, 'tcx>, . ) -> Option { 99,528 ( 0.00%) self.inner . .borrow_mut() . .unwrap_region_constraints() . .region_constraints_added_in_snapshot(&snapshot.undo_snapshot) 74,646 ( 0.00%) } . . pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) { . self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup); . } . 20,928 ( 0.00%) pub fn can_sub(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx> . where . T: at::ToTrace<'tcx>, . { . let origin = &ObligationCause::dummy(); . self.probe(|_| { . self.at(origin, param_env).sub(a, b).map(|InferOk { obligations: _, .. }| { . // Ignore obligations, since we are unrolling . // everything anyway. . }) . }) 15,696 ( 0.00%) } . 15,468 ( 0.00%) pub fn can_eq(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx> . where . T: at::ToTrace<'tcx>, . { . let origin = &ObligationCause::dummy(); . self.probe(|_| { . self.at(origin, param_env).eq(a, b).map(|InferOk { obligations: _, .. }| { . // Ignore obligations, since we are unrolling . // everything anyway. . }) . }) 11,601 ( 0.00%) } . 167,870 ( 0.00%) #[instrument(skip(self), level = "debug")] . pub fn sub_regions( . &self, . origin: SubregionOrigin<'tcx>, . a: ty::Region<'tcx>, . b: ty::Region<'tcx>, . ) { 151,083 ( 0.00%) self.inner.borrow_mut().unwrap_region_constraints().make_subregion(origin, a, b); . } . . /// Require that the region `r` be equal to one of the regions in . /// the set `regions`. . #[instrument(skip(self), level = "debug")] . pub fn member_constraint( . &self, . opaque_type_def_id: DefId, -- line 947 ---------------------------------------- -- line 969 ---------------------------------------- . /// to `subtype_predicate` -- that is, "coercing" `a` to `b` winds up . /// actually requiring `a <: b`. This is of course a valid coercion, . /// but it's not as flexible as `FnCtxt::coerce` would be. . /// . /// (We may refactor this in the future, but there are a number of . /// practical obstacles. Among other things, `FnCtxt::coerce` presently . /// records adjustments that are required on the HIR in order to perform . /// the coercion, and we don't currently have a way to manage that.) 1,134 ( 0.00%) pub fn coerce_predicate( . &self, . cause: &ObligationCause<'tcx>, . param_env: ty::ParamEnv<'tcx>, . predicate: ty::PolyCoercePredicate<'tcx>, . ) -> Option> { 756 ( 0.00%) let subtype_predicate = predicate.map_bound(|p| ty::SubtypePredicate { . a_is_expected: false, // when coercing from `a` to `b`, `b` is expected . a: p.a, . b: p.b, . }); 1,890 ( 0.00%) self.subtype_predicate(cause, param_env, subtype_predicate) 1,512 ( 0.00%) } . 24,948 ( 0.00%) pub fn subtype_predicate( . &self, . cause: &ObligationCause<'tcx>, . param_env: ty::ParamEnv<'tcx>, . predicate: ty::PolySubtypePredicate<'tcx>, . ) -> Option> { . // Check for two unresolved inference variables, in which case we can . // make no progress. This is partly a micro-optimization, but it's . // also an opportunity to "sub-unify" the variables. This isn't -- line 999 ---------------------------------------- -- line 1002 ---------------------------------------- . // earlier that they are sub-unified). . // . // Note that we can just skip the binders here because . // type variables can't (at present, at . // least) capture any of the things bound by this binder. . // . // Note that this sub here is not just for diagnostics - it has semantic . // effects as well. 2,079 ( 0.00%) let r_a = self.shallow_resolve(predicate.skip_binder().a); 2,079 ( 0.00%) let r_b = self.shallow_resolve(predicate.skip_binder().b); 15,082 ( 0.00%) match (r_a.kind(), r_b.kind()) { 3,406 ( 0.00%) (&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => { . self.inner.borrow_mut().type_variables().sub(a_vid, b_vid); 3,406 ( 0.00%) return None; . } . _ => {} . } . . Some(self.commit_if_ok(|_snapshot| { 376 ( 0.00%) let ty::SubtypePredicate { a_is_expected, a, b } = . self.replace_bound_vars_with_placeholders(predicate); . 752 ( 0.00%) let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?; . . Ok(ok.unit()) . })) 18,711 ( 0.00%) } . 42,840 ( 0.00%) pub fn region_outlives_predicate( . &self, . cause: &traits::ObligationCause<'tcx>, . predicate: ty::PolyRegionOutlivesPredicate<'tcx>, . ) -> UnitResult<'tcx> { . self.commit_if_ok(|_snapshot| { . let ty::OutlivesPredicate(r_a, r_b) = . self.replace_bound_vars_with_placeholders(predicate); . let origin = SubregionOrigin::from_obligation_cause(cause, || { . RelateRegionParamBound(cause.span) . }); 35,700 ( 0.00%) self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b` . Ok(()) . }) 28,560 ( 0.00%) } . . /// Number of type variables created so far. 135 ( 0.00%) pub fn num_ty_vars(&self) -> usize { . self.inner.borrow_mut().type_variables().num_vars() 270 ( 0.00%) } . 76,390 ( 0.00%) pub fn next_ty_var_id(&self, origin: TypeVariableOrigin) -> TyVid { 381,950 ( 0.00%) self.inner.borrow_mut().type_variables().new_var(self.universe(), origin) 114,585 ( 0.00%) } . 63,958 ( 0.00%) pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { 261,149 ( 0.00%) self.tcx.mk_ty_var(self.next_ty_var_id(origin)) 95,937 ( 0.00%) } . 6,854 ( 0.00%) pub fn next_ty_var_in_universe( . &self, . origin: TypeVariableOrigin, . universe: ty::UniverseIndex, . ) -> Ty<'tcx> { 37,697 ( 0.00%) let vid = self.inner.borrow_mut().type_variables().new_var(universe, origin); 3,427 ( 0.00%) self.tcx.mk_ty_var(vid) 10,281 ( 0.00%) } . . pub fn next_const_var( . &self, . ty: Ty<'tcx>, . origin: ConstVariableOrigin, . ) -> &'tcx ty::Const<'tcx> { . self.tcx.mk_const_var(self.next_const_var_id(origin), ty) . } -- line 1074 ---------------------------------------- -- line 1090 ---------------------------------------- . pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid<'tcx> { . self.inner.borrow_mut().const_unification_table().new_key(ConstVarValue { . origin, . val: ConstVariableValue::Unknown { universe: self.universe() }, . }) . } . . fn next_int_var_id(&self) -> IntVid { 1,685 ( 0.00%) self.inner.borrow_mut().int_unification_table().new_key(None) . } . 1,011 ( 0.00%) pub fn next_int_var(&self) -> Ty<'tcx> { . self.tcx.mk_int_var(self.next_int_var_id()) 1,348 ( 0.00%) } . . fn next_float_var_id(&self) -> FloatVid { . self.inner.borrow_mut().float_unification_table().new_key(None) . } . . pub fn next_float_var(&self) -> Ty<'tcx> { . self.tcx.mk_float_var(self.next_float_var_id()) . } . . /// Creates a fresh region variable with the next available index. . /// The variable will be created in the maximum universe created . /// thus far, allowing it to name any region created thus far. 28,841 ( 0.00%) pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region<'tcx> { 611,369 ( 0.00%) self.next_region_var_in_universe(origin, self.universe()) 57,682 ( 0.00%) } . . /// Creates a fresh region variable with the next available index . /// in the given universe; typically, you can use . /// `next_region_var` and just use the maximal universe. 259,080 ( 0.00%) pub fn next_region_var_in_universe( . &self, . origin: RegionVariableOrigin, . universe: ty::UniverseIndex, . ) -> ty::Region<'tcx> { . let region_var = 1,684,020 ( 0.01%) self.inner.borrow_mut().unwrap_region_constraints().new_region_var(universe, origin); 647,700 ( 0.00%) self.tcx.mk_region(ty::ReVar(region_var)) 388,620 ( 0.00%) } . . /// Return the universe that the region `r` was created in. For . /// most regions (e.g., `'static`, named regions from the user, . /// etc) this is the root universe U0. For inference variables or . /// placeholders, however, it will return the universe which which . /// they are associated. 40,546 ( 0.00%) pub fn universe_of_region(&self, r: ty::Region<'tcx>) -> ty::UniverseIndex { . self.inner.borrow_mut().unwrap_region_constraints().universe(r) 60,819 ( 0.00%) } . . /// Number of region variables created so far. 9,890 ( 0.00%) pub fn num_region_vars(&self) -> usize { . self.inner.borrow_mut().unwrap_region_constraints().num_region_vars() 14,835 ( 0.00%) } . . /// Just a convenient wrapper of `next_region_var` for using during NLL. 51,133 ( 0.00%) pub fn next_nll_region_var(&self, origin: NllRegionVariableOrigin) -> ty::Region<'tcx> { . self.next_region_var(RegionVariableOrigin::Nll(origin)) 102,266 ( 0.00%) } . . /// Just a convenient wrapper of `next_region_var` for using during NLL. 230 ( 0.00%) pub fn next_nll_region_var_in_universe( . &self, . origin: NllRegionVariableOrigin, . universe: ty::UniverseIndex, . ) -> ty::Region<'tcx> { 2,562 ( 0.00%) self.next_region_var_in_universe(RegionVariableOrigin::Nll(origin), universe) 460 ( 0.00%) } . 489,960 ( 0.00%) pub fn var_for_def(&self, span: Span, param: &ty::GenericParamDef) -> GenericArg<'tcx> { 267,879 ( 0.00%) match param.kind { . GenericParamDefKind::Lifetime => { . // Create a region inference variable for the given . // region parameter definition. 19,173 ( 0.00%) self.next_region_var(EarlyBoundRegion(span, param.name)).into() . } . GenericParamDefKind::Type { .. } => { . // Create a type inference variable for the given . // type parameter definition. The substitutions are . // for actual parameters that may be referred to by . // the default of this type parameter, if it exists. . // e.g., `struct Foo(...);` when . // used in a path such as `Foo::::new()` will . // use an inference variable for `C` with `[T, U]` . // as the substitutions for the default, `(T, U)`. 167,720 ( 0.00%) let ty_var_id = self.inner.borrow_mut().type_variables().new_var( . self.universe(), 209,650 ( 0.00%) TypeVariableOrigin { . kind: TypeVariableOriginKind::TypeParameterDefinition( 41,930 ( 0.00%) param.name, 41,930 ( 0.00%) Some(param.def_id), . ), . span, . }, . ); . 41,930 ( 0.00%) self.tcx.mk_ty_var(ty_var_id).into() . } . GenericParamDefKind::Const { .. } => { . let origin = ConstVariableOrigin { . kind: ConstVariableOriginKind::ConstParameterDefinition( . param.name, . param.def_id, . ), . span, . }; . let const_var_id = 1,562 ( 0.00%) self.inner.borrow_mut().const_unification_table().new_key(ConstVarValue { . origin, . val: ConstVariableValue::Unknown { universe: self.universe() }, . }); 142 ( 0.00%) self.tcx.mk_const_var(const_var_id, self.tcx.type_of(param.def_id)).into() . } . } 1,136 ( 0.00%) } . . /// Given a set of generics defined on a type or impl, returns a substitution mapping each . /// type/region parameter to a fresh inference variable. 80,385 ( 0.00%) pub fn fresh_substs_for_item(&self, span: Span, def_id: DefId) -> SubstsRef<'tcx> { 392,425 ( 0.00%) InternalSubsts::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param)) 53,590 ( 0.00%) } . . /// Returns `true` if errors have been reported since this infcx was . /// created. This is sometimes used as a heuristic to skip . /// reporting errors that often occur as a result of earlier . /// errors, but where it's hard to be 100% sure (e.g., unresolved . /// inference variables, regionck errors). 4,494 ( 0.00%) pub fn is_tainted_by_errors(&self) -> bool { . debug!( . "is_tainted_by_errors(err_count={}, err_count_on_creation={}, \ . tainted_by_errors_flag={})", . self.tcx.sess.err_count(), . self.err_count_on_creation, . self.tainted_by_errors_flag.get() . ); . 99,129 ( 0.00%) if self.tcx.sess.err_count() > self.err_count_on_creation { . return true; // errors reported since this infcx was made . } . self.tainted_by_errors_flag.get() 6,741 ( 0.00%) } . . /// Set the "tainted by errors" flag to true. We call this when we . /// observe an error from a prior pass. . pub fn set_tainted_by_errors(&self) { . debug!("set_tainted_by_errors()"); . self.tainted_by_errors_flag.set(true) . } . . /// Process the region constraints and return any any errors that . /// result. After this, no more unification operations should be . /// done -- or the compiler will panic -- but it is legal to use . /// `resolve_vars_if_possible` as well as `fully_resolve`. 97,300 ( 0.00%) pub fn resolve_regions( . &self, . region_context: DefId, . outlives_env: &OutlivesEnvironment<'tcx>, . mode: RegionckMode, . ) -> Vec> { 264,100 ( 0.00%) let (var_infos, data) = { . let mut inner = self.inner.borrow_mut(); . let inner = &mut *inner; 13,900 ( 0.00%) assert!( 41,700 ( 0.00%) self.is_tainted_by_errors() || inner.region_obligations.is_empty(), . "region_obligations not empty: {:#?}", . inner.region_obligations . ); . inner . .region_constraint_storage . .take() . .expect("regions already resolved") . .with_log(&mut inner.undo_log) . .into_infos_and_data() 13,900 ( 0.00%) }; . . let region_rels = 13,900 ( 0.00%) &RegionRelations::new(self.tcx, region_context, outlives_env.free_region_map()); . 125,100 ( 0.00%) let (lexical_region_resolutions, errors) = 333,600 ( 0.00%) lexical_region_resolve::resolve(region_rels, var_infos, data, mode); . 55,600 ( 0.00%) let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions)); 13,900 ( 0.00%) assert!(old_value.is_none()); . . errors 125,100 ( 0.00%) } . . /// Process the region constraints and report any errors that . /// result. After this, no more unification operations should be . /// done -- or the compiler will panic -- but it is legal to use . /// `resolve_vars_if_possible` as well as `fully_resolve`. 139,000 ( 0.00%) pub fn resolve_regions_and_report_errors( . &self, . region_context: DefId, . outlives_env: &OutlivesEnvironment<'tcx>, . mode: RegionckMode, . ) { 27,800 ( 0.00%) let errors = self.resolve_regions(region_context, outlives_env, mode); . 41,700 ( 0.00%) if !self.is_tainted_by_errors() { . // As a heuristic, just skip reporting region errors . // altogether if other errors have been reported while . // this infcx was in use. This is totally hokey but . // otherwise we have a hard time separating legit region . // errors from silly ones. 27,800 ( 0.00%) self.report_region_errors(&errors); . } 69,500 ( 0.00%) } . . /// Obtains (and clears) the current set of region . /// constraints. The inference context is still usable: further . /// unifications will simply add new constraints. . /// . /// This method is not meant to be used with normal lexical region . /// resolution. Rather, it is used in the NLL mode as a kind of . /// interim hack: basically we run normal type-check and generate -- line 1307 ---------------------------------------- -- line 1319 ---------------------------------------- . } . . /// Gives temporary access to the region constraint data. . pub fn with_region_constraints( . &self, . op: impl FnOnce(&RegionConstraintData<'tcx>) -> R, . ) -> R { . let mut inner = self.inner.borrow_mut(); 33,196 ( 0.00%) op(inner.unwrap_region_constraints().data()) . } . . pub fn region_var_origin(&self, vid: ty::RegionVid) -> RegionVariableOrigin { . let mut inner = self.inner.borrow_mut(); . let inner = &mut *inner; . inner . .region_constraint_storage . .as_mut() -- line 1335 ---------------------------------------- -- line 1338 ---------------------------------------- . .var_origin(vid) . } . . /// Takes ownership of the list of variable regions. This implies . /// that all the region constraints have already been taken, and . /// hence that `resolve_regions_and_report_errors` can never be . /// called. This is used only during NLL processing to "hand off" ownership . /// of the set of region variables into the NLL region context. 6,130 ( 0.00%) pub fn take_region_var_origins(&self) -> VarInfos { . let mut inner = self.inner.borrow_mut(); 23,294 ( 0.00%) let (var_infos, data) = inner . .region_constraint_storage . .take() . .expect("regions already resolved") . .with_log(&mut inner.undo_log) 1,226 ( 0.00%) .into_infos_and_data(); 1,226 ( 0.00%) assert!(data.is_empty()); . var_infos 9,808 ( 0.00%) } . . pub fn ty_to_string(&self, t: Ty<'tcx>) -> String { . self.resolve_vars_if_possible(t).to_string() . } . . /// If `TyVar(vid)` resolves to a type, return that type. Else, return the . /// universe index of `TyVar(vid)`. 48,478 ( 0.00%) pub fn probe_ty_var(&self, vid: TyVid) -> Result, ty::UniverseIndex> { . use self::type_variable::TypeVariableValue; . 145,434 ( 0.00%) match self.inner.borrow_mut().type_variables().probe(vid) { . TypeVariableValue::Known { value } => Ok(value), . TypeVariableValue::Unknown { universe } => Err(universe), . } 169,673 ( 0.00%) } . . /// Resolve any type variables found in `value` -- but only one . /// level. So, if the variable `?X` is bound to some type . /// `Foo`, then this would return `Foo` (but `?Y` may . /// itself be bound to a type). . /// . /// Useful when you only need to inspect the outermost level of . /// the type and don't care about nested types (or perhaps you . /// will be resolving them as well, e.g. in a loop). . pub fn shallow_resolve(&self, value: T) -> T . where . T: TypeFoldable<'tcx>, . { 717,917 ( 0.00%) value.fold_with(&mut ShallowResolver { infcx: self }) . } . 52,876 ( 0.00%) pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid { . self.inner.borrow_mut().type_variables().root_var(var) 79,314 ( 0.00%) } . . /// Where possible, replaces type/const variables in . /// `value` with their final value. Note that region variables . /// are unaffected. If a type/const variable has not been unified, it . /// is left as is. This is an idempotent operation that does . /// not affect inference state in any way and so you can do it . /// at will. 2,352 ( 0.00%) pub fn resolve_vars_if_possible(&self, value: T) -> T . where . T: TypeFoldable<'tcx>, . { 679,955 ( 0.00%) if !value.needs_infer() { 457,906 ( 0.00%) return value; // Avoid duplicated subst-folding. . } 742,138 ( 0.00%) let mut r = resolve::OpportunisticVarResolver::new(self); 895,881 ( 0.00%) value.fold_with(&mut r) 2,282 ( 0.00%) } . . /// Returns the first unresolved variable contained in `T`. In the . /// process of visiting `T`, this will resolve (where possible) . /// type variables in `T`, but it never constructs the final, . /// resolved type, so it's more efficient than . /// `resolve_vars_if_possible()`. . pub fn unresolved_type_vars(&self, value: &T) -> Option<(Ty<'tcx>, Option)> . where -- line 1415 ---------------------------------------- -- line 1490 ---------------------------------------- . expected: &'tcx ty::Const<'tcx>, . actual: &'tcx ty::Const<'tcx>, . err: TypeError<'tcx>, . ) -> DiagnosticBuilder<'tcx> { . let trace = TypeTrace::consts(cause, true, expected, actual); . self.report_and_explain_type_error(trace, &err) . } . 70,641 ( 0.00%) pub fn replace_bound_vars_with_fresh_vars( . &self, . span: Span, . lbrct: LateBoundRegionConversionTime, . value: ty::Binder<'tcx, T>, . ) -> (T, BTreeMap>) . where . T: TypeFoldable<'tcx>, . { . let fld_r = 269,220 ( 0.00%) |br: ty::BoundRegion| self.next_region_var(LateBoundRegion(span, br.kind, lbrct)); . let fld_t = |_| { . self.next_ty_var(TypeVariableOrigin { . kind: TypeVariableOriginKind::MiscVariable, . span, . }) . }; . let fld_c = |_, ty| { . self.next_const_var( . ty, . ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span }, . ) . }; 729,743 ( 0.00%) self.tcx.replace_bound_vars(value, fld_r, fld_t, fld_c) 47,094 ( 0.00%) } . . /// See the [`region_constraints::RegionConstraintCollector::verify_generic_bound`] method. 22,432 ( 0.00%) pub fn verify_generic_bound( . &self, . origin: SubregionOrigin<'tcx>, . kind: GenericKind<'tcx>, . a: ty::Region<'tcx>, . bound: VerifyBound<'tcx>, . ) { . debug!("verify_generic_bound({:?}, {:?} <: {:?})", kind, a, bound); . 8,412 ( 0.00%) self.inner . .borrow_mut() . .unwrap_region_constraints() 47,668 ( 0.00%) .verify_generic_bound(origin, kind, a, bound); 19,628 ( 0.00%) } . . /// Obtains the latest type of the given closure; this may be a . /// closure in the current function, in which case its . /// `ClosureKind` may not yet be known. 856 ( 0.00%) pub fn closure_kind(&self, closure_substs: SubstsRef<'tcx>) -> Option { 1,712 ( 0.00%) let closure_kind_ty = closure_substs.as_closure().kind_ty(); . let closure_kind_ty = self.shallow_resolve(closure_kind_ty); 1,284 ( 0.00%) closure_kind_ty.to_opt_closure_kind() . } . . /// Clears the selection, evaluation, and projection caches. This is useful when . /// repeatedly attempting to select an `Obligation` while changing only . /// its `ParamEnv`, since `FulfillmentContext` doesn't use probing. . pub fn clear_caches(&self) { . self.selection_cache.clear(); . self.evaluation_cache.clear(); . self.inner.borrow_mut().projection_cache().clear(); . } . . pub fn universe(&self) -> ty::UniverseIndex { 1,153,244 ( 0.00%) self.universe.get() 413,006 ( 0.00%) } . . /// Creates and return a fresh universe that extends all previous . /// universes. Updates `self.universe` to that new universe. 150 ( 0.00%) pub fn create_next_universe(&self) -> ty::UniverseIndex { 380 ( 0.00%) let u = self.universe.get().next_universe(); . self.universe.set(u); . u 150 ( 0.00%) } . . /// Resolves and evaluates a constant. . /// . /// The constant can be located on a trait like `::C`, in which case the given . /// substitutions and environment are used to resolve the constant. Alternatively if the . /// constant has generic parameters in scope the substitutions are used to evaluate the value of . /// the constant. For example in `fn foo() { let _ = [0; bar::()]; }` the repeat count . /// constant `bar::()` requires a substitution for `T`, if the substitution for `T` is still -- line 1576 ---------------------------------------- -- line 1606 ---------------------------------------- . // variables, thus we don't need to substitute back the original values. . self.tcx.const_eval_resolve(param_env_erased, unevaluated, span) . } . . /// If `typ` is a type variable of some kind, resolve it one level . /// (but do not resolve types found in the result). If `typ` is . /// not a type variable, just return it unmodified. . // FIXME(eddyb) inline into `ShallowResolver::visit_ty`. 8,246,560 ( 0.03%) fn shallow_resolve_ty(&self, typ: Ty<'tcx>) -> Ty<'tcx> { 4,472,153 ( 0.02%) match *typ.kind() { . ty::Infer(ty::TyVar(v)) => { . // Not entirely obvious: if `typ` is a type variable, . // it can be resolved to an int/float variable, which . // can then be recursively resolved, hence the . // recursion. Note though that we prevent type . // variables from unifying to other type variables . // directly (though they may be embedded . // structurally), and we prevent cycles in any case, . // so this recursion should always be of very limited . // depth. . // . // Note: if these two lines are combined into one we get . // dynamic borrow errors on `self.inner`. 2,373,636 ( 0.01%) let known = self.inner.borrow_mut().type_variables().probe(v).known(); . known.map_or(typ, |t| self.shallow_resolve_ty(t)) . } . 28,760 ( 0.00%) ty::Infer(ty::IntVar(v)) => self . .inner . .borrow_mut() . .int_unification_table() . .probe_value(v) 8,436 ( 0.00%) .map(|v| v.to_type(self.tcx)) . .unwrap_or(typ), . . ty::Infer(ty::FloatVar(v)) => self . .inner . .borrow_mut() . .float_unification_table() . .probe_value(v) . .map(|v| v.to_type(self.tcx)) . .unwrap_or(typ), . . _ => typ, . } 9,277,380 ( 0.03%) } . . /// `ty_or_const_infer_var_changed` is equivalent to one of these two: . /// * `shallow_resolve(ty) != ty` (where `ty.kind = ty::Infer(_)`) . /// * `shallow_resolve(ct) != ct` (where `ct.kind = ty::ConstKind::Infer(_)`) . /// . /// However, `ty_or_const_infer_var_changed` is more efficient. It's always . /// inlined, despite being large, because it has only two call sites that . /// are extremely hot (both in `traits::fulfill`'s checking of `stalled_on` -- line 1659 ---------------------------------------- -- line 1662 ---------------------------------------- . #[inline(always)] . pub fn ty_or_const_infer_var_changed(&self, infer_var: TyOrConstInferVar<'tcx>) -> bool { . match infer_var { . TyOrConstInferVar::Ty(v) => { . use self::type_variable::TypeVariableValue; . . // If `inlined_probe` returns a `Known` value, it never equals . // `ty::Infer(ty::TyVar(v))`. 5,371,430 ( 0.02%) match self.inner.borrow_mut().type_variables().inlined_probe(v) { . TypeVariableValue::Unknown { .. } => false, . TypeVariableValue::Known { .. } => true, . } . } . . TyOrConstInferVar::TyInt(v) => { . // If `inlined_probe_value` returns a value it's always a . // `ty::Int(_)` or `ty::UInt(_)`, which never matches a -- line 1678 ---------------------------------------- -- line 1716 ---------------------------------------- . /// Equivalent to `ty::ConstKind::Infer(ty::InferConst::Var(_))`. . Const(ConstVid<'tcx>), . } . . impl<'tcx> TyOrConstInferVar<'tcx> { . /// Tries to extract an inference variable from a type or a constant, returns `None` . /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`) and . /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`). 28,702 ( 0.00%) pub fn maybe_from_generic_arg(arg: GenericArg<'tcx>) -> Option { . match arg.unpack() { . GenericArgKind::Type(ty) => Self::maybe_from_ty(ty), . GenericArgKind::Const(ct) => Self::maybe_from_const(ct), . GenericArgKind::Lifetime(_) => None, . } 28,702 ( 0.00%) } . . /// Tries to extract an inference variable from a type, returns `None` . /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`). 3,376 ( 0.00%) pub fn maybe_from_ty(ty: Ty<'tcx>) -> Option { 288,177 ( 0.00%) match *ty.kind() { 64,006 ( 0.00%) ty::Infer(ty::TyVar(v)) => Some(TyOrConstInferVar::Ty(v)), . ty::Infer(ty::IntVar(v)) => Some(TyOrConstInferVar::TyInt(v)), . ty::Infer(ty::FloatVar(v)) => Some(TyOrConstInferVar::TyFloat(v)), . _ => None, . } 3,376 ( 0.00%) } . . /// Tries to extract an inference variable from a constant, returns `None` . /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`). . pub fn maybe_from_const(ct: &'tcx ty::Const<'tcx>) -> Option { . match ct.val { . ty::ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)), . _ => None, . } -- line 1749 ---------------------------------------- -- line 1755 ---------------------------------------- . } . . impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { . fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { . self.infcx.tcx . } . . fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { 1,560,416 ( 0.01%) self.infcx.shallow_resolve_ty(ty) . } . 5,200 ( 0.00%) fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { 2,944 ( 0.00%) if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = ct { 860 ( 0.00%) self.infcx . .inner . .borrow_mut() . .const_unification_table() 516 ( 0.00%) .probe_value(*vid) . .val . .known() . .unwrap_or(ct) . } else { . ct . } 6,500 ( 0.00%) } . } . . impl<'tcx> TypeTrace<'tcx> { . pub fn span(&self) -> Span { 352 ( 0.00%) self.cause.span . } . . pub fn types( . cause: &ObligationCause<'tcx>, . a_is_expected: bool, . a: Ty<'tcx>, . b: Ty<'tcx>, . ) -> TypeTrace<'tcx> { -- line 1792 ---------------------------------------- -- line 1800 ---------------------------------------- . b: &'tcx ty::Const<'tcx>, . ) -> TypeTrace<'tcx> { . TypeTrace { cause: cause.clone(), values: Consts(ExpectedFound::new(a_is_expected, a, b)) } . } . } . . impl<'tcx> SubregionOrigin<'tcx> { . pub fn span(&self) -> Span { 880 ( 0.00%) match *self { 176 ( 0.00%) Subtype(ref a) => a.span(), . RelateObjectBound(a) => a, . RelateParamBound(a, ..) => a, . RelateRegionParamBound(a) => a, . Reborrow(a) => a, . ReborrowUpvar(a, _) => a, . DataBorrowed(_, a) => a, . ReferenceOutlivesReferent(_, a) => a, . CompareImplMethodObligation { span, .. } => span, -- line 1817 ---------------------------------------- -- line 1818 ---------------------------------------- . CompareImplTypeObligation { span, .. } => span, . } . } . . pub fn from_obligation_cause(cause: &traits::ObligationCause<'tcx>, default: F) -> Self . where . F: FnOnce() -> Self, . { 53,048 ( 0.00%) match *cause.code() { 7,262 ( 0.00%) traits::ObligationCauseCode::ReferenceOutlivesReferent(ref_type) => { 36,310 ( 0.00%) SubregionOrigin::ReferenceOutlivesReferent(ref_type, cause.span) . } . . traits::ObligationCauseCode::CompareImplMethodObligation { . impl_item_def_id, . trait_item_def_id, . } => SubregionOrigin::CompareImplMethodObligation { . span: cause.span, . impl_item_def_id, -- line 1836 ---------------------------------------- 9,336,998 ( 0.03%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/library/alloc/src/string.rs -------------------------------------------------------------------------------- Ir -- line 375 ---------------------------------------- . /// ``` . /// let s = String::new(); . /// ``` . #[inline] . #[rustc_const_stable(feature = "const_string_new", since = "1.39.0")] . #[stable(feature = "rust1", since = "1.0.0")] . #[must_use] . pub const fn new() -> String { 106,610 ( 0.00%) String { vec: Vec::new() } . } . . /// Creates a new empty `String` with a particular capacity. . /// . /// `String`s have an internal buffer to hold their data. The capacity is . /// the length of that buffer, and can be queried with the [`capacity`] . /// method. This method creates an empty `String`, but one with an initial . /// buffer that can hold `capacity` bytes. This is useful when you may be -- line 391 ---------------------------------------- -- line 420 ---------------------------------------- . /// // ...but this may make the string reallocate . /// s.push('a'); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . #[must_use] . pub fn with_capacity(capacity: usize) -> String { 219,482 ( 0.00%) String { vec: Vec::with_capacity(capacity) } . } . . // HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is . // required for this method definition, is not available. Since we don't . // require this method for testing purposes, I'll just stub it . // NB see the slice::hack module in slice.rs for more information . #[inline] . #[cfg(test)] -- line 436 ---------------------------------------- -- line 492 ---------------------------------------- . /// . /// [`from_utf8_unchecked`]: String::from_utf8_unchecked . /// [`Vec`]: crate::vec::Vec "Vec" . /// [`&str`]: prim@str "&str" . /// [`into_bytes`]: String::into_bytes . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn from_utf8(vec: Vec) -> Result { 10,325 ( 0.00%) match str::from_utf8(&vec) { . Ok(..) => Ok(String { vec }), 2,016 ( 0.00%) Err(e) => Err(FromUtf8Error { bytes: vec, error: e }), . } . } . . /// Converts a slice of bytes to a string, including invalid characters. . /// . /// Strings are made of bytes ([`u8`]), and a slice of bytes . /// ([`&[u8]`][byteslice]) is made of bytes, so this function converts . /// between the two. Not all byte slices are valid strings, however: strings -- line 510 ---------------------------------------- -- line 550 ---------------------------------------- . /// let input = b"Hello \xF0\x90\x80World"; . /// let output = String::from_utf8_lossy(input); . /// . /// assert_eq!("Hello �World", output); . /// ``` . #[must_use] . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] 2,754 ( 0.00%) pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> { 3,060 ( 0.00%) let mut iter = lossy::Utf8Lossy::from_bytes(v).chunks(); . 1,530 ( 0.00%) let first_valid = if let Some(chunk) = iter.next() { . let lossy::Utf8LossyChunk { valid, broken } = chunk; 306 ( 0.00%) if broken.is_empty() { . debug_assert_eq!(valid.len(), v.len()); 306 ( 0.00%) return Cow::Borrowed(valid); . } . valid . } else { . return Cow::Borrowed(""); . }; . . const REPLACEMENT: &str = "\u{FFFD}"; . -- line 573 ---------------------------------------- -- line 578 ---------------------------------------- . for lossy::Utf8LossyChunk { valid, broken } in iter { . res.push_str(valid); . if !broken.is_empty() { . res.push_str(REPLACEMENT); . } . } . . Cow::Owned(res) 2,448 ( 0.00%) } . . /// Decode a UTF-16–encoded vector `v` into a `String`, returning [`Err`] . /// if `v` contains any invalid data. . /// . /// # Examples . /// . /// Basic usage: . /// -- line 594 ---------------------------------------- -- line 762 ---------------------------------------- . /// }; . /// . /// assert_eq!("💖", sparkle_heart); . /// ``` . #[inline] . #[must_use] . #[stable(feature = "rust1", since = "1.0.0")] . pub unsafe fn from_utf8_unchecked(bytes: Vec) -> String { 14,945 ( 0.00%) String { vec: bytes } . } . . /// Converts a `String` into a byte vector. . /// . /// This consumes the `String`, so we do not need to copy its contents. . /// . /// # Examples . /// -- line 778 ---------------------------------------- -- line 1138 ---------------------------------------- . /// s.push('2'); . /// s.push('3'); . /// . /// assert_eq!("abc123", s); . /// ``` . #[cfg(not(no_global_oom_handling))] . #[inline] . #[stable(feature = "rust1", since = "1.0.0")] 22,985,382 ( 0.08%) pub fn push(&mut self, ch: char) { . match ch.len_utf8() { . 1 => self.vec.push(ch as u8), . _ => self.vec.extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()), . } 19,154,485 ( 0.07%) } . . /// Returns a byte slice of this `String`'s contents. . /// . /// The inverse of this method is [`from_utf8`]. . /// . /// [`from_utf8`]: String::from_utf8 . /// . /// # Examples -- line 1159 ---------------------------------------- -- line 1543 ---------------------------------------- . /// let fancy_f = String::from("ƒoo"); . /// assert_eq!(fancy_f.len(), 4); . /// assert_eq!(fancy_f.chars().count(), 3); . /// ``` . #[inline] . #[must_use] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn len(&self) -> usize { 89 ( 0.00%) self.vec.len() . } . . /// Returns `true` if this `String` has a length of zero, and `false` otherwise. . /// . /// # Examples . /// . /// Basic usage: . /// -- line 1559 ---------------------------------------- -- line 1563 ---------------------------------------- . /// . /// v.push('a'); . /// assert!(!v.is_empty()); . /// ``` . #[inline] . #[must_use] . #[stable(feature = "rust1", since = "1.0.0")] . pub fn is_empty(&self) -> bool { 194,688 ( 0.00%) self.len() == 0 . } . . /// Splits the string into two at the given byte index. . /// . /// Returns a newly allocated `String`. `self` contains bytes `[0, at)`, and . /// the returned `String` contains bytes `[at, len)`. `at` must be on the . /// boundary of a UTF-8 code point. . /// -- line 1579 ---------------------------------------- -- line 1845 ---------------------------------------- . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { . fmt::Display::fmt("invalid utf-16: lone surrogate found", f) . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl Clone for String { 14,604 ( 0.00%) fn clone(&self) -> Self { 7,302 ( 0.00%) String { vec: self.vec.clone() } 17,038 ( 0.00%) } . . fn clone_from(&mut self, source: &Self) { . self.vec.clone_from(&source.vec); . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl FromIterator for String { 4,154 ( 0.00%) fn from_iter>(iter: I) -> String { . let mut buf = String::new(); . buf.extend(iter); . buf 4,767 ( 0.00%) } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "string_from_iter_by_ref", since = "1.17.0")] . impl<'a> FromIterator<&'a char> for String { . fn from_iter>(iter: I) -> String { . let mut buf = String::new(); . buf.extend(iter); -- line 1877 ---------------------------------------- -- line 1937 ---------------------------------------- . } . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl Extend for String { . fn extend>(&mut self, iter: I) { 187,622 ( 0.00%) let iterator = iter.into_iter(); 185,120 ( 0.00%) let (lower_bound, _) = iterator.size_hint(); . self.reserve(lower_bound); 11,021,513 ( 0.04%) iterator.for_each(move |c| self.push(c)); . } . . #[inline] . fn extend_one(&mut self, c: char) { . self.push(c); . } . . #[inline] -- line 1956 ---------------------------------------- -- line 2128 ---------------------------------------- . fn default() -> String { . String::new() . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl fmt::Display for String { . #[inline] 13,406 ( 0.00%) fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 26,980 ( 0.00%) fmt::Display::fmt(&**self, f) . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl fmt::Debug for String { . #[inline] . fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { . fmt::Debug::fmt(&**self, f) . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl hash::Hash for String { . #[inline] . fn hash(&self, hasher: &mut H) { 5,683 ( 0.00%) (**self).hash(hasher) . } . } . . /// Implements the `+` operator for concatenating two strings. . /// . /// This consumes the `String` on the left-hand side and re-uses its buffer (growing it if . /// necessary). This is done to avoid allocating a new `String` and copying the entire contents on . /// every operation, which would lead to *O*(*n*^2) running time when building an *n*-byte string by -- line 2161 ---------------------------------------- -- line 2194 ---------------------------------------- . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl Add<&str> for String { . type Output = String; . . #[inline] . fn add(mut self, other: &str) -> String { . self.push_str(other); 2 ( 0.00%) self . } . } . . /// Implements the `+=` operator for appending to a `String`. . /// . /// This has the same behavior as the [`push_str`][String::push_str] method. . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "stringaddassign", since = "1.12.0")] -- line 2210 ---------------------------------------- -- line 2233 ---------------------------------------- . &self[..][index] . } . } . #[stable(feature = "rust1", since = "1.0.0")] . impl ops::Index> for String { . type Output = str; . . #[inline] 2,028 ( 0.00%) fn index(&self, index: ops::RangeFrom) -> &str { . &self[..][index] 2,028 ( 0.00%) } . } . #[stable(feature = "rust1", since = "1.0.0")] . impl ops::Index for String { . type Output = str; . . #[inline] . fn index(&self, _index: ops::RangeFull) -> &str { . unsafe { str::from_utf8_unchecked(&self.vec) } -- line 2251 ---------------------------------------- -- line 2388 ---------------------------------------- . impl ToString for T { . // A common guideline is to not inline generic functions. However, . // removing `#[inline]` from this method causes non-negligible regressions. . // See , the last attempt . // to try to remove it. . #[inline] . default fn to_string(&self) -> String { . let mut buf = String::new(); 432,933 ( 0.00%) let mut formatter = core::fmt::Formatter::new(&mut buf); . // Bypass format_args!() to avoid write_str with zero-length strs 104,878 ( 0.00%) fmt::Display::fmt(self, &mut formatter) . .expect("a Display implementation returned an error unexpectedly"); . buf . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "char_to_string_specialization", since = "1.46.0")] . impl ToString for char { -- line 2406 ---------------------------------------- -- line 2553 ---------------------------------------- . /// . /// ``` . /// let s1: String = String::from("hello world"); . /// let s2: Box = s1.into_boxed_str(); . /// let s3: String = String::from(s2); . /// . /// assert_eq!("hello world", s3) . /// ``` 619 ( 0.00%) fn from(s: Box) -> String { . s.into_string() 619 ( 0.00%) } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "box_from_str", since = "1.20.0")] . impl From for Box { . /// Converts the given [`String`] to a boxed `str` slice that is owned. . /// . /// # Examples -- line 2571 ---------------------------------------- -- line 2620 ---------------------------------------- . /// ``` . /// # use std::borrow::Cow; . /// assert_eq!(Cow::from("eggplant"), Cow::Borrowed("eggplant")); . /// ``` . /// . /// [`Borrowed`]: crate::borrow::Cow::Borrowed "borrow::Cow::Borrowed" . #[inline] . fn from(s: &'a str) -> Cow<'a, str> { 71,330 ( 0.00%) Cow::Borrowed(s) . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl<'a> From for Cow<'a, str> { . /// Converts a [`String`] into an [`Owned`] variant. . /// No heap allocation is performed, and the string -- line 2636 ---------------------------------------- -- line 2643 ---------------------------------------- . /// let s = "eggplant".to_string(); . /// let s2 = "eggplant".to_string(); . /// assert_eq!(Cow::from(s), Cow::<'static, str>::Owned(s2)); . /// ``` . /// . /// [`Owned`]: crate::borrow::Cow::Owned "borrow::Cow::Owned" . #[inline] . fn from(s: String) -> Cow<'a, str> { 13,000 ( 0.00%) Cow::Owned(s) . } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "cow_from_string_ref", since = "1.28.0")] . impl<'a> From<&'a String> for Cow<'a, str> { . /// Converts a [`String`] reference into a [`Borrowed`] variant. . /// No heap allocation is performed, and the string -- line 2659 ---------------------------------------- -- line 2709 ---------------------------------------- . /// ``` . /// let s1 = String::from("hello world"); . /// let v1 = Vec::from(s1); . /// . /// for b in v1 { . /// println!("{}", b); . /// } . /// ``` 100 ( 0.00%) fn from(string: String) -> Vec { 400 ( 0.00%) string.into_bytes() 100 ( 0.00%) } . } . . #[cfg(not(no_global_oom_handling))] . #[stable(feature = "rust1", since = "1.0.0")] . impl fmt::Write for String { . #[inline] 1,229,128 ( 0.00%) fn write_str(&mut self, s: &str) -> fmt::Result { . self.push_str(s); . Ok(()) 1,075,487 ( 0.00%) } . . #[inline] 119,778 ( 0.00%) fn write_char(&mut self, c: char) -> fmt::Result { 14 ( 0.00%) self.push(c); . Ok(()) 119,778 ( 0.00%) } . } . . /// A draining iterator for `String`. . /// . /// This struct is created by the [`drain`] method on [`String`]. See its . /// documentation for more. . /// . /// [`drain`]: String::drain -- line 2743 ---------------------------------------- 202,976 ( 0.00%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/library/core/src/hash/sip.rs -------------------------------------------------------------------------------- Ir -- line 124 ---------------------------------------- . /// sizes and avoid calling `memcpy`, which is good for speed. . /// . /// Unsafe because: unchecked indexing at start..start+len . #[inline] . unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 { . debug_assert!(len < 8); . let mut i = 0; // current byte index (from LSB) in the output u64 . let mut out = 0; 4,397,922 ( 0.02%) if i + 3 < len { . // SAFETY: `i` cannot be greater than `len`, and the caller must guarantee . // that the index start..start+len is in bounds. . out = unsafe { load_int_le!(buf, start + i, u32) } as u64; . i += 4; . } 9,124,708 ( 0.03%) if i + 1 < len { . // SAFETY: same as above. 4,562,355 ( 0.02%) out |= (unsafe { load_int_le!(buf, start + i, u16) } as u64) << (i * 8); 2,280,954 ( 0.01%) i += 2 . } 5,095,913 ( 0.02%) if i < len { . // SAFETY: same as above. 7,347,282 ( 0.03%) out |= (unsafe { *buf.get_unchecked(start + i) } as u64) << (i * 8); . i += 1; . } . debug_assert_eq!(i, len); . out . } . . impl SipHasher { . /// Creates a new `SipHasher` with the two initial keys set to 0. -- line 153 ---------------------------------------- -- line 190 ---------------------------------------- . /// Creates a `SipHasher13` that is keyed off the provided keys. . #[inline] . #[unstable(feature = "hashmap_internals", issue = "none")] . #[rustc_deprecated( . since = "1.13.0", . reason = "use `std::collections::hash_map::DefaultHasher` instead" . )] . pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 { 877,929 ( 0.00%) SipHasher13 { hasher: Hasher::new_with_keys(key0, key1) } . } . } . . impl Hasher { . #[inline] . fn new_with_keys(key0: u64, key1: u64) -> Hasher { 9 ( 0.00%) let mut state = Hasher { . k0: key0, . k1: key1, . length: 0, . state: State { v0: 0, v1: 0, v2: 0, v3: 0 }, . tail: 0, . ntail: 0, . _marker: PhantomData, . }; . state.reset(); . state . } . . #[inline] . fn reset(&mut self) { . self.length = 0; 1,316,889 ( 0.00%) self.state.v0 = self.k0 ^ 0x736f6d6570736575; 1,399,106 ( 0.01%) self.state.v1 = self.k1 ^ 0x646f72616e646f6d; . self.state.v2 = self.k0 ^ 0x6c7967656e657261; . self.state.v3 = self.k1 ^ 0x7465646279746573; . self.ntail = 0; . } . } . . #[stable(feature = "rust1", since = "1.0.0")] . impl super::Hasher for SipHasher { -- line 230 ---------------------------------------- -- line 258 ---------------------------------------- . // in librustc_data_structures/sip128.rs, and add `write_u*`/`write_i*` . // methods to `SipHasher`, `SipHasher13`, and `DefaultHasher`. This would . // greatly speed up integer hashing by those hashers, at the cost of . // slightly slowing down compile speeds on some benchmarks. See #69152 for . // details. . #[inline] . fn write(&mut self, msg: &[u8]) { . let length = msg.len(); 5,607,880 ( 0.02%) self.length += length; . . let mut needed = 0; . 5,525,652 ( 0.02%) if self.ntail != 0 { 2,805,712 ( 0.01%) needed = 8 - self.ntail; . // SAFETY: `cmp::min(length, needed)` is guaranteed to not be over `length` 14,028,510 ( 0.05%) self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail); 2,805,702 ( 0.01%) if length < needed { 1,927,154 ( 0.01%) self.ntail += length; . return; . } else { 439,274 ( 0.00%) self.state.v3 ^= self.tail; . S::c_rounds(&mut self.state); 878,548 ( 0.00%) self.state.v0 ^= self.tail; 439,274 ( 0.00%) self.ntail = 0; . } . } . . // Buffered tail is now flushed, process new input. 1,592,169 ( 0.01%) let len = length - needed; 1,592,180 ( 0.01%) let left = len & 0x7; // len % 8 . . let mut i = needed; 2,388,596 ( 0.01%) while i < len - left { . // SAFETY: because `len - left` is the biggest multiple of 8 under . // `len`, and because `i` starts at `needed` where `len` is `length - needed`, . // `i + 8` is guaranteed to be less than or equal to `length`. . let mi = unsafe { load_int_le!(msg, i, u64) }; . 163 ( 0.00%) self.state.v3 ^= mi; . S::c_rounds(&mut self.state); 163 ( 0.00%) self.state.v0 ^= mi; . 326 ( 0.00%) i += 8; . } . . // SAFETY: `i` is now `needed + len.div_euclid(8) * 8`, . // so `i + left` = `needed + len` = `length`, which is by . // definition equal to `msg.len()`. 1,674,386 ( 0.01%) self.tail = unsafe { u8to64_le(msg, i, left) }; . self.ntail = left; . } . . #[inline] . fn finish(&self) -> u64 { 438,966 ( 0.00%) let mut state = self.state; . 2,194,830 ( 0.01%) let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail; . 438,966 ( 0.00%) state.v3 ^= b; . S::c_rounds(&mut state); 438,966 ( 0.00%) state.v0 ^= b; . 438,966 ( 0.00%) state.v2 ^= 0xff; . S::d_rounds(&mut state); . 877,932 ( 0.00%) state.v0 ^ state.v1 ^ state.v2 ^ state.v3 . } . } . . impl Clone for Hasher { . #[inline] . fn clone(&self) -> Hasher { . Hasher { . k0: self.k0, -- line 331 ---------------------------------------- -- line 354 ---------------------------------------- . } . . #[derive(Debug, Clone, Default)] . struct Sip13Rounds; . . impl Sip for Sip13Rounds { . #[inline] . fn c_rounds(state: &mut State) { 5,710,218 ( 0.02%) compress!(state); . } . . #[inline] . fn d_rounds(state: &mut State) { 1,755,864 ( 0.01%) compress!(state); 1,755,864 ( 0.01%) compress!(state); 1,316,898 ( 0.00%) compress!(state); . } . } . . #[derive(Debug, Clone, Default)] . struct Sip24Rounds; . . impl Sip for Sip24Rounds { . #[inline] -- line 377 ---------------------------------------- 13,065,768 ( 0.05%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/compiler/rustc_middle/src/ty/sty.rs -------------------------------------------------------------------------------- Ir -- line 21 ---------------------------------------- . use rustc_target::spec::abi; . use std::borrow::Cow; . use std::cmp::Ordering; . use std::marker::PhantomData; . use std::ops::Range; . use ty::util::IntTypeExt; . . #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] 19 ( 0.00%) #[derive(HashStable, TypeFoldable, Lift)] . pub struct TypeAndMut<'tcx> { 18,879 ( 0.00%) pub ty: Ty<'tcx>, 94,395 ( 0.00%) 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 { 61,109 ( 0.00%) pub scope: DefId, 117,093 ( 0.00%) pub bound_region: BoundRegionKind, . } . 1,024,986 ( 0.00%) #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)] 94 ( 0.00%) #[derive(HashStable)] . pub enum BoundRegionKind { . /// An anonymous region parameter for a given fn (&T) 29,230 ( 0.00%) BrAnon(u32), . . /// Named region parameters for functions (a in &'a T) . /// . /// The `DefId` is needed to distinguish free regions in . /// the event of shadowing. 504 ( 0.00%) BrNamed(DefId, Symbol), . . /// Anonymous region for the implicit env pointer parameter . /// to a closure . BrEnv, . } . 1,644 ( 0.00%) #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)] . #[derive(HashStable)] . pub struct BoundRegion { 272,189 ( 0.00%) pub var: BoundVar, 241,091 ( 0.00%) pub kind: BoundRegionKind, . } . . impl BoundRegionKind { . pub fn is_named(&self) -> bool { . match *self { . BoundRegionKind::BrNamed(_, name) => name != kw::UnderscoreLifetime, . _ => false, . } . } . } . . /// Defines the kinds of types. . /// . /// N.B., if you change this, you'll probably want to change the corresponding . /// AST structure in `rustc_ast/src/ast.rs` as well. 36,464,148 ( 0.13%) #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable, Debug)] 183,256 ( 0.00%) #[derive(HashStable)] . #[rustc_diagnostic_item = "TyKind"] . pub enum TyKind<'tcx> { . /// The primitive boolean type. Written as `bool`. . Bool, . . /// The primitive character type; holds a Unicode scalar value . /// (a non-surrogate code point). Written as `char`. . Char, -- line 90 ---------------------------------------- -- line 99 ---------------------------------------- . Float(ty::FloatTy), . . /// Algebraic data types (ADT). For example: structures, enumerations and unions. . /// . /// InternalSubsts here, possibly against intuition, *may* contain `Param`s. . /// That is, even after substitution it is possible that there are type . /// variables. This happens when the `Adt` corresponds to an ADT . /// definition and not a concrete use of it. 5,337,569 ( 0.02%) Adt(&'tcx AdtDef, SubstsRef<'tcx>), . . /// An unsized FFI type that is opaque to Rust. Written as `extern type T`. . Foreign(DefId), . . /// The pointee of a string slice. Written as `str`. . Str, . . /// An array with the given length. Written as `[T; n]`. 43,781 ( 0.00%) Array(Ty<'tcx>, &'tcx ty::Const<'tcx>), . . /// The pointee of an array slice. Written as `[T]`. . Slice(Ty<'tcx>), . . /// A raw pointer. Written as `*mut T` or `*const T` . RawPtr(TypeAndMut<'tcx>), . . /// A reference; a pointer with an associated lifetime. Written as . /// `&'a mut T` or `&'a T`. 3,021,225 ( 0.01%) Ref(Region<'tcx>, Ty<'tcx>, hir::Mutability), . . /// The anonymous type of a function declaration/definition. Each . /// function has a unique type, which is output (for a function . /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`. . /// . /// For example the type of `bar` here: . /// . /// ```rust -- line 134 ---------------------------------------- -- line 143 ---------------------------------------- . /// . /// ```rust . /// fn foo() -> i32 { 1 } . /// let bar: fn() -> i32 = foo; . /// ``` . FnPtr(PolyFnSig<'tcx>), . . /// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`. 75,568 ( 0.00%) Dynamic(&'tcx List>>, ty::Region<'tcx>), . . /// The anonymous type of a closure. Used to represent the type of . /// `|a| a`. . Closure(DefId, SubstsRef<'tcx>), . . /// The anonymous type of a generator. Used to represent the type of . /// `|a| yield a`. . Generator(DefId, SubstsRef<'tcx>, hir::Movability), -- line 159 ---------------------------------------- -- line 180 ---------------------------------------- . /// The substitutions are for the generics of the function in question. . /// After typeck, the concrete type can be found in the `types` map. . Opaque(DefId, SubstsRef<'tcx>), . . /// A type parameter; for example, `T` in `fn f(x: T) {}`. . Param(ParamTy), . . /// Bound type variable, used only when preparing a trait query. 21,558 ( 0.00%) Bound(ty::DebruijnIndex, BoundTy), . . /// A placeholder type - universally quantified higher-ranked type. . Placeholder(ty::PlaceholderType), . . /// A type variable used during type checking. . Infer(InferTy), . . /// A placeholder for a type which could not be computed; this is -- line 196 ---------------------------------------- -- line 330 ---------------------------------------- . pub closure_kind_ty: T, . pub closure_sig_as_fn_ptr_ty: T, . pub tupled_upvars_ty: T, . } . . impl<'tcx> ClosureSubsts<'tcx> { . /// Construct `ClosureSubsts` from `ClosureSubstsParts`, containing `Substs` . /// for the closure parent, alongside additional closure-specific components. 41 ( 0.00%) pub fn new( . tcx: TyCtxt<'tcx>, . parts: ClosureSubstsParts<'tcx, Ty<'tcx>>, . ) -> ClosureSubsts<'tcx> { . ClosureSubsts { . substs: tcx.mk_substs( 82 ( 0.00%) parts.parent_substs.iter().copied().chain( 164 ( 0.00%) [parts.closure_kind_ty, parts.closure_sig_as_fn_ptr_ty, parts.tupled_upvars_ty] . .iter() . .map(|&ty| ty.into()), . ), . ), . } 82 ( 0.00%) } . . /// Divides the closure substs into their respective components. . /// The ordering assumed here must match that used by `ClosureSubsts::new` above. 833 ( 0.00%) fn split(self) -> ClosureSubstsParts<'tcx, GenericArg<'tcx>> { . match self.substs[..] { 7,806 ( 0.00%) [ 2,009 ( 0.00%) ref parent_substs @ .., 2,046 ( 0.00%) closure_kind_ty, 1,125 ( 0.00%) closure_sig_as_fn_ptr_ty, 1,565 ( 0.00%) tupled_upvars_ty, 3,332 ( 0.00%) ] => ClosureSubstsParts { . parent_substs, . closure_kind_ty, . closure_sig_as_fn_ptr_ty, . tupled_upvars_ty, . }, . _ => bug!("closure substs missing synthetics"), . } 2,499 ( 0.00%) } . . /// Returns `true` only if enough of the synthetic types are known to . /// allow using all of the methods on `ClosureSubsts` 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.substs.len() >= 3 -- line 378 ---------------------------------------- -- line 383 ---------------------------------------- . pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] { . self.split().parent_substs . } . . /// 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] 24 ( 0.00%) pub fn upvar_tys(self) -> impl Iterator> + 'tcx { 668 ( 0.00%) match self.tupled_upvars_ty().kind() { . TyKind::Error(_) => None, 240 ( 0.00%) 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() 16 ( 0.00%) } . . /// Returns the tuple type representing the upvars for this closure. . #[inline] . pub fn tupled_upvars_ty(self) -> Ty<'tcx> { 4,085 ( 0.00%) 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(substs)`. 428 ( 0.00%) pub fn kind_ty(self) -> Ty<'tcx> { . self.split().closure_kind_ty.expect_ty() 856 ( 0.00%) } . . /// 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 `ClosureSubsts`, . // see `rustc_typeck::check::closure`. . pub fn sig_as_fn_ptr_ty(self) -> Ty<'tcx> { . self.split().closure_sig_as_fn_ptr_ty.expect_ty() . } . . /// Returns the closure kind for this closure; only usable outside . /// of an inference context, because in that context we know that . /// there are no type variables. . /// . /// If you have an inference context, use `infcx.closure_kind()`. 1 ( 0.00%) pub fn kind(self) -> ty::ClosureKind { 58 ( 0.00%) self.kind_ty().to_opt_closure_kind().unwrap() 2 ( 0.00%) } . . /// Extracts the signature from the closure. 537 ( 0.00%) pub fn sig(self) -> ty::PolyFnSig<'tcx> { . let ty = self.sig_as_fn_ptr_ty(); 1,074 ( 0.00%) match ty.kind() { 2,148 ( 0.00%) ty::FnPtr(sig) => *sig, . _ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind()), . } 1,611 ( 0.00%) } . } . . /// Similar to `ClosureSubsts`; see the above documentation for more. . #[derive(Copy, Clone, Debug, TypeFoldable)] . pub struct GeneratorSubsts<'tcx> { . pub substs: SubstsRef<'tcx>, . } . -- line 448 ---------------------------------------- -- line 676 ---------------------------------------- . } . . impl<'tcx> UpvarSubsts<'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 { 84 ( 0.00%) let tupled_tys = match self { 125 ( 0.00%) UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(), . UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(), . }; . 208 ( 0.00%) match tupled_tys.kind() { . TyKind::Error(_) => None, 167 ( 0.00%) 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> { 166 ( 0.00%) match self { 167 ( 0.00%) UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(), . UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(), . } . } . } . . /// An inline const is modeled like . /// . /// const InlineConst<'l0...'li, T0...Tj, R>: R; -- line 710 ---------------------------------------- -- line 760 ---------------------------------------- . } . . /// Returns the type of this inline const. . pub fn ty(self) -> Ty<'tcx> { . self.split().ty.expect_ty() . } . } . 55,651 ( 0.00%) #[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, TyEncodable, TyDecodable)] 61,376 ( 0.00%) #[derive(HashStable, TypeFoldable)] . pub enum ExistentialPredicate<'tcx> { . /// E.g., `Iterator`. . Trait(ExistentialTraitRef<'tcx>), . /// E.g., `Iterator::Item = T`. . Projection(ExistentialProjection<'tcx>), . /// E.g., `Send`. 58 ( 0.00%) AutoTrait(DefId), . } . . 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. 290 ( 0.00%) pub fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering { . use self::ExistentialPredicate::*; 388 ( 0.00%) match (*self, *other) { . (Trait(_), Trait(_)) => Ordering::Equal, . (Projection(ref a), Projection(ref b)) => { . tcx.def_path_hash(a.item_def_id).cmp(&tcx.def_path_hash(b.item_def_id)) . } . (AutoTrait(ref a), AutoTrait(ref b)) => { . tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b)) . } . (Trait(_), _) => Ordering::Less, . (Projection(_), Trait(_)) => Ordering::Greater, . (Projection(_), _) => Ordering::Less, . (AutoTrait(_), _) => Ordering::Greater, . } 348 ( 0.00%) } . } . . impl<'tcx> Binder<'tcx, ExistentialPredicate<'tcx>> { 6,822 ( 0.00%) pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> { . use crate::ty::ToPredicate; 3,790 ( 0.00%) 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 trait_ref = self.rebind(ty::TraitRef { . def_id: did, . substs: tcx.mk_substs_trait(self_ty, &[]), . }); . trait_ref.without_const().to_predicate(tcx) . } . } 6,064 ( 0.00%) } . } . . 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 826 ---------------------------------------- -- line 839 ---------------------------------------- . /// are the set `{Sync}`. . /// . /// 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. 712 ( 0.00%) pub fn principal(&self) -> Option>> { 5,174 ( 0.00%) self[0] 3,038 ( 0.00%) .map_bound(|this| match this { . ExistentialPredicate::Trait(tr) => Some(tr), . _ => None, 2,848 ( 0.00%) }) . .transpose() 2,136 ( 0.00%) } . 766 ( 0.00%) pub fn principal_def_id(&self) -> Option { . self.principal().map(|trait_ref| trait_ref.skip_binder().def_id) 1,532 ( 0.00%) } . . #[inline] . pub fn projection_bounds<'a>( . &'a self, . ) -> impl Iterator>> + 'a { . self.iter().filter_map(|predicate| { . predicate 8 ( 0.00%) .map_bound(|pred| match pred { . ExistentialPredicate::Projection(projection) => Some(projection), . _ => None, . }) . .transpose() . }) . } . . #[inline] . pub fn auto_traits<'a>(&'a self) -> impl Iterator + 'a { 2 ( 0.00%) 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 884 ---------------------------------------- -- line 886 ---------------------------------------- . /// T: Foo . /// . /// This would be represented by a trait-reference where the `DefId` is the . /// `DefId` for the trait `Foo` and the substs 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,868 ( 0.00%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 4,837,812 ( 0.02%) #[derive(HashStable, TypeFoldable)] . pub struct TraitRef<'tcx> { 1,749 ( 0.00%) pub def_id: DefId, 2,978,259 ( 0.01%) pub substs: SubstsRef<'tcx>, . } . . impl<'tcx> TraitRef<'tcx> { 4,394 ( 0.00%) pub fn new(def_id: DefId, substs: SubstsRef<'tcx>) -> TraitRef<'tcx> { . TraitRef { def_id, substs } 17,576 ( 0.00%) } . . /// Returns a `TraitRef` of the form `P0: Foo` where `Pi` . /// are the parameters defined on trait. 891 ( 0.00%) pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> Binder<'tcx, TraitRef<'tcx>> { 396 ( 0.00%) ty::Binder::dummy(TraitRef { . def_id, 594 ( 0.00%) substs: InternalSubsts::identity_for_item(tcx, def_id), . }) 792 ( 0.00%) } . . #[inline] 3 ( 0.00%) pub fn self_ty(&self) -> Ty<'tcx> { . self.substs.type_at(0) 2 ( 0.00%) } . 11,144 ( 0.00%) pub fn from_method( . tcx: TyCtxt<'tcx>, . trait_id: DefId, . substs: SubstsRef<'tcx>, . ) -> ty::TraitRef<'tcx> { . let defs = tcx.generics_of(trait_id); . 1,393 ( 0.00%) ty::TraitRef { def_id: trait_id, substs: tcx.intern_substs(&substs[..defs.params.len()]) } 15,323 ( 0.00%) } . } . . pub type PolyTraitRef<'tcx> = Binder<'tcx, TraitRef<'tcx>>; . . impl<'tcx> PolyTraitRef<'tcx> { . pub fn self_ty(&self) -> Binder<'tcx, Ty<'tcx>> { . self.map_bound_ref(|tr| tr.self_ty()) . } . . pub fn def_id(&self) -> DefId { 45,537 ( 0.00%) self.skip_binder().def_id 15,179 ( 0.00%) } . 9,201 ( 0.00%) pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> { 18,402 ( 0.00%) self.map_bound(|trait_ref| ty::TraitPredicate { . trait_ref, . constness: ty::BoundConstness::NotConst, . polarity: ty::ImplPolarity::Positive, . }) 9,201 ( 0.00%) } . } . . /// An existential reference to a trait, where `Self` is erased. . /// For example, the trait object `Trait<'a, 'b, X, Y>` is: . /// . /// 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). 180 ( 0.00%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 30,710 ( 0.00%) #[derive(HashStable, TypeFoldable)] . pub struct ExistentialTraitRef<'tcx> { 4,186 ( 0.00%) pub def_id: DefId, 36,578 ( 0.00%) pub substs: SubstsRef<'tcx>, . } . . impl<'tcx> ExistentialTraitRef<'tcx> { 672 ( 0.00%) pub fn erase_self_ty( . tcx: TyCtxt<'tcx>, . trait_ref: ty::TraitRef<'tcx>, . ) -> ty::ExistentialTraitRef<'tcx> { . // Assert there is a Self. . trait_ref.substs.type_at(0); . . ty::ExistentialTraitRef { . def_id: trait_ref.def_id, . substs: tcx.intern_substs(&trait_ref.substs[1..]), . } 672 ( 0.00%) } . . /// 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. 4 ( 0.00%) 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()); . 2 ( 0.00%) ty::TraitRef { def_id: self.def_id, substs: tcx.mk_substs_trait(self_ty, self.substs) } 10 ( 0.00%) } . } . . pub type PolyExistentialTraitRef<'tcx> = Binder<'tcx, ExistentialTraitRef<'tcx>>; . . impl<'tcx> PolyExistentialTraitRef<'tcx> { . pub fn def_id(&self) -> DefId { . self.skip_binder().def_id . } . . /// 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. 1,074 ( 0.00%) pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::PolyTraitRef<'tcx> { 1,642 ( 0.00%) self.map_bound(|trait_ref| trait_ref.with_self_ty(tcx, self_ty)) 1,432 ( 0.00%) } . } . 96,034 ( 0.00%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] 190 ( 0.00%) #[derive(HashStable)] . pub enum BoundVariableKind { . Ty(BoundTyKind), . Region(BoundRegionKind), . Const, . } . . /// Binder is a binder for higher-ranked lifetimes or types. It is part of the . /// 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. 77,681 ( 0.00%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] 1,285,619 ( 0.00%) pub struct Binder<'tcx, T>(T, &'tcx List); . . impl<'tcx, T> Binder<'tcx, T> . where . T: TypeFoldable<'tcx>, . { . /// 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. 74,790 ( 0.00%) pub fn dummy(value: T) -> Binder<'tcx, T> { 409,341 ( 0.00%) assert!(!value.has_escaping_bound_vars()); 897,553 ( 0.00%) Binder(value, ty::List::empty()) 74,373 ( 0.00%) } . . pub fn bind_with_vars(value: T, vars: &'tcx List) -> Binder<'tcx, T> { . if cfg!(debug_assertions) { . let mut validator = ValidateBoundVars::new(vars); . value.visit_with(&mut validator); . } 57,467 ( 0.00%) Binder(value, 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 { 3,587,474 ( 0.01%) self.0 . } . . pub fn bound_vars(&self) -> &'tcx List { 6,170 ( 0.00%) self.1 . } . . pub fn as_ref(&self) -> Binder<'tcx, &T> { 21,018 ( 0.00%) Binder(&self.0, self.1) . } . . pub fn map_bound_ref_unchecked(&self, f: F) -> Binder<'tcx, U> . where . F: FnOnce(&T) -> U, . { . let value = f(&self.0); . Binder(value, self.1) -- line 1083 ---------------------------------------- -- line 1085 ---------------------------------------- . . pub fn map_bound_ref>(&self, f: F) -> Binder<'tcx, U> . where . F: FnOnce(&T) -> U, . { . self.as_ref().map_bound(f) . } . 364 ( 0.00%) pub fn map_bound>(self, f: F) -> Binder<'tcx, U> . where . F: FnOnce(T) -> U, . { 114,601 ( 0.00%) let value = f(self.0); . if cfg!(debug_assertions) { . let mut validator = ValidateBoundVars::new(self.1); . value.visit_with(&mut validator); . } 835,303 ( 0.00%) Binder(value, self.1) 364 ( 0.00%) } . . pub fn try_map_bound, E>(self, f: F) -> Result, E> . where . F: FnOnce(T) -> Result, . { . let value = f(self.0)?; . if cfg!(debug_assertions) { . let mut validator = ValidateBoundVars::new(self.1); . value.visit_with(&mut validator); . } 19,821 ( 0.00%) Ok(Binder(value, self.1)) . } . . /// 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 -- line 1122 ---------------------------------------- -- line 1126 ---------------------------------------- . pub fn rebind(&self, value: U) -> Binder<'tcx, U> . where . U: TypeFoldable<'tcx>, . { . if cfg!(debug_assertions) { . let mut validator = ValidateBoundVars::new(self.bound_vars()); . value.visit_with(&mut validator); . } 50,383 ( 0.00%) Binder(value, self.1) . } . . /// 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 1142 ---------------------------------------- -- line 1143 ---------------------------------------- . /// 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: TypeFoldable<'tcx>, . { 561,386 ( 0.00%) if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) } 770 ( 0.00%) } . . /// 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. . pub fn split(self, f: F) -> (Binder<'tcx, U>, Binder<'tcx, V>) -- line 1160 ---------------------------------------- -- line 1170 ---------------------------------------- . pub fn transpose(self) -> Option> { . let bound_vars = self.1; . self.0.map(|v| Binder(v, bound_vars)) . } . } . . /// Represents the projection of an associated type. In explicit UFCS . /// form this would be written `>::N`. 4,847 ( 0.00%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] 443,023 ( 0.00%) #[derive(HashStable, TypeFoldable)] . pub struct ProjectionTy<'tcx> { . /// The parameters of the associated item. 296,147 ( 0.00%) pub substs: SubstsRef<'tcx>, . . /// The `DefId` of the `TraitItem` for the associated type `N`. . /// . /// Note that this is not the `DefId` of the `TraitRef` containing this . /// associated type, which is in `tcx.associated_item(item_def_id).container`. 486,972 ( 0.00%) pub item_def_id: DefId, . } . . impl<'tcx> ProjectionTy<'tcx> { 57,820 ( 0.00%) pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId { 16,520 ( 0.00%) tcx.associated_item(self.item_def_id).container.id() 66,080 ( 0.00%) } . . /// Extracts the underlying trait reference and own substs from this projection. . /// For example, if this is a projection of `::Item<'a>`, . /// then this function would return a `T: Iterator` trait reference and `['a]` as the own substs 156,107 ( 0.00%) pub fn trait_ref_and_own_substs( . &self, . tcx: TyCtxt<'tcx>, . ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { 66,903 ( 0.00%) let def_id = tcx.associated_item(self.item_def_id).container.id(); . let trait_generics = tcx.generics_of(def_id); 111,505 ( 0.00%) ( . ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, trait_generics) }, . &self.substs[trait_generics.count()..], . ) 200,709 ( 0.00%) } . . /// 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 substs for generic associated types . /// consider calling [Self::trait_ref_and_own_substs] to get those . /// as well. 73,971 ( 0.00%) pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> { 8,219 ( 0.00%) let def_id = self.trait_def_id(tcx); 8,219 ( 0.00%) ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, tcx.generics_of(def_id)) } 90,409 ( 0.00%) } . 16,475 ( 0.00%) pub fn self_ty(&self) -> Ty<'tcx> { 49,425 ( 0.00%) self.substs.type_at(0) 32,950 ( 0.00%) } . } . . #[derive(Copy, Clone, Debug, TypeFoldable)] . pub struct GenSig<'tcx> { . pub resume_ty: Ty<'tcx>, . pub yield_ty: Ty<'tcx>, . pub return_ty: Ty<'tcx>, . } -- line 1233 ---------------------------------------- -- line 1235 ---------------------------------------- . 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. 162,621 ( 0.00%) #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 94,409 ( 0.00%) #[derive(HashStable, TypeFoldable)] . pub struct FnSig<'tcx> { 6,114 ( 0.00%) pub inputs_and_output: &'tcx List>, 61,971 ( 0.00%) pub c_variadic: bool, 11,741 ( 0.00%) pub unsafety: hir::Unsafety, 61,800 ( 0.00%) pub abi: abi::Abi, . } . . impl<'tcx> FnSig<'tcx> { 72,607 ( 0.00%) pub fn inputs(&self) -> &'tcx [Ty<'tcx>] { 311,470 ( 0.00%) &self.inputs_and_output[..self.inputs_and_output.len() - 1] 145,214 ( 0.00%) } . 43,371 ( 0.00%) pub fn output(&self) -> Ty<'tcx> { 332,772 ( 0.00%) self.inputs_and_output[self.inputs_and_output.len() - 1] 86,742 ( 0.00%) } . . // 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 1267 ---------------------------------------- -- line 1270 ---------------------------------------- . } . } . . pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>; . . impl<'tcx> PolyFnSig<'tcx> { . #[inline] . pub fn inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]> { 24,797 ( 0.00%) self.map_bound_ref_unchecked(|fn_sig| fn_sig.inputs()) . } . #[inline] . pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> { 58,545 ( 0.00%) self.map_bound_ref(|fn_sig| fn_sig.inputs()[index]) . } . pub fn inputs_and_output(&self) -> ty::Binder<'tcx, &'tcx List>> { . self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output) 1,086 ( 0.00%) } . #[inline] . pub fn output(&self) -> ty::Binder<'tcx, Ty<'tcx>> { 44,537 ( 0.00%) self.map_bound_ref(|fn_sig| fn_sig.output()) . } . pub fn c_variadic(&self) -> bool { 2,172 ( 0.00%) self.skip_binder().c_variadic 1,086 ( 0.00%) } . pub fn unsafety(&self) -> hir::Unsafety { 10,368 ( 0.00%) self.skip_binder().unsafety 5,184 ( 0.00%) } . pub fn abi(&self) -> abi::Abi { 97,064 ( 0.00%) self.skip_binder().abi 24,266 ( 0.00%) } . } . . pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>; . 116 ( 0.00%) #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 1,126 ( 0.00%) #[derive(HashStable)] . pub struct ParamTy { 186 ( 0.00%) pub index: u32, . pub name: Symbol, . } . . impl<'tcx> ParamTy { 1,050 ( 0.00%) pub fn new(index: u32, name: Symbol) -> ParamTy { . ParamTy { index, name } 525 ( 0.00%) } . . pub fn for_def(def: &ty::GenericParamDef) -> ParamTy { 46 ( 0.00%) ParamTy::new(def.index, def.name) 23 ( 0.00%) } . . #[inline] . pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { . tcx.mk_ty_param(self.index, self.name) . } . } . . #[derive(Copy, Clone, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)] 45 ( 0.00%) #[derive(HashStable)] . pub struct ParamConst { 252 ( 0.00%) pub index: u32, 252 ( 0.00%) pub name: Symbol, . } . . impl ParamConst { . pub fn new(index: u32, name: Symbol) -> ParamConst { . ParamConst { index, name } . } . . pub fn for_def(def: &ty::GenericParamDef) -> ParamConst { -- line 1338 ---------------------------------------- -- line 1440 ---------------------------------------- . /// the inference variable is supposed to satisfy the relation . /// *for every value of the placeholder region*. To ensure that doesn't . /// happen, you can use `leak_check`. This is more clearly explained . /// by the [rustc dev guide]. . /// . /// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/ . /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ . /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html 11,182,487 ( 0.04%) #[derive(Clone, PartialEq, Eq, Hash, Copy, TyEncodable, TyDecodable, PartialOrd, Ord)] 2,726 ( 0.00%) pub enum RegionKind { . /// Region bound in a type or fn declaration which will be . /// substituted 'early' -- that is, at the same time when type . /// parameters are substituted. . ReEarlyBound(EarlyBoundRegion), . . /// Region bound in a function scope, which will be substituted when the . /// function is called. 481,482 ( 0.00%) ReLateBound(ty::DebruijnIndex, BoundRegion), . . /// When checking a function body, the types of all arguments and so forth . /// that refer to bound region parameters are modified to refer to free . /// region parameters. . ReFree(FreeRegion), . . /// Static data that has an "infinite" lifetime. Top in the region lattice. . ReStatic, -- line 1465 ---------------------------------------- -- line 1478 ---------------------------------------- . /// regions visible from `U`, but not less than regions not visible . /// from `U`. . ReEmpty(ty::UniverseIndex), . . /// Erased region, used by trait selection, in MIR and during codegen. . ReErased, . } . 37,160 ( 0.00%) #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)] . pub struct EarlyBoundRegion { 137,239 ( 0.00%) pub def_id: DefId, 89,297 ( 0.00%) pub index: u32, 346,809 ( 0.00%) pub name: Symbol, . } . . /// A **`const`** **v**ariable **ID**. . #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] . pub struct ConstVid<'tcx> { 5,511 ( 0.00%) pub index: u32, 516 ( 0.00%) pub phantom: PhantomData<&'tcx ()>, . } . . rustc_index::newtype_index! { . /// A **region** (lifetime) **v**ariable **ID**. . pub struct RegionVid { . DEBUG_FORMAT = custom, . } . } -- line 1505 ---------------------------------------- -- line 1513 ---------------------------------------- . rustc_index::newtype_index! { . pub struct BoundVar { .. } . } . . #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] . #[derive(HashStable)] . pub struct BoundTy { . pub var: BoundVar, 21,558 ( 0.00%) pub kind: BoundTyKind, . } . 366,657 ( 0.00%) #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] . #[derive(HashStable)] . pub enum BoundTyKind { . Anon, . Param(Symbol), . } . . impl From for BoundTy { . fn from(var: BoundVar) -> Self { . BoundTy { var, kind: BoundTyKind::Anon } . } . } . . /// A `ProjectionPredicate` for an `ExistentialTraitRef`. . #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] 32 ( 0.00%) #[derive(HashStable, TypeFoldable)] . pub struct ExistentialProjection<'tcx> { . pub item_def_id: DefId, 28 ( 0.00%) pub substs: SubstsRef<'tcx>, 7 ( 0.00%) pub term: Term<'tcx>, . } . . pub type PolyExistentialProjection<'tcx> = Binder<'tcx, ExistentialProjection<'tcx>>; . . impl<'tcx> ExistentialProjection<'tcx> { . /// Extracts the underlying existential trait reference from this projection. . /// For example, if this is a projection of `exists T. ::Item == X`, . /// then this function would return an `exists T. T: Iterator` existential trait -- line 1551 ---------------------------------------- -- line 1616 ---------------------------------------- . RegionKind::RePlaceholder(placeholder) => placeholder.name.is_named(), . RegionKind::ReEmpty(_) => false, . RegionKind::ReErased => false, . } . } . . #[inline] . pub fn is_late_bound(&self) -> bool { 8,044 ( 0.00%) matches!(*self, ty::ReLateBound(..)) . } . . #[inline] . pub fn is_placeholder(&self) -> bool { 2 ( 0.00%) matches!(*self, ty::RePlaceholder(..)) . } . . #[inline] . pub fn bound_at_or_above_binder(&self, index: ty::DebruijnIndex) -> bool { 478,643 ( 0.00%) match *self { . ty::ReLateBound(debruijn, _) => debruijn >= index, . _ => false, . } . } . . pub fn type_flags(&self) -> TypeFlags { . let mut flags = TypeFlags::empty(); . 588,405 ( 0.00%) 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 1651 ---------------------------------------- -- line 1669 ---------------------------------------- . ty::ReErased => { . flags = flags | TypeFlags::HAS_RE_ERASED; . } . } . . debug!("type_flags({:?}) = {:?}", self, flags); . . flags 74,922 ( 0.00%) } . . /// Given an early-bound or free region, returns the `DefId` where it was bound. . /// For example, consider the regions in this snippet of code: . /// . /// ``` . /// impl<'a> Foo { . /// ^^ -- early bound, declared on an impl . /// -- line 1685 ---------------------------------------- -- line 1713 ---------------------------------------- . . #[inline(always)] . pub fn flags(&self) -> TypeFlags { . self.flags . } . . #[inline] . pub fn is_unit(&self) -> bool { 11,246 ( 0.00%) match self.kind() { 2,478 ( 0.00%) Tuple(ref tys) => tys.is_empty(), . _ => false, . } . } . . #[inline] . pub fn is_never(&self) -> bool { 146,931 ( 0.00%) matches!(self.kind(), Never) . } . . #[inline] . pub fn is_primitive(&self) -> bool { . self.kind().is_primitive() . } . . #[inline] -- line 1737 ---------------------------------------- -- line 1741 ---------------------------------------- . . #[inline] . pub fn is_ref(&self) -> bool { . matches!(self.kind(), Ref(..)) . } . . #[inline] . pub fn is_ty_var(&self) -> bool { 206,102 ( 0.00%) matches!(self.kind(), Infer(TyVar(_))) . } . . #[inline] . pub fn ty_vid(&self) -> Option { 164,270 ( 0.00%) match self.kind() { 29,029 ( 0.00%) &Infer(TyVar(vid)) => Some(vid), . _ => None, . } . } . . #[inline] . pub fn is_ty_infer(&self) -> bool { 123 ( 0.00%) matches!(self.kind(), Infer(_)) . } . . #[inline] . pub fn is_phantom_data(&self) -> bool { . if let Adt(def, _) = self.kind() { def.is_phantom_data() } else { false } . } . . #[inline] -- line 1770 ---------------------------------------- -- line 1775 ---------------------------------------- . /// 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 { 2,265 ( 0.00%) match self.kind() { . ty::Param(ref data) => data.index == index, . _ => false, . } . } . . #[inline] . pub fn is_slice(&self) -> bool { . match self.kind() { . RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => matches!(ty.kind(), Slice(_) | Str), . _ => false, . } . } . . #[inline] . pub fn is_array(&self) -> bool { 57 ( 0.00%) matches!(self.kind(), Array(..)) . } . . #[inline] . pub fn is_simd(&self) -> bool { . match self.kind() { . Adt(def, _) => def.repr.simd(), . _ => false, . } . } . 420 ( 0.00%) pub fn sequence_element_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 840 ( 0.00%) match self.kind() { . Array(ty, _) | Slice(ty) => ty, . Str => tcx.mk_mach_uint(ty::UintTy::U8), . _ => bug!("`sequence_element_type` called on non-sequence value: {}", self), . } 420 ( 0.00%) } . . pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) { . match self.kind() { . Adt(def, substs) => { . assert!(def.repr.simd(), "`simd_size_and_type` called on non-SIMD type"); . let variant = def.non_enum_variant(); . let f0_ty = variant.fields[0].ty(tcx, substs); . -- line 1824 ---------------------------------------- -- line 1838 ---------------------------------------- . } . } . _ => bug!("`simd_size_and_type` called on invalid type"), . } . } . . #[inline] . pub fn is_region_ptr(&self) -> bool { 50 ( 0.00%) matches!(self.kind(), Ref(..)) . } . . #[inline] . pub fn is_mutable_ptr(&self) -> bool { . matches!( . self.kind(), . RawPtr(TypeAndMut { mutbl: hir::Mutability::Mut, .. }) . | Ref(_, _, hir::Mutability::Mut) -- line 1854 ---------------------------------------- -- line 1861 ---------------------------------------- . match self.kind() { . Ref(_, _, mutability) => Some(*mutability), . _ => None, . } . } . . #[inline] . pub fn is_unsafe_ptr(&self) -> bool { 19,132 ( 0.00%) 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 { 80 ( 0.00%) self.is_region_ptr() || self.is_unsafe_ptr() || self.is_fn_ptr() . } . . #[inline] . pub fn is_box(&self) -> bool { 199,348 ( 0.00%) match self.kind() { 42,495 ( 0.00%) Adt(def, _) => def.is_box(), . _ => false, . } . } . . /// Panics if called on any type other than `Box`. 124 ( 0.00%) pub fn boxed_ty(&self) -> Ty<'tcx> { 124 ( 0.00%) match self.kind() { 310 ( 0.00%) Adt(def, substs) if def.is_box() => substs.type_at(0), . _ => bug!("`boxed_ty` is called on non-box type {:?}", self), . } 124 ( 0.00%) } . . /// 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 { 3,104 ( 0.00%) matches!( 7,205 ( 0.00%) self.kind(), . Bool | Char . | Int(_) . | Float(_) . | Uint(_) . | FnDef(..) . | FnPtr(_) . | RawPtr(_) . | Infer(IntVar(_) | FloatVar(_)) . ) . } . . /// Returns `true` if this type is a floating point type. . #[inline] . pub fn is_floating_point(&self) -> bool { 4,946 ( 0.00%) matches!(self.kind(), Float(_) | Infer(FloatVar(_))) . } . . #[inline] . pub fn is_trait(&self) -> bool { 1,502 ( 0.00%) matches!(self.kind(), Dynamic(..)) . } . . #[inline] . pub fn is_enum(&self) -> bool { 11,376 ( 0.00%) matches!(self.kind(), Adt(adt_def, _) if adt_def.is_enum()) . } . . #[inline] . pub fn is_union(&self) -> bool { 40,672 ( 0.00%) matches!(self.kind(), Adt(adt_def, _) if adt_def.is_union()) . } . . #[inline] . pub fn is_closure(&self) -> bool { 8,252 ( 0.00%) matches!(self.kind(), Closure(..)) . } . . #[inline] . pub fn is_generator(&self) -> bool { 14,550 ( 0.00%) matches!(self.kind(), Generator(..)) . } . . #[inline] . pub fn is_integral(&self) -> bool { 71,248 ( 0.00%) 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 { 11,790 ( 0.00%) matches!(self.kind(), Infer(FreshTy(_) | FreshIntTy(_) | FreshFloatTy(_))) . } . . #[inline] . pub fn is_char(&self) -> bool { . 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 { 1,104 ( 0.00%) matches!(self.kind(), Int(_)) . } . . #[inline] . pub fn is_ptr_sized_integral(&self) -> bool { 2,727 ( 0.00%) 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(_)) . } . . /// 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. 37,800 ( 0.00%) pub fn builtin_deref(&self, explicit: bool) -> Option> { 264,779 ( 0.00%) match self.kind() { 682 ( 0.00%) Adt(def, _) if def.is_box() => { 98 ( 0.00%) Some(TypeAndMut { ty: self.boxed_ty(), mutbl: hir::Mutability::Not }) . } 158,294 ( 0.00%) Ref(_, ty, mutbl) => Some(TypeAndMut { ty, mutbl: *mutbl }), 9,868 ( 0.00%) RawPtr(mt) if explicit => Some(*mt), . _ => None, . } 75,600 ( 0.00%) } . . /// Returns the type of `ty[i]`. . pub fn builtin_index(&self) -> Option> { 30,533 ( 0.00%) match self.kind() { . Array(ty, _) | Slice(ty) => Some(ty), . _ => None, . } 2,345 ( 0.00%) } . 348,360 ( 0.00%) pub fn fn_sig(&self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> { 174,180 ( 0.00%) match self.kind() { 130,635 ( 0.00%) FnDef(def_id, substs) => tcx.fn_sig(*def_id).subst(tcx, substs), . FnPtr(f) => *f, . Error(_) => { . // ignore errors (#54954) . ty::Binder::dummy(FnSig::fake()) . } . Closure(..) => bug!( . "to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`", . ), . _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self), . } 391,905 ( 0.00%) } . . #[inline] . pub fn is_fn(&self) -> bool { 23,739 ( 0.00%) 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(), Opaque(..)) . } . . #[inline] . pub fn ty_adt_def(&self) -> Option<&'tcx AdtDef> { 15,091 ( 0.00%) match self.kind() { . Adt(adt, _) => Some(adt), . _ => None, . } . } . . /// Iterates over tuple fields. . /// Panics when called on anything but a tuple. 344 ( 0.00%) pub fn tuple_fields(&self) -> impl DoubleEndedIterator> { 6,162 ( 0.00%) match self.kind() { 3,622 ( 0.00%) Tuple(substs) => substs.iter().map(|field| field.expect_ty()), . _ => bug!("tuple_fields called on non-tuple"), . } 688 ( 0.00%) } . . /// Get the `i`-th element of a tuple. . /// Panics when called on anything but a tuple. 3 ( 0.00%) pub fn tuple_element_ty(&self, i: usize) -> Option> { 6 ( 0.00%) match self.kind() { 6 ( 0.00%) Tuple(substs) => substs.iter().nth(i).map(|field| field.expect_ty()), . _ => bug!("tuple_fields called on non-tuple"), . } 6 ( 0.00%) } . . /// If the type contains variants, returns the valid range of variant indices. . // . // FIXME: This requires the optimized MIR in the case of generators. . #[inline] . pub fn variant_range(&self, tcx: TyCtxt<'tcx>) -> Option> { . match self.kind() { . TyKind::Adt(adt, _) => Some(adt.variant_range()), -- line 2068 ---------------------------------------- -- line 2073 ---------------------------------------- . } . } . . /// If the type contains variants, returns the variant for `variant_index`. . /// Panics if `variant_index` is out of range. . // . // FIXME: This requires the optimized MIR in the case of generators. . #[inline] 25,370 ( 0.00%) pub fn discriminant_for_variant( . &self, . tcx: TyCtxt<'tcx>, . variant_index: VariantIdx, . ) -> Option> { 23,965 ( 0.00%) match self.kind() { 7,748 ( 0.00%) TyKind::Adt(adt, _) if adt.variants.is_empty() => { . // This can actually happen during CTFE, see . // https://github.com/rust-lang/rust/issues/89765. . None . } 3,874 ( 0.00%) TyKind::Adt(adt, _) if adt.is_enum() => { . Some(adt.discriminant_for_variant(tcx, variant_index)) . } . TyKind::Generator(def_id, substs, _) => { . Some(substs.as_generator().discriminant_for_variant(*def_id, tcx, variant_index)) . } . _ => None, . } 20,296 ( 0.00%) } . . /// Returns the type of the discriminant of this type. 60,880 ( 0.00%) pub fn discriminant_ty(&'tcx self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 30,440 ( 0.00%) match self.kind() { 48,704 ( 0.00%) ty::Adt(adt, _) if adt.is_enum() => adt.repr.discr_type().to_ty(tcx), . ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx), . . ty::Param(_) | ty::Projection(_) | ty::Opaque(..) | ty::Infer(ty::TyVar(_)) => { . let assoc_items = tcx.associated_item_def_ids( . tcx.require_lang_item(hir::LangItem::DiscriminantKind, None), . ); . tcx.mk_projection(assoc_items[0], tcx.intern_substs(&[self.into()])) . } -- line 2113 ---------------------------------------- -- line 2135 ---------------------------------------- . | 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) . } . } 48,704 ( 0.00%) } . . /// Returns the type of metadata for (potentially fat) pointers to this type. 306 ( 0.00%) pub fn ptr_metadata_ty( . &'tcx self, . tcx: TyCtxt<'tcx>, . normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>, . ) -> Ty<'tcx> { 306 ( 0.00%) let tail = tcx.struct_tail_with_normalize(self, normalize); 170 ( 0.00%) match tail.kind() { . // Sized types . ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) . | ty::Uint(_) . | ty::Int(_) . | ty::Bool . | ty::Float(_) . | ty::FnDef(..) . | ty::FnPtr(_) -- line 2160 ---------------------------------------- -- line 2170 ---------------------------------------- . | 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 . | ty::Tuple(..) => tcx.types.unit, . 68 ( 0.00%) ty::Str | ty::Slice(_) => tcx.types.usize, . ty::Dynamic(..) => { . let dyn_metadata = tcx.lang_items().dyn_metadata().unwrap(); . tcx.type_of(dyn_metadata).subst(tcx, &[tail.into()]) . }, . . ty::Projection(_) . | ty::Param(_) . | ty::Opaque(..) . | 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) . } . } 272 ( 0.00%) } . . /// When we create a closure, we record its kind (i.e., what trait . /// it implements) into its `ClosureSubsts` 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 . /// `tcx.closure_kind_ty(closure_kind)`. . /// . /// 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_typeck/src/check/upvar.rs`) . /// is complete, that type variable will be unified. 1,250 ( 0.00%) pub fn to_opt_closure_kind(&self) -> Option { 2,500 ( 0.00%) match self.kind() { 2,500 ( 0.00%) 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), . } 1,250 ( 0.00%) } . . /// 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`. 721,332 ( 0.00%) pub fn is_trivially_sized(&self, tcx: TyCtxt<'tcx>) -> bool { 480,888 ( 0.00%) match self.kind() { . ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) . | ty::Uint(_) . | ty::Int(_) . | ty::Bool . | ty::Float(_) . | ty::FnDef(..) . | ty::FnPtr(_) . | ty::RawPtr(..) -- line 2246 ---------------------------------------- -- line 2250 ---------------------------------------- . | ty::GeneratorWitness(..) . | ty::Array(..) . | ty::Closure(..) . | ty::Never . | ty::Error(_) => true, . . ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => false, . 4,705 ( 0.00%) ty::Tuple(tys) => tys.iter().all(|ty| ty.expect_ty().is_trivially_sized(tcx)), . 76,443 ( 0.00%) ty::Adt(def, _substs) => def.sized_constraint(tcx).is_empty(), . . ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => false, . . ty::Infer(ty::TyVar(_)) => false, . . ty::Bound(..) . | ty::Placeholder(..) . | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { . bug!("`is_trivially_sized` applied to unexpected type: {:?}", self) . } . } 721,332 ( 0.00%) } . } . . /// Extra information about why we ended up with a particular variance. . /// This is only used to add more information to error messages, and . /// has no effect on soundness. While choosing the 'wrong' `VarianceDiagInfo` . /// may lead to confusing notes in error messages, it will never cause . /// a miscompilation or unsoundness. . /// . /// When in doubt, use `VarianceDiagInfo::default()` 201 ( 0.00%) #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] . pub enum VarianceDiagInfo<'tcx> { . /// No additional information - this is the default. . /// We will not add any additional information to error messages. . #[default] . None, . /// We switched our variance because a generic argument occurs inside . /// the invariant generic argument of another type. . Invariant { -- line 2290 ---------------------------------------- -- line 2295 ---------------------------------------- . /// (e.g. `0` for `*mut T`, `1` for `MyStruct<'CovariantParam, 'InvariantParam>`) . param_index: u32, . }, . } . . impl<'tcx> VarianceDiagInfo<'tcx> { . /// Mirrors `Variance::xform` - used to 'combine' the existing . /// and new `VarianceDiagInfo`s when our variance changes. 152,536 ( 0.00%) pub fn xform(self, other: VarianceDiagInfo<'tcx>) -> VarianceDiagInfo<'tcx> { . // For now, just use the first `VarianceDiagInfo::Invariant` that we see 228,804 ( 0.00%) match self { . VarianceDiagInfo::None => other, . VarianceDiagInfo::Invariant { .. } => self, . } 76,268 ( 0.00%) } . } 48,107,026 ( 0.18%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/compiler/rustc_data_structures/src/sip128.rs -------------------------------------------------------------------------------- Ir -- line 91 ---------------------------------------- . // maximum of number bytes needed to fill an 8-byte-sized element on which . // SipHash operates. Note that for variable-sized copies which are known to be . // less than 8 bytes, this function will perform more work than necessary unless . // the compiler is able to optimize the extra work away. . #[inline] . unsafe fn copy_nonoverlapping_small(src: *const u8, dst: *mut u8, count: usize) { . debug_assert!(count <= 8); . 184,018 ( 0.00%) if count == 8 { . ptr::copy_nonoverlapping(src, dst, 8); . return; . } . . let mut i = 0; 198,646 ( 0.00%) if i + 3 < count { . ptr::copy_nonoverlapping(src.add(i), dst.add(i), 4); . i += 4; . } . 424,276 ( 0.00%) if i + 1 < count { . ptr::copy_nonoverlapping(src.add(i), dst.add(i), 2); 61,890 ( 0.00%) i += 2 . } . 198,646 ( 0.00%) if i < count { 135,990 ( 0.00%) *dst.add(i) = *src.add(i); . i += 1; . } . . debug_assert_eq!(i, count); . } . . // # Implementation . // -- line 124 ---------------------------------------- -- line 201 ---------------------------------------- . . hasher . } . . // A specialized write function for values with size <= 8. . #[inline] . fn short_write(&mut self, x: T) { . let size = mem::size_of::(); 2,801,261 ( 0.01%) let nbuf = self.nbuf; . debug_assert!(size <= 8); . debug_assert!(nbuf < BUFFER_SIZE); . debug_assert!(nbuf + size < BUFFER_WITH_SPILL_SIZE); . 19,337,054 ( 0.07%) if nbuf + size < BUFFER_SIZE { . unsafe { . // The memcpy call is optimized away because the size is known. . let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf); . ptr::copy_nonoverlapping(&x as *const _ as *const u8, dst, size); . } . 6,148,263 ( 0.02%) self.nbuf = nbuf + size; . . return; . } . 1,063,696 ( 0.00%) unsafe { self.short_write_process_buffer(x) } . } . . // A specialized write function for values with size <= 8 that should only . // be called when the write would cause the buffer to fill. . // . // SAFETY: the write of `x` into `self.buf` starting at byte offset . // `self.nbuf` must cause `self.buf` to become fully initialized (and not . // overflow) if it wasn't already. . #[inline(never)] 313,125 ( 0.00%) unsafe fn short_write_process_buffer(&mut self, x: T) { . let size = mem::size_of::(); 313,125 ( 0.00%) let nbuf = self.nbuf; . debug_assert!(size <= 8); . debug_assert!(nbuf < BUFFER_SIZE); . debug_assert!(nbuf + size >= BUFFER_SIZE); . debug_assert!(nbuf + size < BUFFER_WITH_SPILL_SIZE); . . // Copy first part of input into end of buffer, possibly into spill . // element. The memcpy call is optimized away because the size is known. . let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf); . ptr::copy_nonoverlapping(&x as *const _ as *const u8, dst, size); . . // Process buffer. . for i in 0..BUFFER_CAPACITY { 3,131,250 ( 0.01%) let elem = self.buf.get_unchecked(i).assume_init().to_le(); 2,505,000 ( 0.01%) self.state.v3 ^= elem; . Sip24Rounds::c_rounds(&mut self.state); 2,818,125 ( 0.01%) self.state.v0 ^= elem; . } . . // Copy remaining input into start of buffer by copying size - 1 . // elements from spill (at most size - 1 bytes could have overflowed . // into the spill). The memcpy call is optimized away because the size . // is known. And the whole copy is optimized away for size == 1. . let src = self.buf.get_unchecked(BUFFER_SPILL_INDEX) as *const _ as *const u8; . ptr::copy_nonoverlapping(src, self.buf.as_mut_ptr() as *mut u8, size - 1); . . // This function should only be called when the write fills the buffer. . // Therefore, when size == 1, the new `self.nbuf` must be zero. The size . // is statically known, so the branch is optimized away. 1,490,013 ( 0.01%) self.nbuf = if size == 1 { 0 } else { nbuf + size - BUFFER_SIZE }; 1,252,500 ( 0.00%) self.processed += BUFFER_SIZE; 626,250 ( 0.00%) } . . // A write function for byte slices. . #[inline] . fn slice_write(&mut self, msg: &[u8]) { . let length = msg.len(); 22,903 ( 0.00%) let nbuf = self.nbuf; . debug_assert!(nbuf < BUFFER_SIZE); . 621,724 ( 0.00%) if nbuf + length < BUFFER_SIZE { . unsafe { . let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf); . 225,772 ( 0.00%) if length <= 8 { . copy_nonoverlapping_small(msg.as_ptr(), dst, length); . } else { . // This memcpy is *not* optimized away. . ptr::copy_nonoverlapping(msg.as_ptr(), dst, length); . } . } . 114,022 ( 0.00%) self.nbuf = nbuf + length; . . return; . } . 93,928 ( 0.00%) unsafe { self.slice_write_process_buffer(msg) } . } . . // A write function for byte slices that should only be called when the . // write would cause the buffer to fill. . // . // SAFETY: `self.buf` must be initialized up to the byte offset `self.nbuf`, . // and `msg` must contain enough bytes to initialize the rest of the element . // containing the byte offset `self.nbuf`. . #[inline(never)] 54,525 ( 0.00%) unsafe fn slice_write_process_buffer(&mut self, msg: &[u8]) { . let length = msg.len(); 10,905 ( 0.00%) let nbuf = self.nbuf; . debug_assert!(nbuf < BUFFER_SIZE); . debug_assert!(nbuf + length >= BUFFER_SIZE); . . // Always copy first part of input into current element of buffer. . // This function should only be called when the write fills the buffer, . // so we know that there is enough input to fill the current element. 32,715 ( 0.00%) let valid_in_elem = nbuf % ELEM_SIZE; 10,905 ( 0.00%) let needed_in_elem = ELEM_SIZE - valid_in_elem; . . let src = msg.as_ptr(); . let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf); . copy_nonoverlapping_small(src, dst, needed_in_elem); . . // Process buffer. . . // Using `nbuf / ELEM_SIZE + 1` rather than `(nbuf + needed_in_elem) / . // ELEM_SIZE` to show the compiler that this loop's upper bound is > 0. . // We know that is true, because last step ensured we have a full . // element in the buffer. 21,810 ( 0.00%) let last = nbuf / ELEM_SIZE + 1; . . for i in 0..last { 84,833 ( 0.00%) let elem = self.buf.get_unchecked(i).assume_init().to_le(); 95,738 ( 0.00%) self.state.v3 ^= elem; . Sip24Rounds::c_rounds(&mut self.state); 169,666 ( 0.00%) self.state.v0 ^= elem; . } . . // Process the remaining element-sized chunks of input. . let mut processed = needed_in_elem; 21,810 ( 0.00%) let input_left = length - processed; 9,603 ( 0.00%) let elems_left = input_left / ELEM_SIZE; . let extra_bytes_left = input_left % ELEM_SIZE; . . for _ in 0..elems_left { 4,138 ( 0.00%) let elem = (msg.as_ptr().add(processed) as *const u64).read_unaligned().to_le(); 4,138 ( 0.00%) self.state.v3 ^= elem; . Sip24Rounds::c_rounds(&mut self.state); 4,138 ( 0.00%) self.state.v0 ^= elem; 8,276 ( 0.00%) processed += ELEM_SIZE; . } . . // Copy remaining input into start of buffer. . let src = msg.as_ptr().add(processed); . let dst = self.buf.as_mut_ptr() as *mut u8; . copy_nonoverlapping_small(src, dst, extra_bytes_left); . 10,905 ( 0.00%) self.nbuf = extra_bytes_left; 54,525 ( 0.00%) self.processed += nbuf + processed; 65,430 ( 0.00%) } . . #[inline] . pub fn finish128(mut self) -> (u64, u64) { . debug_assert!(self.nbuf < BUFFER_SIZE); . . // Process full elements in buffer. 87,939 ( 0.00%) let last = self.nbuf / ELEM_SIZE; . . // Since we're consuming self, avoid updating members for a potential . // performance gain. 117,252 ( 0.00%) let mut state = self.state; . . for i in 0..last { 86,178 ( 0.00%) let elem = unsafe { self.buf.get_unchecked(i).assume_init().to_le() }; 86,178 ( 0.00%) state.v3 ^= elem; . Sip24Rounds::c_rounds(&mut state); 86,178 ( 0.00%) state.v0 ^= elem; . } . . // Get remaining partial element. 58,626 ( 0.00%) let elem = if self.nbuf % ELEM_SIZE != 0 { . unsafe { . // Ensure element is initialized by writing zero bytes. At most . // `ELEM_SIZE - 1` are required given the above check. It's safe . // to write this many because we have the spill and we maintain . // `self.nbuf` such that this write will start before the spill. . let dst = (self.buf.as_mut_ptr() as *mut u8).add(self.nbuf); . ptr::write_bytes(dst, 0, ELEM_SIZE - 1); 25,481 ( 0.00%) self.buf.get_unchecked(last).assume_init().to_le() . } . } else { . 0 . }; . . // Finalize the hash. 80,979 ( 0.00%) let length = self.processed + self.nbuf; 52,360 ( 0.00%) let b: u64 = ((length as u64 & 0xff) << 56) | elem; . 26,180 ( 0.00%) state.v3 ^= b; . Sip24Rounds::c_rounds(&mut state); 26,180 ( 0.00%) state.v0 ^= b; . 26,180 ( 0.00%) state.v2 ^= 0xee; . Sip24Rounds::d_rounds(&mut state); 84,058 ( 0.00%) let _0 = state.v0 ^ state.v1 ^ state.v2 ^ state.v3; . 31,694 ( 0.00%) state.v1 ^= 0xdd; . Sip24Rounds::d_rounds(&mut state); 31,694 ( 0.00%) let _1 = state.v0 ^ state.v1 ^ state.v2 ^ state.v3; . . (_0, _1) . } . } . . impl Hasher for SipHasher128 { . #[inline] . fn write_u8(&mut self, i: u8) { -- line 414 ---------------------------------------- -- line 471 ---------------------------------------- . } . . #[derive(Debug, Clone, Default)] . struct Sip24Rounds; . . impl Sip24Rounds { . #[inline] . fn c_rounds(state: &mut State) { 11,171,156 ( 0.04%) compress!(state); 12,019,190 ( 0.04%) compress!(state); . } . . #[inline] . fn d_rounds(state: &mut State) { 168,108 ( 0.00%) compress!(state); 168,108 ( 0.00%) compress!(state); 168,108 ( 0.00%) compress!(state); 141,930 ( 0.00%) compress!(state); . } . } 2,226,613 ( 0.01%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/library/proc_macro/src/bridge/server.rs -------------------------------------------------------------------------------- Ir -- line 28 ---------------------------------------- . (type SourceFile: 'static + Clone;); . (type MultiSpan) => . (type MultiSpan: 'static;); . (type Diagnostic) => . (type Diagnostic: 'static;); . (type Span) => . (type Span: 'static + Copy + Eq + Hash;); . (fn drop(&mut self, $arg:ident: $arg_ty:ty)) => 114,918 ( 0.00%) (fn drop(&mut self, $arg: $arg_ty) { mem::drop($arg) }); . (fn clone(&mut self, $arg:ident: $arg_ty:ty) -> $ret_ty:ty) => 10,026 ( 0.00%) (fn clone(&mut self, $arg: $arg_ty) -> $ret_ty { $arg.clone() }); . ($($item:tt)*) => ($($item)*;) . } . . macro_rules! declare_server_traits { . ($($name:ident { . $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* . }),* $(,)?) => { . pub trait Types { -- line 46 ---------------------------------------- -- line 63 ---------------------------------------- . ($($name:ident { . $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* . }),* $(,)?) => { . impl Types for MarkedTypes { . $(type $name = Marked;)* . } . . $(impl $name for MarkedTypes { 4,362 ( 0.00%) $(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)? { 4,522,000 ( 0.02%) <_>::mark($name::$method(&mut self.0, $($arg.unmark()),*)) 4,362 ( 0.00%) })* . })* . } . } . with_api!(Self, self_, define_mark_types_impls); . . struct Dispatcher { . handle_store: HandleStore, . server: S, -- line 81 ---------------------------------------- -- line 89 ---------------------------------------- . pub trait DispatcherTrait { . // HACK(eddyb) these are here to allow `Self::$name` to work below. . $(type $name;)* . fn dispatch(&mut self, b: Buffer) -> Buffer; . } . . impl DispatcherTrait for Dispatcher> { . $(type $name = as Types>::$name;)* 11,289,020 ( 0.04%) fn dispatch(&mut self, mut b: Buffer) -> Buffer { . let Dispatcher { handle_store, server } = self; . 3,386,706 ( 0.01%) let mut reader = &b[..]; 7,902,314 ( 0.03%) match api_tags::Method::decode(&mut reader, &mut ()) { 5,443,779 ( 0.02%) $(api_tags::Method::$name(m) => match m { . $(api_tags::$name::$method => { . let mut call_method = || { 3,540,113 ( 0.01%) reverse_decode!(reader, handle_store; $($arg: $arg_ty),*); 2,181 ( 0.00%) $name::$method(server, $($arg),*) . }; . // HACK(eddyb) don't use `panic::catch_unwind` in a panic. . // If client and server happen to use the same `libstd`, . // `catch_unwind` asserts that the panic counter was 0, . // even when the closure passed to it didn't panic. . let r = if thread::panicking() { . Ok(call_method()) . } else { 5,071,722 ( 0.02%) panic::catch_unwind(panic::AssertUnwindSafe(call_method)) . .map_err(PanicMessage::from) . }; . . b.clear(); 12,469,309 ( 0.05%) r.encode(&mut b, handle_store); . })* . }),* . } 6,773,412 ( 0.02%) b 10,160,118 ( 0.04%) } . } . } . } . with_api!(Self, self_, define_dispatcher_impl); . . pub trait ExecutionStrategy { . fn run_bridge_and_client( . &self, -- line 133 ---------------------------------------- -- line 145 ---------------------------------------- . fn run_bridge_and_client( . &self, . dispatcher: &mut impl DispatcherTrait, . input: Buffer, . run_client: extern "C" fn(Bridge<'_>, D) -> Buffer, . client_data: D, . force_show_panics: bool, . ) -> Buffer { 10,160,216 ( 0.04%) let mut dispatch = |b| dispatcher.dispatch(b); . 980 ( 0.00%) run_client( 1,078 ( 0.00%) Bridge { cached_buffer: input, dispatch: (&mut dispatch).into(), force_show_panics }, . client_data, . ) . } . } . . // NOTE(eddyb) Two implementations are provided, the second one is a bit . // faster but neither is anywhere near as fast as same-thread execution. . -- line 164 ---------------------------------------- -- line 263 ---------------------------------------- . *state.lock().unwrap() = State::Res(b); . join_handle.thread().unpark(); . } . . join_handle.join().unwrap() . } . } . 1,274 ( 0.00%) fn run_server< . S: Server, . I: Encode>>, . O: for<'a, 's> DecodeMut<'a, 's, HandleStore>>, . D: Copy + Send + 'static, . >( . strategy: &impl ExecutionStrategy, . handle_counters: &'static client::HandleCounters, . server: S, . input: I, . run_client: extern "C" fn(Bridge<'_>, D) -> Buffer, . client_data: D, . force_show_panics: bool, . ) -> Result { . let mut dispatcher = 1,666 ( 0.00%) Dispatcher { handle_store: HandleStore::new(handle_counters), server: MarkedTypes(server) }; . . let mut b = Buffer::new(); 294 ( 0.00%) input.encode(&mut b, &mut dispatcher.handle_store); . 588 ( 0.00%) b = strategy.run_bridge_and_client( . &mut dispatcher, . b, . run_client, . client_data, . force_show_panics, . ); . 490 ( 0.00%) Result::decode(&mut &b[..], &mut dispatcher.handle_store) 980 ( 0.00%) } . . impl client::Client crate::TokenStream> { . pub fn run( . &self, . strategy: &impl ExecutionStrategy, . server: S, . input: S::TokenStream, . force_show_panics: bool, . ) -> Result { 196 ( 0.00%) let client::Client { get_handle_counters, run, f } = *self; 1,078 ( 0.00%) run_server( . strategy, 98 ( 0.00%) get_handle_counters(), 980 ( 0.00%) server, . as Types>::TokenStream::mark(input), . run, . f, . force_show_panics, . ) . .map( as Types>::TokenStream::unmark) . } . } -- line 322 ---------------------------------------- 2,576,751 ( 0.01%) -------------------------------------------------------------------------------- -- Auto-annotated source: /usr/home/liquid/rust/worktree-benchmarking/library/std/src/sys/unix/alloc.rs -------------------------------------------------------------------------------- Ir -- line 5 ---------------------------------------- . #[stable(feature = "alloc_system_type", since = "1.28.0")] . unsafe impl GlobalAlloc for System { . #[inline] . unsafe fn alloc(&self, layout: Layout) -> *mut u8 { . // jemalloc provides alignment less than MIN_ALIGN for small allocations. . // So only rely on MIN_ALIGN if size >= align. . // Also see and . // . 17,468,594 ( 0.06%) if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { 13,101,444 ( 0.05%) libc::malloc(layout.size()) as *mut u8 . } else { . #[cfg(target_os = "macos")] . { . if layout.align() > (1 << 31) { . return ptr::null_mut(); . } . } . aligned_malloc(&layout) . } . } . . #[inline] . unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { . // See the comment above in `alloc` for why this check looks the way it does. 557,452 ( 0.00%) if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { 836,178 ( 0.00%) libc::calloc(layout.size(), 1) as *mut u8 . } else { . let ptr = self.alloc(layout); . if !ptr.is_null() { . ptr::write_bytes(ptr, 0, layout.size()); . } . ptr . } . } . . #[inline] . unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { 4,506,500 ( 0.02%) libc::free(ptr as *mut libc::c_void) . } . . #[inline] . unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { 1,635,904 ( 0.01%) if layout.align() <= MIN_ALIGN && layout.align() <= new_size { 3,271,808 ( 0.01%) libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 . } else { . realloc_fallback(self, ptr, layout, new_size) . } . } . } . . cfg_if::cfg_if! { . if #[cfg(any( -- line 56 ---------------------------------------- -- line 84 ---------------------------------------- . } else if #[cfg(target_os = "wasi")] { . #[inline] . unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { . libc::aligned_alloc(layout.align(), layout.size()) as *mut u8 . } . } else { . #[inline] . unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { 1 ( 0.00%) let mut out = ptr::null_mut(); . // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`. . // Since these are all powers of 2, we can just use max. . let align = layout.align().max(crate::mem::size_of::()); 2 ( 0.00%) let ret = libc::posix_memalign(&mut out, align, layout.size()); 2 ( 0.00%) if ret != 0 { ptr::null_mut() } else { out as *mut u8 } . } . } . } 1 ( 0.00%) -------------------------------------------------------------------------------- The following files chosen for auto-annotation could not be found: -------------------------------------------------------------------------------- ./elf/../elf/dl-tls.c ./malloc/malloc.c ./string/../sysdeps/x86_64/multiarch/memcmp-avx2-movbe.S ./string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S ./string/../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S ./string/../sysdeps/x86_64/multiarch/strcmp-avx2.S ./string/../sysdeps/x86_64/multiarch/strlen-avx2.S /tmp/gcc-build/x86_64-unknown-linux-gnu/libstdc++-v3/libsupc++/../../../../gcc-5.5.0/libstdc++-v3/libsupc++/new_op.cc -------------------------------------------------------------------------------- Ir -------------------------------------------------------------------------------- 1,935,430,408 ( 7.10%) events annotated