From 11ec2a47a43ceba5506165e0db5fc8355bff4073 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 13 Oct 2021 21:31:18 +0200 Subject: [PATCH 1/2] extract Res to `generics_of` def_id conversion --- compiler/rustc_middle/src/ty/util.rs | 33 +++++++++++++++- compiler/rustc_typeck/src/collect/type_of.rs | 40 +++----------------- 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c2a4cea2b1ae6..92d9cb2fc1b2b 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -17,7 +17,7 @@ use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_errors::ErrorReported; use rustc_hir as hir; -use rustc_hir::def::DefKind; +use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_macros::HashStable; use rustc_query_system::ich::NodeIdHashingMode; @@ -146,6 +146,37 @@ impl<'tcx> TyCtxt<'tcx> { hasher.finish() } + pub fn res_generics_def_id(self, res: Res) -> Option { + match res { + Res::Def(DefKind::Ctor(CtorOf::Variant, _), def_id) => { + Some(self.parent(def_id).and_then(|def_id| self.parent(def_id)).unwrap()) + } + Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Struct, _), def_id) => { + Some(self.parent(def_id).unwrap()) + } + // Other `DefKind`s don't have generics and would ICE when calling + // `generics_of`. + Res::Def( + DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Trait + | DefKind::OpaqueTy + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::AssocTy + | DefKind::Fn + | DefKind::AssocFn + | DefKind::AssocConst + | DefKind::Impl, + def_id, + ) => Some(def_id), + Res::Err => None, + _ => None, + } + } + pub fn has_error_field(self, ty: Ty<'tcx>) -> bool { if let ty::Adt(def, substs) = *ty.kind() { for field in def.all_fields() { diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 90555b213c1ca..65aa49971cb77 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -1,7 +1,6 @@ use rustc_errors::{Applicability, ErrorReported, StashKey}; use rustc_hir as hir; -use rustc_hir::def::CtorOf; -use rustc_hir::def::{DefKind, Res}; +use rustc_hir::def::Res; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit; use rustc_hir::intravisit::Visitor; @@ -9,7 +8,7 @@ use rustc_hir::{HirId, Node}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::IntTypeExt; -use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable, TypeFolder}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder}; use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; @@ -198,38 +197,9 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< // Try to use the segment resolution if it is valid, otherwise we // default to the path resolution. let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res); - let generics = match res { - Res::Def(DefKind::Ctor(CtorOf::Variant, _), def_id) => tcx - .generics_of(tcx.parent(def_id).and_then(|def_id| tcx.parent(def_id)).unwrap()), - Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Struct, _), def_id) => { - tcx.generics_of(tcx.parent(def_id).unwrap()) - } - // Other `DefKind`s don't have generics and would ICE when calling - // `generics_of`. - Res::Def( - DefKind::Struct - | DefKind::Union - | DefKind::Enum - | DefKind::Trait - | DefKind::OpaqueTy - | DefKind::TyAlias - | DefKind::ForeignTy - | DefKind::TraitAlias - | DefKind::AssocTy - | DefKind::Fn - | DefKind::AssocFn - | DefKind::AssocConst - | DefKind::Impl, - def_id, - ) => tcx.generics_of(def_id), - Res::Err => { - tcx.sess.delay_span_bug(tcx.def_span(def_id), "anon const with Res::Err"); - return None; - } - _ => { - // If the user tries to specify generics on a type that does not take them, - // e.g. `usize`, we may hit this branch, in which case we treat it as if - // no arguments have been passed. An error should already have been emitted. + let generics = match tcx.res_generics_def_id(res) { + Some(def_id) => tcx.generics_of(def_id), + None => { tcx.sess.delay_span_bug( tcx.def_span(def_id), &format!("unexpected anon const res {:?} in path: {:?}", res, path), From 1b7c3bcef9dc88e65c4914887071e432436a0b04 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 14 Feb 2022 14:13:02 +0100 Subject: [PATCH 2/2] allow special behavior when printing const infer --- .../infer/error_reporting/need_type_info.rs | 30 +++++++++++++----- compiler/rustc_middle/src/ty/print/pretty.rs | 31 ++++++++++++++----- .../const-generics/defaults/doesnt_infer.rs | 2 +- .../defaults/doesnt_infer.stderr | 2 +- .../generic_arg_infer/issue-91614.rs | 2 +- .../generic_arg_infer/issue-91614.stderr | 2 +- 6 files changed, 51 insertions(+), 18 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 aba5666b58cd7..4ea8241072ebe 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 @@ -497,16 +497,32 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let ty_to_string = |ty: Ty<'tcx>| -> String { let mut s = String::new(); let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS); - let mut inner = self.inner.borrow_mut(); - let ty_vars = inner.type_variables(); - let getter = move |ty_vid| { - let var_origin = ty_vars.var_origin(ty_vid); - if let TypeVariableOriginKind::TypeParameterDefinition(name, _) = var_origin.kind { + let ty_getter = move |ty_vid| { + if let TypeVariableOriginKind::TypeParameterDefinition(name, _) = + self.inner.borrow_mut().type_variables().var_origin(ty_vid).kind + { + Some(name.to_string()) + } else { + None + } + }; + printer.ty_infer_name_resolver = Some(Box::new(ty_getter)); + let const_getter = move |ct_vid| { + if let ConstVariableOriginKind::ConstParameterDefinition(name, _) = self + .inner + .borrow_mut() + .const_unification_table() + .probe_value(ct_vid) + .origin + .kind + { return Some(name.to_string()); + } else { + None } - None }; - printer.name_resolver = Some(Box::new(&getter)); + printer.const_infer_name_resolver = Some(Box::new(const_getter)); + let _ = if let ty::FnDef(..) = ty.kind() { // We don't want the regular output for `fn`s because it includes its path in // invalid pseudo-syntax, we want the `fn`-pointer output instead. diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 893df1a009cfc..94bbb711cfe38 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -606,7 +606,7 @@ pub trait PrettyPrinter<'tcx>: ty::Infer(infer_ty) => { let verbose = self.tcx().sess.verbose(); if let ty::TyVar(ty_vid) = infer_ty { - if let Some(name) = self.infer_ty_name(ty_vid) { + if let Some(name) = self.ty_infer_name(ty_vid) { p!(write("{}", name)) } else { if verbose { @@ -1015,7 +1015,11 @@ pub trait PrettyPrinter<'tcx>: } } - fn infer_ty_name(&self, _: ty::TyVid) -> Option { + fn ty_infer_name(&self, _: ty::TyVid) -> Option { + None + } + + fn const_infer_name(&self, _: ty::ConstVid<'tcx>) -> Option { None } @@ -1203,7 +1207,14 @@ pub trait PrettyPrinter<'tcx>: } } } - ty::ConstKind::Infer(..) => print_underscore!(), + ty::ConstKind::Infer(infer_ct) => { + match infer_ct { + ty::InferConst::Var(ct_vid) + if let Some(name) = self.const_infer_name(ct_vid) => + p!(write("{}", name)), + _ => print_underscore!(), + } + } ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)), ty::ConstKind::Value(value) => { return self.pretty_print_const_value(value, ct.ty(), print_ty); @@ -1551,7 +1562,8 @@ pub struct FmtPrinterData<'a, 'tcx, F> { pub region_highlight_mode: RegionHighlightMode<'tcx>, - pub name_resolver: Option Option>>, + pub ty_infer_name_resolver: Option Option + 'a>>, + pub const_infer_name_resolver: Option) -> Option + 'a>>, } impl<'a, 'tcx, F> Deref for FmtPrinter<'a, 'tcx, F> { @@ -1580,7 +1592,8 @@ impl<'a, 'tcx, F> FmtPrinter<'a, 'tcx, F> { binder_depth: 0, printed_type_count: 0, region_highlight_mode: RegionHighlightMode::new(tcx), - name_resolver: None, + ty_infer_name_resolver: None, + const_infer_name_resolver: None, })) } } @@ -1835,8 +1848,12 @@ impl<'tcx, F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { } impl<'tcx, F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { - fn infer_ty_name(&self, id: ty::TyVid) -> Option { - self.0.name_resolver.as_ref().and_then(|func| func(id)) + fn ty_infer_name(&self, id: ty::TyVid) -> Option { + self.0.ty_infer_name_resolver.as_ref().and_then(|func| func(id)) + } + + fn const_infer_name(&self, id: ty::ConstVid<'tcx>) -> Option { + self.0.const_infer_name_resolver.as_ref().and_then(|func| func(id)) } fn print_value_path( diff --git a/src/test/ui/const-generics/defaults/doesnt_infer.rs b/src/test/ui/const-generics/defaults/doesnt_infer.rs index cd533b57bc31f..9c59e672d8e4c 100644 --- a/src/test/ui/const-generics/defaults/doesnt_infer.rs +++ b/src/test/ui/const-generics/defaults/doesnt_infer.rs @@ -9,5 +9,5 @@ impl Foo { fn main() { let foo = Foo::<1>::foo(); let foo = Foo::foo(); - //~^ error: type annotations needed for `Foo<{_: u32}>` + //~^ error: type annotations needed for `Foo` } diff --git a/src/test/ui/const-generics/defaults/doesnt_infer.stderr b/src/test/ui/const-generics/defaults/doesnt_infer.stderr index 1551e81ea7577..cccf433e32864 100644 --- a/src/test/ui/const-generics/defaults/doesnt_infer.stderr +++ b/src/test/ui/const-generics/defaults/doesnt_infer.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `Foo<{_: u32}>` +error[E0282]: type annotations needed for `Foo` --> $DIR/doesnt_infer.rs:11:15 | LL | let foo = Foo::foo(); diff --git a/src/test/ui/const-generics/generic_arg_infer/issue-91614.rs b/src/test/ui/const-generics/generic_arg_infer/issue-91614.rs index 413cc1539248a..b45e2cbc7372b 100644 --- a/src/test/ui/const-generics/generic_arg_infer/issue-91614.rs +++ b/src/test/ui/const-generics/generic_arg_infer/issue-91614.rs @@ -4,5 +4,5 @@ use std::simd::Mask; fn main() { let y = Mask::<_, _>::splat(false); - //~^ error: type annotations needed for `Mask<_, {_: usize}>` + //~^ ERROR: type annotations needed for } diff --git a/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr b/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr index 71a5ff79280fd..347cd2364b266 100644 --- a/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/src/test/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -1,4 +1,4 @@ -error[E0283]: type annotations needed for `Mask<_, {_: usize}>` +error[E0283]: type annotations needed for `Mask<_, LANES>` --> $DIR/issue-91614.rs:6:13 | LL | let y = Mask::<_, _>::splat(false);