From 9835e2ae736235810b4ea1c162ca5e65c547e770 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 04:49:50 +0200 Subject: Merging upstream version 1.71.1+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_hir_analysis/src/collect/type_of.rs | 583 ++++----------------- 1 file changed, 110 insertions(+), 473 deletions(-) (limited to 'compiler/rustc_hir_analysis/src/collect/type_of.rs') diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index c173bd913..8e082d3c5 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -1,10 +1,7 @@ use rustc_errors::{Applicability, StashKey}; use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::intravisit; -use rustc_hir::intravisit::Visitor; -use rustc_hir::{HirId, Node}; -use rustc_middle::hir::nested_filter; +use rustc_hir::def_id::LocalDefId; +use rustc_hir::HirId; use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::IntTypeExt; @@ -14,24 +11,84 @@ use rustc_span::{Span, DUMMY_SP}; use super::ItemCtxt; use super::{bad_placeholder, is_suggestable_infer_ty}; -use crate::errors::UnconstrainedOpaqueType; -/// Computes the relevant generic parameter for a potential generic const argument. -/// -/// This should be called using the query `tcx.opt_const_param_of`. -pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { +mod opaque; + +fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { use hir::*; let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - match tcx.hir().get(hir_id) { - Node::AnonConst(_) => (), - _ => return None, - }; + let Node::AnonConst(_) = tcx.hir().get(hir_id) else { panic!() }; let parent_node_id = tcx.hir().parent_id(hir_id); let parent_node = tcx.hir().get(parent_node_id); let (generics, arg_idx) = match parent_node { + // Easy case: arrays repeat expressions. + Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. }) + | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) + if constant.hir_id() == hir_id => + { + return tcx.types.usize + } + Node::Ty(&Ty { kind: TyKind::Typeof(ref e), .. }) if e.hir_id == hir_id => { + return tcx.typeck(def_id).node_type(e.hir_id) + } + Node::Expr(&Expr { kind: ExprKind::ConstBlock(ref anon_const), .. }) + if anon_const.hir_id == hir_id => + { + let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); + return substs.as_inline_const().ty() + } + Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) + | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) + if asm.operands.iter().any(|(op, _op_sp)| match op { + hir::InlineAsmOperand::Const { anon_const } + | hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id, + _ => false, + }) => + { + return tcx.typeck(def_id).node_type(hir_id) + } + Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => { + return tcx + .adt_def(tcx.hir().get_parent_item(hir_id)) + .repr() + .discr_type() + .to_ty(tcx) + } + Node::GenericParam(&GenericParam { + def_id: param_def_id, + kind: GenericParamKind::Const { default: Some(ct), .. }, + .. + }) if ct.hir_id == hir_id => { + return tcx.type_of(param_def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic") + } + + Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. }) + if let Node::TraitRef(trait_ref) = tcx.hir().get( + tcx.hir().parent_id(binding_id) + ) => + { + let Some(trait_def_id) = trait_ref.trait_def_id() else { + return tcx.ty_error_with_message(tcx.def_span(def_id), "Could not find trait"); + }; + let assoc_items = tcx.associated_items(trait_def_id); + let assoc_item = assoc_items.find_by_name_and_kind( + tcx, binding.ident, ty::AssocKind::Const, def_id.to_def_id(), + ); + return if let Some(assoc_item) = assoc_item { + tcx.type_of(assoc_item.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic") + } else { + // FIXME(associated_const_equality): add a useful error message here. + tcx.ty_error_with_message(tcx.def_span(def_id), "Could not find associated const on trait") + } + } + // This match arm is for when the def_id appears in a GAT whose // path can't be resolved without typechecking e.g. // @@ -68,7 +125,7 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< // the def_id that this query was called with. We filter to only type and const args here // as a precaution for if it's ever allowed to elide lifetimes in GAT's. It currently isn't // but it can't hurt to be safe ^^ - if let ty::Alias(ty::Projection, projection) = ty.kind() { + if let ty::Alias(ty::Projection | ty::Inherent, projection) = ty.kind() { let generics = tcx.generics_of(projection.def_id); let arg_index = segment @@ -86,11 +143,10 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< (generics, arg_index) } else { // I dont think it's possible to reach this but I'm not 100% sure - BoxyUwU - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), "unexpected non-GAT usage of an anon const", ); - return None; } } Node::Expr(&Expr { @@ -103,7 +159,12 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< // This may fail in case the method/path does not actually exist. // As there is no relevant param for `def_id`, we simply return // `None` here. - let type_dependent_def = tables.type_dependent_def_id(parent_node_id)?; + let Some(type_dependent_def) = tables.type_dependent_def_id(parent_node_id) else { + return tcx.ty_error_with_message( + tcx.def_span(def_id), + format!("unable to find type-dependent def for {:?}", parent_node_id), + ); + }; let idx = segment .args .and_then(|args| { @@ -140,19 +201,17 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< if let Some(path) = get_path_containing_arg_in_pat(pat, hir_id) { path } else { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), - &format!("unable to find const parent for {} in pat {:?}", hir_id, pat), + format!("unable to find const parent for {} in pat {:?}", hir_id, pat), ); - return None; } } _ => { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), - &format!("unexpected const parent path {:?}", parent_node), + format!("unexpected const parent path {:?}", parent_node), ); - return None; } }; @@ -171,32 +230,34 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< .position(|ct| ct.hir_id == hir_id) .map(|idx| (idx, seg))) }) else { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), "no arg matching AnonConst in path", ); - return None; }; let generics = match tcx.res_generics_def_id(segment.res) { Some(def_id) => tcx.generics_of(def_id), None => { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), - &format!("unexpected anon const res {:?} in path: {:?}", segment.res, path), + format!("unexpected anon const res {:?} in path: {:?}", segment.res, path), ); - return None; } }; (generics, arg_index) } - _ => return None, + + _ => return tcx.ty_error_with_message( + tcx.def_span(def_id), + format!("unexpected const parent in type_of(): {parent_node:?}"), + ), }; debug!(?parent_node); debug!(?generics, ?arg_idx); - generics + if let Some(param_def_id) = generics .params .iter() .filter(|param| param.kind.is_ty_or_const()) @@ -211,6 +272,14 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< } _ => None, }) + { + tcx.type_of(param_def_id).no_bound_vars().expect("const parameter types cannot be generic") + } else { + return tcx.ty_error_with_message( + tcx.def_span(def_id), + format!("const generic parameter not found in {generics:?} at position {arg_idx:?}"), + ); + } } fn get_path_containing_arg_in_pat<'hir>( @@ -251,7 +320,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder { let assoc_item = tcx.associated_item(def_id); - return ty::EarlyBinder(map[&assoc_item.trait_item_def_id.unwrap()]); + return map[&assoc_item.trait_item_def_id.unwrap()]; } Err(_) => { return ty::EarlyBinder(tcx.ty_error_with_message( @@ -355,9 +424,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder { - find_opaque_ty_constraints_for_tait(tcx, def_id) - } + ItemKind::OpaqueTy(OpaqueTy { + origin: hir::OpaqueTyOrigin::TyAlias { .. }, + .. + }) => opaque::find_opaque_ty_constraints_for_tait(tcx, def_id), // Opaque types desugared from `impl Trait`. ItemKind::OpaqueTy(OpaqueTy { origin: @@ -371,7 +441,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder, def_id: LocalDefId) -> ty::EarlyBinder { - // We defer to `type_of` of the corresponding parameter - // for generic arguments. - tcx.type_of(param).subst_identity() - } - - Node::AnonConst(_) => { - let parent_node = tcx.hir().get_parent(hir_id); - match parent_node { - Node::Ty(Ty { kind: TyKind::Array(_, constant), .. }) - | Node::Expr(Expr { kind: ExprKind::Repeat(_, constant), .. }) - if constant.hir_id() == hir_id => - { - tcx.types.usize - } - Node::Ty(Ty { kind: TyKind::Typeof(e), .. }) if e.hir_id == hir_id => { - tcx.typeck(def_id).node_type(e.hir_id) - } - - Node::Expr(Expr { kind: ExprKind::ConstBlock(anon_const), .. }) - if anon_const.hir_id == hir_id => - { - let substs = InternalSubsts::identity_for_item(tcx, def_id); - substs.as_inline_const().ty() - } - - Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) - | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) - if asm.operands.iter().any(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } - | hir::InlineAsmOperand::SymFn { anon_const } => { - anon_const.hir_id == hir_id - } - _ => false, - }) => - { - tcx.typeck(def_id).node_type(hir_id) - } - - Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => { - tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) - } - - Node::TypeBinding(TypeBinding { - hir_id: binding_id, - kind: TypeBindingKind::Equality { term: Term::Const(e) }, - ident, - .. - }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id) - && e.hir_id == hir_id => - { - let Some(trait_def_id) = trait_ref.trait_def_id() else { - return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait")); - }; - let assoc_items = tcx.associated_items(trait_def_id); - let assoc_item = assoc_items.find_by_name_and_kind( - tcx, - *ident, - ty::AssocKind::Const, - def_id.to_def_id(), - ); - if let Some(assoc_item) = assoc_item { - tcx.type_of(assoc_item.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic") - } else { - // FIXME(associated_const_equality): add a useful error message here. - tcx.ty_error_with_message( - DUMMY_SP, - "Could not find associated const on trait", - ) - } - } - - Node::TypeBinding(TypeBinding { - hir_id: binding_id, - gen_args, - kind, - ident, - .. - }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id) - && let Some((idx, _)) = - gen_args.args.iter().enumerate().find(|(_, arg)| { - if let GenericArg::Const(ct) = arg { - ct.value.hir_id == hir_id - } else { - false - } - }) => - { - let Some(trait_def_id) = trait_ref.trait_def_id() else { - return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait")); - }; - let assoc_items = tcx.associated_items(trait_def_id); - let assoc_item = assoc_items.find_by_name_and_kind( - tcx, - *ident, - match kind { - // I think `` type bindings requires that `A` is a type - TypeBindingKind::Constraint { .. } - | TypeBindingKind::Equality { term: Term::Ty(..) } => { - ty::AssocKind::Type - } - TypeBindingKind::Equality { term: Term::Const(..) } => { - ty::AssocKind::Const - } - }, - def_id.to_def_id(), - ); - if let Some(assoc_item) = assoc_item - && let param = &tcx.generics_of(assoc_item.def_id).params[idx] - && matches!(param.kind, ty::GenericParamDefKind::Const { .. }) - { - tcx.type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic") - } else { - // FIXME(associated_const_equality): add a useful error message here. - tcx.ty_error_with_message( - DUMMY_SP, - "Could not find const param on associated item", - ) - } - } - - Node::GenericParam(&GenericParam { - def_id: param_def_id, - kind: GenericParamKind::Const { default: Some(ct), .. }, - .. - }) if ct.hir_id == hir_id => tcx.type_of(param_def_id).subst_identity(), - - x => tcx.ty_error_with_message( - DUMMY_SP, - &format!("unexpected const parent in type_of(): {x:?}"), - ), - } - } + Node::AnonConst(_) => anon_const_type_of(tcx, def_id), Node::GenericParam(param) => match ¶m.kind { GenericParamKind::Type { default: Some(ty), .. } @@ -566,303 +500,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder = impl Bar; -/// -/// // Okay -- `Foo` is applied to two distinct, generic types. -/// fn a() -> Foo { .. } -/// -/// // Not okay -- `Foo` is applied to `T` twice. -/// fn b() -> Foo { .. } -/// -/// // Not okay -- `Foo` is applied to a non-generic type. -/// fn b() -> Foo { .. } -/// ``` -/// -fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { - use rustc_hir::{Expr, ImplItem, Item, TraitItem}; - - struct ConstraintLocator<'tcx> { - tcx: TyCtxt<'tcx>, - - /// def_id of the opaque type whose defining uses are being checked - def_id: LocalDefId, - - /// as we walk the defining uses, we are checking that all of them - /// define the same hidden type. This variable is set to `Some` - /// with the first type that we find, and then later types are - /// checked against it (we also carry the span of that first - /// type). - found: Option>, - - /// In the presence of dead code, typeck may figure out a hidden type - /// while borrowck will not. We collect these cases here and check at - /// the end that we actually found a type that matches (modulo regions). - typeck_types: Vec>, - } - - impl ConstraintLocator<'_> { - #[instrument(skip(self), level = "debug")] - fn check(&mut self, item_def_id: LocalDefId) { - // Don't try to check items that cannot possibly constrain the type. - if !self.tcx.has_typeck_results(item_def_id) { - debug!("no constraint: no typeck results"); - return; - } - // Calling `mir_borrowck` can lead to cycle errors through - // const-checking, avoid calling it if we don't have to. - // ```rust - // type Foo = impl Fn() -> usize; // when computing type for this - // const fn bar() -> Foo { - // || 0usize - // } - // const BAZR: Foo = bar(); // we would mir-borrowck this, causing cycles - // // because we again need to reveal `Foo` so we can check whether the - // // constant does not contain interior mutability. - // ``` - let tables = self.tcx.typeck(item_def_id); - if let Some(guar) = tables.tainted_by_errors { - self.found = - Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error(guar) }); - return; - } - let Some(&typeck_hidden_ty) = tables.concrete_opaque_types.get(&self.def_id) else { - debug!("no constraints in typeck results"); - return; - }; - if self.typeck_types.iter().all(|prev| prev.ty != typeck_hidden_ty.ty) { - self.typeck_types.push(typeck_hidden_ty); - } - - // Use borrowck to get the type with unerased regions. - let concrete_opaque_types = &self.tcx.mir_borrowck(item_def_id).concrete_opaque_types; - debug!(?concrete_opaque_types); - if let Some(&concrete_type) = concrete_opaque_types.get(&self.def_id) { - debug!(?concrete_type, "found constraint"); - if let Some(prev) = &mut self.found { - if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() { - let guar = prev.report_mismatch(&concrete_type, self.tcx); - prev.ty = self.tcx.ty_error(guar); - } - } else { - self.found = Some(concrete_type); - } - } - } - } - - impl<'tcx> intravisit::Visitor<'tcx> for ConstraintLocator<'tcx> { - type NestedFilter = nested_filter::All; - - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() - } - fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) { - if let hir::ExprKind::Closure(closure) = ex.kind { - self.check(closure.def_id); - } - intravisit::walk_expr(self, ex); - } - fn visit_item(&mut self, it: &'tcx Item<'tcx>) { - trace!(?it.owner_id); - // The opaque type itself or its children are not within its reveal scope. - if it.owner_id.def_id != self.def_id { - self.check(it.owner_id.def_id); - intravisit::walk_item(self, it); - } - } - fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) { - trace!(?it.owner_id); - // The opaque type itself or its children are not within its reveal scope. - if it.owner_id.def_id != self.def_id { - self.check(it.owner_id.def_id); - intravisit::walk_impl_item(self, it); - } - } - fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) { - trace!(?it.owner_id); - self.check(it.owner_id.def_id); - intravisit::walk_trait_item(self, it); - } - } - - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - let scope = tcx.hir().get_defining_scope(hir_id); - let mut locator = ConstraintLocator { def_id, tcx, found: None, typeck_types: vec![] }; - - debug!(?scope); - - if scope == hir::CRATE_HIR_ID { - tcx.hir().walk_toplevel_module(&mut locator); - } else { - trace!("scope={:#?}", tcx.hir().get(scope)); - match tcx.hir().get(scope) { - // We explicitly call `visit_*` methods, instead of using `intravisit::walk_*` methods - // This allows our visitor to process the defining item itself, causing - // it to pick up any 'sibling' defining uses. - // - // For example, this code: - // ``` - // fn foo() { - // type Blah = impl Debug; - // let my_closure = || -> Blah { true }; - // } - // ``` - // - // requires us to explicitly process `foo()` in order - // to notice the defining usage of `Blah`. - Node::Item(it) => locator.visit_item(it), - Node::ImplItem(it) => locator.visit_impl_item(it), - Node::TraitItem(it) => locator.visit_trait_item(it), - other => bug!("{:?} is not a valid scope for an opaque type item", other), - } - } - - let Some(hidden) = locator.found else { - let reported = tcx.sess.emit_err(UnconstrainedOpaqueType { - span: tcx.def_span(def_id), - name: tcx.item_name(tcx.local_parent(def_id).to_def_id()), - what: match tcx.hir().get(scope) { - _ if scope == hir::CRATE_HIR_ID => "module", - Node::Item(hir::Item { kind: hir::ItemKind::Mod(_), .. }) => "module", - Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => "impl", - _ => "item", - }, - }); - return tcx.ty_error(reported); - }; - - // Only check against typeck if we didn't already error - if !hidden.ty.references_error() { - for concrete_type in locator.typeck_types { - if tcx.erase_regions(concrete_type.ty) != tcx.erase_regions(hidden.ty) - && !(concrete_type, hidden).references_error() - { - hidden.report_mismatch(&concrete_type, tcx); - } - } - } - - hidden.ty -} - -fn find_opaque_ty_constraints_for_rpit( - tcx: TyCtxt<'_>, - def_id: LocalDefId, - owner_def_id: LocalDefId, -) -> Ty<'_> { - use rustc_hir::{Expr, ImplItem, Item, TraitItem}; - - struct ConstraintChecker<'tcx> { - tcx: TyCtxt<'tcx>, - - /// def_id of the opaque type whose defining uses are being checked - def_id: LocalDefId, - - found: ty::OpaqueHiddenType<'tcx>, - } - - impl ConstraintChecker<'_> { - #[instrument(skip(self), level = "debug")] - fn check(&self, def_id: LocalDefId) { - // Use borrowck to get the type with unerased regions. - let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types; - debug!(?concrete_opaque_types); - for (&def_id, &concrete_type) in concrete_opaque_types { - if def_id != self.def_id { - // Ignore constraints for other opaque types. - continue; - } - - debug!(?concrete_type, "found constraint"); - - if concrete_type.ty != self.found.ty - && !(concrete_type, self.found).references_error() - { - self.found.report_mismatch(&concrete_type, self.tcx); - } - } - } - } - - impl<'tcx> intravisit::Visitor<'tcx> for ConstraintChecker<'tcx> { - type NestedFilter = nested_filter::OnlyBodies; - - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() - } - fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) { - if let hir::ExprKind::Closure(closure) = ex.kind { - self.check(closure.def_id); - } - intravisit::walk_expr(self, ex); - } - fn visit_item(&mut self, it: &'tcx Item<'tcx>) { - trace!(?it.owner_id); - // The opaque type itself or its children are not within its reveal scope. - if it.owner_id.def_id != self.def_id { - self.check(it.owner_id.def_id); - intravisit::walk_item(self, it); - } - } - fn visit_impl_item(&mut self, it: &'tcx ImplItem<'tcx>) { - trace!(?it.owner_id); - // The opaque type itself or its children are not within its reveal scope. - if it.owner_id.def_id != self.def_id { - self.check(it.owner_id.def_id); - intravisit::walk_impl_item(self, it); - } - } - fn visit_trait_item(&mut self, it: &'tcx TraitItem<'tcx>) { - trace!(?it.owner_id); - self.check(it.owner_id.def_id); - intravisit::walk_trait_item(self, it); - } - } - - let concrete = tcx.mir_borrowck(owner_def_id).concrete_opaque_types.get(&def_id).copied(); - - if let Some(concrete) = concrete { - let scope = tcx.hir().local_def_id_to_hir_id(owner_def_id); - debug!(?scope); - let mut locator = ConstraintChecker { def_id, tcx, found: concrete }; - - match tcx.hir().get(scope) { - Node::Item(it) => intravisit::walk_item(&mut locator, it), - Node::ImplItem(it) => intravisit::walk_impl_item(&mut locator, it), - Node::TraitItem(it) => intravisit::walk_trait_item(&mut locator, it), - other => bug!("{:?} is not a valid scope for an opaque type item", other), - } - } - - concrete.map(|concrete| concrete.ty).unwrap_or_else(|| { - let table = tcx.typeck(owner_def_id); - if let Some(guar) = table.tainted_by_errors { - // Some error in the - // owner fn prevented us from populating - // the `concrete_opaque_types` table. - tcx.ty_error(guar) - } else { - table.concrete_opaque_types.get(&def_id).map(|ty| ty.ty).unwrap_or_else(|| { - // We failed to resolve the opaque type or it - // resolves to itself. We interpret this as the - // no values of the hidden type ever being constructed, - // so we can just make the hidden type be `!`. - // For backwards compatibility reasons, we fall back to - // `()` until we the diverging default is changed. - tcx.mk_diverging_default() - }) - } - }) -} - fn infer_placeholder_type<'a>( tcx: TyCtxt<'a>, def_id: LocalDefId, @@ -893,14 +530,14 @@ fn infer_placeholder_type<'a>( if let Some(ty) = ty.make_suggestable(tcx, false) { err.span_suggestion( span, - &format!("provide a type for the {item}", item = kind), + format!("provide a type for the {item}", item = kind), format!("{colon} {ty}"), Applicability::MachineApplicable, ); } else { with_forced_trimmed_paths!(err.span_note( tcx.hir().body(body_id).value.span, - &format!("however, the inferred type `{ty}` cannot be named"), + format!("however, the inferred type `{ty}` cannot be named"), )); } } @@ -921,7 +558,7 @@ fn infer_placeholder_type<'a>( } else { with_forced_trimmed_paths!(diag.span_note( tcx.hir().body(body_id).value.span, - &format!("however, the inferred type `{ty}` cannot be named"), + format!("however, the inferred type `{ty}` cannot be named"), )); } } -- cgit v1.2.3