about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-10-19 05:04:38 +0000
committerbors <bors@rust-lang.org>2021-10-19 05:04:38 +0000
commit2f22e63cc4b61d2f42b92eee11480a4f93dc2771 (patch)
tree644a5c3af1367a2bd0afe7fbdefd7898d379f1db /compiler
parentcd8b56f528631b128f36605b28ae06e36377dc68 (diff)
parent5bcaf04cbb7a3a6f11df3a4b9034e8d490e8c08c (diff)
downloadrust-2f22e63cc4b61d2f42b92eee11480a4f93dc2771.tar.gz
rust-2f22e63cc4b61d2f42b92eee11480a4f93dc2771.zip
Auto merge of #90037 - matthiaskrgr:rollup-cdfhxtn, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #89766 (RustWrapper: adapt for an LLVM API change)
 - #89867 (Fix macro_rules! duplication when reexported in the same module)
 - #89941 (removing TLS support in x86_64-unknown-none-hermitkernel)
 - #89956 (Suggest a case insensitive match name regardless of levenshtein distance)
 - #89988 (Do not promote values with const drop that need to be dropped)
 - #89997 (Add test for issue #84957 - `str.as_bytes()` in a `const` expression)
 - #90002 (:arrow_up: rust-analyzer)
 - #90034 (Tiny tweak to Iterator::unzip() doc comment example.)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs45
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs33
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h1
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp5
-rw-r--r--compiler/rustc_middle/src/mir/query.rs1
-rw-r--r--compiler/rustc_span/src/lev_distance.rs36
-rw-r--r--compiler/rustc_span/src/lev_distance/tests.rs10
-rw-r--r--compiler/rustc_target/src/spec/hermit_kernel_base.rs4
10 files changed, 92 insertions, 47 deletions
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index d704c4335c7..03e60deea27 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -22,7 +22,7 @@ use std::mem;
 use std::ops::Deref;
 
 use super::ops::{self, NonConstOp, Status};
-use super::qualifs::{self, CustomEq, HasMutInterior, NeedsNonConstDrop};
+use super::qualifs::{self, CustomEq, HasMutInterior, NeedsDrop, NeedsNonConstDrop};
 use super::resolver::FlowSensitiveAnalysis;
 use super::{is_lang_panic_fn, is_lang_special_const_fn, ConstCx, Qualif};
 use crate::const_eval::is_unstable_const_fn;
@@ -39,7 +39,8 @@ type QualifResults<'mir, 'tcx, Q> =
 #[derive(Default)]
 pub struct Qualifs<'mir, 'tcx> {
     has_mut_interior: Option<QualifResults<'mir, 'tcx, HasMutInterior>>,
-    needs_drop: Option<QualifResults<'mir, 'tcx, NeedsNonConstDrop>>,
+    needs_drop: Option<QualifResults<'mir, 'tcx, NeedsDrop>>,
+    needs_non_const_drop: Option<QualifResults<'mir, 'tcx, NeedsNonConstDrop>>,
     indirectly_mutable: Option<IndirectlyMutableResults<'mir, 'tcx>>,
 }
 
@@ -80,14 +81,14 @@ impl Qualifs<'mir, 'tcx> {
         location: Location,
     ) -> bool {
         let ty = ccx.body.local_decls[local].ty;
-        if !NeedsNonConstDrop::in_any_value_of_ty(ccx, ty) {
+        if !NeedsDrop::in_any_value_of_ty(ccx, ty) {
             return false;
         }
 
         let needs_drop = self.needs_drop.get_or_insert_with(|| {
             let ConstCx { tcx, body, .. } = *ccx;
 
-            FlowSensitiveAnalysis::new(NeedsNonConstDrop, ccx)
+            FlowSensitiveAnalysis::new(NeedsDrop, ccx)
                 .into_engine(tcx, &body)
                 .iterate_to_fixpoint()
                 .into_results_cursor(&body)
@@ -97,6 +98,33 @@ impl Qualifs<'mir, 'tcx> {
         needs_drop.get().contains(local) || self.indirectly_mutable(ccx, local, location)
     }
 
+    /// Returns `true` if `local` is `NeedsNonConstDrop` at the given `Location`.
+    ///
+    /// Only updates the cursor if absolutely necessary
+    pub fn needs_non_const_drop(
+        &mut self,
+        ccx: &'mir ConstCx<'mir, 'tcx>,
+        local: Local,
+        location: Location,
+    ) -> bool {
+        let ty = ccx.body.local_decls[local].ty;
+        if !NeedsNonConstDrop::in_any_value_of_ty(ccx, ty) {
+            return false;
+        }
+
+        let needs_non_const_drop = self.needs_non_const_drop.get_or_insert_with(|| {
+            let ConstCx { tcx, body, .. } = *ccx;
+
+            FlowSensitiveAnalysis::new(NeedsNonConstDrop, ccx)
+                .into_engine(tcx, &body)
+                .iterate_to_fixpoint()
+                .into_results_cursor(&body)
+        });
+
+        needs_non_const_drop.seek_before_primary_effect(location);
+        needs_non_const_drop.get().contains(local) || self.indirectly_mutable(ccx, local, location)
+    }
+
     /// Returns `true` if `local` is `HasMutInterior` at the given `Location`.
     ///
     /// Only updates the cursor if absolutely necessary.
@@ -173,6 +201,7 @@ impl Qualifs<'mir, 'tcx> {
 
         ConstQualifs {
             needs_drop: self.needs_drop(ccx, RETURN_PLACE, return_loc),
+            needs_non_const_drop: self.needs_non_const_drop(ccx, RETURN_PLACE, return_loc),
             has_mut_interior: self.has_mut_interior(ccx, RETURN_PLACE, return_loc),
             custom_eq,
             error_occured,
@@ -999,7 +1028,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
             }
 
             // Forbid all `Drop` terminators unless the place being dropped is a local with no
-            // projections that cannot be `NeedsDrop`.
+            // projections that cannot be `NeedsNonConstDrop`.
             TerminatorKind::Drop { place: dropped_place, .. }
             | TerminatorKind::DropAndReplace { place: dropped_place, .. } => {
                 // If we are checking live drops after drop-elaboration, don't emit duplicate
@@ -1019,15 +1048,15 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
                     return;
                 }
 
-                let needs_drop = if let Some(local) = dropped_place.as_local() {
+                let needs_non_const_drop = if let Some(local) = dropped_place.as_local() {
                     // Use the span where the local was declared as the span of the drop error.
                     err_span = self.body.local_decls[local].source_info.span;
-                    self.qualifs.needs_drop(self.ccx, local, location)
+                    self.qualifs.needs_non_const_drop(self.ccx, local, location)
                 } else {
                     true
                 };
 
-                if needs_drop {
+                if needs_non_const_drop {
                     self.check_op_spanned(
                         ops::LiveDrop { dropped_at: Some(terminator.source_info.span) },
                         err_span,
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs
index 1a8c8b1c78d..7a2be3c3bad 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs
@@ -97,7 +97,7 @@ impl Visitor<'tcx> for CheckLiveDrops<'mir, 'tcx> {
                 // `src/test/ui/consts/control-flow/drop-pass.rs`; e.g., when an `Option<Vec<T>>` is
                 // initialized with `None` and never changed, it still emits drop glue.
                 // Hence we additionally check the qualifs here to allow more code to pass.
-                if self.qualifs.needs_drop(self.ccx, dropped_place.local, location) {
+                if self.qualifs.needs_non_const_drop(self.ccx, dropped_place.local, location) {
                     // Use the span where the dropped local was declared for the error.
                     let span = self.body.local_decls[dropped_place.local].source_info.span;
                     self.check_live_drop(span);
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index 5eb7d7a91cc..dd2980d40ad 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -21,7 +21,8 @@ pub fn in_any_value_of_ty(
 ) -> ConstQualifs {
     ConstQualifs {
         has_mut_interior: HasMutInterior::in_any_value_of_ty(cx, ty),
-        needs_drop: NeedsNonConstDrop::in_any_value_of_ty(cx, ty),
+        needs_drop: NeedsDrop::in_any_value_of_ty(cx, ty),
+        needs_non_const_drop: NeedsNonConstDrop::in_any_value_of_ty(cx, ty),
         custom_eq: CustomEq::in_any_value_of_ty(cx, ty),
         error_occured,
     }
@@ -98,9 +99,31 @@ impl Qualif for HasMutInterior {
 }
 
 /// Constant containing an ADT that implements `Drop`.
-/// This must be ruled out (a) because we cannot run `Drop` during compile-time
-/// as that might not be a `const fn`, and (b) because implicit promotion would
-/// remove side-effects that occur as part of dropping that value.
+/// This must be ruled out because implicit promotion would remove side-effects
+/// that occur as part of dropping that value. N.B., the implicit promotion has
+/// to reject const Drop implementations because even if side-effects are ruled
+/// out through other means, the execution of the drop could diverge.
+pub struct NeedsDrop;
+
+impl Qualif for NeedsDrop {
+    const ANALYSIS_NAME: &'static str = "flow_needs_drop";
+    const IS_CLEARED_ON_MOVE: bool = true;
+
+    fn in_qualifs(qualifs: &ConstQualifs) -> bool {
+        qualifs.needs_drop
+    }
+
+    fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
+        ty.needs_drop(cx.tcx, cx.param_env)
+    }
+
+    fn in_adt_inherently(cx: &ConstCx<'_, 'tcx>, adt: &'tcx AdtDef, _: SubstsRef<'tcx>) -> bool {
+        adt.has_dtor(cx.tcx)
+    }
+}
+
+/// Constant containing an ADT that implements non-const `Drop`.
+/// This must be ruled out because we cannot run `Drop` during compile-time.
 pub struct NeedsNonConstDrop;
 
 impl Qualif for NeedsNonConstDrop {
@@ -108,7 +131,7 @@ impl Qualif for NeedsNonConstDrop {
     const IS_CLEARED_ON_MOVE: bool = true;
 
     fn in_qualifs(qualifs: &ConstQualifs) -> bool {
-        qualifs.needs_drop
+        qualifs.needs_non_const_drop
     }
 
     fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, mut ty: Ty<'tcx>) -> bool {
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index 7cfe3d7f809..ebcc8213c60 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -230,7 +230,7 @@ impl<'tcx> Validator<'_, 'tcx> {
 
                         // We cannot promote things that need dropping, since the promoted value
                         // would not get dropped.
-                        if self.qualif_local::<qualifs::NeedsNonConstDrop>(place.local) {
+                        if self.qualif_local::<qualifs::NeedsDrop>(place.local) {
                             return Err(Unpromotable);
                         }
 
diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
index 0b1b68d83b7..ebe495872c4 100644
--- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
+++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
@@ -18,7 +18,6 @@
 #include "llvm/Support/Host.h"
 #include "llvm/Support/Memory.h"
 #include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 87f423fb2d5..6d2e7d25336 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -21,6 +21,11 @@
 #include "llvm/Support/CBindingWrapping.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Host.h"
+#if LLVM_VERSION_LT(14, 0)
+#include "llvm/Support/TargetRegistry.h"
+#else
+#include "llvm/MC/TargetRegistry.h"
+#endif
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index d5541d7890c..cb3f3850958 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -225,6 +225,7 @@ pub struct BorrowCheckResult<'tcx> {
 pub struct ConstQualifs {
     pub has_mut_interior: bool,
     pub needs_drop: bool,
+    pub needs_non_const_drop: bool,
     pub custom_eq: bool,
     pub error_occured: Option<ErrorReported>,
 }
diff --git a/compiler/rustc_span/src/lev_distance.rs b/compiler/rustc_span/src/lev_distance.rs
index cea7871923b..c10968e06d7 100644
--- a/compiler/rustc_span/src/lev_distance.rs
+++ b/compiler/rustc_span/src/lev_distance.rs
@@ -58,34 +58,28 @@ pub fn find_best_match_for_name(
     let lookup = &lookup.as_str();
     let max_dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3);
 
-    let (case_insensitive_match, levenshtein_match) = name_vec
+    // Priority of matches:
+    // 1. Exact case insensitive match
+    // 2. Levenshtein distance match
+    // 3. Sorted word match
+    if let Some(case_insensitive_match) =
+        name_vec.iter().find(|candidate| candidate.as_str().to_uppercase() == lookup.to_uppercase())
+    {
+        return Some(*case_insensitive_match);
+    }
+    let levenshtein_match = name_vec
         .iter()
         .filter_map(|&name| {
             let dist = lev_distance(lookup, &name.as_str());
             if dist <= max_dist { Some((name, dist)) } else { None }
         })
         // Here we are collecting the next structure:
-        // (case_insensitive_match, (levenshtein_match, levenshtein_distance))
-        .fold((None, None), |result, (candidate, dist)| {
-            (
-                if candidate.as_str().to_uppercase() == lookup.to_uppercase() {
-                    Some(candidate)
-                } else {
-                    result.0
-                },
-                match result.1 {
-                    None => Some((candidate, dist)),
-                    Some((c, d)) => Some(if dist < d { (candidate, dist) } else { (c, d) }),
-                },
-            )
+        // (levenshtein_match, levenshtein_distance)
+        .fold(None, |result, (candidate, dist)| match result {
+            None => Some((candidate, dist)),
+            Some((c, d)) => Some(if dist < d { (candidate, dist) } else { (c, d) }),
         });
-    // Priority of matches:
-    // 1. Exact case insensitive match
-    // 2. Levenshtein distance match
-    // 3. Sorted word match
-    if let Some(candidate) = case_insensitive_match {
-        Some(candidate)
-    } else if levenshtein_match.is_some() {
+    if levenshtein_match.is_some() {
         levenshtein_match.map(|(candidate, _)| candidate)
     } else {
         find_match_by_sorted_words(name_vec, lookup)
diff --git a/compiler/rustc_span/src/lev_distance/tests.rs b/compiler/rustc_span/src/lev_distance/tests.rs
index 11822e9ef97..b32f8d32c13 100644
--- a/compiler/rustc_span/src/lev_distance/tests.rs
+++ b/compiler/rustc_span/src/lev_distance/tests.rs
@@ -31,17 +31,13 @@ fn test_find_best_match_for_name() {
 
         assert_eq!(find_best_match_for_name(&input, Symbol::intern("1111111111"), None), None);
 
-        let input = vec![Symbol::intern("aAAA")];
+        let input = vec![Symbol::intern("AAAA")];
         assert_eq!(
-            find_best_match_for_name(&input, Symbol::intern("AAAA"), None),
-            Some(Symbol::intern("aAAA"))
+            find_best_match_for_name(&input, Symbol::intern("aaaa"), None),
+            Some(Symbol::intern("AAAA"))
         );
 
         let input = vec![Symbol::intern("AAAA")];
-        // Returns None because `lev_distance > max_dist / 3`
-        assert_eq!(find_best_match_for_name(&input, Symbol::intern("aaaa"), None), None);
-
-        let input = vec![Symbol::intern("AAAA")];
         assert_eq!(
             find_best_match_for_name(&input, Symbol::intern("aaaa"), Some(4)),
             Some(Symbol::intern("AAAA"))
diff --git a/compiler/rustc_target/src/spec/hermit_kernel_base.rs b/compiler/rustc_target/src/spec/hermit_kernel_base.rs
index c55a46e69a8..414b0f7ff23 100644
--- a/compiler/rustc_target/src/spec/hermit_kernel_base.rs
+++ b/compiler/rustc_target/src/spec/hermit_kernel_base.rs
@@ -1,4 +1,4 @@
-use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions, TlsModel};
+use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions};
 
 pub fn opts() -> TargetOptions {
     let mut pre_link_args = LinkArgs::new();
@@ -13,12 +13,10 @@ pub fn opts() -> TargetOptions {
         disable_redzone: true,
         linker: Some("rust-lld".to_owned()),
         executables: true,
-        has_elf_tls: true,
         pre_link_args,
         panic_strategy: PanicStrategy::Abort,
         position_independent_executables: true,
         static_position_independent_executables: true,
-        tls_model: TlsModel::InitialExec,
         ..Default::default()
     }
 }