From 37ed2db1e04e5b9dcdf833374d364b1f5e374fc3 Mon Sep 17 00:00:00 2001 From: b-naber Date: Sun, 7 Nov 2021 22:38:33 +0100 Subject: [PATCH] consider unevaluated consts in extract_inference_diagnostics_data --- .../infer/error_reporting/need_type_info.rs | 94 +++++++++++++------ .../const_eval_resolve_canonical.rs | 1 + .../const_eval_resolve_canonical.stderr | 28 +++++- .../const-generics/issues/issue-83249.stderr | 15 +-- 4 files changed, 96 insertions(+), 42 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 e00003face9..5b39897bc1d 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,5 +1,6 @@ use crate::infer::type_variable::TypeVariableOriginKind; use crate::infer::InferCtxt; +use crate::rustc_middle::ty::TypeFoldable; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace}; @@ -390,36 +391,75 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } GenericArgKind::Const(ct) => { - if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val { - let origin = - self.inner.borrow_mut().const_unification_table().probe_value(vid).origin; - if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) = - origin.kind - { - return InferenceDiagnosticsData { - name: name.to_string(), - span: Some(origin.span), - kind: UnderspecifiedArgKind::Const { is_parameter: true }, - parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id), - }; - } + match ct.val { + ty::ConstKind::Infer(InferConst::Var(vid)) => { + let origin = self + .inner + .borrow_mut() + .const_unification_table() + .probe_value(vid) + .origin; + if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) = + origin.kind + { + return InferenceDiagnosticsData { + name: name.to_string(), + span: Some(origin.span), + kind: UnderspecifiedArgKind::Const { is_parameter: true }, + parent: InferenceDiagnosticsParentData::for_def_id( + self.tcx, def_id, + ), + }; + } - debug_assert!(!origin.span.is_dummy()); - let mut s = String::new(); - let mut printer = - ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::ValueNS); - if let Some(highlight) = highlight { - printer.region_highlight_mode = highlight; + debug_assert!(!origin.span.is_dummy()); + let mut s = String::new(); + let mut printer = + ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::ValueNS); + if let Some(highlight) = highlight { + printer.region_highlight_mode = highlight; + } + let _ = ct.print(printer); + InferenceDiagnosticsData { + name: s, + span: Some(origin.span), + kind: UnderspecifiedArgKind::Const { is_parameter: false }, + parent: None, + } } - let _ = ct.print(printer); - InferenceDiagnosticsData { - name: s, - span: Some(origin.span), - kind: UnderspecifiedArgKind::Const { is_parameter: false }, - parent: None, + ty::ConstKind::Unevaluated(ty::Unevaluated { + substs_: Some(substs), .. + }) => { + assert!(substs.has_infer_types_or_consts()); + + // FIXME: We only use the first inference variable we encounter in + // `substs` here, this gives insufficiently informative diagnostics + // in case there are multiple inference variables + for s in substs.iter() { + match s.unpack() { + GenericArgKind::Type(t) => match t.kind() { + ty::Infer(_) => { + return self.extract_inference_diagnostics_data(s, None); + } + _ => {} + }, + GenericArgKind::Const(c) => match c.val { + ty::ConstKind::Infer(InferConst::Var(_)) => { + return self.extract_inference_diagnostics_data(s, None); + } + _ => {} + }, + _ => {} + } + } + bug!( + "expected an inference variable in substs of unevaluated const {:?}", + ct + ); + } + _ => { + bug!("unexpect const: {:?}", ct); } - } else { - bug!("unexpect const: {:?}", ct); } } GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"), diff --git a/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs b/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs index bcb3e83b73a..18f33acaabb 100644 --- a/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs +++ b/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs @@ -27,4 +27,5 @@ fn main() { //~^ ERROR type annotations needed _q = foo::<_, 2>(_q); + //~^ ERROR type annotations needed } diff --git a/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.stderr b/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.stderr index 75bca058e7c..e59f1ac8027 100644 --- a/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.stderr @@ -4,6 +4,30 @@ error[E0282]: type annotations needed LL | let mut _q = Default::default(); | ^^^^^^ consider giving `_q` a type -error: aborting due to previous error +error[E0283]: type annotations needed + --> $DIR/const_eval_resolve_canonical.rs:29:10 + | +LL | _q = foo::<_, 2>(_q); + | ^^^^^^^^^^^ cannot infer type + | +note: multiple `impl`s satisfying `(): Foo<{ N + 1 }>` found + --> $DIR/const_eval_resolve_canonical.rs:8:1 + | +LL | impl Foo<0> for () { + | ^^^^^^^^^^^^^^^^^^ +... +LL | impl Foo<3> for () { + | ^^^^^^^^^^^^^^^^^^ +note: required by a bound in `foo` + --> $DIR/const_eval_resolve_canonical.rs:18:9 + | +LL | fn foo(_: T) -> <() as Foo<{ N + 1 }>>::Assoc + | --- required by a bound in this +LL | where +LL | (): Foo<{ N + 1 }>, + | ^^^^^^^^^^^^^^ required by this bound in `foo` -For more information about this error, try `rustc --explain E0282`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0282, E0283. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/const-generics/issues/issue-83249.stderr b/src/test/ui/const-generics/issues/issue-83249.stderr index 13914134eb2..402b3aa2d61 100644 --- a/src/test/ui/const-generics/issues/issue-83249.stderr +++ b/src/test/ui/const-generics/issues/issue-83249.stderr @@ -1,22 +1,11 @@ -error[E0283]: type annotations needed +error[E0282]: type annotations needed --> $DIR/issue-83249.rs:19:13 | LL | let _ = foo([0; 1]); | - ^^^ cannot infer type for type parameter `T` declared on the function `foo` | | | consider giving this pattern a type - | - = note: cannot satisfy `_: Foo` -note: required by a bound in `foo` - --> $DIR/issue-83249.rs:12:11 - | -LL | fn foo(_: [u8; T::N]) -> T { - | ^^^ required by this bound in `foo` -help: consider specifying the type argument in the function call - | -LL | let _ = foo::([0; 1]); - | +++++ error: aborting due to previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0282`.