consider unevaluated consts in extract_inference_diagnostics_data
This commit is contained in:
parent
dae2407368
commit
37ed2db1e0
4 changed files with 96 additions and 42 deletions
|
@ -1,5 +1,6 @@
|
||||||
use crate::infer::type_variable::TypeVariableOriginKind;
|
use crate::infer::type_variable::TypeVariableOriginKind;
|
||||||
use crate::infer::InferCtxt;
|
use crate::infer::InferCtxt;
|
||||||
|
use crate::rustc_middle::ty::TypeFoldable;
|
||||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
|
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Namespace};
|
use rustc_hir::def::{DefKind, Namespace};
|
||||||
|
@ -390,36 +391,75 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GenericArgKind::Const(ct) => {
|
GenericArgKind::Const(ct) => {
|
||||||
if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val {
|
match ct.val {
|
||||||
let origin =
|
ty::ConstKind::Infer(InferConst::Var(vid)) => {
|
||||||
self.inner.borrow_mut().const_unification_table().probe_value(vid).origin;
|
let origin = self
|
||||||
if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) =
|
.inner
|
||||||
origin.kind
|
.borrow_mut()
|
||||||
{
|
.const_unification_table()
|
||||||
return InferenceDiagnosticsData {
|
.probe_value(vid)
|
||||||
name: name.to_string(),
|
.origin;
|
||||||
span: Some(origin.span),
|
if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) =
|
||||||
kind: UnderspecifiedArgKind::Const { is_parameter: true },
|
origin.kind
|
||||||
parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id),
|
{
|
||||||
};
|
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());
|
debug_assert!(!origin.span.is_dummy());
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
let mut printer =
|
let mut printer =
|
||||||
ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::ValueNS);
|
ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::ValueNS);
|
||||||
if let Some(highlight) = highlight {
|
if let Some(highlight) = highlight {
|
||||||
printer.region_highlight_mode = 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);
|
ty::ConstKind::Unevaluated(ty::Unevaluated {
|
||||||
InferenceDiagnosticsData {
|
substs_: Some(substs), ..
|
||||||
name: s,
|
}) => {
|
||||||
span: Some(origin.span),
|
assert!(substs.has_infer_types_or_consts());
|
||||||
kind: UnderspecifiedArgKind::Const { is_parameter: false },
|
|
||||||
parent: None,
|
// 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"),
|
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
|
||||||
|
|
|
@ -27,4 +27,5 @@ fn main() {
|
||||||
//~^ ERROR type annotations needed
|
//~^ ERROR type annotations needed
|
||||||
|
|
||||||
_q = foo::<_, 2>(_q);
|
_q = foo::<_, 2>(_q);
|
||||||
|
//~^ ERROR type annotations needed
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,30 @@ error[E0282]: type annotations needed
|
||||||
LL | let mut _q = Default::default();
|
LL | let mut _q = Default::default();
|
||||||
| ^^^^^^ consider giving `_q` a type
|
| ^^^^^^ 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`
|
||||||
|
|
||||||
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`.
|
||||||
|
|
|
@ -1,22 +1,11 @@
|
||||||
error[E0283]: type annotations needed
|
error[E0282]: type annotations needed
|
||||||
--> $DIR/issue-83249.rs:19:13
|
--> $DIR/issue-83249.rs:19:13
|
||||||
|
|
|
|
||||||
LL | let _ = foo([0; 1]);
|
LL | let _ = foo([0; 1]);
|
||||||
| - ^^^ cannot infer type for type parameter `T` declared on the function `foo`
|
| - ^^^ cannot infer type for type parameter `T` declared on the function `foo`
|
||||||
| |
|
| |
|
||||||
| consider giving this pattern a type
|
| 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
|
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`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue