From f2d7c05db0e4876b9c409a8be8e99aceadc34b1a Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 20 Dec 2020 21:07:13 -0500 Subject: Don't try to add nested predicate to Rustdoc auto-trait `ParamEnv` Fixes #80233 We already have logic in `evaluate_predicates` that tries to add unimplemented predicates to our `ParamEnv`. Trying to add a predicate that already holds can lead to errors later on, since projection will prefer trait candidates from the `ParamEnv` to predicates from an impl. --- .../rustdoc/issue-80233-normalize-auto-trait.rs | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/test/rustdoc/issue-80233-normalize-auto-trait.rs (limited to 'src') diff --git a/src/test/rustdoc/issue-80233-normalize-auto-trait.rs b/src/test/rustdoc/issue-80233-normalize-auto-trait.rs new file mode 100644 index 00000000000..585a0864bb2 --- /dev/null +++ b/src/test/rustdoc/issue-80233-normalize-auto-trait.rs @@ -0,0 +1,37 @@ +// Regression test for issue #80233 +// Tests that we don't ICE when processing auto traits + +#![crate_type = "lib"] +pub trait Trait1 {} + +pub trait Trait2 { + type Type2; +} + +pub trait Trait3 { + type Type3; +} + +impl Trait2 for Struct1 { + type Type2 = Struct1; +} + +impl Trait2 for Vec { + type Type2 = Vec; +} + +impl Trait3 for T { + type Type3 = Struct1; +} + +impl Trait3 for Vec { + type Type3 = Vec; +} + +pub struct Struct1 {} + +// @has issue_80233_normalize_auto_trait/struct.Question.html +// @has - '//code' 'impl Send for Question' +pub struct Question { + pub ins: < as Trait3>::Type3 as Trait2>::Type2, +} -- cgit 1.4.1-3-g733a5 From 5ea1d0e865e3a15c054233198622b711ed0b5f86 Mon Sep 17 00:00:00 2001 From: Tomasz Miąsko Date: Thu, 14 Jan 2021 00:00:00 +0000 Subject: Don't ICE when computing a layout of a generator tainted by errors --- .../rustc_codegen_llvm/src/debuginfo/metadata.rs | 5 ++-- compiler/rustc_middle/src/ty/layout.rs | 6 +++-- compiler/rustc_middle/src/ty/mod.rs | 6 +++-- compiler/rustc_middle/src/ty/sty.rs | 4 ++-- src/test/ui/generator/layout-error.rs | 28 ++++++++++++++++++++++ src/test/ui/generator/layout-error.stderr | 9 +++++++ 6 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/generator/layout-error.rs create mode 100644 src/test/ui/generator/layout-error.stderr (limited to 'src') diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 36a21b38c03..b9ae7963250 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1832,8 +1832,9 @@ impl<'tcx> VariantInfo<'_, 'tcx> { fn source_info(&self, cx: &CodegenCx<'ll, 'tcx>) -> Option> { match self { VariantInfo::Generator { def_id, variant_index, .. } => { - let span = - cx.tcx.generator_layout(*def_id).variant_source_info[*variant_index].span; + let span = cx.tcx.generator_layout(*def_id).unwrap().variant_source_info + [*variant_index] + .span; if !span.is_dummy() { let loc = cx.lookup_debug_loc(span.lo()); return Some(SourceInfo { diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 4475d4e9f2d..195e840866a 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1466,10 +1466,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { ) -> Result<&'tcx Layout, LayoutError<'tcx>> { use SavedLocalEligibility::*; let tcx = self.tcx; - let subst_field = |ty: Ty<'tcx>| ty.subst(tcx, substs); - let info = tcx.generator_layout(def_id); + let info = match tcx.generator_layout(def_id) { + None => return Err(LayoutError::Unknown(ty)), + Some(info) => info, + }; let (ineligible_locals, assignments) = self.generator_saved_local_eligibility(&info); // Build a prefix layout, including "promoting" all ineligible diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8068574a38f..1399fc76e02 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -3068,8 +3068,10 @@ impl<'tcx> TyCtxt<'tcx> { self.trait_def(trait_def_id).has_auto_impl } - pub fn generator_layout(self, def_id: DefId) -> &'tcx GeneratorLayout<'tcx> { - self.optimized_mir(def_id).generator_layout.as_ref().unwrap() + /// Returns layout of a generator. Layout might be unavailable if the + /// generator is tainted by errors. + pub fn generator_layout(self, def_id: DefId) -> Option<&'tcx GeneratorLayout<'tcx>> { + self.optimized_mir(def_id).generator_layout.as_ref() } /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 744c7a541a5..d43c5135d90 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -605,7 +605,7 @@ impl<'tcx> GeneratorSubsts<'tcx> { #[inline] pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range { // FIXME requires optimized MIR - let num_variants = tcx.generator_layout(def_id).variant_fields.len(); + let num_variants = tcx.generator_layout(def_id).unwrap().variant_fields.len(); VariantIdx::new(0)..VariantIdx::new(num_variants) } @@ -666,7 +666,7 @@ impl<'tcx> GeneratorSubsts<'tcx> { def_id: DefId, tcx: TyCtxt<'tcx>, ) -> impl Iterator> + Captures<'tcx>> { - let layout = tcx.generator_layout(def_id); + let layout = tcx.generator_layout(def_id).unwrap(); layout.variant_fields.iter().map(move |variant| { variant.iter().map(move |field| layout.field_tys[*field].subst(tcx, self.substs)) }) diff --git a/src/test/ui/generator/layout-error.rs b/src/test/ui/generator/layout-error.rs new file mode 100644 index 00000000000..059867277ad --- /dev/null +++ b/src/test/ui/generator/layout-error.rs @@ -0,0 +1,28 @@ +// Verifies that computing a layout of a generator tainted by type errors +// doesn't ICE. Regression test for #80998. +// +// edition:2018 + +#![feature(type_alias_impl_trait)] +use std::future::Future; + +pub struct Task(F); +impl Task { + fn new() -> Self { + todo!() + } + fn spawn(&self, _: impl FnOnce() -> F) { + todo!() + } +} + +fn main() { + async fn cb() { + let a = Foo; //~ ERROR cannot find value `Foo` in this scope + } + + type F = impl Future; + // Check that statics are inhabited computes they layout. + static POOL: Task = Task::new(); + Task::spawn(&POOL, || cb()); +} diff --git a/src/test/ui/generator/layout-error.stderr b/src/test/ui/generator/layout-error.stderr new file mode 100644 index 00000000000..b1a258f4f2c --- /dev/null +++ b/src/test/ui/generator/layout-error.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `Foo` in this scope + --> $DIR/layout-error.rs:21:17 + | +LL | let a = Foo; + | ^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. -- cgit 1.4.1-3-g733a5 From 744f885e2a505136203e3e0eef51f72dbe78b511 Mon Sep 17 00:00:00 2001 From: Dániel Buga Date: Sat, 9 Jan 2021 10:22:06 +0100 Subject: Remove unreachable panics from VecDeque --- library/alloc/src/collections/vec_deque/mod.rs | 9 ++++----- src/test/codegen/vecdeque_no_panic.rs | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 src/test/codegen/vecdeque_no_panic.rs (limited to 'src') diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index f8fad6de1a3..5b61e8911a5 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -1292,7 +1292,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn front(&self) -> Option<&T> { - if !self.is_empty() { Some(&self[0]) } else { None } + self.get(0) } /// Provides a mutable reference to the front element, or `None` if the @@ -1316,7 +1316,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn front_mut(&mut self) -> Option<&mut T> { - if !self.is_empty() { Some(&mut self[0]) } else { None } + self.get_mut(0) } /// Provides a reference to the back element, or `None` if the `VecDeque` is @@ -1336,7 +1336,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn back(&self) -> Option<&T> { - if !self.is_empty() { Some(&self[self.len() - 1]) } else { None } + self.get(self.len().wrapping_sub(1)) } /// Provides a mutable reference to the back element, or `None` if the @@ -1360,8 +1360,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn back_mut(&mut self) -> Option<&mut T> { - let len = self.len(); - if !self.is_empty() { Some(&mut self[len - 1]) } else { None } + self.get_mut(self.len().wrapping_sub(1)) } /// Removes the first element and returns it, or `None` if the `VecDeque` is diff --git a/src/test/codegen/vecdeque_no_panic.rs b/src/test/codegen/vecdeque_no_panic.rs new file mode 100644 index 00000000000..cbf420bada9 --- /dev/null +++ b/src/test/codegen/vecdeque_no_panic.rs @@ -0,0 +1,19 @@ +// This test checks that `VecDeque::front[_mut]()` and `VecDeque::back[_mut]()` can't panic. + +// compile-flags: -O +// ignore-debug: the debug assertions get in the way + +#![crate_type = "lib"] + +use std::collections::VecDeque; + +// CHECK-LABEL: @dont_panic +#[no_mangle] +pub fn dont_panic(v: &mut VecDeque) { + // CHECK-NOT: expect + // CHECK-NOT: panic + v.front(); + v.front_mut(); + v.back(); + v.back_mut(); +} -- cgit 1.4.1-3-g733a5 From c54678ab2f464a0275b9cb57765913a3a6a0f691 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Thu, 14 Jan 2021 15:21:44 -0500 Subject: Remove doctree::Variant --- src/librustdoc/clean/mod.rs | 13 ------------- src/librustdoc/doctree.rs | 6 ------ 2 files changed, 19 deletions(-) (limited to 'src') diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c74a5659942..5ec79c586dc 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1837,19 +1837,6 @@ impl Clean for rustc_hir::VariantData<'_> { } } -impl Clean for doctree::Variant<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let what_rustc_thinks = Item::from_hir_id_and_parts( - self.id, - Some(self.name), - VariantItem(Variant { kind: self.def.clean(cx) }), - cx, - ); - // don't show `pub` for variants, which are always public - Item { visibility: Inherited, ..what_rustc_thinks } - } -} - impl Clean for ty::VariantDef { fn clean(&self, cx: &DocContext<'_>) -> Item { let kind = match self.ctor_kind { diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index bc9f1cf8806..4710c91f929 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -48,12 +48,6 @@ crate enum StructType { Unit, } -crate struct Variant<'hir> { - crate name: Symbol, - crate id: hir::HirId, - crate def: &'hir hir::VariantData<'hir>, -} - #[derive(Debug)] crate struct Import<'hir> { crate name: Symbol, -- cgit 1.4.1-3-g733a5