about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-01-12 09:11:57 +0000
committerbors <bors@rust-lang.org>2024-01-12 09:11:57 +0000
commitbfd799f1a5a86d16e6b8caa2857bcb4aac6e0174 (patch)
treefe9cbaf736d3e96c6108070c7f84d629c23582bc
parent2b1365b34f0d5ee43944c4266a625923a7b312dd (diff)
parentd7a720a863ac55f3c8e4a12cbdd7a99c57907b28 (diff)
downloadrust-bfd799f1a5a86d16e6b8caa2857bcb4aac6e0174.tar.gz
rust-bfd799f1a5a86d16e6b8caa2857bcb4aac6e0174.zip
Auto merge of #119879 - matthiaskrgr:rollup-y710der, r=matthiaskrgr
Rollup of 4 pull requests

Successful merges:

 - #119781 (fix typo)
 - #119865 (Set `c_str_literals` stabilization version back to `CURRENT_RUSTC_VERSION`)
 - #119866 (Convert `effects` description to doc comment)
 - #119868 (Register even erroneous impls)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.toml2
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_middle/src/arena.rs1
-rw-r--r--compiler/rustc_middle/src/query/mod.rs3
-rw-r--r--compiler/rustc_middle/src/query/on_disk_cache.rs9
-rw-r--r--compiler/rustc_middle/src/traits/specialization_graph.rs14
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs4
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs68
-rw-r--r--tests/ui/generic-associated-types/unknown-lifetime-ice-119827.rs16
-rw-r--r--tests/ui/generic-associated-types/unknown-lifetime-ice-119827.stderr119
12 files changed, 190 insertions, 54 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 03915078838..2ea16c22666 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -64,7 +64,7 @@ exclude = [
 ]
 
 [profile.release.package.compiler_builtins]
-# The compiler-builtins crate cannot reference libcore, and it's own CI will
+# The compiler-builtins crate cannot reference libcore, and its own CI will
 # verify that this is the case. This requires, however, that the crate is built
 # without overflow checks and debug assertions. Forcefully disable debug
 # assertions and overflow checks here which should ensure that even if these
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index aa0db9891a5..6e3996b4509 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -77,7 +77,7 @@ declare_features! (
     /// Allows empty structs and enum variants with braces.
     (accepted, braced_empty_structs, "1.8.0", Some(29720)),
     /// Allows `c"foo"` literals.
-    (accepted, c_str_literals, "1.76.0", Some(105723)),
+    (accepted, c_str_literals, "CURRENT_RUSTC_VERSION", Some(105723)),
     /// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
     (accepted, cfg_attr_multi, "1.33.0", Some(54881)),
     /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 59ea828440f..2f2b551e6ec 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -450,7 +450,7 @@ declare_features! (
     (unstable, doc_masked, "1.21.0", Some(44027)),
     /// Allows `dyn* Trait` objects.
     (incomplete, dyn_star, "1.65.0", Some(102425)),
-    // Uses generic effect parameters for ~const bounds
+    /// Uses generic effect parameters for ~const bounds
     (unstable, effects, "1.72.0", Some(102090)),
     /// Allows `X..Y` patterns.
     (unstable, exclusive_range_pattern, "1.11.0", Some(37854)),
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index 0ab09dadf58..8a4fd01437f 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -113,6 +113,7 @@ macro_rules! arena_types {
             [] stripped_cfg_items: rustc_ast::expand::StrippedCfgItem,
             [] mod_child: rustc_middle::metadata::ModChild,
             [] features: rustc_feature::Features,
+            [decode] specialization_graph: rustc_middle::traits::specialization_graph::Graph,
         ]);
     )
 }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 0e3b9984423..1dc77220881 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1294,8 +1294,7 @@ rustc_queries! {
         desc { |tcx| "finding trait impls of `{}`", tcx.def_path_str(trait_id) }
     }
 
-    query specialization_graph_of(trait_id: DefId) -> &'tcx specialization_graph::Graph {
-        arena_cache
+    query specialization_graph_of(trait_id: DefId) -> Result<&'tcx specialization_graph::Graph, ErrorGuaranteed> {
         desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) }
         cache_on_disk_if { true }
     }
diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs
index 31db4ba62fb..f4dfbe059eb 100644
--- a/compiler/rustc_middle/src/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -786,6 +786,15 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [rustc_ast::InlineAsm
     }
 }
 
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
+    for &'tcx crate::traits::specialization_graph::Graph
+{
+    #[inline]
+    fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
+        RefDecodable::decode(d)
+    }
+}
+
 macro_rules! impl_ref_decoder {
     (<$tcx:tt> $($ty:ty,)*) => {
         $(impl<'a, $tcx> Decodable<CacheDecoder<'a, $tcx>> for &$tcx [$ty] {
diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs
index 898258445dc..ba29d4040a1 100644
--- a/compiler/rustc_middle/src/traits/specialization_graph.rs
+++ b/compiler/rustc_middle/src/traits/specialization_graph.rs
@@ -30,18 +30,16 @@ pub struct Graph {
 
     /// The "root" impls are found by looking up the trait's def_id.
     pub children: DefIdMap<Children>,
-
-    /// Whether an error was emitted while constructing the graph.
-    pub has_errored: Option<ErrorGuaranteed>,
 }
 
 impl Graph {
     pub fn new() -> Graph {
-        Graph { parent: Default::default(), children: Default::default(), has_errored: None }
+        Graph { parent: Default::default(), children: Default::default() }
     }
 
     /// The parent of a given impl, which is the `DefId` of the trait when the
     /// impl is a "specialization root".
+    #[track_caller]
     pub fn parent(&self, child: DefId) -> DefId {
         *self.parent.get(&child).unwrap_or_else(|| panic!("Failed to get parent for {child:?}"))
     }
@@ -255,13 +253,9 @@ pub fn ancestors(
     trait_def_id: DefId,
     start_from_impl: DefId,
 ) -> Result<Ancestors<'_>, ErrorGuaranteed> {
-    let specialization_graph = tcx.specialization_graph_of(trait_def_id);
+    let specialization_graph = tcx.specialization_graph_of(trait_def_id)?;
 
-    if let Some(reported) = specialization_graph.has_errored {
-        Err(reported)
-    } else if let Err(reported) =
-        tcx.type_of(start_from_impl).instantiate_identity().error_reported()
-    {
+    if let Err(reported) = tcx.type_of(start_from_impl).instantiate_identity().error_reported() {
         Err(reported)
     } else {
         Ok(Ancestors {
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 6ed68f90eb3..b71919adc58 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -32,6 +32,7 @@ pub enum SimplifiedType {
     CoroutineWitness(DefId),
     Function(usize),
     Placeholder,
+    Error,
 }
 
 /// Generic parameters are pretty much just bound variables, e.g.
@@ -153,7 +154,8 @@ pub fn simplify_type<'tcx>(
             TreatParams::ForLookup | TreatParams::AsCandidateKey => None,
         },
         ty::Foreign(def_id) => Some(SimplifiedType::Foreign(def_id)),
-        ty::Bound(..) | ty::Infer(_) | ty::Error(_) => None,
+        ty::Error(_) => Some(SimplifiedType::Error),
+        ty::Bound(..) | ty::Infer(_) => None,
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index bf9b244936f..227a0753d04 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -1,6 +1,5 @@
 use crate::traits::specialization_graph;
 use crate::ty::fast_reject::{self, SimplifiedType, TreatParams, TreatProjections};
-use crate::ty::visit::TypeVisitableExt;
 use crate::ty::{Ident, Ty, TyCtxt};
 use hir::def_id::LOCAL_CRATE;
 use rustc_hir as hir;
@@ -241,9 +240,6 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
         let impl_def_id = impl_def_id.to_def_id();
 
         let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity();
-        if impl_self_ty.references_error() {
-            continue;
-        }
 
         if let Some(simplified_self_ty) =
             fast_reject::simplify_type(tcx, impl_self_ty, TreatParams::AsCandidateKey)
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 10329c623b3..200d022c80c 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -26,7 +26,7 @@ use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{GenericArgs, GenericArgsRef};
 use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
 use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
 
 use super::util;
 use super::SelectionContext;
@@ -258,7 +258,7 @@ fn fulfill_implication<'tcx>(
 pub(super) fn specialization_graph_provider(
     tcx: TyCtxt<'_>,
     trait_id: DefId,
-) -> specialization_graph::Graph {
+) -> Result<&'_ specialization_graph::Graph, ErrorGuaranteed> {
     let mut sg = specialization_graph::Graph::new();
     let overlap_mode = specialization_graph::OverlapMode::get(tcx, trait_id);
 
@@ -271,6 +271,8 @@ pub(super) fn specialization_graph_provider(
     trait_impls
         .sort_unstable_by_key(|def_id| (-(def_id.krate.as_u32() as i64), def_id.index.index()));
 
+    let mut errored = Ok(());
+
     for impl_def_id in trait_impls {
         if let Some(impl_def_id) = impl_def_id.as_local() {
             // This is where impl overlap checking happens:
@@ -283,15 +285,21 @@ pub(super) fn specialization_graph_provider(
             };
 
             if let Some(overlap) = overlap {
-                report_overlap_conflict(tcx, overlap, impl_def_id, used_to_be_allowed, &mut sg);
+                errored = errored.and(report_overlap_conflict(
+                    tcx,
+                    overlap,
+                    impl_def_id,
+                    used_to_be_allowed,
+                ));
             }
         } else {
             let parent = tcx.impl_parent(impl_def_id).unwrap_or(trait_id);
             sg.record_impl_from_cstore(tcx, parent, impl_def_id)
         }
     }
+    errored?;
 
-    sg
+    Ok(tcx.arena.alloc(sg))
 }
 
 // This function is only used when
@@ -304,36 +312,31 @@ fn report_overlap_conflict<'tcx>(
     overlap: OverlapError<'tcx>,
     impl_def_id: LocalDefId,
     used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
-    sg: &mut specialization_graph::Graph,
-) {
+) -> Result<(), ErrorGuaranteed> {
     let impl_polarity = tcx.impl_polarity(impl_def_id.to_def_id());
     let other_polarity = tcx.impl_polarity(overlap.with_impl);
     match (impl_polarity, other_polarity) {
         (ty::ImplPolarity::Negative, ty::ImplPolarity::Positive) => {
-            report_negative_positive_conflict(
+            Err(report_negative_positive_conflict(
                 tcx,
                 &overlap,
                 impl_def_id,
                 impl_def_id.to_def_id(),
                 overlap.with_impl,
-                sg,
-            );
+            ))
         }
 
         (ty::ImplPolarity::Positive, ty::ImplPolarity::Negative) => {
-            report_negative_positive_conflict(
+            Err(report_negative_positive_conflict(
                 tcx,
                 &overlap,
                 impl_def_id,
                 overlap.with_impl,
                 impl_def_id.to_def_id(),
-                sg,
-            );
+            ))
         }
 
-        _ => {
-            report_conflicting_impls(tcx, overlap, impl_def_id, used_to_be_allowed, sg);
-        }
+        _ => report_conflicting_impls(tcx, overlap, impl_def_id, used_to_be_allowed),
     }
 }
 
@@ -343,16 +346,16 @@ fn report_negative_positive_conflict<'tcx>(
     local_impl_def_id: LocalDefId,
     negative_impl_def_id: DefId,
     positive_impl_def_id: DefId,
-    sg: &mut specialization_graph::Graph,
-) {
-    let err = tcx.dcx().create_err(NegativePositiveConflict {
-        impl_span: tcx.def_span(local_impl_def_id),
-        trait_desc: overlap.trait_ref,
-        self_ty: overlap.self_ty,
-        negative_impl_span: tcx.span_of_impl(negative_impl_def_id),
-        positive_impl_span: tcx.span_of_impl(positive_impl_def_id),
-    });
-    sg.has_errored = Some(err.emit());
+) -> ErrorGuaranteed {
+    tcx.dcx()
+        .create_err(NegativePositiveConflict {
+            impl_span: tcx.def_span(local_impl_def_id),
+            trait_desc: overlap.trait_ref,
+            self_ty: overlap.self_ty,
+            negative_impl_span: tcx.span_of_impl(negative_impl_def_id),
+            positive_impl_span: tcx.span_of_impl(positive_impl_def_id),
+        })
+        .emit()
 }
 
 fn report_conflicting_impls<'tcx>(
@@ -360,8 +363,7 @@ fn report_conflicting_impls<'tcx>(
     overlap: OverlapError<'tcx>,
     impl_def_id: LocalDefId,
     used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
-    sg: &mut specialization_graph::Graph,
-) {
+) -> Result<(), ErrorGuaranteed> {
     let impl_span = tcx.def_span(impl_def_id);
 
     // Work to be done after we've built the DiagnosticBuilder. We have to define it
@@ -429,14 +431,11 @@ fn report_conflicting_impls<'tcx>(
                 let mut err = tcx.dcx().struct_span_err(impl_span, msg);
                 err.code(error_code!(E0119));
                 decorate(tcx, &overlap, impl_span, &mut err);
-                Some(err.emit())
+                err.emit()
             } else {
-                Some(
-                    tcx.dcx()
-                        .span_delayed_bug(impl_span, "impl should have failed the orphan check"),
-                )
+                tcx.dcx().span_delayed_bug(impl_span, "impl should have failed the orphan check")
             };
-            sg.has_errored = reported;
+            Err(reported)
         }
         Some(kind) => {
             let lint = match kind {
@@ -452,8 +451,9 @@ fn report_conflicting_impls<'tcx>(
                     decorate(tcx, &overlap, impl_span, err);
                 },
             );
+            Ok(())
         }
-    };
+    }
 }
 
 /// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a
diff --git a/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.rs b/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.rs
new file mode 100644
index 00000000000..cd3acf9bc41
--- /dev/null
+++ b/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.rs
@@ -0,0 +1,16 @@
+trait Foo {
+    type Context<'c>
+    where
+        Self: 'c;
+}
+
+impl Foo for Box<dyn Foo> {}
+//~^ ERROR `Foo` cannot be made into an object
+//~| ERROR `Foo` cannot be made into an object
+//~| ERROR cycle detected
+//~| ERROR cycle detected
+//~| ERROR cycle detected
+//~| ERROR the trait bound `Box<(dyn Foo + 'static)>: Foo` is not satisfied
+//~| ERROR not all trait items implemented
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.stderr b/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.stderr
new file mode 100644
index 00000000000..8e6b69f7461
--- /dev/null
+++ b/tests/ui/generic-associated-types/unknown-lifetime-ice-119827.stderr
@@ -0,0 +1,119 @@
+error[E0391]: cycle detected when computing type of `<impl at $DIR/unknown-lifetime-ice-119827.rs:7:1: 7:26>`
+  --> $DIR/unknown-lifetime-ice-119827.rs:7:1
+   |
+LL | impl Foo for Box<dyn Foo> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: ...which requires finding trait impls of `Foo`...
+  --> $DIR/unknown-lifetime-ice-119827.rs:1:1
+   |
+LL | trait Foo {
+   | ^^^^^^^^^
+   = note: ...which again requires computing type of `<impl at $DIR/unknown-lifetime-ice-119827.rs:7:1: 7:26>`, completing the cycle
+note: cycle used when collecting item types in top-level module
+  --> $DIR/unknown-lifetime-ice-119827.rs:1:1
+   |
+LL | / trait Foo {
+LL | |     type Context<'c>
+LL | |     where
+LL | |         Self: 'c;
+...  |
+LL | |
+LL | | fn main() {}
+   | |____________^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error[E0391]: cycle detected when computing type of `<impl at $DIR/unknown-lifetime-ice-119827.rs:7:1: 7:26>`
+  --> $DIR/unknown-lifetime-ice-119827.rs:7:1
+   |
+LL | impl Foo for Box<dyn Foo> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: ...which immediately requires computing type of `<impl at $DIR/unknown-lifetime-ice-119827.rs:7:1: 7:26>` again
+note: cycle used when collecting item types in top-level module
+  --> $DIR/unknown-lifetime-ice-119827.rs:1:1
+   |
+LL | / trait Foo {
+LL | |     type Context<'c>
+LL | |     where
+LL | |         Self: 'c;
+...  |
+LL | |
+LL | | fn main() {}
+   | |____________^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error[E0391]: cycle detected when computing type of `<impl at $DIR/unknown-lifetime-ice-119827.rs:7:1: 7:26>`
+  --> $DIR/unknown-lifetime-ice-119827.rs:7:1
+   |
+LL | impl Foo for Box<dyn Foo> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: ...which immediately requires computing type of `<impl at $DIR/unknown-lifetime-ice-119827.rs:7:1: 7:26>` again
+note: cycle used when collecting item types in top-level module
+  --> $DIR/unknown-lifetime-ice-119827.rs:1:1
+   |
+LL | / trait Foo {
+LL | |     type Context<'c>
+LL | |     where
+LL | |         Self: 'c;
+...  |
+LL | |
+LL | | fn main() {}
+   | |____________^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/unknown-lifetime-ice-119827.rs:7:22
+   |
+LL | impl Foo for Box<dyn Foo> {}
+   |                      ^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/unknown-lifetime-ice-119827.rs:2:10
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     type Context<'c>
+   |          ^^^^^^^ ...because it contains the generic associated type `Context`
+   = help: consider moving `Context` to another trait
+   = help: only type `{type error}` implements the trait, consider using it directly instead
+
+error[E0277]: the trait bound `Box<(dyn Foo + 'static)>: Foo` is not satisfied
+  --> $DIR/unknown-lifetime-ice-119827.rs:7:14
+   |
+LL | impl Foo for Box<dyn Foo> {}
+   |              ^^^^^^^^^^^^ the trait `Foo` is not implemented for `Box<(dyn Foo + 'static)>`
+   |
+   = help: the trait `Foo` is implemented for `Box<(dyn Foo + 'static)>`
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/unknown-lifetime-ice-119827.rs:7:14
+   |
+LL | impl Foo for Box<dyn Foo> {}
+   |              ^^^^^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/unknown-lifetime-ice-119827.rs:2:10
+   |
+LL | trait Foo {
+   |       --- this trait cannot be made into an object...
+LL |     type Context<'c>
+   |          ^^^^^^^ ...because it contains the generic associated type `Context`
+   = help: consider moving `Context` to another trait
+   = help: only type `std::boxed::Box<(dyn Foo + 'static)>` implements the trait, consider using it directly instead
+
+error[E0046]: not all trait items implemented, missing: `Context`
+  --> $DIR/unknown-lifetime-ice-119827.rs:7:1
+   |
+LL |     type Context<'c>
+   |     ---------------- `Context` from trait
+...
+LL | impl Foo for Box<dyn Foo> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Context` in implementation
+
+error: aborting due to 7 previous errors
+
+Some errors have detailed explanations: E0038, E0046, E0277, E0391.
+For more information about an error, try `rustc --explain E0038`.