From e1ff02bb818fc85b0820bc989cd7fa64dd1e4300 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Sat, 4 Dec 2021 11:19:33 -0800 Subject: [PATCH 01/12] Make rustdoc headings black, and markdown blue --- src/librustdoc/html/render/print_item.rs | 2 +- src/librustdoc/html/static/css/themes/ayu.css | 2 +- src/librustdoc/html/static/css/themes/dark.css | 2 +- src/librustdoc/html/static/css/themes/light.css | 2 +- src/test/rustdoc-gui/headers-color.goml | 15 ++++++++++++--- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index e139ac8581e72..1691de93bdda2 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -296,7 +296,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl let (short, name) = item_ty_to_strs(myty.unwrap()); write!( w, - "

\ + "

\ {name}\

\n{}", ITEM_TABLE_OPEN, diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 13e8dc85a243c..532bc0e351dbd 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -219,7 +219,7 @@ a { a.srclink, a#toggle-all-docs, a.anchor, -.section-header a, +.small-section-header a, #source-sidebar a, pre.rust a, .sidebar a, diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 8caf8a05d507f..56ed8a2006d09 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -181,7 +181,7 @@ a { a.srclink, a#toggle-all-docs, a.anchor, -.section-header a, +.small-section-header a, #source-sidebar a, pre.rust a, .sidebar a, diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index fec71674e634f..d63614191822e 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -176,7 +176,7 @@ a { a.srclink, a#toggle-all-docs, a.anchor, -.section-header a, +.small-section-header a, #source-sidebar a, pre.rust a, .sidebar a, diff --git a/src/test/rustdoc-gui/headers-color.goml b/src/test/rustdoc-gui/headers-color.goml index 7002812bb62c4..03b10e3f78d43 100644 --- a/src/test/rustdoc-gui/headers-color.goml +++ b/src/test/rustdoc-gui/headers-color.goml @@ -18,7 +18,10 @@ goto: file://|DOC_PATH|/test_docs/struct.Foo.html#method.must_use assert-css: ("#method\.must_use", {"color": "rgb(197, 197, 197)", "background-color": "rgba(255, 236, 164, 0.06)"}, ALL) goto: file://|DOC_PATH|/test_docs/index.html -assert-css: (".section-header a", {"color": "rgb(197, 197, 197)"}, ALL) +assert-css: (".small-section-header a", {"color": "rgb(197, 197, 197)"}, ALL) + +goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html +assert-css: (".section-header a", {"color": "rgb(57, 175, 215)"}, ALL) // Dark theme local-storage: {"rustdoc-theme": "dark", "rustdoc-preferred-dark-theme": "dark", "rustdoc-use-system-theme": "false"} @@ -34,7 +37,10 @@ goto: file://|DOC_PATH|/test_docs/struct.Foo.html#method.must_use assert-css: ("#method\.must_use", {"color": "rgb(221, 221, 221)", "background-color": "rgb(73, 74, 61)"}, ALL) goto: file://|DOC_PATH|/test_docs/index.html -assert-css: (".section-header a", {"color": "rgb(221, 221, 221)"}, ALL) +assert-css: (".small-section-header a", {"color": "rgb(221, 221, 221)"}, ALL) + +goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html +assert-css: (".section-header a", {"color": "rgb(210, 153, 29)"}, ALL) // Light theme local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"} @@ -52,4 +58,7 @@ goto: file://|DOC_PATH|/test_docs/struct.Foo.html#method.must_use assert-css: ("#method\.must_use", {"color": "rgb(0, 0, 0)", "background-color": "rgb(253, 255, 211)"}, ALL) goto: file://|DOC_PATH|/test_docs/index.html -assert-css: (".section-header a", {"color": "rgb(0, 0, 0)"}, ALL) +assert-css: (".small-section-header a", {"color": "rgb(0, 0, 0)"}, ALL) + +goto: file://|DOC_PATH|/test_docs/struct.HeavilyDocumentedStruct.html +assert-css: (".section-header a", {"color": "rgb(56, 115, 173)"}, ALL) From 3cbe0f1b48dfdb7866f45a1d683b1391ed4d0508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 7 Dec 2021 00:00:00 +0000 Subject: [PATCH 02/12] Add test for packed drops in generators --- .../ui/packed/packed-struct-drop-aligned.rs | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/test/ui/packed/packed-struct-drop-aligned.rs b/src/test/ui/packed/packed-struct-drop-aligned.rs index fab3bbedac667..b95cdbbbaad3b 100644 --- a/src/test/ui/packed/packed-struct-drop-aligned.rs +++ b/src/test/ui/packed/packed-struct-drop-aligned.rs @@ -1,6 +1,10 @@ // run-pass +#![feature(generators)] +#![feature(generator_trait)] use std::cell::Cell; use std::mem; +use std::ops::Generator; +use std::pin::Pin; struct Aligned<'a> { drop_count: &'a Cell @@ -19,15 +23,35 @@ impl<'a> Drop for Aligned<'a> { } } +#[repr(transparent)] +struct NotCopy(u8); + #[repr(packed)] -struct Packed<'a>(u8, Aligned<'a>); +struct Packed<'a>(NotCopy, Aligned<'a>); fn main() { let drop_count = &Cell::new(0); { - let mut p = Packed(0, Aligned { drop_count }); + let mut p = Packed(NotCopy(0), Aligned { drop_count }); p.1 = Aligned { drop_count }; assert_eq!(drop_count.get(), 1); } assert_eq!(drop_count.get(), 2); + + let drop_count = &Cell::new(0); + let mut g = || { + let mut p = Packed(NotCopy(0), Aligned { drop_count }); + let _ = &p; + p.1 = Aligned { drop_count }; + assert_eq!(drop_count.get(), 1); + // Test that a generator drop function moves a value from a packed + // struct to a separate local before dropping it. We move out the + // first field to generate and open drop for the second field. + drop(p.0); + yield; + }; + Pin::new(&mut g).resume(()); + assert_eq!(drop_count.get(), 1); + drop(g); + assert_eq!(drop_count.get(), 2); } From 78e88f46d60c5487946fc7632a7561bdff6b9fcc Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Mon, 8 Nov 2021 19:15:54 +0000 Subject: [PATCH 03/12] Only shown relevant type params in E0283 label When we point at a binding to suggest giving it a type, erase all the type for ADTs that have been resolved, leaving only the ones that could not be inferred. For small shallow types this is not a problem, but for big nested types with lots of params, this can otherwise cause a lot of unnecessary visual output. --- .../infer/error_reporting/need_type_info.rs | 100 +++++++++++++++++- .../defaults/doesnt_infer.stderr | 2 +- .../inference/erase-type-params-in-label.rs | 13 +++ .../erase-type-params-in-label.stderr | 22 ++++ src/test/ui/inference/issue-83606.stderr | 2 +- 5 files changed, 136 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/inference/erase-type-params-in-label.rs create mode 100644 src/test/ui/inference/erase-type-params-in-label.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 32c02033dc9b9..6b9952ba5d684 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -11,7 +11,7 @@ use rustc_middle::hir::map::Map; use rustc_middle::infer::unify_key::ConstVariableOriginKind; use rustc_middle::ty::print::Print; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; -use rustc_middle::ty::{self, DefIdTree, InferConst, Ty, TyCtxt}; +use rustc_middle::ty::{self, DefIdTree, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder}; use rustc_span::symbol::kw; use rustc_span::Span; use std::borrow::Cow; @@ -629,6 +629,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { format!("the explicit type `{}`, with the type parameters specified", ty) } Some(ty) if is_named_and_not_impl_trait(ty) && ty.to_string() != arg_data.name => { + let ty = ResolvedTypeParamEraser::new(self.tcx).fold_ty(ty); + let ty = ErrTypeParamEraser(self.tcx).fold_ty(ty); let ty = ty_to_string(ty); format!( "the explicit type `{}`, where the type parameter `{}` is specified", @@ -908,3 +910,99 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err } } + +/// Turn resolved type params into `[type error]` to signal we don't want to display them. +struct ResolvedTypeParamEraser<'tcx> { + tcx: TyCtxt<'tcx>, + level: usize, +} + +impl<'tcx> ResolvedTypeParamEraser<'tcx> { + fn new(tcx: TyCtxt<'tcx>) -> Self { + ResolvedTypeParamEraser { tcx, level: 0 } + } +} +impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> { + fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + self.level += 1; + let t = match t.kind() { + // We'll hide this type only if all its type params are hidden as well. + ty::Adt(def, substs) => { + let generics = self.tcx().generics_of(def.did); + // Account for params with default values, like `Vec`, where we + // want to show `Vec`, not `Vec`. If we replaced that + // subst, then we'd get the incorrect output, so we passthrough. + let substs: Vec<_> = substs + .iter() + .zip(generics.params.iter()) + .map(|(subst, param)| match ¶m.kind { + ty::GenericParamDefKind::Type { has_default: true, .. } => subst, + _ => subst.super_fold_with(self), + }) + .collect(); + if self.level == 1 + || substs.iter().any(|subst| match subst.unpack() { + ty::subst::GenericArgKind::Type(t) => match t.kind() { + ty::Error(_) => false, + _ => true, + }, + // Account for `const` params here, otherwise `doesnt_infer.rs` + // shows `_` instead of `Foo<{ _: u32 }>` + ty::subst::GenericArgKind::Const(_) => true, + _ => false, + }) + { + let substs = self.tcx().intern_substs(&substs[..]); + self.tcx().mk_ty(ty::Adt(def, substs)) + } else { + self.tcx().ty_error() + } + } + ty::Ref(_, ty, _) => { + let ty = self.fold_ty(ty); + match ty.kind() { + // Avoid `&_`, these can be safely presented as `_`. + ty::Error(_) => self.tcx().ty_error(), + _ => t.super_fold_with(self), + } + } + // We could account for `()` if we wanted to replace it, but it's assured to be short. + ty::Tuple(_) + | ty::Slice(_) + | ty::RawPtr(_) + | ty::FnDef(..) + | ty::FnPtr(_) + | ty::Opaque(..) + | ty::Projection(_) + | ty::Never + | ty::Array(..) => t.super_fold_with(self), + // We don't want to hide type params that haven't been resolved yet. + // This would be the type that will be written out with the type param + // name in the output. + ty::Infer(_) => t, + // We don't want to hide the outermost type, only its type params. + _ if self.level == 1 => t.super_fold_with(self), + // Hide this type + _ => self.tcx().ty_error(), + }; + self.level -= 1; + t + } +} + +/// Replace `[type error]` with `ty::Infer(ty::Var)` to display `_`. +struct ErrTypeParamEraser<'tcx>(TyCtxt<'tcx>); +impl<'tcx> TypeFolder<'tcx> for ErrTypeParamEraser<'tcx> { + fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + self.0 + } + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + match t.kind() { + ty::Error(_) => self.tcx().mk_ty_var(ty::TyVid::from_u32(0)), + _ => t.super_fold_with(self), + } + } +} diff --git a/src/test/ui/const-generics/defaults/doesnt_infer.stderr b/src/test/ui/const-generics/defaults/doesnt_infer.stderr index b57975e26f290..183be1b1517a7 100644 --- a/src/test/ui/const-generics/defaults/doesnt_infer.stderr +++ b/src/test/ui/const-generics/defaults/doesnt_infer.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `Foo<{_: u32}>` LL | let foo = Foo::foo(); | --- ^^^^^^^^ cannot infer the value of const parameter `N` | | - | consider giving `foo` the explicit type `Foo<{_: u32}>`, where the type parameter `N` is specified + | consider giving `foo` the explicit type `Foo<{_: _}>`, where the type parameter `N` is specified error: aborting due to previous error diff --git a/src/test/ui/inference/erase-type-params-in-label.rs b/src/test/ui/inference/erase-type-params-in-label.rs new file mode 100644 index 0000000000000..4a163d0b81094 --- /dev/null +++ b/src/test/ui/inference/erase-type-params-in-label.rs @@ -0,0 +1,13 @@ +fn main() { + let foo = new(1, ""); //~ ERROR E0283 +} + +struct Bar { + t: T, + k: K, + n: N, +} + +fn new(t: T, k: K) -> Bar { + Bar { t, k, n: Default::default() } +} diff --git a/src/test/ui/inference/erase-type-params-in-label.stderr b/src/test/ui/inference/erase-type-params-in-label.stderr new file mode 100644 index 0000000000000..b665fade9d88f --- /dev/null +++ b/src/test/ui/inference/erase-type-params-in-label.stderr @@ -0,0 +1,22 @@ +error[E0283]: type annotations needed for `Bar` + --> $DIR/erase-type-params-in-label.rs:2:15 + | +LL | let foo = new(1, ""); + | --- ^^^ cannot infer type for type parameter `Z` declared on the function `new` + | | + | consider giving `foo` the explicit type `Bar<_, _, Z>`, where the type parameter `Z` is specified + | + = note: cannot satisfy `_: Default` +note: required by a bound in `new` + --> $DIR/erase-type-params-in-label.rs:11:17 + | +LL | fn new(t: T, k: K) -> Bar { + | ^^^^^^^ required by this bound in `new` +help: consider specifying the type arguments in the function call + | +LL | let foo = new::(1, ""); + | +++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/inference/issue-83606.stderr b/src/test/ui/inference/issue-83606.stderr index 65f3336b9358a..c66606b9c8304 100644 --- a/src/test/ui/inference/issue-83606.stderr +++ b/src/test/ui/inference/issue-83606.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `[usize; _]` LL | let _ = foo("foo"); //<- Do not suggest `foo::("foo");`! | - ^^^ cannot infer the value of const parameter `N` declared on the function `foo` | | - | consider giving this pattern the explicit type `[usize; _]`, where the type parameter `N` is specified + | consider giving this pattern the explicit type `[_; _]`, where the type parameter `N` is specified error: aborting due to previous error From 3fd15c8404626c6622555e66299c9f3442bf2322 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Mon, 8 Nov 2021 20:32:17 +0000 Subject: [PATCH 04/12] Refer to uninferred `const` params by their name, instead of `{ _: _ }` When the value of a const param isn't inferred, replace it with the param name from the definition. --- .../infer/error_reporting/need_type_info.rs | 31 +++++++++++++++---- .../defaults/doesnt_infer.stderr | 2 +- src/test/ui/inference/issue-83606.stderr | 2 +- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 6b9952ba5d684..56f0b5c192786 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -1,6 +1,5 @@ use crate::infer::type_variable::TypeVariableOriginKind; -use crate::infer::InferCtxt; -use crate::rustc_middle::ty::TypeFoldable; +use crate::infer::{InferCtxt, Symbol}; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace}; @@ -938,8 +937,17 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> { let substs: Vec<_> = substs .iter() .zip(generics.params.iter()) - .map(|(subst, param)| match ¶m.kind { - ty::GenericParamDefKind::Type { has_default: true, .. } => subst, + .map(|(subst, param)| match &(subst.unpack(), ¶m.kind) { + (_, ty::GenericParamDefKind::Type { has_default: true, .. }) => subst, + (crate::infer::GenericArgKind::Const(c), _) => { + match c.val { + ty::ConstKind::Infer(..) => { + // Replace not yet inferred const params with their def name. + self.tcx().mk_const_param(param.index, param.name, c.ty).into() + } + _ => subst, + } + } _ => subst.super_fold_with(self), }) .collect(); @@ -977,8 +985,19 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> { | ty::FnPtr(_) | ty::Opaque(..) | ty::Projection(_) - | ty::Never - | ty::Array(..) => t.super_fold_with(self), + | ty::Never => t.super_fold_with(self), + ty::Array(ty, c) => { + self.tcx().mk_ty(ty::Array( + self.fold_ty(ty), + match c.val { + ty::ConstKind::Infer(..) => { + // Replace not yet inferred const params with their def name. + self.tcx().mk_const_param(0, Symbol::intern("N"), c.ty).into() + } + _ => c, + }, + )) + } // We don't want to hide type params that haven't been resolved yet. // This would be the type that will be written out with the type param // name in the output. diff --git a/src/test/ui/const-generics/defaults/doesnt_infer.stderr b/src/test/ui/const-generics/defaults/doesnt_infer.stderr index 183be1b1517a7..10cd491b480c1 100644 --- a/src/test/ui/const-generics/defaults/doesnt_infer.stderr +++ b/src/test/ui/const-generics/defaults/doesnt_infer.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `Foo<{_: u32}>` LL | let foo = Foo::foo(); | --- ^^^^^^^^ cannot infer the value of const parameter `N` | | - | consider giving `foo` the explicit type `Foo<{_: _}>`, where the type parameter `N` is specified + | consider giving `foo` the explicit type `Foo`, where the type parameter `N` is specified error: aborting due to previous error diff --git a/src/test/ui/inference/issue-83606.stderr b/src/test/ui/inference/issue-83606.stderr index c66606b9c8304..0746b2491fbd6 100644 --- a/src/test/ui/inference/issue-83606.stderr +++ b/src/test/ui/inference/issue-83606.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `[usize; _]` LL | let _ = foo("foo"); //<- Do not suggest `foo::("foo");`! | - ^^^ cannot infer the value of const parameter `N` declared on the function `foo` | | - | consider giving this pattern the explicit type `[_; _]`, where the type parameter `N` is specified + | consider giving this pattern the explicit type `[_; N]`, where the type parameter `N` is specified error: aborting due to previous error From 6a691b1d92c0c34ee8b43a6d04df30c908c4d6a3 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Mon, 8 Nov 2021 21:10:00 +0000 Subject: [PATCH 05/12] Refer to const params as "const params" and not "type params" --- .../infer/error_reporting/need_type_info.rs | 82 +++++++++++-------- .../defaults/doesnt_infer.stderr | 2 +- src/test/ui/inference/issue-83606.stderr | 2 +- 3 files changed, 48 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 56f0b5c192786..739987e850a01 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -10,7 +10,7 @@ use rustc_middle::hir::map::Map; use rustc_middle::infer::unify_key::ConstVariableOriginKind; use rustc_middle::ty::print::Print; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; -use rustc_middle::ty::{self, DefIdTree, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder}; +use rustc_middle::ty::{self, Const, DefIdTree, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder}; use rustc_span::symbol::kw; use rustc_span::Span; use std::borrow::Cow; @@ -305,6 +305,15 @@ pub enum UnderspecifiedArgKind { Const { is_parameter: bool }, } +impl UnderspecifiedArgKind { + fn descr(&self) -> &'static str { + match self { + Self::Type { .. } => "type", + Self::Const { .. } => "const", + } + } +} + impl InferenceDiagnosticsData { /// Generate a label for a generic argument which can't be inferred. When not /// much is known about the argument, `use_diag` may be used to describe the @@ -587,6 +596,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + let param_type = arg_data.kind.descr(); let suffix = match local_visitor.found_node_ty { Some(ty) if ty.is_closure() => { let substs = @@ -625,15 +635,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } Some(ty) if is_named_and_not_impl_trait(ty) && arg_data.name == "_" => { let ty = ty_to_string(ty); - format!("the explicit type `{}`, with the type parameters specified", ty) + format!("the explicit type `{}`, with the {} parameters specified", ty, param_type) } Some(ty) if is_named_and_not_impl_trait(ty) && ty.to_string() != arg_data.name => { let ty = ResolvedTypeParamEraser::new(self.tcx).fold_ty(ty); let ty = ErrTypeParamEraser(self.tcx).fold_ty(ty); let ty = ty_to_string(ty); format!( - "the explicit type `{}`, where the type parameter `{}` is specified", - ty, arg_data.name, + "the explicit type `{}`, where the {} parameter `{}` is specified", + ty, param_type, arg_data.name, ) } _ => "a type".to_string(), @@ -910,7 +920,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } -/// Turn resolved type params into `[type error]` to signal we don't want to display them. +/// Turn *resolved* type params into `[type error]` to signal we don't want to display them. After +/// performing that replacement, we'll turn all remaining infer type params to use their name from +/// their definition, and replace all the `[type error]`s back to being infer so they display in +/// the output as `_`. If we didn't go through `[type error]`, we would either show all type params +/// by their name *or* `_`, neither of which is desireable: we want to show all types that we could +/// infer as `_` to reduce verbosity and avoid telling the user about unnecessary type annotations. struct ResolvedTypeParamEraser<'tcx> { tcx: TyCtxt<'tcx>, level: usize, @@ -920,7 +935,18 @@ impl<'tcx> ResolvedTypeParamEraser<'tcx> { fn new(tcx: TyCtxt<'tcx>) -> Self { ResolvedTypeParamEraser { tcx, level: 0 } } + + /// Replace not yet inferred const params with their def name. + fn replace_infers(&self, c: &'tcx Const<'tcx>, index: u32, name: Symbol) -> &'tcx Const<'tcx> { + match c.val { + ty::ConstKind::Infer(..) => { + self.tcx().mk_const_param(index, name, c.ty) + } + _ => c, + } + } } + impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { self.tcx @@ -940,29 +966,22 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> { .map(|(subst, param)| match &(subst.unpack(), ¶m.kind) { (_, ty::GenericParamDefKind::Type { has_default: true, .. }) => subst, (crate::infer::GenericArgKind::Const(c), _) => { - match c.val { - ty::ConstKind::Infer(..) => { - // Replace not yet inferred const params with their def name. - self.tcx().mk_const_param(param.index, param.name, c.ty).into() - } - _ => subst, - } + self.replace_infers(c, param.index, param.name).into() } _ => subst.super_fold_with(self), }) .collect(); - if self.level == 1 - || substs.iter().any(|subst| match subst.unpack() { - ty::subst::GenericArgKind::Type(t) => match t.kind() { - ty::Error(_) => false, - _ => true, - }, - // Account for `const` params here, otherwise `doesnt_infer.rs` - // shows `_` instead of `Foo<{ _: u32 }>` - ty::subst::GenericArgKind::Const(_) => true, - _ => false, - }) - { + let should_keep = |subst: &GenericArg<'_>| match subst.unpack() { + ty::subst::GenericArgKind::Type(t) => match t.kind() { + ty::Error(_) => false, + _ => true, + }, + // Account for `const` params here, otherwise `doesnt_infer.rs` + // shows `_` instead of `Foo<{ _: u32 }>` + ty::subst::GenericArgKind::Const(_) => true, + _ => false, + }; + if self.level == 1 || substs.iter().any(should_keep) { let substs = self.tcx().intern_substs(&substs[..]); self.tcx().mk_ty(ty::Adt(def, substs)) } else { @@ -986,18 +1005,9 @@ impl<'tcx> TypeFolder<'tcx> for ResolvedTypeParamEraser<'tcx> { | ty::Opaque(..) | ty::Projection(_) | ty::Never => t.super_fold_with(self), - ty::Array(ty, c) => { - self.tcx().mk_ty(ty::Array( - self.fold_ty(ty), - match c.val { - ty::ConstKind::Infer(..) => { - // Replace not yet inferred const params with their def name. - self.tcx().mk_const_param(0, Symbol::intern("N"), c.ty).into() - } - _ => c, - }, - )) - } + ty::Array(ty, c) => self + .tcx() + .mk_ty(ty::Array(self.fold_ty(ty), self.replace_infers(c, 0, Symbol::intern("N")))), // We don't want to hide type params that haven't been resolved yet. // This would be the type that will be written out with the type param // name in the output. diff --git a/src/test/ui/const-generics/defaults/doesnt_infer.stderr b/src/test/ui/const-generics/defaults/doesnt_infer.stderr index 10cd491b480c1..d6c64d58be5f3 100644 --- a/src/test/ui/const-generics/defaults/doesnt_infer.stderr +++ b/src/test/ui/const-generics/defaults/doesnt_infer.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `Foo<{_: u32}>` LL | let foo = Foo::foo(); | --- ^^^^^^^^ cannot infer the value of const parameter `N` | | - | consider giving `foo` the explicit type `Foo`, where the type parameter `N` is specified + | consider giving `foo` the explicit type `Foo`, where the const parameter `N` is specified error: aborting due to previous error diff --git a/src/test/ui/inference/issue-83606.stderr b/src/test/ui/inference/issue-83606.stderr index 0746b2491fbd6..9ca8f35fd545a 100644 --- a/src/test/ui/inference/issue-83606.stderr +++ b/src/test/ui/inference/issue-83606.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `[usize; _]` LL | let _ = foo("foo"); //<- Do not suggest `foo::("foo");`! | - ^^^ cannot infer the value of const parameter `N` declared on the function `foo` | | - | consider giving this pattern the explicit type `[_; N]`, where the type parameter `N` is specified + | consider giving this pattern the explicit type `[_; N]`, where the const parameter `N` is specified error: aborting due to previous error From 7271d1f803ba4a2f850d19c570d04993b61881a9 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Fri, 19 Nov 2021 06:10:43 +0000 Subject: [PATCH 06/12] Add test with multiple type params failing inference --- .../infer/error_reporting/need_type_info.rs | 4 +- .../inference/erase-type-params-in-label.rs | 18 ++++++++- .../erase-type-params-in-label.stderr | 39 ++++++++++++++----- 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 739987e850a01..9cf6cde259150 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -939,9 +939,7 @@ impl<'tcx> ResolvedTypeParamEraser<'tcx> { /// Replace not yet inferred const params with their def name. fn replace_infers(&self, c: &'tcx Const<'tcx>, index: u32, name: Symbol) -> &'tcx Const<'tcx> { match c.val { - ty::ConstKind::Infer(..) => { - self.tcx().mk_const_param(index, name, c.ty) - } + ty::ConstKind::Infer(..) => self.tcx().mk_const_param(index, name, c.ty), _ => c, } } diff --git a/src/test/ui/inference/erase-type-params-in-label.rs b/src/test/ui/inference/erase-type-params-in-label.rs index 4a163d0b81094..1fea2da92da94 100644 --- a/src/test/ui/inference/erase-type-params-in-label.rs +++ b/src/test/ui/inference/erase-type-params-in-label.rs @@ -1,5 +1,8 @@ fn main() { - let foo = new(1, ""); //~ ERROR E0283 + let foo = foo(1, ""); //~ ERROR E0283 +} +fn baz() { + let bar = bar(1, ""); //~ ERROR E0283 } struct Bar { @@ -8,6 +11,17 @@ struct Bar { n: N, } -fn new(t: T, k: K) -> Bar { +fn bar(t: T, k: K) -> Bar { Bar { t, k, n: Default::default() } } + +struct Foo { + t: T, + k: K, + n: N, + m: M, +} + +fn foo(t: T, k: K) -> Foo { + Foo { t, k, n: Default::default(), m: Default::default() } +} diff --git a/src/test/ui/inference/erase-type-params-in-label.stderr b/src/test/ui/inference/erase-type-params-in-label.stderr index b665fade9d88f..d0b06cde9d63a 100644 --- a/src/test/ui/inference/erase-type-params-in-label.stderr +++ b/src/test/ui/inference/erase-type-params-in-label.stderr @@ -1,22 +1,41 @@ -error[E0283]: type annotations needed for `Bar` +error[E0283]: type annotations needed for `Foo` --> $DIR/erase-type-params-in-label.rs:2:15 | -LL | let foo = new(1, ""); - | --- ^^^ cannot infer type for type parameter `Z` declared on the function `new` +LL | let foo = foo(1, ""); + | --- ^^^ cannot infer type for type parameter `W` declared on the function `foo` + | | + | consider giving `foo` the explicit type `Foo<_, _, W, Z>`, where the type parameter `W` is specified + | + = note: cannot satisfy `_: Default` +note: required by a bound in `foo` + --> $DIR/erase-type-params-in-label.rs:25:17 + | +LL | fn foo(t: T, k: K) -> Foo { + | ^^^^^^^ required by this bound in `foo` +help: consider specifying the type arguments in the function call + | +LL | let foo = foo::(1, ""); + | ++++++++++++++ + +error[E0283]: type annotations needed for `Bar` + --> $DIR/erase-type-params-in-label.rs:5:15 + | +LL | let bar = bar(1, ""); + | --- ^^^ cannot infer type for type parameter `Z` declared on the function `bar` | | - | consider giving `foo` the explicit type `Bar<_, _, Z>`, where the type parameter `Z` is specified + | consider giving `bar` the explicit type `Bar<_, _, Z>`, where the type parameter `Z` is specified | = note: cannot satisfy `_: Default` -note: required by a bound in `new` - --> $DIR/erase-type-params-in-label.rs:11:17 +note: required by a bound in `bar` + --> $DIR/erase-type-params-in-label.rs:14:17 | -LL | fn new(t: T, k: K) -> Bar { - | ^^^^^^^ required by this bound in `new` +LL | fn bar(t: T, k: K) -> Bar { + | ^^^^^^^ required by this bound in `bar` help: consider specifying the type arguments in the function call | -LL | let foo = new::(1, ""); +LL | let bar = bar::(1, ""); | +++++++++++ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0283`. From 6e7ec0c5b4b961a9260e72613b7d5477f09d7187 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 12 Nov 2021 14:45:19 +0100 Subject: [PATCH 07/12] Simplify collect_in_band_defs. --- compiler/rustc_ast_lowering/src/lib.rs | 71 +++++++++++++------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index d0fbc2d0f11d4..ec5022679d439 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -646,31 +646,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// parameter while `f` is running (and restored afterwards). fn collect_in_band_defs( &mut self, - parent_def_id: LocalDefId, - anonymous_lifetime_mode: AnonymousLifetimeMode, - f: impl FnOnce(&mut Self) -> (Vec>, T), - ) -> (Vec>, T) { + f: impl FnOnce(&mut Self) -> T, + ) -> (Vec<(Span, ParamName)>, T) { assert!(!self.is_collecting_in_band_lifetimes); assert!(self.lifetimes_to_define.is_empty()); - let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode; - - self.anonymous_lifetime_mode = anonymous_lifetime_mode; self.is_collecting_in_band_lifetimes = true; - let (in_band_ty_params, res) = f(self); + let res = f(self); self.is_collecting_in_band_lifetimes = false; - self.anonymous_lifetime_mode = old_anonymous_lifetime_mode; - - let lifetimes_to_define = self.lifetimes_to_define.split_off(0); - let params = lifetimes_to_define - .into_iter() - .map(|(span, hir_name)| self.lifetime_to_generic_param(span, hir_name, parent_def_id)) - .chain(in_band_ty_params.into_iter()) - .collect(); - - (params, res) + let lifetimes_to_define = std::mem::take(&mut self.lifetimes_to_define); + (lifetimes_to_define, res) } /// Converts a lifetime into a new generic parameter. @@ -785,27 +772,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { anonymous_lifetime_mode: AnonymousLifetimeMode, f: impl FnOnce(&mut Self, &mut Vec>) -> T, ) -> (hir::Generics<'hir>, T) { - let (in_band_defs, (mut lowered_generics, res)) = - self.with_in_scope_lifetime_defs(&generics.params, |this| { - this.collect_in_band_defs(parent_def_id, anonymous_lifetime_mode, |this| { - let mut params = Vec::new(); - // Note: it is necessary to lower generics *before* calling `f`. - // When lowering `async fn`, there's a final step when lowering - // the return type that assumes that all in-scope lifetimes have - // already been added to either `in_scope_lifetimes` or - // `lifetimes_to_define`. If we swapped the order of these two, - // in-band-lifetimes introduced by generics or where-clauses - // wouldn't have been added yet. - let generics = this.lower_generics_mut( - generics, - ImplTraitContext::Universal(&mut params, this.current_hir_id_owner), - ); - let res = f(this, &mut params); - (params, (generics, res)) + let (lifetimes_to_define, (mut lowered_generics, impl_trait_defs, res)) = self + .collect_in_band_defs(|this| { + this.with_anonymous_lifetime_mode(anonymous_lifetime_mode, |this| { + this.with_in_scope_lifetime_defs(&generics.params, |this| { + let mut impl_trait_defs = Vec::new(); + // Note: it is necessary to lower generics *before* calling `f`. + // When lowering `async fn`, there's a final step when lowering + // the return type that assumes that all in-scope lifetimes have + // already been added to either `in_scope_lifetimes` or + // `lifetimes_to_define`. If we swapped the order of these two, + // in-band-lifetimes introduced by generics or where-clauses + // wouldn't have been added yet. + let generics = this.lower_generics_mut( + generics, + ImplTraitContext::Universal( + &mut impl_trait_defs, + this.current_hir_id_owner, + ), + ); + let res = f(this, &mut impl_trait_defs); + (generics, impl_trait_defs, res) + }) }) }); - lowered_generics.params.extend(in_band_defs); + lowered_generics.params.extend( + lifetimes_to_define + .into_iter() + .map(|(span, hir_name)| { + self.lifetime_to_generic_param(span, hir_name, parent_def_id) + }) + .chain(impl_trait_defs), + ); let lowered_generics = lowered_generics.into_generics(self.arena); (lowered_generics, res) From 72b6f7049c0903ac266dc67510b655441528bdf2 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 29 Nov 2021 22:59:13 +0100 Subject: [PATCH 08/12] Use collect_in_band_defs for async lifetime captures. --- compiler/rustc_ast_lowering/src/lib.rs | 98 +++++++++---------- .../ui/async-await/generics-and-bounds.rs | 11 +++ 2 files changed, 55 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index ec5022679d439..667e94656f600 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -648,15 +648,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, f: impl FnOnce(&mut Self) -> T, ) -> (Vec<(Span, ParamName)>, T) { - assert!(!self.is_collecting_in_band_lifetimes); - assert!(self.lifetimes_to_define.is_empty()); - self.is_collecting_in_band_lifetimes = true; + let was_collecting = std::mem::replace(&mut self.is_collecting_in_band_lifetimes, true); + let len = self.lifetimes_to_define.len(); let res = f(self); - self.is_collecting_in_band_lifetimes = false; - - let lifetimes_to_define = std::mem::take(&mut self.lifetimes_to_define); + let lifetimes_to_define = self.lifetimes_to_define.split_off(len); + self.is_collecting_in_band_lifetimes = was_collecting; (lifetimes_to_define, res) } @@ -1688,18 +1686,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // this is because the elided lifetimes from the return type // should be figured out using the ordinary elision rules, and // this desugaring achieves that. + + debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", self.in_scope_lifetimes); + debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", self.lifetimes_to_define); + + // Calculate all the lifetimes that should be captured + // by the opaque type. This should include all in-scope + // lifetime parameters, including those defined in-band. // - // The variable `input_lifetimes_count` tracks the number of - // lifetime parameters to the opaque type *not counting* those - // lifetimes elided in the return type. This includes those - // that are explicitly declared (`in_scope_lifetimes`) and - // those elided lifetimes we found in the arguments (current - // content of `lifetimes_to_define`). Next, we will process - // the return type, which will cause `lifetimes_to_define` to - // grow. - let input_lifetimes_count = self.in_scope_lifetimes.len() + self.lifetimes_to_define.len(); - - let mut lifetime_params = Vec::new(); + // `lifetime_params` is a vector of tuple (span, parameter name, lifetime name). + + // Input lifetime like `'a` or `'1`: + let mut lifetime_params: Vec<_> = self + .in_scope_lifetimes + .iter() + .cloned() + .map(|name| (name.ident().span, name, hir::LifetimeName::Param(name))) + .chain( + self.lifetimes_to_define + .iter() + .map(|&(span, name)| (span, name, hir::LifetimeName::Param(name))), + ) + .collect(); + self.with_hir_id_owner(opaque_ty_node_id, |this| { // We have to be careful to get elision right here. The // idea is that we create a lifetime parameter for each @@ -1709,34 +1718,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and // hence the elision takes place at the fn site. - let future_bound = this - .with_anonymous_lifetime_mode(AnonymousLifetimeMode::CreateParameter, |this| { - this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span) + let (lifetimes_to_define, future_bound) = + this.with_anonymous_lifetime_mode(AnonymousLifetimeMode::CreateParameter, |this| { + this.collect_in_band_defs(|this| { + this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span) + }) }); - debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound); + debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", lifetimes_to_define); - // Calculate all the lifetimes that should be captured - // by the opaque type. This should include all in-scope - // lifetime parameters, including those defined in-band. - // - // Note: this must be done after lowering the output type, - // as the output type may introduce new in-band lifetimes. - lifetime_params = this - .in_scope_lifetimes - .iter() - .cloned() - .map(|name| (name.ident().span, name)) - .chain(this.lifetimes_to_define.iter().cloned()) - .collect(); - - debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", this.in_scope_lifetimes); - debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", this.lifetimes_to_define); + lifetime_params.extend( + // Output lifetime like `'_`: + lifetimes_to_define + .into_iter() + .map(|(span, name)| (span, name, hir::LifetimeName::Implicit(false))), + ); debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params); let generic_params = - this.arena.alloc_from_iter(lifetime_params.iter().map(|(span, hir_name)| { - this.lifetime_to_generic_param(*span, *hir_name, opaque_ty_def_id) + this.arena.alloc_from_iter(lifetime_params.iter().map(|&(span, hir_name, _)| { + this.lifetime_to_generic_param(span, hir_name, opaque_ty_def_id) })); let opaque_ty_item = hir::OpaqueTy { @@ -1770,25 +1771,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // // For the "output" lifetime parameters, we just want to // generate `'_`. - let mut generic_args = Vec::with_capacity(lifetime_params.len()); - generic_args.extend(lifetime_params[..input_lifetimes_count].iter().map( - |&(span, hir_name)| { - // Input lifetime like `'a` or `'1`: + let generic_args = + self.arena.alloc_from_iter(lifetime_params.into_iter().map(|(span, _, name)| { GenericArg::Lifetime(hir::Lifetime { hir_id: self.next_id(), span: self.lower_span(span), - name: hir::LifetimeName::Param(hir_name), + name, }) - }, - )); - generic_args.extend(lifetime_params[input_lifetimes_count..].iter().map(|&(span, _)| - // Output lifetime like `'_`. - GenericArg::Lifetime(hir::Lifetime { - hir_id: self.next_id(), - span: self.lower_span(span), - name: hir::LifetimeName::Implicit(false), - }))); - let generic_args = self.arena.alloc_from_iter(generic_args); + })); // Create the `Foo<...>` reference itself. Note that the `type // Foo = impl Trait` is, internally, created as a child of the diff --git a/src/test/ui/async-await/generics-and-bounds.rs b/src/test/ui/async-await/generics-and-bounds.rs index 963b19b34a620..90ab0c01f5450 100644 --- a/src/test/ui/async-await/generics-and-bounds.rs +++ b/src/test/ui/async-await/generics-and-bounds.rs @@ -2,6 +2,8 @@ // edition:2018 // compile-flags: --crate-type lib +#![feature(in_band_lifetimes)] + use std::future::Future; pub async fn simple_generic() {} @@ -71,6 +73,10 @@ pub fn call_with_ref_block<'a>(f: &'a (impl Foo + 'a)) -> impl Future impl Future + 'a { + async move { f.foo() } +} + pub fn async_block_with_same_generic_params_unifies() { let mut a = call_generic_bound_block(FooType); a = call_generic_bound_block(FooType); @@ -85,4 +91,9 @@ pub fn async_block_with_same_generic_params_unifies() { let f_two = FooType; let mut d = call_with_ref_block(&f_one); d = call_with_ref_block(&f_two); + + let f_one = FooType; + let f_two = FooType; + let mut d = call_with_ref_block_in_band(&f_one); + d = call_with_ref_block_in_band(&f_two); } From 8576ab45e4fc192524ab615f3309d9b552528828 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 30 Nov 2021 19:11:35 +0100 Subject: [PATCH 09/12] Store impl_trait_fn inside OpaqueTyOrigin. --- compiler/rustc_ast_lowering/src/item.rs | 9 +-- compiler/rustc_ast_lowering/src/lib.rs | 25 +++--- .../src/region_infer/opaque_types.rs | 2 +- compiler/rustc_hir/src/hir.rs | 9 ++- .../error_reporting/nice_region_error/util.rs | 2 +- .../rustc_infer/src/infer/opaque_types.rs | 22 +++--- compiler/rustc_middle/src/ty/mod.rs | 18 +++-- compiler/rustc_resolve/src/late/lifetimes.rs | 15 +++- compiler/rustc_ty_utils/src/ty.rs | 4 +- compiler/rustc_typeck/src/astconv/mod.rs | 13 ++- compiler/rustc_typeck/src/check/check.rs | 8 +- compiler/rustc_typeck/src/collect.rs | 79 +++++++++++-------- compiler/rustc_typeck/src/collect/type_of.rs | 8 +- 13 files changed, 118 insertions(+), 96 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 692f39368243a..ca7a64e254e14 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -247,12 +247,7 @@ impl<'hir> LoweringContext<'_, 'hir> { AnonymousLifetimeMode::PassThrough, |this, idty| { let ret_id = asyncness.opt_return_id(); - this.lower_fn_decl( - &decl, - Some((fn_def_id.to_def_id(), idty)), - true, - ret_id, - ) + this.lower_fn_decl(&decl, Some((fn_def_id, idty)), true, ret_id) }, ); let sig = hir::FnSig { @@ -1264,7 +1259,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |this, idty| { this.lower_fn_decl( &sig.decl, - Some((fn_def_id.to_def_id(), idty)), + Some((fn_def_id, idty)), impl_trait_return_allow, is_async, ) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 667e94656f600..c04b0471cb72f 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -228,7 +228,7 @@ enum ImplTraitContext<'b, 'a> { ReturnPositionOpaqueTy { /// `DefId` for the parent function, used to look up necessary /// information later. - fn_def_id: DefId, + fn_def_id: LocalDefId, /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn, origin: hir::OpaqueTyOrigin, }, @@ -1377,7 +1377,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_opaque_impl_trait( &mut self, span: Span, - fn_def_id: Option, + fn_def_id: Option, origin: hir::OpaqueTyOrigin, opaque_ty_node_id: NodeId, capturable_lifetimes: Option<&FxHashSet>, @@ -1449,7 +1449,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: lctx.lower_span(span), }, bounds: hir_bounds, - impl_trait_fn: fn_def_id, origin, }; @@ -1519,7 +1518,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_fn_decl( &mut self, decl: &FnDecl, - mut in_band_ty_params: Option<(DefId, &mut Vec>)>, + mut in_band_ty_params: Option<(LocalDefId, &mut Vec>)>, impl_trait_return_allow: bool, make_ret_async: Option, ) -> &'hir hir::FnDecl<'hir> { @@ -1577,7 +1576,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Some((def_id, _)) if impl_trait_return_allow => { ImplTraitContext::ReturnPositionOpaqueTy { fn_def_id: def_id, - origin: hir::OpaqueTyOrigin::FnReturn, + origin: hir::OpaqueTyOrigin::FnReturn(def_id), } } _ => ImplTraitContext::disallowed(), @@ -1632,7 +1631,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_async_fn_ret_ty( &mut self, output: &FnRetTy, - fn_def_id: DefId, + fn_def_id: LocalDefId, opaque_ty_node_id: NodeId, ) -> hir::FnRetTy<'hir> { debug!( @@ -1747,8 +1746,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: this.lower_span(span), }, bounds: arena_vec![this; future_bound], - impl_trait_fn: Some(fn_def_id), - origin: hir::OpaqueTyOrigin::AsyncFn, + origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id), }; trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id); @@ -1794,7 +1792,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_async_fn_output_type_to_future_bound( &mut self, output: &FnRetTy, - fn_def_id: DefId, + fn_def_id: LocalDefId, span: Span, ) -> hir::GenericBound<'hir> { // Compute the `T` in `Future` from the return type. @@ -1805,7 +1803,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // generates. let context = ImplTraitContext::ReturnPositionOpaqueTy { fn_def_id, - origin: hir::OpaqueTyOrigin::FnReturn, + origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id), }; self.lower_ty(ty, context) } @@ -2442,17 +2440,12 @@ impl<'hir> GenericArgsCtor<'hir> { } } +#[tracing::instrument(level = "debug")] fn lifetimes_from_impl_trait_bounds( opaque_ty_id: NodeId, bounds: hir::GenericBounds<'_>, lifetimes_to_include: Option<&FxHashSet>, ) -> Vec<(hir::LifetimeName, Span)> { - debug!( - "lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \ - bounds={:#?})", - opaque_ty_id, bounds, - ); - // This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that // appear in the bounds, excluding lifetimes that are created within the bounds. // E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`. diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 4eb7be542e7a1..76b3be7976c61 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -173,7 +173,7 @@ fn check_opaque_type_parameter_valid( // fn foo() -> foo::<'static..'static>::Foo<'l0..'lm>. // // which would error here on all of the `'static` args. - OpaqueTyOrigin::FnReturn | OpaqueTyOrigin::AsyncFn => return true, + OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return true, // Check these OpaqueTyOrigin::TyAlias => {} } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 487ae87052ba3..d393ea6893849 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2248,7 +2248,6 @@ pub struct BareFnTy<'hir> { pub struct OpaqueTy<'hir> { pub generics: Generics<'hir>, pub bounds: GenericBounds<'hir>, - pub impl_trait_fn: Option, pub origin: OpaqueTyOrigin, } @@ -2256,9 +2255,9 @@ pub struct OpaqueTy<'hir> { #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)] pub enum OpaqueTyOrigin { /// `-> impl Trait` - FnReturn, + FnReturn(LocalDefId), /// `async fn` - AsyncFn, + AsyncFn(LocalDefId), /// type aliases: `type Foo = impl Trait;` TyAlias, } @@ -2809,7 +2808,9 @@ impl ItemKind<'_> { Some(match *self { ItemKind::Fn(_, ref generics, _) | ItemKind::TyAlias(_, ref generics) - | ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. }) + | ItemKind::OpaqueTy(OpaqueTy { + ref generics, origin: OpaqueTyOrigin::TyAlias, .. + }) | ItemKind::Enum(_, ref generics) | ItemKind::Struct(_, ref generics) | ItemKind::Union(_, ref generics) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index 90bc5b3b2fed1..04eceecc5f072 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -107,7 +107,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, - origin: hir::OpaqueTyOrigin::AsyncFn, + origin: hir::OpaqueTyOrigin::AsyncFn(..), .. }), .. diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index d9ab4ae1eda29..754d5a6ed7251 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -276,7 +276,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { debug!(?concrete_ty); let first_own_region = match opaque_defn.origin { - hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => { + hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => { // We lower // // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm> @@ -463,20 +463,24 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { let parent_def_id = self.infcx.defining_use_anchor; let (in_definition_scope, origin) = match tcx.hir().expect_item(def_id).kind { + // Async `impl Trait` + hir::ItemKind::OpaqueTy(hir::OpaqueTy { + origin: hir::OpaqueTyOrigin::AsyncFn(parent), + .. + }) => (parent == parent_def_id, hir::OpaqueTyOrigin::AsyncFn(parent)), // Anonymous `impl Trait` hir::ItemKind::OpaqueTy(hir::OpaqueTy { - impl_trait_fn: Some(parent), - origin, + origin: hir::OpaqueTyOrigin::FnReturn(parent), .. - }) => (parent == parent_def_id.to_def_id(), origin), + }) => (parent == parent_def_id, hir::OpaqueTyOrigin::FnReturn(parent)), // Named `type Foo = impl Bar;` hir::ItemKind::OpaqueTy(hir::OpaqueTy { - impl_trait_fn: None, - origin, + origin: hir::OpaqueTyOrigin::TyAlias, .. - }) => { - (may_define_opaque_type(tcx, parent_def_id, opaque_hir_id), origin) - } + }) => ( + may_define_opaque_type(tcx, parent_def_id, opaque_hir_id), + hir::OpaqueTyOrigin::TyAlias, + ), ref itemkind => { span_bug!( self.value_span, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7e1804673df2c..fd1409949f0a7 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2055,13 +2055,17 @@ impl<'tcx> TyCtxt<'tcx> { } } -/// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition. -pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { - if let Some(def_id) = def_id.as_local() { - if let Node::Item(item) = tcx.hir().get(tcx.hir().local_def_id_to_hir_id(def_id)) { - if let hir::ItemKind::OpaqueTy(ref opaque_ty) = item.kind { - return opaque_ty.impl_trait_fn; - } +/// Yields the parent function's `LocalDefId` if `def_id` is an `impl Trait` definition. +pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { + let def_id = def_id.as_local()?; + if let Node::Item(item) = tcx.hir().get(tcx.hir().local_def_id_to_hir_id(def_id)) { + if let hir::ItemKind::OpaqueTy(ref opaque_ty) = item.kind { + return match opaque_ty.origin { + hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => { + Some(parent) + } + hir::OpaqueTyOrigin::TyAlias => None, + }; } } None diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 1ff33689b53c7..c94c56df75b78 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -968,7 +968,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let (generics, bounds) = match opaque_ty.kind { // Named opaque `impl Trait` types are reached via `TyKind::Path`. // This arm is for `impl Trait` in the types of statics, constants and locals. - hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: None, .. }) => { + hir::ItemKind::OpaqueTy(hir::OpaqueTy { + origin: hir::OpaqueTyOrigin::TyAlias, + .. + }) => { intravisit::walk_ty(self, ty); // Elided lifetimes are not allowed in non-return @@ -985,7 +988,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } // RPIT (return position impl trait) hir::ItemKind::OpaqueTy(hir::OpaqueTy { - impl_trait_fn: Some(_), + origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..), ref generics, bounds, .. @@ -1695,7 +1698,11 @@ fn compute_object_lifetime_defaults( hir::ItemKind::Struct(_, ref generics) | hir::ItemKind::Union(_, ref generics) | hir::ItemKind::Enum(_, ref generics) - | hir::ItemKind::OpaqueTy(hir::OpaqueTy { ref generics, impl_trait_fn: None, .. }) + | hir::ItemKind::OpaqueTy(hir::OpaqueTy { + ref generics, + origin: hir::OpaqueTyOrigin::TyAlias, + .. + }) | hir::ItemKind::TyAlias(_, ref generics) | hir::ItemKind::Trait(_, _, ref generics, ..) => { let result = object_lifetime_defaults_for_item(tcx, generics); @@ -2067,7 +2074,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .. }) = self.tcx.hir().get(parent_hir_id) { - if opaque.origin != hir::OpaqueTyOrigin::AsyncFn { + if !matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn(..)) { continue 'lifetimes; } // We want to do this only if the liftime identifier is already defined diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 711a6f2fbebdd..74a015d4c348e 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -248,7 +248,7 @@ fn trait_of_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option { fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { // The param_env of an impl Trait type is its defining function's param_env if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) { - return param_env(tcx, parent); + return param_env(tcx, parent.to_def_id()); } // Compute the bounds on Self and the type parameters. @@ -313,7 +313,7 @@ fn well_formed_types_in_env<'tcx>( // The environment of an impl Trait type is its defining function's environment. if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) { - return well_formed_types_in_env(tcx, parent); + return well_formed_types_in_env(tcx, parent.to_def_id()); } // Compute the bounds on `Self` and the type parameters. diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 08261fedd4a25..908adeb22b364 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2336,9 +2336,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let def_id = item_id.def_id.to_def_id(); match opaque_ty.kind { - hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => { - self.impl_trait_ty_to_ty(def_id, lifetimes, impl_trait_fn.is_some()) - } + hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => self + .impl_trait_ty_to_ty( + def_id, + lifetimes, + matches!( + origin, + hir::OpaqueTyOrigin::FnReturn(..) + | hir::OpaqueTyOrigin::AsyncFn(..) + ), + ), ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i), } } diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 2061f955d968f..a6b16e7f0d4d8 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -541,7 +541,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( } if let ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn, + origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..), .. }) = item.kind { @@ -567,7 +567,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( visitor.visit_item(&item); let is_async = match item.kind { ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => { - matches!(origin, hir::OpaqueTyOrigin::AsyncFn) + matches!(origin, hir::OpaqueTyOrigin::AsyncFn(..)) } _ => unreachable!(), }; @@ -604,7 +604,7 @@ pub(super) fn check_opaque_for_cycles<'tcx>( ) -> Result<(), ErrorReported> { if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() { match origin { - hir::OpaqueTyOrigin::AsyncFn => async_opaque_type_cycle_error(tcx, span), + hir::OpaqueTyOrigin::AsyncFn(..) => async_opaque_type_cycle_error(tcx, span), _ => opaque_type_cycle_error(tcx, def_id, span), } Err(ErrorReported) @@ -635,7 +635,7 @@ fn check_opaque_meets_bounds<'tcx>( ) { match origin { // Checked when type checking the function containing them. - hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => return, + hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => return, // Can have different predicates to their defining use hir::OpaqueTyOrigin::TyAlias => {} } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 67a3053c60786..e8d28dd75d6aa 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -594,7 +594,11 @@ fn type_param_predicates( ItemKind::Fn(.., ref generics, _) | ItemKind::Impl(hir::Impl { ref generics, .. }) | ItemKind::TyAlias(_, ref generics) - | ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. }) + | ItemKind::OpaqueTy(OpaqueTy { + ref generics, + origin: hir::OpaqueTyOrigin::TyAlias, + .. + }) | ItemKind::Enum(_, ref generics) | ItemKind::Struct(_, ref generics) | ItemKind::Union(_, ref generics) => generics, @@ -793,7 +797,10 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { } // Desugared from `impl Trait`, so visited by the function's return type. - hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) => {} + hir::ItemKind::OpaqueTy(hir::OpaqueTy { + origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..), + .. + }) => {} // Don't call `type_of` on opaque types, since that depends on type // checking function bodies. `check_item_type` ensures that it's called @@ -1488,15 +1495,18 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { Some(tcx.typeck_root_def_id(def_id)) } Node::Item(item) => match item.kind { - ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => { - impl_trait_fn.or_else(|| { - let parent_id = tcx.hir().get_parent_item(hir_id); - assert!(parent_id != hir_id && parent_id != CRATE_HIR_ID); - debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); - // Opaque types are always nested within another item, and - // inherit the generics of the item. - Some(tcx.hir().local_def_id(parent_id).to_def_id()) - }) + ItemKind::OpaqueTy(hir::OpaqueTy { + origin: + hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id), + .. + }) => Some(fn_def_id.to_def_id()), + ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => { + let parent_id = tcx.hir().get_parent_item(hir_id); + assert!(parent_id != hir_id && parent_id != CRATE_HIR_ID); + debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); + // Opaque types are always nested within another item, and + // inherit the generics of the item. + Some(tcx.hir().local_def_id(parent_id).to_def_id()) } _ => None, }, @@ -2051,31 +2061,32 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP generics } ItemKind::OpaqueTy(OpaqueTy { - bounds: _, - impl_trait_fn, + origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..), + .. + }) => { + // return-position impl trait + // + // We don't inherit predicates from the parent here: + // If we have, say `fn f<'a, T: 'a>() -> impl Sized {}` + // then the return type is `f::<'static, T>::{{opaque}}`. + // + // If we inherited the predicates of `f` then we would + // require that `T: 'static` to show that the return + // type is well-formed. + // + // The only way to have something with this opaque type + // is from the return type of the containing function, + // which will ensure that the function's predicates + // hold. + return ty::GenericPredicates { parent: None, predicates: &[] }; + } + ItemKind::OpaqueTy(OpaqueTy { ref generics, - origin: _, + origin: hir::OpaqueTyOrigin::TyAlias, + .. }) => { - if impl_trait_fn.is_some() { - // return-position impl trait - // - // We don't inherit predicates from the parent here: - // If we have, say `fn f<'a, T: 'a>() -> impl Sized {}` - // then the return type is `f::<'static, T>::{{opaque}}`. - // - // If we inherited the predicates of `f` then we would - // require that `T: 'static` to show that the return - // type is well-formed. - // - // The only way to have something with this opaque type - // is from the return type of the containing function, - // which will ensure that the function's predicates - // hold. - return ty::GenericPredicates { parent: None, predicates: &[] }; - } else { - // type-alias impl trait - generics - } + // type-alias impl trait + generics } _ => NO_GENERICS, diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index b684844744de3..af199ca99460f 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -394,13 +394,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); tcx.mk_adt(def, substs) } - ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }) => { + ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => { find_opaque_ty_constraints(tcx, def_id) } // Opaque types desugared from `impl Trait`. - ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: Some(owner), .. }) => { + ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), .. }) => { let concrete_ty = tcx - .mir_borrowck(owner.expect_local()) + .mir_borrowck(owner) .concrete_opaque_types .get_value_matching(|(key, _)| key.def_id == def_id.to_def_id()) .copied() @@ -413,7 +413,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { ), ); if let Some(ErrorReported) = - tcx.typeck(owner.expect_local()).tainted_by_errors + tcx.typeck(owner).tainted_by_errors { // Some error in the // owner fn prevented us from populating From 54ff72132c860726f40e0ff6d547b039de0a1323 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 7 Dec 2021 22:49:07 +0100 Subject: [PATCH 10/12] Simplify match. --- .../rustc_infer/src/infer/opaque_types.rs | 40 +++++++------------ 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 754d5a6ed7251..c2ef0b41e27bf 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -461,39 +461,29 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> { if let Some(def_id) = def_id.as_local() { let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let parent_def_id = self.infcx.defining_use_anchor; - let (in_definition_scope, origin) = match tcx.hir().expect_item(def_id).kind - { + let item_kind = &tcx.hir().expect_item(def_id).kind; + let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item_kind else { + span_bug!( + self.value_span, + "weird opaque type: {:#?}, {:#?}", + ty.kind(), + item_kind + ) + }; + let in_definition_scope = match *origin { // Async `impl Trait` - hir::ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::AsyncFn(parent), - .. - }) => (parent == parent_def_id, hir::OpaqueTyOrigin::AsyncFn(parent)), + hir::OpaqueTyOrigin::AsyncFn(parent) => parent == parent_def_id, // Anonymous `impl Trait` - hir::ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::FnReturn(parent), - .. - }) => (parent == parent_def_id, hir::OpaqueTyOrigin::FnReturn(parent)), + hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id, // Named `type Foo = impl Bar;` - hir::ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::TyAlias, - .. - }) => ( - may_define_opaque_type(tcx, parent_def_id, opaque_hir_id), - hir::OpaqueTyOrigin::TyAlias, - ), - ref itemkind => { - span_bug!( - self.value_span, - "weird opaque type: {:#?}, {:#?}", - ty.kind(), - itemkind - ) + hir::OpaqueTyOrigin::TyAlias => { + may_define_opaque_type(tcx, parent_def_id, opaque_hir_id) } }; if in_definition_scope { let opaque_type_key = OpaqueTypeKey { def_id: def_id.to_def_id(), substs }; - return self.fold_opaque_ty(ty, opaque_type_key, origin); + return self.fold_opaque_ty(ty, opaque_type_key, *origin); } debug!( From d3167a22e005d9655a4b4f4e9ccada96abd810ed Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 8 Dec 2021 10:53:12 -0500 Subject: [PATCH 11/12] update Miri --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri b/src/tools/miri index 81e59e6b92cf1..dadcbebfbd017 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 81e59e6b92cf1729aabbbbf09b81a81a03775d64 +Subproject commit dadcbebfbd017aac2358cf652a4bd71a91694edc From edd881474b7e517f7239549babc8acaf7ddfd61e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 8 Dec 2021 17:31:56 +0100 Subject: [PATCH 12/12] Fix indent of itemTypes in search.js --- src/librustdoc/html/static/js/search.js | 54 +++++++++++++------------ 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index c2ea54abd2ea8..7c55d10836c45 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -4,32 +4,34 @@ (function() { // This mapping table should match the discriminants of // `rustdoc::html::item_type::ItemType` type in Rust. -var itemTypes = ["mod", - "externcrate", - "import", - "struct", - "enum", - "fn", - "type", - "static", - "trait", - "impl", - "tymethod", - "method", - "structfield", - "variant", - "macro", - "primitive", - "associatedtype", - "constant", - "associatedconstant", - "union", - "foreigntype", - "keyword", - "existential", - "attr", - "derive", - "traitalias"]; +var itemTypes = [ + "mod", + "externcrate", + "import", + "struct", + "enum", + "fn", + "type", + "static", + "trait", + "impl", + "tymethod", + "method", + "structfield", + "variant", + "macro", + "primitive", + "associatedtype", + "constant", + "associatedconstant", + "union", + "foreigntype", + "keyword", + "existential", + "attr", + "derive", + "traitalias", +]; // used for special search precedence var TY_PRIMITIVE = itemTypes.indexOf("primitive");