Rollup merge of #108961 - compiler-errors:refine-ct-errors, r=BoxyUwU
Refine error spans for const args in hir typeck Improve just a couple of error messages having to do with mismatched consts. r? `@ghost` i'll put this up when the dependent commits are merged
This commit is contained in:
commit
eb82a5a0c8
@ -4,7 +4,7 @@
|
|||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::traits::ObligationCauseCode;
|
use rustc_infer::traits::ObligationCauseCode;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
||||||
use rustc_span::{self, Span};
|
use rustc_span::{self, symbol::kw, Span};
|
||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
|
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
@ -25,17 +25,28 @@ pub fn adjust_fulfillment_error_for_expr_obligation(
|
|||||||
|
|
||||||
let generics = self.tcx.generics_of(def_id);
|
let generics = self.tcx.generics_of(def_id);
|
||||||
let predicate_substs = match unsubstituted_pred.kind().skip_binder() {
|
let predicate_substs = match unsubstituted_pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => pred.trait_ref.substs,
|
ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => pred.trait_ref.substs.to_vec(),
|
||||||
ty::PredicateKind::Clause(ty::Clause::Projection(pred)) => pred.projection_ty.substs,
|
ty::PredicateKind::Clause(ty::Clause::Projection(pred)) => {
|
||||||
_ => ty::List::empty(),
|
pred.projection_ty.substs.to_vec()
|
||||||
|
}
|
||||||
|
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(arg, ty)) => {
|
||||||
|
vec![ty.into(), arg.into()]
|
||||||
|
}
|
||||||
|
ty::PredicateKind::ConstEvaluatable(e) => vec![e.into()],
|
||||||
|
_ => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let find_param_matching = |matches: &dyn Fn(&ty::ParamTy) -> bool| {
|
let find_param_matching = |matches: &dyn Fn(ty::ParamTerm) -> bool| {
|
||||||
predicate_substs.types().find_map(|ty| {
|
predicate_substs.iter().find_map(|arg| {
|
||||||
ty.walk().find_map(|arg| {
|
arg.walk().find_map(|arg| {
|
||||||
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||||
&& let ty::Param(param_ty) = ty.kind()
|
&& let ty::Param(param_ty) = *ty.kind()
|
||||||
&& matches(param_ty)
|
&& matches(ty::ParamTerm::Ty(param_ty))
|
||||||
|
{
|
||||||
|
Some(arg)
|
||||||
|
} else if let ty::GenericArgKind::Const(ct) = arg.unpack()
|
||||||
|
&& let ty::ConstKind::Param(param_ct) = ct.kind()
|
||||||
|
&& matches(ty::ParamTerm::Const(param_ct))
|
||||||
{
|
{
|
||||||
Some(arg)
|
Some(arg)
|
||||||
} else {
|
} else {
|
||||||
@ -47,21 +58,22 @@ pub fn adjust_fulfillment_error_for_expr_obligation(
|
|||||||
|
|
||||||
// Prefer generics that are local to the fn item, since these are likely
|
// Prefer generics that are local to the fn item, since these are likely
|
||||||
// to be the cause of the unsatisfied predicate.
|
// to be the cause of the unsatisfied predicate.
|
||||||
let mut param_to_point_at = find_param_matching(&|param_ty| {
|
let mut param_to_point_at = find_param_matching(&|param_term| {
|
||||||
self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) == def_id
|
self.tcx.parent(generics.param_at(param_term.index(), self.tcx).def_id) == def_id
|
||||||
});
|
});
|
||||||
// Fall back to generic that isn't local to the fn item. This will come
|
// Fall back to generic that isn't local to the fn item. This will come
|
||||||
// from a trait or impl, for example.
|
// from a trait or impl, for example.
|
||||||
let mut fallback_param_to_point_at = find_param_matching(&|param_ty| {
|
let mut fallback_param_to_point_at = find_param_matching(&|param_term| {
|
||||||
self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) != def_id
|
self.tcx.parent(generics.param_at(param_term.index(), self.tcx).def_id) != def_id
|
||||||
&& param_ty.name != rustc_span::symbol::kw::SelfUpper
|
&& !matches!(param_term, ty::ParamTerm::Ty(ty) if ty.name == kw::SelfUpper)
|
||||||
});
|
});
|
||||||
// Finally, the `Self` parameter is possibly the reason that the predicate
|
// Finally, the `Self` parameter is possibly the reason that the predicate
|
||||||
// is unsatisfied. This is less likely to be true for methods, because
|
// is unsatisfied. This is less likely to be true for methods, because
|
||||||
// method probe means that we already kinda check that the predicates due
|
// method probe means that we already kinda check that the predicates due
|
||||||
// to the `Self` type are true.
|
// to the `Self` type are true.
|
||||||
let mut self_param_to_point_at =
|
let mut self_param_to_point_at = find_param_matching(
|
||||||
find_param_matching(&|param_ty| param_ty.name == rustc_span::symbol::kw::SelfUpper);
|
&|param_term| matches!(param_term, ty::ParamTerm::Ty(ty) if ty.name == kw::SelfUpper),
|
||||||
|
);
|
||||||
|
|
||||||
// Finally, for ambiguity-related errors, we actually want to look
|
// Finally, for ambiguity-related errors, we actually want to look
|
||||||
// for a parameter that is the source of the inference type left
|
// for a parameter that is the source of the inference type left
|
||||||
@ -225,14 +237,12 @@ fn point_at_generic_if_possible(
|
|||||||
.own_substs(ty::InternalSubsts::identity_for_item(self.tcx, def_id));
|
.own_substs(ty::InternalSubsts::identity_for_item(self.tcx, def_id));
|
||||||
let Some((index, _)) = own_substs
|
let Some((index, _)) = own_substs
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
|
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(_, arg)| **arg == param_to_point_at) else { return false };
|
.find(|(_, arg)| **arg == param_to_point_at) else { return false };
|
||||||
let Some(arg) = segment
|
let Some(arg) = segment
|
||||||
.args()
|
.args()
|
||||||
.args
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|arg| matches!(arg, hir::GenericArg::Type(_)))
|
|
||||||
.nth(index) else { return false; };
|
.nth(index) else { return false; };
|
||||||
error.obligation.cause.span = arg
|
error.obligation.cause.span = arg
|
||||||
.span()
|
.span()
|
||||||
|
@ -1051,6 +1051,21 @@ fn pack(self) -> Term<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub enum ParamTerm {
|
||||||
|
Ty(ParamTy),
|
||||||
|
Const(ParamConst),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParamTerm {
|
||||||
|
pub fn index(self) -> usize {
|
||||||
|
match self {
|
||||||
|
ParamTerm::Ty(ty) => ty.index as usize,
|
||||||
|
ParamTerm::Const(ct) => ct.index as usize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This kind of predicate has no *direct* correspondent in the
|
/// This kind of predicate has no *direct* correspondent in the
|
||||||
/// syntax, but it roughly corresponds to the syntactic forms:
|
/// syntax, but it roughly corresponds to the syntactic forms:
|
||||||
///
|
///
|
||||||
|
@ -1282,10 +1282,20 @@ fn report_selection_error(
|
|||||||
),
|
),
|
||||||
|
|
||||||
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => {
|
||||||
self.tcx.sess.struct_span_err(
|
let mut diag = self.tcx.sess.struct_span_err(
|
||||||
span,
|
span,
|
||||||
&format!("the constant `{}` is not of type `{}`", ct, ty),
|
&format!("the constant `{}` is not of type `{}`", ct, ty),
|
||||||
)
|
);
|
||||||
|
self.note_type_err(
|
||||||
|
&mut diag,
|
||||||
|
&obligation.cause,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
TypeError::Sorts(ty::error::ExpectedFound::new(true, ty, ct.ty())),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
diag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: unconstrained generic constant
|
error: unconstrained generic constant
|
||||||
--> $DIR/cross_crate_predicate.rs:7:13
|
--> $DIR/cross_crate_predicate.rs:7:44
|
||||||
|
|
|
|
||||||
LL | let _ = const_evaluatable_lib::test1::<T>();
|
LL | let _ = const_evaluatable_lib::test1::<T>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^
|
||||||
|
|
|
|
||||||
= help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
|
= help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
|
||||||
note: required by a bound in `test1`
|
note: required by a bound in `test1`
|
||||||
@ -12,10 +12,10 @@ LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
|
||||||
|
|
||||||
error: unconstrained generic constant
|
error: unconstrained generic constant
|
||||||
--> $DIR/cross_crate_predicate.rs:7:13
|
--> $DIR/cross_crate_predicate.rs:7:44
|
||||||
|
|
|
|
||||||
LL | let _ = const_evaluatable_lib::test1::<T>();
|
LL | let _ = const_evaluatable_lib::test1::<T>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^
|
||||||
|
|
|
|
||||||
= help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
|
= help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
|
||||||
note: required by a bound in `test1`
|
note: required by a bound in `test1`
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: the constant `N` is not of type `u8`
|
error: the constant `N` is not of type `u8`
|
||||||
--> $DIR/type_mismatch.rs:2:5
|
--> $DIR/type_mismatch.rs:2:11
|
||||||
|
|
|
|
||||||
LL | bar::<N>()
|
LL | bar::<N>()
|
||||||
| ^^^^^^^^
|
| ^ expected `u8`, found `usize`
|
||||||
|
|
|
|
||||||
note: required by a bound in `bar`
|
note: required by a bound in `bar`
|
||||||
--> $DIR/type_mismatch.rs:6:8
|
--> $DIR/type_mismatch.rs:6:8
|
||||||
|
@ -2,7 +2,7 @@ error: the constant `N` is not of type `usize`
|
|||||||
--> $DIR/bad-const-wf-doesnt-specialize.rs:8:29
|
--> $DIR/bad-const-wf-doesnt-specialize.rs:8:29
|
||||||
|
|
|
|
||||||
LL | impl<const N: i32> Copy for S<N> {}
|
LL | impl<const N: i32> Copy for S<N> {}
|
||||||
| ^^^^
|
| ^^^^ expected `usize`, found `i32`
|
||||||
|
|
|
|
||||||
note: required by a bound in `S`
|
note: required by a bound in `S`
|
||||||
--> $DIR/bad-const-wf-doesnt-specialize.rs:6:10
|
--> $DIR/bad-const-wf-doesnt-specialize.rs:6:10
|
||||||
|
@ -8,7 +8,7 @@ error: the constant `ASSUME_ALIGNMENT` is not of type `Assume`
|
|||||||
--> $DIR/issue-101739-1.rs:8:14
|
--> $DIR/issue-101739-1.rs:8:14
|
||||||
|
|
|
|
||||||
LL | Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>,
|
LL | Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>,
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
|
||||||
|
|
|
|
||||||
note: required by a bound in `BikeshedIntrinsicFrom`
|
note: required by a bound in `BikeshedIntrinsicFrom`
|
||||||
--> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
|
--> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
|
||||||
|
Loading…
Reference in New Issue
Block a user