From a141d2961289774f15ed884a52cd03c7d096aac5 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 21 Jun 2021 14:53:50 +0900 Subject: [PATCH 1/3] Do not panic in `return_type_impl_trait` --- compiler/rustc_middle/src/ty/context.rs | 7 ++++ .../generic-associated-types/issue-86483.rs | 15 ++++++++ .../issue-86483.stderr | 36 +++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 src/test/ui/generic-associated-types/issue-86483.rs create mode 100644 src/test/ui/generic-associated-types/issue-86483.stderr diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a74070100f413..bf5176f658509 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -44,6 +44,7 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{ Constness, HirId, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet, Node, TraitCandidate, + TraitItemKind, }; use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; @@ -1509,6 +1510,12 @@ impl<'tcx> TyCtxt<'tcx> { } } } + Node::TraitItem(item) => { + // #86483: Return early if it doesn't have a concrete type. + if let TraitItemKind::Type(_, None) = item.kind { + return None; + } + } _ => { /* `type_of_def_id()` will work or panic */ } } diff --git a/src/test/ui/generic-associated-types/issue-86483.rs b/src/test/ui/generic-associated-types/issue-86483.rs new file mode 100644 index 0000000000000..9d03c9dab8d90 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-86483.rs @@ -0,0 +1,15 @@ +// Regression test of #86483. + +#![feature(generic_associated_types)] +#![allow(incomplete_features)] + +pub trait IceIce //~ ERROR: the parameter type `T` may not live long enough +where + for<'a> T: 'a, +{ + type Ice<'v>: IntoIterator; + //~^ ERROR: the parameter type `T` may not live long enough + //~| ERROR: the parameter type `T` may not live long enough +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-86483.stderr b/src/test/ui/generic-associated-types/issue-86483.stderr new file mode 100644 index 0000000000000..c8efc2ed88264 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-86483.stderr @@ -0,0 +1,36 @@ +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/issue-86483.rs:6:1 + | +LL | pub trait IceIce + | ^ - help: consider adding an explicit lifetime bound...: `T: 'a` + | _| + | | +LL | | where +LL | | for<'a> T: 'a, +LL | | { +... | +LL | | +LL | | } + | |_^ ...so that the type `T` will meet its required lifetime bounds + +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/issue-86483.rs:10:5 + | +LL | pub trait IceIce + | - help: consider adding an explicit lifetime bound...: `T: 'a` +... +LL | type Ice<'v>: IntoIterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/issue-86483.rs:10:32 + | +LL | pub trait IceIce + | - help: consider adding an explicit lifetime bound...: `T: 'v` +... +LL | type Ice<'v>: IntoIterator; + | ^^^^^^^^^^^^ ...so that the reference type `&'v T` does not outlive the data it points at + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0309`. From 462c74007eea1b71a62aa5565352e82ef481a129 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 24 Jun 2021 14:21:50 +0900 Subject: [PATCH 2/3] Rename function name in comments --- compiler/rustc_middle/src/ty/context.rs | 6 +++--- compiler/rustc_typeck/src/collect/type_of.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index bf5176f658509..1988bc17376d2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1499,12 +1499,12 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> { - // HACK: `type_of_def_id()` will fail on these (#55796), so return `None`. + // HACK: `type_of()` will fail on these (#55796), so return `None`. let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id); match self.hir().get(hir_id) { Node::Item(item) => { match item.kind { - ItemKind::Fn(..) => { /* `type_of_def_id()` will work */ } + ItemKind::Fn(..) => { /* `type_of()` will work */ } _ => { return None; } @@ -1516,7 +1516,7 @@ impl<'tcx> TyCtxt<'tcx> { return None; } } - _ => { /* `type_of_def_id()` will work or panic */ } + _ => { /* `type_of()` will work or panic */ } } let ret_ty = self.type_of(scope_def_id); diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 78fa8074a64cf..ee84974cb73c2 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -492,7 +492,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { x => tcx.ty_error_with_message( DUMMY_SP, - &format!("unexpected const parent in type_of_def_id(): {:?}", x), + &format!("unexpected const parent in type_of(): {:?}", x), ), } } @@ -504,7 +504,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { }, x => { - bug!("unexpected sort of node in type_of_def_id(): {:?}", x); + bug!("unexpected sort of node in type_of(): {:?}", x); } } } From 9323a2824b188ddb741e702fd632a9061f5c4fc4 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 24 Jun 2021 14:59:43 +0900 Subject: [PATCH 3/3] Prefer "allow list" structure to check a type --- compiler/rustc_middle/src/ty/context.rs | 26 ++++++++----------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1988bc17376d2..77f955e93b9dd 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -43,8 +43,8 @@ use rustc_hir::definitions::Definitions; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{ - Constness, HirId, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet, Node, TraitCandidate, - TraitItemKind, + Constness, ExprKind, HirId, ImplItemKind, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet, + Node, TraitCandidate, TraitItemKind, }; use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; @@ -1499,24 +1499,14 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> { - // HACK: `type_of()` will fail on these (#55796), so return `None`. + // `type_of()` will fail on these (#55796, #86483), so only allow `fn`s or closures. let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id); match self.hir().get(hir_id) { - Node::Item(item) => { - match item.kind { - ItemKind::Fn(..) => { /* `type_of()` will work */ } - _ => { - return None; - } - } - } - Node::TraitItem(item) => { - // #86483: Return early if it doesn't have a concrete type. - if let TraitItemKind::Type(_, None) = item.kind { - return None; - } - } - _ => { /* `type_of()` will work or panic */ } + Node::Item(&hir::Item { kind: ItemKind::Fn(..), .. }) => {} + Node::TraitItem(&hir::TraitItem { kind: TraitItemKind::Fn(..), .. }) => {} + Node::ImplItem(&hir::ImplItem { kind: ImplItemKind::Fn(..), .. }) => {} + Node::Expr(&hir::Expr { kind: ExprKind::Closure(..), .. }) => {} + _ => return None, } let ret_ty = self.type_of(scope_def_id);