From 24289a050a8eeb1385f73acb7c1a6de804840d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 8 Nov 2018 15:18:55 -0800 Subject: [PATCH 1/2] Sidestep ICE in `type_of_def_id()` when called from `return_type_impl_trait` --- src/librustc/ty/context.rs | 22 +++++++++++- src/test/ui/issues/issue-55796.rs | 22 ++++++++++++ src/test/ui/issues/issue-55796.stderr | 50 +++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issues/issue-55796.rs create mode 100644 src/test/ui/issues/issue-55796.stderr diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 05d9d4bc37d79..da0bec80a891d 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -17,7 +17,7 @@ use session::Session; use session::config::{BorrowckMode, OutputFilenames}; use session::config::CrateType; use middle; -use hir::{TraitCandidate, HirId, ItemLocalId, Node}; +use hir::{TraitCandidate, HirId, ItemKind, ItemLocalId, Node}; use hir::def::{Def, Export}; use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; use hir::map as hir_map; @@ -1602,6 +1602,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { &self, scope_def_id: DefId, ) -> Option> { + // HACK: `type_of_def_id()` will fail on these (#55796), so return None + let node_id = self.hir.as_local_node_id(scope_def_id).unwrap(); + match self.hir.get(node_id) { + Node::Item(item) => { + match item.node { + ItemKind::Trait(..) + | ItemKind::TraitAlias(..) + | ItemKind::Mod(..) + | ItemKind::ForeignMod(..) + | ItemKind::GlobalAsm(..) + | ItemKind::ExternCrate(..) + | ItemKind::Use(..) => { + return None; + } + _ => { /* type_of_def_id() will work */ } + } + } + _ => { /* type_of_def_id() will work or panic */ } + } + let ret_ty = self.type_of(scope_def_id); match ret_ty.sty { ty::FnDef(_, _) => { diff --git a/src/test/ui/issues/issue-55796.rs b/src/test/ui/issues/issue-55796.rs new file mode 100644 index 0000000000000..b48d4a9c022f4 --- /dev/null +++ b/src/test/ui/issues/issue-55796.rs @@ -0,0 +1,22 @@ +pub trait EdgeTrait { + fn target(&self) -> N; +} + +pub trait Graph<'a> { + type Node; + type Edge: EdgeTrait; + type NodesIter: Iterator + 'a; + type EdgesIter: Iterator + 'a; + + fn nodes(&'a self) -> Self::NodesIter; + fn out_edges(&'a self, u: &Self::Node) -> Self::EdgesIter; + fn in_edges(&'a self, u: &Self::Node) -> Self::EdgesIter; + + fn out_neighbors(&'a self, u: &Self::Node) -> Box> { + Box::new(self.out_edges(u).map(|e| e.target())) + } + + fn in_neighbors(&'a self, u: &Self::Node) -> Box> { + Box::new(self.in_edges(u).map(|e| e.target())) + } +} diff --git a/src/test/ui/issues/issue-55796.stderr b/src/test/ui/issues/issue-55796.stderr new file mode 100644 index 0000000000000..60ce8293a5ceb --- /dev/null +++ b/src/test/ui/issues/issue-55796.stderr @@ -0,0 +1,50 @@ +error[E0601]: `main` function not found in crate `issue_55796` + | + = note: consider adding a `main` function to `$DIR/issue-55796.rs` + +error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements + --> $DIR/issue-55796.rs:16:9 + | +LL | Box::new(self.out_edges(u).map(|e| e.target())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the lifetime 'a as defined on the trait at 5:17... + --> $DIR/issue-55796.rs:5:17 + | +LL | pub trait Graph<'a> { + | ^^ +note: ...so that the type `std::iter::Map<>::EdgesIter, [closure@$DIR/issue-55796.rs:16:40: 16:54]>` will meet its required lifetime bounds + --> $DIR/issue-55796.rs:16:9 + | +LL | Box::new(self.out_edges(u).map(|e| e.target())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: but, the lifetime must be valid for the static lifetime... + = note: ...so that the expression is assignable: + expected std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)> + found std::boxed::Box>::Node>> + +error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements + --> $DIR/issue-55796.rs:20:9 + | +LL | Box::new(self.in_edges(u).map(|e| e.target())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the lifetime 'a as defined on the trait at 5:17... + --> $DIR/issue-55796.rs:5:17 + | +LL | pub trait Graph<'a> { + | ^^ +note: ...so that the type `std::iter::Map<>::EdgesIter, [closure@$DIR/issue-55796.rs:20:39: 20:53]>` will meet its required lifetime bounds + --> $DIR/issue-55796.rs:20:9 + | +LL | Box::new(self.in_edges(u).map(|e| e.target())) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: but, the lifetime must be valid for the static lifetime... + = note: ...so that the expression is assignable: + expected std::boxed::Box<(dyn std::iter::Iterator>::Node> + 'static)> + found std::boxed::Box>::Node>> + +error: aborting due to 3 previous errors + +Some errors occurred: E0495, E0601. +For more information about an error, try `rustc --explain E0495`. From a90240d2791b2eaa4ae1401a1b7e280f0da4c524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 9 Nov 2018 10:16:07 -0800 Subject: [PATCH 2/2] Simplify logic --- src/librustc/ty/context.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index da0bec80a891d..82095a2f5b01d 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1607,16 +1607,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { match self.hir.get(node_id) { Node::Item(item) => { match item.node { - ItemKind::Trait(..) - | ItemKind::TraitAlias(..) - | ItemKind::Mod(..) - | ItemKind::ForeignMod(..) - | ItemKind::GlobalAsm(..) - | ItemKind::ExternCrate(..) - | ItemKind::Use(..) => { + ItemKind::Fn(..) => { /* type_of_def_id() will work */ } + _ => { return None; } - _ => { /* type_of_def_id() will work */ } } } _ => { /* type_of_def_id() will work or panic */ }