diff options
| author | bors <bors@rust-lang.org> | 2020-10-02 19:42:07 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-10-02 19:42:07 +0000 |
| commit | 8876ffc9235dade728e1fbc4be4c85415fdd0bcd (patch) | |
| tree | 6620cd20a64fe21bbe2a0dcb57e389315be3801e /compiler | |
| parent | be3808108e15d84881f07af85b3145bcdd626e48 (diff) | |
| parent | 0c5f0b1c690d108df0951333b1c24f6ebc02dc0c (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.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/dataflow/impls/mod.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/ops.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/validation.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/pat.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 34 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 29 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/lifetimes.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_session/src/options.rs | 4 |
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], |
