about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-10-02 19:42:07 +0000
committerbors <bors@rust-lang.org>2020-10-02 19:42:07 +0000
commit8876ffc9235dade728e1fbc4be4c85415fdd0bcd (patch)
tree6620cd20a64fe21bbe2a0dcb57e389315be3801e /compiler
parentbe3808108e15d84881f07af85b3145bcdd626e48 (diff)
parent0c5f0b1c690d108df0951333b1c24f6ebc02dc0c (diff)
Auto merge of #77462 - jonas-schievink:rollup-m0rqdh5, r=jonas-schievink
Rollup of 12 pull requests

Successful merges:

 - #76101 (Update RELEASES.md for 1.47.0)
 - #76739 (resolve: prohibit anon const non-static lifetimes)
 - #76811 (Doc alias name restriction)
 - #77405 (Add tracking issue of iter_advance_by feature)
 - #77409 (Add example for iter chain struct)
 - #77415 (Better error message for `async` blocks in a const-context)
 - #77423 (Add `-Zprecise-enum-drop-elaboration`)
 - #77432 (Use posix_spawn on musl targets)
 - #77441 (Fix AVR stack corruption bug)
 - #77442 (Clean up on example doc fixes for ptr::copy)
 - #77444 (Fix span for incorrect pattern field and add label)
 - #77453 (Stop running macOS builds on Azure Pipelines)

Failed merges:

r? `@ghost`
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_mir/src/dataflow/impls/mod.rs8
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/ops.rs5
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/validation.rs10
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs3
-rw-r--r--compiler/rustc_passes/src/check_attr.rs34
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs29
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs4
-rw-r--r--compiler/rustc_session/src/options.rs4
9 files changed, 87 insertions, 11 deletions
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 72e10bc4304..07ce9d0cd94 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -568,6 +568,7 @@ fn test_debugging_options_tracking_hash() {
     tracked!(osx_rpath_install_name, true);
     tracked!(panic_abort_tests, true);
     tracked!(plt, Some(true));
+    tracked!(precise_enum_drop_elaboration, false);
     tracked!(print_fuel, Some("abc".to_string()));
     tracked!(profile, true);
     tracked!(profile_emit, Some(PathBuf::from("abc")));
diff --git a/compiler/rustc_mir/src/dataflow/impls/mod.rs b/compiler/rustc_mir/src/dataflow/impls/mod.rs
index d4b9600f766..185f0edfeb6 100644
--- a/compiler/rustc_mir/src/dataflow/impls/mod.rs
+++ b/compiler/rustc_mir/src/dataflow/impls/mod.rs
@@ -358,6 +358,10 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
         discr: &mir::Operand<'tcx>,
         edge_effects: &mut impl SwitchIntEdgeEffects<G>,
     ) {
+        if !self.tcx.sess.opts.debugging_opts.precise_enum_drop_elaboration {
+            return;
+        }
+
         let enum_ = discr.place().and_then(|discr| {
             switch_on_enum_discriminant(self.tcx, &self.body, &self.body[block], discr)
         });
@@ -469,6 +473,10 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
         discr: &mir::Operand<'tcx>,
         edge_effects: &mut impl SwitchIntEdgeEffects<G>,
     ) {
+        if !self.tcx.sess.opts.debugging_opts.precise_enum_drop_elaboration {
+            return;
+        }
+
         if !self.mark_inactive_variants_as_uninit {
             return;
         }
diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs
index 25ed7859d21..32e233e337d 100644
--- a/compiler/rustc_mir/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs
@@ -151,14 +151,15 @@ impl NonConstOp for FnPtrCast {
 }
 
 #[derive(Debug)]
-pub struct Generator;
+pub struct Generator(pub hir::GeneratorKind);
 impl NonConstOp for Generator {
     fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
         Status::Forbidden
     }
 
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
-        ccx.tcx.sess.struct_span_err(span, "Generators and `async` functions cannot be `const`")
+        let msg = format!("{}s are not allowed in {}s", self.0, ccx.const_kind());
+        ccx.tcx.sess.struct_span_err(span, &msg)
     }
 }
 
diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs
index ab63fd03a33..4e714bfeed3 100644
--- a/compiler/rustc_mir/src/transform/check_consts/validation.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs
@@ -770,6 +770,14 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
                     return;
                 }
 
+                // `async` blocks get lowered to `std::future::from_generator(/* a closure */)`.
+                let is_async_block = Some(callee) == tcx.lang_items().from_generator_fn();
+                if is_async_block {
+                    let kind = hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block);
+                    self.check_op(ops::Generator(kind));
+                    return;
+                }
+
                 // HACK: This is to "unstabilize" the `transmute` intrinsic
                 // within const fns. `transmute` is allowed in all other const contexts.
                 // This won't really scale to more intrinsics or functions. Let's allow const
@@ -869,7 +877,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
             TerminatorKind::Abort => self.check_op(ops::Abort),
 
             TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => {
-                self.check_op(ops::Generator)
+                self.check_op(ops::Generator(hir::GeneratorKind::Gen))
             }
 
             TerminatorKind::Assert { .. }
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 2c0133a24dc..5aced9dc37c 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -795,6 +795,7 @@ impl<'a> Parser<'a> {
         }
         self.bump();
         let (fields, etc) = self.parse_pat_fields().unwrap_or_else(|mut e| {
+            e.span_label(path.span, "while parsing the fields for this pattern");
             e.emit();
             self.recover_stmt();
             (vec![], true)
@@ -844,7 +845,7 @@ impl<'a> Parser<'a> {
 
             // check that a comma comes after every field
             if !ate_comma {
-                let err = self.struct_span_err(self.prev_token.span, "expected `,`");
+                let err = self.struct_span_err(self.token.span, "expected `,`");
                 if let Some(mut delayed) = delayed_err {
                     delayed.emit();
                 }
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 1ec251326a8..b52216c45ce 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -260,23 +260,42 @@ impl CheckAttrVisitor<'tcx> {
         }
     }
 
+    fn doc_alias_str_error(&self, meta: &NestedMetaItem) {
+        self.tcx
+            .sess
+            .struct_span_err(
+                meta.span(),
+                "doc alias attribute expects a string: #[doc(alias = \"0\")]",
+            )
+            .emit();
+    }
+
     fn check_doc_alias(&self, attr: &Attribute, hir_id: HirId, target: Target) -> bool {
         if let Some(mi) = attr.meta() {
             if let Some(list) = mi.meta_item_list() {
                 for meta in list {
                     if meta.has_name(sym::alias) {
-                        if !meta.is_value_str()
-                            || meta
-                                .value_str()
-                                .map(|s| s.to_string())
-                                .unwrap_or_else(String::new)
-                                .is_empty()
+                        if !meta.is_value_str() {
+                            self.doc_alias_str_error(meta);
+                            return false;
+                        }
+                        let doc_alias =
+                            meta.value_str().map(|s| s.to_string()).unwrap_or_else(String::new);
+                        if doc_alias.is_empty() {
+                            self.doc_alias_str_error(meta);
+                            return false;
+                        }
+                        if let Some(c) =
+                            doc_alias.chars().find(|&c| c == '"' || c == '\'' || c.is_whitespace())
                         {
                             self.tcx
                                 .sess
                                 .struct_span_err(
                                     meta.span(),
-                                    "doc alias attribute expects a string: #[doc(alias = \"0\")]",
+                                    &format!(
+                                        "{:?} character isn't allowed in `#[doc(alias = \"...\")]`",
+                                        c,
+                                    ),
                                 )
                                 .emit();
                             return false;
@@ -312,6 +331,7 @@ impl CheckAttrVisitor<'tcx> {
                                     &format!("`#[doc(alias = \"...\")]` isn't allowed on {}", err),
                                 )
                                 .emit();
+                            return false;
                         }
                     }
                 }
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index ced272e474d..521ea7ad184 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -16,6 +16,7 @@ use rustc_hir::def::{self, CtorKind, DefKind};
 use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::PrimTy;
 use rustc_session::config::nightly_options;
+use rustc_session::parse::feature_err;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{BytePos, Span, DUMMY_SP};
@@ -1599,4 +1600,32 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
             _ => {}
         }
     }
+
+    /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics` so
+    /// this function will emit an error if `min_const_generics` is enabled, the body identified by
+    /// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
+    crate fn maybe_emit_forbidden_non_static_lifetime_error(
+        &self,
+        body_id: hir::BodyId,
+        lifetime_ref: &'tcx hir::Lifetime,
+    ) {
+        let is_anon_const = matches!(
+            self.tcx.def_kind(self.tcx.hir().body_owner_def_id(body_id)),
+            hir::def::DefKind::AnonConst
+        );
+        let is_allowed_lifetime = matches!(
+            lifetime_ref.name,
+            hir::LifetimeName::Implicit | hir::LifetimeName::Static | hir::LifetimeName::Underscore
+        );
+
+        if self.tcx.features().min_const_generics && is_anon_const && !is_allowed_lifetime {
+            feature_err(
+                &self.tcx.sess.parse_sess,
+                sym::const_generics,
+                lifetime_ref.span,
+                "a non-static lifetime is not allowed in a `const`",
+            )
+            .emit();
+        }
+    }
 }
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index 31360d47473..072fb509b19 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -1777,6 +1777,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         let result = loop {
             match *scope {
                 Scope::Body { id, s } => {
+                    // Non-static lifetimes are prohibited in anonymous constants under
+                    // `min_const_generics`.
+                    self.maybe_emit_forbidden_non_static_lifetime_error(id, lifetime_ref);
+
                     outermost_body = Some(id);
                     scope = s;
                 }
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 712c9cb87c9..b705ab6d931 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1008,6 +1008,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "a single extra argument to prepend the linker invocation (can be used several times)"),
     pre_link_args: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],
         "extra arguments to prepend to the linker invocation (space separated)"),
+    precise_enum_drop_elaboration: bool = (true, parse_bool, [TRACKED],
+        "use a more precise version of drop elaboration for matches on enums (default: yes). \
+        This results in better codegen, but has caused miscompilations on some tier 2 platforms. \
+        See #77382 and #74551."),
     print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
         "make rustc print the total optimization fuel used by a crate"),
     print_link_args: bool = (false, parse_bool, [UNTRACKED],