From b65bad99f7e9c7c2d9a19a54ff385146f522082c Mon Sep 17 00:00:00 2001 From: Spencer Imbleau Date: Wed, 12 May 2021 09:02:13 -0400 Subject: [PATCH 01/11] Clarified the attribute which prompts the warning The example call was lacking clarification of the `#![warn(rustdoc::invalid_codeblock_attributes)]` attribute which generates the specified warning. --- src/doc/rustdoc/src/lints.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index a6626679a7d60..c494eef1b5705 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -227,6 +227,8 @@ This lint **warns by default**. It detects code block attributes in documentation examples that have potentially mis-typed values. For example: ```rust +#![warn(rustdoc::invalid_codeblock_attributes)] + /// Example. /// /// ```should-panic From 2b27c82fbb691f6b2d3440535a13780fdf36ee23 Mon Sep 17 00:00:00 2001 From: Spencer Imbleau Date: Wed, 12 May 2021 09:52:28 -0400 Subject: [PATCH 02/11] Clarified all attributes which prompt warnings All calls which trigger rustdoc warnings and are now properly verbose for consistency. This uses the attribute in the examples which provides the user with more context. --- src/doc/rustdoc/src/lints.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index c494eef1b5705..dddff0475ad5c 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -70,6 +70,8 @@ This lint **warns by default**. This lint detects when [intra-doc links] from pu For example: ```rust +#![warn(private_intra_doc_links)] + /// [private] pub fn public() {} fn private() {} @@ -302,6 +304,8 @@ This lint is **warn-by-default**. It detects URLs which are not links. For example: ```rust +#![warn(bare_urls)] + /// http://example.org /// [http://example.net] pub fn foo() {} From d7884d4b08f0eedbdc6a3dabd0fdaa3779d393b6 Mon Sep 17 00:00:00 2001 From: Spencer Imbleau Date: Sun, 16 May 2021 12:54:53 -0400 Subject: [PATCH 03/11] Noted necessessity and fixed rustdoc:: prefix Now shows that certain warnings are unnecessary but includes them for consistency. --- src/doc/rustdoc/src/lints.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index dddff0475ad5c..a496db600ef93 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -70,7 +70,7 @@ This lint **warns by default**. This lint detects when [intra-doc links] from pu For example: ```rust -#![warn(private_intra_doc_links)] +#![warn(rustdoc::private_intra_doc_links)] // note: unecessary - warns by default. /// [private] pub fn public() {} @@ -112,7 +112,7 @@ This lint is **allowed by default**. It detects items missing documentation. For example: ```rust -#![warn(missing_docs)] +#![warn(rustdoc::missing_docs)] pub fn undocumented() {} # fn main() {} @@ -229,7 +229,7 @@ This lint **warns by default**. It detects code block attributes in documentation examples that have potentially mis-typed values. For example: ```rust -#![warn(rustdoc::invalid_codeblock_attributes)] +#![warn(rustdoc::invalid_codeblock_attributes)] // note: unecessary - warns by default. /// Example. /// @@ -304,7 +304,7 @@ This lint is **warn-by-default**. It detects URLs which are not links. For example: ```rust -#![warn(bare_urls)] +#![warn(rustdoc::bare_urls)] // note: unecessary - warns by default. /// http://example.org /// [http://example.net] From 8a7bb2bb66f86f2e106b85145eae824f84da2419 Mon Sep 17 00:00:00 2001 From: Spencer Imbleau Date: Sun, 16 May 2021 12:58:52 -0400 Subject: [PATCH 04/11] Fixed item typo which did not need prefix --- src/doc/rustdoc/src/lints.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index a496db600ef93..1c85ee0eeb553 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -112,7 +112,7 @@ This lint is **allowed by default**. It detects items missing documentation. For example: ```rust -#![warn(rustdoc::missing_docs)] +#![warn(missing_docs)] pub fn undocumented() {} # fn main() {} From 20f236c71ea45dcffb86b721c2b9548539dcef6b Mon Sep 17 00:00:00 2001 From: oliverbr <5881331+oliverbr@users.noreply.github.com> Date: Sat, 11 Sep 2021 09:13:47 +0200 Subject: [PATCH 05/11] correct ARM+MUSL notes - use "with MUSL" style where applicable - add "hardfloat" suffix for "armv7-unknown-linux-musleabihf" --- src/doc/rustc/src/platform-support.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 6da0703beacc9..382fcd857f26a 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -133,8 +133,8 @@ target | std | notes `armv5te-unknown-linux-musleabi` | ✓ | ARMv5TE Linux with MUSL `armv7-linux-androideabi` | ✓ | ARMv7a Android `armv7-unknown-linux-gnueabi` | ✓ |ARMv7 Linux (kernel 4.15, glibc 2.27) -`armv7-unknown-linux-musleabi` | ✓ |ARMv7 Linux, MUSL -`armv7-unknown-linux-musleabihf` | ✓ | ARMv7 Linux with MUSL +`armv7-unknown-linux-musleabi` | ✓ |ARMv7 Linux with MUSL +`armv7-unknown-linux-musleabihf` | ✓ | ARMv7 Linux with MUSL, hardfloat `armv7a-none-eabi` | * | Bare ARMv7-A `armv7r-none-eabi` | * | Bare ARMv7-R `armv7r-none-eabihf` | * | Bare ARMv7-R, hardfloat From d3f981b144c742c3e886a6234002a716a177bc98 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 15 Sep 2021 10:03:03 +0000 Subject: [PATCH 06/11] Move is_const_fn to under TyCtxt --- .../src/const_eval/fn_queries.rs | 19 +----------------- .../src/transform/promote_consts.rs | 6 ++---- compiler/rustc_middle/src/ty/context.rs | 20 +++++++++++++++++++ src/librustdoc/clean/mod.rs | 4 ++-- src/tools/clippy/clippy_utils/src/lib.rs | 1 - .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 10afd9560fa95..df4cc295fac5f 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -6,23 +6,6 @@ use rustc_middle::ty::TyCtxt; use rustc_span::symbol::Symbol; use rustc_target::spec::abi::Abi; -/// Whether the `def_id` counts as const fn in your current crate, considering all active -/// feature gates -pub fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - tcx.is_const_fn_raw(def_id) - && match is_unstable_const_fn(tcx, def_id) { - Some(feature_name) => { - // has a `rustc_const_unstable` attribute, check whether the user enabled the - // corresponding feature gate. - tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == feature_name) - } - // functions without const stability are either stable user written - // const fn or the user is using feature gates and we thus don't - // care what they do - None => true, - } -} - /// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { if tcx.is_const_fn_raw(def_id) { @@ -77,7 +60,7 @@ fn is_const_fn_raw(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - is_const_fn(tcx, def_id) + tcx.is_const_fn(def_id) && match tcx.lookup_const_stability(def_id) { Some(stab) => { if cfg!(debug_assertions) && stab.promotable { diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 52d04cb4ff1e0..35c6ae201037a 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -26,7 +26,6 @@ use rustc_index::vec::{Idx, IndexVec}; use std::cell::Cell; use std::{cmp, iter, mem}; -use crate::const_eval::{is_const_fn, is_unstable_const_fn}; use crate::transform::check_consts::{is_lang_panic_fn, qualifs, ConstCx}; use crate::transform::MirPass; @@ -656,8 +655,7 @@ impl<'tcx> Validator<'_, 'tcx> { let is_const_fn = match *fn_ty.kind() { ty::FnDef(def_id, _) => { - is_const_fn(self.tcx, def_id) - || is_unstable_const_fn(self.tcx, def_id).is_some() + self.tcx.is_const_fn_raw(def_id) || is_lang_panic_fn(self.tcx, def_id) } _ => false, @@ -1079,7 +1077,7 @@ pub fn is_const_fn_in_array_repeat_expression<'tcx>( if let ty::FnDef(def_id, _) = *literal.ty().kind() { if let Some((destination_place, _)) = destination { if destination_place == place { - if is_const_fn(ccx.tcx, def_id) { + if ccx.tcx.is_const_fn(def_id) { return true; } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1f5057d1da22f..2521b34a6b94e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2741,6 +2741,26 @@ impl<'tcx> TyCtxt<'tcx> { pub fn lifetime_scope(self, id: HirId) -> Option { self.lifetime_scope_map(id.owner).and_then(|mut map| map.remove(&id.local_id)) } + + /// Whether the `def_id` counts as const fn in the current crate, considering all active + /// feature gates + pub fn is_const_fn(self, def_id: DefId) -> bool { + if self.is_const_fn_raw(def_id) { + match self.lookup_const_stability(def_id) { + Some(stability) if stability.level.is_unstable() => { + // has a `rustc_const_unstable` attribute, check whether the user enabled the + // corresponding feature gate. + self.features().declared_lib_features.iter().any(|&(sym, _)| sym == stability.feature) + } + // functions without const stability are either stable user written + // const fn or the user is using feature gates and we thus don't + // care what they do + _ => true, + } + } else { + false + } + } } impl TyCtxtAt<'tcx> { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e281bbc59c255..ae7e818f106a6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -11,7 +11,7 @@ crate mod utils; use rustc_ast as ast; use rustc_attr as attr; -use rustc_const_eval::const_eval::{is_const_fn, is_unstable_const_fn}; +use rustc_const_eval::const_eval::is_unstable_const_fn; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; @@ -787,7 +787,7 @@ fn clean_fn_or_proc_macro( let mut func = (sig, generics, body_id).clean(cx); let def_id = item.def_id.to_def_id(); func.header.constness = - if is_const_fn(cx.tcx, def_id) && is_unstable_const_fn(cx.tcx, def_id).is_none() { + if cx.tcx.is_const_fn(def_id) && is_unstable_const_fn(cx.tcx, def_id).is_none() { hir::Constness::Const } else { hir::Constness::NotConst diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 3a94f47298390..beddc6f09be81 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -18,7 +18,6 @@ extern crate rustc_ast; extern crate rustc_ast_pretty; extern crate rustc_attr; -extern crate rustc_const_eval; extern crate rustc_data_structures; extern crate rustc_errors; extern crate rustc_hir; diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index e9a9895cb746f..67dda33e9daaf 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -364,7 +364,7 @@ fn check_terminator( } fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: Option<&RustcVersion>) -> bool { - rustc_const_eval::const_eval::is_const_fn(tcx, def_id) + tcx.is_const_fn(def_id) && tcx.lookup_const_stability(def_id).map_or(true, |const_stab| { if let rustc_attr::StabilityLevel::Stable { since } = const_stab.level { // Checking MSRV is manually necessary because `rustc` has no such concept. This entire From f8aa73d3dd951d69903e962054f2614b083c5b9c Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 15 Sep 2021 11:28:10 +0000 Subject: [PATCH 07/11] Coerce const FnDefs to implement const Fn traits --- .../src/transform/promote_consts.rs | 3 +- compiler/rustc_middle/src/traits/select.rs | 4 ++- compiler/rustc_middle/src/ty/context.rs | 5 ++- .../src/traits/select/candidate_assembly.rs | 6 ++-- .../src/traits/select/confirmation.rs | 2 +- .../src/traits/select/mod.rs | 17 ++++++---- .../const-closures.rs | 31 +++++++++++++++++++ 7 files changed, 55 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/rfc-2632-const-trait-impl/const-closures.rs diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 35c6ae201037a..c1cb5326ca35a 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -655,8 +655,7 @@ impl<'tcx> Validator<'_, 'tcx> { let is_const_fn = match *fn_ty.kind() { ty::FnDef(def_id, _) => { - self.tcx.is_const_fn_raw(def_id) - || is_lang_panic_fn(self.tcx, def_id) + self.tcx.is_const_fn_raw(def_id) || is_lang_panic_fn(self.tcx, def_id) } _ => false, }; diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index 3c0fedb360827..e236c4712c883 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -120,7 +120,9 @@ pub enum SelectionCandidate<'tcx> { /// Implementation of a `Fn`-family trait by one of the anonymous /// types generated for a fn pointer type (e.g., `fn(int) -> int`) - FnPointerCandidate, + FnPointerCandidate { + is_const: bool, + }, /// Builtin implementation of `DiscriminantKind`. DiscriminantKindCandidate, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 2521b34a6b94e..8cbae81f67348 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2750,7 +2750,10 @@ impl<'tcx> TyCtxt<'tcx> { Some(stability) if stability.level.is_unstable() => { // has a `rustc_const_unstable` attribute, check whether the user enabled the // corresponding feature gate. - self.features().declared_lib_features.iter().any(|&(sym, _)| sym == stability.feature) + self.features() + .declared_lib_features + .iter() + .any(|&(sym, _)| sym == stability.feature) } // functions without const stability are either stable user written // const fn or the user is using feature gates and we thus don't diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 6d64dc8254bb4..d31ae216d3a57 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -475,7 +475,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .. } = self_ty.fn_sig(self.tcx()).skip_binder() { - candidates.vec.push(FnPointerCandidate); + candidates.vec.push(FnPointerCandidate { is_const: false }); } } // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396). @@ -488,7 +488,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } = self_ty.fn_sig(self.tcx()).skip_binder() { if self.tcx().codegen_fn_attrs(def_id).target_features.is_empty() { - candidates.vec.push(FnPointerCandidate); + candidates + .vec + .push(FnPointerCandidate { is_const: self.tcx().is_const_fn(def_id) }); } } } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 3b6555de912e9..b3ebd1cb1c440 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -92,7 +92,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Ok(ImplSource::Generator(vtable_generator)) } - FnPointerCandidate => { + FnPointerCandidate { .. } => { let data = self.confirm_fn_pointer_candidate(obligation)?; Ok(ImplSource::FnPointer(data)) } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 7b948a0939fff..8dfd71e9cfb65 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1100,6 +1100,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // generator, this will raise error in other places // or ignore error with const_async_blocks feature GeneratorCandidate => {} + // FnDef where the function is const + FnPointerCandidate { is_const: true } => {} ConstDropCandidate => {} _ => { // reject all other types of candidates @@ -1513,6 +1515,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } + // Drop otherwise equivalent non-const fn pointer candidates + (FnPointerCandidate { .. }, FnPointerCandidate { is_const: false }) => true, + // Global bounds from the where clause should be ignored // here (see issue #50825). Otherwise, we have a where // clause so don't go around looking for impls. @@ -1523,7 +1528,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplCandidate(..) | ClosureCandidate | GeneratorCandidate - | FnPointerCandidate + | FnPointerCandidate { .. } | BuiltinObjectCandidate | BuiltinUnsizeCandidate | TraitUpcastingUnsizeCandidate(_) @@ -1541,7 +1546,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplCandidate(_) | ClosureCandidate | GeneratorCandidate - | FnPointerCandidate + | FnPointerCandidate { .. } | BuiltinObjectCandidate | BuiltinUnsizeCandidate | TraitUpcastingUnsizeCandidate(_) @@ -1571,7 +1576,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplCandidate(..) | ClosureCandidate | GeneratorCandidate - | FnPointerCandidate + | FnPointerCandidate { .. } | BuiltinObjectCandidate | BuiltinUnsizeCandidate | TraitUpcastingUnsizeCandidate(_) @@ -1583,7 +1588,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplCandidate(..) | ClosureCandidate | GeneratorCandidate - | FnPointerCandidate + | FnPointerCandidate { .. } | BuiltinObjectCandidate | BuiltinUnsizeCandidate | TraitUpcastingUnsizeCandidate(_) @@ -1664,7 +1669,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplCandidate(_) | ClosureCandidate | GeneratorCandidate - | FnPointerCandidate + | FnPointerCandidate { .. } | BuiltinObjectCandidate | BuiltinUnsizeCandidate | TraitUpcastingUnsizeCandidate(_) @@ -1673,7 +1678,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplCandidate(_) | ClosureCandidate | GeneratorCandidate - | FnPointerCandidate + | FnPointerCandidate { .. } | BuiltinObjectCandidate | BuiltinUnsizeCandidate | TraitUpcastingUnsizeCandidate(_) diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-closures.rs b/src/test/ui/rfc-2632-const-trait-impl/const-closures.rs new file mode 100644 index 0000000000000..99e608797ff65 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-closures.rs @@ -0,0 +1,31 @@ +// run-pass + +#![feature(const_trait_impl)] +#![feature(const_fn_trait_bound)] + +const fn answer_p1(f: &F) -> u8 + where + F: ~const FnOnce() -> u8, + F: ~const FnMut() -> u8, + F: ~const Fn() -> u8, +{ + f() * 7 +} + +const fn three() -> u8 { + 3 +} + +const fn answer_p2() -> u8 { + answer_p1(&three) +} + +const fn answer u8>(f: &F) -> u8 { + f() + f() +} + +const ANSWER: u8 = answer(&answer_p2); + +fn main() { + assert_eq!(ANSWER, 42) +} From d90934ce87352e7478f8c872a5a65363206082a0 Mon Sep 17 00:00:00 2001 From: Andreas Jonson Date: Wed, 29 Sep 2021 22:58:33 +0200 Subject: [PATCH 08/11] Fix use after drop in self-profile with llvm events --- compiler/rustc_codegen_llvm/src/back/write.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 92199f611bad0..985640fb60e04 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -405,13 +405,15 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager( None }; - let llvm_selfprofiler = if cgcx.prof.llvm_recording_enabled() { - let mut llvm_profiler = LlvmSelfProfiler::new(cgcx.prof.get_self_profiler().unwrap()); - &mut llvm_profiler as *mut _ as *mut c_void + let mut llvm_profiler = if cgcx.prof.llvm_recording_enabled() { + Some(LlvmSelfProfiler::new(cgcx.prof.get_self_profiler().unwrap())) } else { - std::ptr::null_mut() + None }; + let llvm_selfprofiler = + llvm_profiler.as_mut().map(|s| s as *mut _ as *mut c_void).unwrap_or(std::ptr::null_mut()); + let extra_passes = config.passes.join(","); // FIXME: NewPM doesn't provide a facility to pass custom InlineParams. From 1a796441f5d4578923cb5dd6859dacc8c7b823d0 Mon Sep 17 00:00:00 2001 From: chrismit3s Date: Fri, 1 Oct 2021 20:07:36 +0200 Subject: [PATCH 09/11] Clarify a sentence in the documentation of Vec (#84488) --- library/alloc/src/vec/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index c37ec37556157..92b6aaadf587c 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -369,7 +369,7 @@ mod spec_extend; /// scratch space that it may use however it wants. It will generally just do /// whatever is most efficient or otherwise easy to implement. Do not rely on /// removed data to be erased for security purposes. Even if you drop a `Vec`, its -/// buffer may simply be reused by another `Vec`. Even if you zero a `Vec`'s memory +/// buffer may simply be reused by another allocation. Even if you zero a `Vec`'s memory /// first, that might not actually happen because the optimizer does not consider /// this a side-effect that must be preserved. There is one case which we will /// not break, however: using `unsafe` code to write to the excess capacity, From 68b76a48358e611e31de8e96c56b9e50862a960e Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Fri, 1 Oct 2021 19:09:43 +0100 Subject: [PATCH 10/11] Normalize after substituting via `field.ty()` --- compiler/rustc_middle/src/ty/mod.rs | 4 +- .../src/thir/pattern/deconstruct_pat.rs | 4 +- .../src/thir/pattern/usefulness.rs | 3 +- .../issue-72476-and-89393-associated-type.rs | 56 +++++++++++++++++++ .../usefulness/issue-72476-associated-type.rs | 22 -------- 5 files changed, 62 insertions(+), 27 deletions(-) create mode 100644 src/test/ui/pattern/usefulness/issue-72476-and-89393-associated-type.rs delete mode 100644 src/test/ui/pattern/usefulness/issue-72476-associated-type.rs diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 777c6035be831..02c3b391a9715 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1627,8 +1627,8 @@ impl ReprOptions { } impl<'tcx> FieldDef { - /// Returns the type of this field. The `subst` is typically obtained - /// via the second field of `TyKind::AdtDef`. + /// Returns the type of this field. The resulting type is not normalized. The `subst` is + /// typically obtained via the second field of `TyKind::AdtDef`. pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> { tcx.type_of(self.did).subst(tcx, subst) } diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 69a7d44ff3972..dfcbd0da3a6e1 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -1154,6 +1154,8 @@ impl<'p, 'tcx> Fields<'p, 'tcx> { variant.fields.iter().enumerate().filter_map(move |(i, field)| { let ty = field.ty(cx.tcx, substs); + // `field.ty()` doesn't normalize after substituting. + let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty); let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx); let is_uninhabited = cx.is_uninhabited(ty); @@ -1671,7 +1673,7 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> { write!(f, "{}", hi) } IntRange(range) => write!(f, "{:?}", range), // Best-effort, will render e.g. `false` as `0..=0` - Wildcard | Missing { .. } | NonExhaustive => write!(f, "_"), + Wildcard | Missing { .. } | NonExhaustive => write!(f, "_ : {:?}", self.ty), Or => { for pat in self.iter_fields() { write!(f, "{}{:?}", start_or_continue(" | "), pat)?; diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index 650a87b2d8859..43adef3d03bed 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -781,8 +781,7 @@ fn is_useful<'p, 'tcx>( assert!(rows.iter().all(|r| r.len() == v.len())); - // FIXME(Nadrieril): Hack to work around type normalization issues (see #72476). - let ty = matrix.heads().next().map_or(v.head().ty(), |r| r.ty()); + let ty = v.head().ty(); let is_non_exhaustive = cx.is_foreign_non_exhaustive_enum(ty); let pcx = PatCtxt { cx, ty, span: v.head().span(), is_top_level, is_non_exhaustive }; diff --git a/src/test/ui/pattern/usefulness/issue-72476-and-89393-associated-type.rs b/src/test/ui/pattern/usefulness/issue-72476-and-89393-associated-type.rs new file mode 100644 index 0000000000000..058f419679847 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-72476-and-89393-associated-type.rs @@ -0,0 +1,56 @@ +// check-pass + +// From https://github.com/rust-lang/rust/issues/72476 +// and https://github.com/rust-lang/rust/issues/89393 + +trait Trait { + type Projection; +} + +struct A; +impl Trait for A { + type Projection = bool; +} + +struct B; +impl Trait for B { + type Projection = (u32, u32); +} + +struct Next(T::Projection); + +fn foo1(item: Next) { + match item { + Next(true) => {} + Next(false) => {} + } +} + +fn foo2(x: ::Projection) { + match x { + true => {} + false => {} + } +} + +fn foo3(x: Next) { + let Next((_, _)) = x; + match x { + Next((_, _)) => {} + } +} + +fn foo4(x: ::Projection) { + let (_, _) = x; + match x { + (_, _) => {} + } +} + +fn foo5(x: ::Projection) { + match x { + _ => {} + } +} + +fn main() {} diff --git a/src/test/ui/pattern/usefulness/issue-72476-associated-type.rs b/src/test/ui/pattern/usefulness/issue-72476-associated-type.rs deleted file mode 100644 index 1e1d21433b79c..0000000000000 --- a/src/test/ui/pattern/usefulness/issue-72476-associated-type.rs +++ /dev/null @@ -1,22 +0,0 @@ -// check-pass - -// From https://github.com/rust-lang/rust/issues/72476 - -trait A { - type Projection; -} - -impl A for () { - type Projection = bool; -} - -struct Next(T::Projection); - -fn f(item: Next<()>) { - match item { - Next(true) => {} - Next(false) => {} - } -} - -fn main() {} From 3792be6ac94186f3cffeaea98eff7477a0b1776f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 1 Oct 2021 11:46:34 +0200 Subject: [PATCH 11/11] Replace whitespaces in doctests' name with dashes --- src/librustdoc/doctest.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index ac760fad103c1..43abcf095d858 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -853,6 +853,7 @@ impl Collector { fn generate_name(&self, line: usize, filename: &FileName) -> String { let mut item_path = self.names.join("::"); + item_path.retain(|c| c != ' '); if !item_path.is_empty() { item_path.push(' '); }