]> git.lizzy.rs Git - rust.git/commitdiff
consider unevaluated consts in extract_inference_diagnostics_data
authorb-naber <bn263@gmx.de>
Sun, 7 Nov 2021 21:38:33 +0000 (22:38 +0100)
committerb-naber <bn263@gmx.de>
Sun, 7 Nov 2021 21:59:41 +0000 (22:59 +0100)
compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs
src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.stderr
src/test/ui/const-generics/issues/issue-83249.stderr

index e00003face9ced40b6f7d3e13367b05b4e7d68cc..5b39897bc1d20e227744baad3bca8b4be1acd85c 100644 (file)
@@ -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 @@ pub fn extract_inference_diagnostics_data(
                 }
             }
             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(),
+                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;
+                        }
+                        let _ = ct.print(printer);
+                        InferenceDiagnosticsData {
+                            name: s,
                             span: Some(origin.span),
-                            kind: UnderspecifiedArgKind::Const { is_parameter: true },
-                            parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id),
-                        };
+                            kind: UnderspecifiedArgKind::Const { is_parameter: false },
+                            parent: None,
+                        }
                     }
-
-                    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;
+                    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
+                        );
                     }
-                    let _ = ct.print(printer);
-                    InferenceDiagnosticsData {
-                        name: s,
-                        span: Some(origin.span),
-                        kind: UnderspecifiedArgKind::Const { is_parameter: false },
-                        parent: None,
+                    _ => {
+                        bug!("unexpect const: {:?}", ct);
                     }
-                } else {
-                    bug!("unexpect const: {:?}", ct);
                 }
             }
             GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
index bcb3e83b73a5fbf791012ee58a7a791fa40a1a3b..18f33acaabbba19fbcc73a699924d4c26b0cad2b 100644 (file)
@@ -27,4 +27,5 @@ fn main() {
     //~^ ERROR type annotations needed
 
     _q = foo::<_, 2>(_q);
+    //~^ ERROR type annotations needed
 }
index 75bca058e7c5c55da1eadbd148ee668978b5279a..e59f1ac8027de3edde0a3324e2a32d848c99d57b 100644 (file)
@@ -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, const N: usize>(_: T) -> <() as Foo<{ N + 1 }>>::Assoc
+   |    --- required by a bound in this
+LL | where
+LL |     (): Foo<{ N + 1 }>,
+   |         ^^^^^^^^^^^^^^ required by this bound in `foo`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0282`.
+Some errors have detailed explanations: E0282, E0283.
+For more information about an error, try `rustc --explain E0282`.
index 13914134eb2de469b3460f1a3d0c55f89b28b352..402b3aa2d61dcfca63815196aa639c036f48fae0 100644 (file)
@@ -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<T: Foo>(_: [u8; T::N]) -> T {
-   |           ^^^ required by this bound in `foo`
-help: consider specifying the type argument in the function call
-   |
-LL |     let _ = foo::<T>([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`.