From 5ad60888275852136adea38aebc7fcce69b52474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 24 Feb 2021 12:21:18 -0800 Subject: [PATCH] Substitute erased lifetimes on bad placeholder type Fix #82455. --- compiler/rustc_typeck/src/collect.rs | 12 ++++++++++ .../ui/typeck/typeck_type_placeholder_item.rs | 12 ++++++++++ .../typeck_type_placeholder_item.stderr | 22 +++++++++++++++++-- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index fc8e50b4b65ba..d754a24c58be1 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -371,6 +371,11 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { span: Span, ) -> &'tcx Const<'tcx> { bad_placeholder_type(self.tcx(), vec![span]).emit(); + // Typeck doesn't expect erased regions to be returned from `type_of`. + let ty = self.tcx.fold_regions(ty, &mut false, |r, _| match r { + ty::ReErased => self.tcx.lifetimes.re_static, + _ => r, + }); self.tcx().const_error(ty) } @@ -1647,6 +1652,12 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { match get_infer_ret_ty(&sig.decl.output) { Some(ty) => { let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id]; + // Typeck doesn't expect erased regions to be returned from `type_of`. + let fn_sig = tcx.fold_regions(fn_sig, &mut false, |r, _| match r { + ty::ReErased => tcx.lifetimes.re_static, + _ => r, + }); + let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_ty(ty); let mut diag = bad_placeholder_type(tcx, visitor.0); @@ -1675,6 +1686,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { } } diag.emit(); + ty::Binder::bind(fn_sig) } None => AstConv::ty_of_fn( diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index 2c8b1e76b1b82..2523362fdc4b6 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -208,3 +208,15 @@ impl Qux for Struct { const D: _ = 42; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures } + +fn map(_: fn() -> Option<&'static T>) -> Option { + None +} + +fn value() -> Option<&'static _> { +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures + Option::<&'static u8>::None +} + +const _: Option<_> = map(value); +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index 684f451b7c3f6..1034402bfb08d 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -158,7 +158,7 @@ LL | fn test11(x: &usize) -> &_ { | -^ | || | |not allowed in type signatures - | help: replace with the correct return type: `&&usize` + | help: replace with the correct return type: `&'static &'static usize` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:52:52 @@ -410,6 +410,24 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa LL | type Y = impl Trait<_>; | ^ not allowed in type signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:216:31 + | +LL | fn value() -> Option<&'static _> { + | ----------------^- + | | | + | | not allowed in type signatures + | help: replace with the correct return type: `Option<&'static u8>` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:221:10 + | +LL | const _: Option<_> = map(value); + | ^^^^^^^^^ + | | + | not allowed in type signatures + | help: replace `_` with the correct type: `Option` + error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:140:31 | @@ -614,7 +632,7 @@ LL | const D: _ = 42; | not allowed in type signatures | help: replace `_` with the correct type: `i32` -error: aborting due to 67 previous errors +error: aborting due to 69 previous errors Some errors have detailed explanations: E0121, E0282, E0403. For more information about an error, try `rustc --explain E0121`.