From 200f466d1a3cd1530752842b6895c73fc61b0cb6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 18 Jan 2023 18:03:06 +0000 Subject: [PATCH 1/3] Encode whether foreign opaques are TAITs or not --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 11 +++++++++++ .../rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 1 + compiler/rustc_metadata/src/rmeta/mod.rs | 1 + compiler/rustc_middle/src/query/mod.rs | 6 ++++++ compiler/rustc_middle/src/ty/parameterized.rs | 1 + compiler/rustc_trait_selection/src/traits/wf.rs | 2 +- 8 files changed, 23 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 9031c04849dfe..ce72b78f42f93 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2602,7 +2602,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { match path.res { Res::Def(DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder, did) => { // Check for desugared `impl Trait`. - assert!(ty::is_impl_trait_defn(tcx, did).is_none()); + assert!(tcx.is_type_alias_impl_trait(did)); let item_segment = path.segments.split_last().unwrap(); self.prohibit_generics(item_segment.1.iter(), |err| { err.note("`impl Trait` types can't have type parameters"); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 35f47dfc1a5e2..9be37dbe8c6b5 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -76,6 +76,7 @@ pub fn provide(providers: &mut Providers) { is_foreign_item, generator_kind, collect_mod_item_types, + is_type_alias_impl_trait, ..*providers }; } @@ -1537,3 +1538,13 @@ fn generator_kind(tcx: TyCtxt<'_>, def_id: DefId) -> Option _ => bug!("generator_kind applied to non-local def-id {:?}", def_id), } } + +fn is_type_alias_impl_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { + match tcx.hir().get_if_local(def_id) { + Some(Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(opaque), .. })) => { + matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias) + } + Some(_) => bug!("tried getting opaque_ty_origin for non-opaque: {:?}", def_id), + _ => bug!("tried getting opaque_ty_origin for non-local def-id {:?}", def_id), + } +} diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index cb451931dfe17..c00a95607aadc 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -223,6 +223,7 @@ provide! { tcx, def_id, other, cdata, generator_kind => { table } trait_def => { table } deduced_param_attrs => { table } + is_type_alias_impl_trait => { table } collect_return_position_impl_trait_in_trait_tys => { Ok(cdata .root diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index a3d44fa890dd1..69adefe432c62 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1514,6 +1514,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } hir::ItemKind::OpaqueTy(..) => { self.encode_explicit_item_bounds(def_id); + record!(self.tables.is_type_alias_impl_trait[def_id] <- self.tcx.is_type_alias_impl_trait(def_id)); } hir::ItemKind::Enum(..) => { let adt_def = self.tcx.adt_def(def_id); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 5b7b096b4edf1..5e2b7938bd510 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -404,6 +404,7 @@ define_tables! { proc_macro: Table, module_reexports: Table>, deduced_param_attrs: Table>, + is_type_alias_impl_trait: Table>, trait_impl_trait_tys: Table>>>, } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0ec6f481af1ff..6bbf7fa3914e6 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -177,6 +177,12 @@ rustc_queries! { separate_provide_extern } + query is_type_alias_impl_trait(key: DefId) -> bool + { + desc { "determine whether the opaque is a type-alias impl trait" } + separate_provide_extern + } + query analysis(key: ()) -> Result<(), ErrorGuaranteed> { eval_always desc { "running analysis passes on this crate" } diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index e32a7ee1c3545..24f3d1acff188 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -52,6 +52,7 @@ trivially_parameterized_over_tcx! { usize, (), u32, + bool, std::string::String, crate::metadata::ModChild, crate::middle::codegen_fn_attrs::CodegenFnAttrs, diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index b47a70b4e7b96..12d4cb4fc6920 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -654,7 +654,7 @@ impl<'tcx> WfPredicates<'tcx> { // All of the requirements on type parameters // have already been checked for `impl Trait` in // return position. We do need to check type-alias-impl-trait though. - if ty::is_impl_trait_defn(self.tcx, def_id).is_none() { + if self.tcx.is_type_alias_impl_trait(def_id) { let obligations = self.nominal_obligations(def_id, substs); self.out.extend(obligations); } From 9793abc2092ab37e406a07b8e35bfaf5a9e26fe6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 18 Jan 2023 18:11:19 +0000 Subject: [PATCH 2/3] Add test --- tests/ui/async-await/auxiliary/issue-107036.rs | 12 ++++++++++++ tests/ui/async-await/issue-107036.rs | 14 ++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/ui/async-await/auxiliary/issue-107036.rs create mode 100644 tests/ui/async-await/issue-107036.rs diff --git a/tests/ui/async-await/auxiliary/issue-107036.rs b/tests/ui/async-await/auxiliary/issue-107036.rs new file mode 100644 index 0000000000000..c3f6141b28403 --- /dev/null +++ b/tests/ui/async-await/auxiliary/issue-107036.rs @@ -0,0 +1,12 @@ +// edition:2021 + +pub trait T {} +impl T for () {} + +pub struct S {} + +impl S { + pub async fn f<'a>(&self) -> impl T + 'a { + () + } +} diff --git a/tests/ui/async-await/issue-107036.rs b/tests/ui/async-await/issue-107036.rs new file mode 100644 index 0000000000000..6a22de2c94354 --- /dev/null +++ b/tests/ui/async-await/issue-107036.rs @@ -0,0 +1,14 @@ +// aux-build:issue-107036.rs +// edition:2021 +// check-pass + +extern crate issue_107036; +use issue_107036::S; + +async fn f() { + S{}.f().await; +} + +fn main() { + let _ = f(); +} From 7e0b1f11154bc5e9af996b821b2c28680c3f46c8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 19 Jan 2023 16:09:10 +0000 Subject: [PATCH 3/3] Conditionally encode boolean --- .../rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 10 +++++++++- compiler/rustc_metadata/src/rmeta/encoder.rs | 6 ++++-- compiler/rustc_metadata/src/rmeta/mod.rs | 3 ++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index c00a95607aadc..0d924f27c21a6 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -223,7 +223,15 @@ provide! { tcx, def_id, other, cdata, generator_kind => { table } trait_def => { table } deduced_param_attrs => { table } - is_type_alias_impl_trait => { table } + is_type_alias_impl_trait => { + debug_assert_eq!(tcx.def_kind(def_id), DefKind::OpaqueTy); + cdata + .root + .tables + .is_type_alias_impl_trait + .get(cdata, def_id.index) + .is_some() + } collect_return_position_impl_trait_in_trait_tys => { Ok(cdata .root diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 69adefe432c62..ab2ad79b876d4 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1512,9 +1512,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemKind::Mod(ref m) => { return self.encode_info_for_mod(item.owner_id.def_id, m); } - hir::ItemKind::OpaqueTy(..) => { + hir::ItemKind::OpaqueTy(ref opaque) => { self.encode_explicit_item_bounds(def_id); - record!(self.tables.is_type_alias_impl_trait[def_id] <- self.tcx.is_type_alias_impl_trait(def_id)); + if matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias) { + self.tables.is_type_alias_impl_trait.set(def_id.index, ()); + } } hir::ItemKind::Enum(..) => { let adt_def = self.tcx.adt_def(def_id); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 5e2b7938bd510..5066dbbb90f3a 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -404,7 +404,8 @@ define_tables! { proc_macro: Table, module_reexports: Table>, deduced_param_attrs: Table>, - is_type_alias_impl_trait: Table>, + // Slot is full when opaque is TAIT. + is_type_alias_impl_trait: Table, trait_impl_trait_tys: Table>>>, }