Rollup merge of #105332 - estebank:iterator-chains, r=oli-obk
Point out the type of associated types in every method call of iterator chains Partially address #105184 by pointing out the type of associated types in every method call of iterator chains: ``` note: the expression is of type `Map<std::slice::Iter<'_, {integer}>, [closure@src/test/ui/iterators/invalid-iterator-chain.rs:12:18: 12:21]>` --> src/test/ui/iterators/invalid-iterator-chain.rs:12:14 | 10 | vec![0, 1] | ---------- this expression has type `Vec<{integer}>` 11 | .iter() | ------ associated type `std::iter::Iterator::Item` is `&{integer}` here 12 | .map(|x| { x; }) | ^^^^^^^^^^^^^^^ associated type `std::iter::Iterator::Item` is `()` here ``` We also reduce the number of impls we mention when any of the candidates is an "exact match". This benefits the output of cases with numerics greatly. Outstanding work would be to provide a structured suggestion for appropriate changes, like in this case detecting the spurious `;` in the closure.
This commit is contained in:
commit
8917cc0f23
33 changed files with 743 additions and 184 deletions
|
@ -370,7 +370,11 @@ impl Diagnostic {
|
|||
self.set_span(after);
|
||||
for span_label in before.span_labels() {
|
||||
if let Some(label) = span_label.label {
|
||||
self.span.push_span_label(after, label);
|
||||
if span_label.is_primary {
|
||||
self.span.push_span_label(after, label);
|
||||
} else {
|
||||
self.span.push_span_label(span_label.span, label);
|
||||
}
|
||||
}
|
||||
}
|
||||
self
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
use crate::infer::InferCtxt;
|
||||
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
|
||||
pub struct CollectAllMismatches<'a, 'tcx> {
|
||||
pub infcx: &'a InferCtxt<'tcx>,
|
||||
pub param_env: ty::ParamEnv<'tcx>,
|
||||
pub errors: Vec<TypeError<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> {
|
||||
fn tag(&self) -> &'static str {
|
||||
"CollectAllMismatches"
|
||||
}
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
fn intercrate(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.param_env
|
||||
}
|
||||
fn a_is_expected(&self) -> bool {
|
||||
true
|
||||
} // irrelevant
|
||||
fn mark_ambiguous(&mut self) {
|
||||
bug!()
|
||||
}
|
||||
fn relate_with_variance<T: Relate<'tcx>>(
|
||||
&mut self,
|
||||
_: ty::Variance,
|
||||
_: ty::VarianceDiagInfo<'tcx>,
|
||||
a: T,
|
||||
b: T,
|
||||
) -> RelateResult<'tcx, T> {
|
||||
self.relate(a, b)
|
||||
}
|
||||
fn regions(
|
||||
&mut self,
|
||||
a: ty::Region<'tcx>,
|
||||
_b: ty::Region<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||
Ok(a)
|
||||
}
|
||||
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||
if a == b || matches!(a.kind(), ty::Infer(_)) || matches!(b.kind(), ty::Infer(_)) {
|
||||
return Ok(a);
|
||||
}
|
||||
relate::super_relate_tys(self, a, b).or_else(|e| {
|
||||
self.errors.push(e);
|
||||
Ok(a)
|
||||
})
|
||||
}
|
||||
fn consts(
|
||||
&mut self,
|
||||
a: ty::Const<'tcx>,
|
||||
b: ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
}
|
||||
relate::super_relate_consts(self, a, b) // could do something similar here for constants!
|
||||
}
|
||||
fn binders<T: Relate<'tcx>>(
|
||||
&mut self,
|
||||
a: ty::Binder<'tcx, T>,
|
||||
b: ty::Binder<'tcx, T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<'tcx, T>> {
|
||||
Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
mod ambiguity;
|
||||
pub mod method_chain;
|
||||
pub mod on_unimplemented;
|
||||
pub mod suggestions;
|
||||
|
||||
|
@ -536,7 +537,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
|err| {
|
||||
self.note_obligation_cause_code(
|
||||
err,
|
||||
&predicate,
|
||||
predicate,
|
||||
obligation.param_env,
|
||||
obligation.cause.code(),
|
||||
&mut vec![],
|
||||
|
@ -1587,7 +1588,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
{
|
||||
self.note_obligation_cause_code(
|
||||
&mut diag,
|
||||
&error.obligation.predicate,
|
||||
error.obligation.predicate,
|
||||
error.obligation.param_env,
|
||||
code,
|
||||
&mut vec![],
|
||||
|
@ -2602,7 +2603,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
if !self.maybe_note_obligation_cause_for_async_await(err, obligation) {
|
||||
self.note_obligation_cause_code(
|
||||
err,
|
||||
&obligation.predicate,
|
||||
obligation.predicate,
|
||||
obligation.param_env,
|
||||
obligation.cause.code(),
|
||||
&mut vec![],
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
// ignore-tidy-filelength
|
||||
use super::{DefIdOrName, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation};
|
||||
|
||||
use crate::autoderef::Autoderef;
|
||||
use crate::infer::InferCtxt;
|
||||
use crate::traits::NormalizeExt;
|
||||
use crate::traits::{NormalizeExt, ObligationCtxt};
|
||||
|
||||
use hir::def::CtorOf;
|
||||
use hir::HirId;
|
||||
|
@ -22,17 +23,20 @@ use rustc_infer::infer::error_reporting::TypeErrCtxt;
|
|||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::{InferOk, LateBoundRegionConversionTime};
|
||||
use rustc_middle::hir::map;
|
||||
use rustc_middle::ty::error::TypeError::{self, Sorts};
|
||||
use rustc_middle::ty::relate::TypeRelation;
|
||||
use rustc_middle::ty::{
|
||||
self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
|
||||
GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, IsSuggestable,
|
||||
ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
|
||||
GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, InternalSubsts,
|
||||
IsSuggestable, ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeFolder,
|
||||
TypeSuperFoldable, TypeVisitable, TypeckResults,
|
||||
};
|
||||
use rustc_middle::ty::{TypeAndMut, TypeckResults};
|
||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||
use rustc_span::{BytePos, DesugaringKind, ExpnKind, Span, DUMMY_SP};
|
||||
use rustc_target::spec::abi;
|
||||
use std::fmt;
|
||||
use std::ops::Deref;
|
||||
|
||||
use super::method_chain::CollectAllMismatches;
|
||||
use super::InferCtxtPrivExt;
|
||||
use crate::infer::InferCtxtExt as _;
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
|
@ -292,13 +296,13 @@ pub trait TypeErrCtxtExt<'tcx> {
|
|||
fn note_obligation_cause_code<T>(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
predicate: &T,
|
||||
predicate: T,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
cause_code: &ObligationCauseCode<'tcx>,
|
||||
obligated_types: &mut Vec<Ty<'tcx>>,
|
||||
seen_requirements: &mut FxHashSet<DefId>,
|
||||
) where
|
||||
T: fmt::Display + ToPredicate<'tcx>;
|
||||
T: ToPredicate<'tcx>;
|
||||
|
||||
/// Suggest to await before try: future? => future.await?
|
||||
fn suggest_await_before_try(
|
||||
|
@ -329,6 +333,23 @@ pub trait TypeErrCtxtExt<'tcx> {
|
|||
err: &mut Diagnostic,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
);
|
||||
fn function_argument_obligation(
|
||||
&self,
|
||||
arg_hir_id: HirId,
|
||||
err: &mut Diagnostic,
|
||||
parent_code: &ObligationCauseCode<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
predicate: ty::Predicate<'tcx>,
|
||||
call_hir_id: HirId,
|
||||
);
|
||||
fn point_at_chain(
|
||||
&self,
|
||||
expr: &hir::Expr<'_>,
|
||||
typeck_results: &TypeckResults<'tcx>,
|
||||
type_diffs: Vec<TypeError<'tcx>>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
);
|
||||
}
|
||||
|
||||
fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -> (Span, String) {
|
||||
|
@ -2336,7 +2357,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
debug!(?next_code);
|
||||
self.note_obligation_cause_code(
|
||||
err,
|
||||
&obligation.predicate,
|
||||
obligation.predicate,
|
||||
obligation.param_env,
|
||||
next_code.unwrap(),
|
||||
&mut Vec::new(),
|
||||
|
@ -2347,15 +2368,16 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
fn note_obligation_cause_code<T>(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
predicate: &T,
|
||||
predicate: T,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
cause_code: &ObligationCauseCode<'tcx>,
|
||||
obligated_types: &mut Vec<Ty<'tcx>>,
|
||||
seen_requirements: &mut FxHashSet<DefId>,
|
||||
) where
|
||||
T: fmt::Display + ToPredicate<'tcx>,
|
||||
T: ToPredicate<'tcx>,
|
||||
{
|
||||
let tcx = self.tcx;
|
||||
let predicate = predicate.to_predicate(tcx);
|
||||
match *cause_code {
|
||||
ObligationCauseCode::ExprAssignable
|
||||
| ObligationCauseCode::MatchExpressionArm { .. }
|
||||
|
@ -2390,12 +2412,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
err.note("only the last element of a tuple may have a dynamically sized type");
|
||||
}
|
||||
ObligationCauseCode::ProjectionWf(data) => {
|
||||
err.note(&format!("required so that the projection `{}` is well-formed", data,));
|
||||
err.note(&format!("required so that the projection `{data}` is well-formed"));
|
||||
}
|
||||
ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => {
|
||||
err.note(&format!(
|
||||
"required so that reference `{}` does not outlive its referent",
|
||||
ref_ty,
|
||||
"required so that reference `{ref_ty}` does not outlive its referent"
|
||||
));
|
||||
}
|
||||
ObligationCauseCode::ObjectTypeBound(object_ty, region) => {
|
||||
|
@ -2689,7 +2710,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
ensure_sufficient_stack(|| {
|
||||
self.note_obligation_cause_code(
|
||||
err,
|
||||
&parent_predicate,
|
||||
parent_predicate,
|
||||
param_env,
|
||||
&data.parent_code,
|
||||
obligated_types,
|
||||
|
@ -2700,7 +2721,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
ensure_sufficient_stack(|| {
|
||||
self.note_obligation_cause_code(
|
||||
err,
|
||||
&parent_predicate,
|
||||
parent_predicate,
|
||||
param_env,
|
||||
cause_code.peel_derives(),
|
||||
obligated_types,
|
||||
|
@ -2809,7 +2830,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
ensure_sufficient_stack(|| {
|
||||
self.note_obligation_cause_code(
|
||||
err,
|
||||
&parent_predicate,
|
||||
parent_predicate,
|
||||
param_env,
|
||||
&data.parent_code,
|
||||
obligated_types,
|
||||
|
@ -2824,7 +2845,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
ensure_sufficient_stack(|| {
|
||||
self.note_obligation_cause_code(
|
||||
err,
|
||||
&parent_predicate,
|
||||
parent_predicate,
|
||||
param_env,
|
||||
&data.parent_code,
|
||||
obligated_types,
|
||||
|
@ -2837,43 +2858,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
call_hir_id,
|
||||
ref parent_code,
|
||||
} => {
|
||||
let hir = self.tcx.hir();
|
||||
if let Some(Node::Expr(expr @ hir::Expr { kind: hir::ExprKind::Block(..), .. })) =
|
||||
hir.find(arg_hir_id)
|
||||
{
|
||||
let parent_id = hir.get_parent_item(arg_hir_id);
|
||||
let typeck_results: &TypeckResults<'tcx> = match &self.typeck_results {
|
||||
Some(t) if t.hir_owner == parent_id => t,
|
||||
_ => self.tcx.typeck(parent_id.def_id),
|
||||
};
|
||||
let expr = expr.peel_blocks();
|
||||
let ty = typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error());
|
||||
let span = expr.span;
|
||||
if Some(span) != err.span.primary_span() {
|
||||
err.span_label(
|
||||
span,
|
||||
if ty.references_error() {
|
||||
String::new()
|
||||
} else {
|
||||
format!("this tail expression is of type `{:?}`", ty)
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(Node::Expr(hir::Expr {
|
||||
kind:
|
||||
hir::ExprKind::Call(hir::Expr { span, .. }, _)
|
||||
| hir::ExprKind::MethodCall(
|
||||
hir::PathSegment { ident: Ident { span, .. }, .. },
|
||||
..,
|
||||
),
|
||||
..
|
||||
})) = hir.find(call_hir_id)
|
||||
{
|
||||
if Some(*span) != err.span.primary_span() {
|
||||
err.span_label(*span, "required by a bound introduced by this call");
|
||||
}
|
||||
}
|
||||
self.function_argument_obligation(
|
||||
arg_hir_id,
|
||||
err,
|
||||
parent_code,
|
||||
param_env,
|
||||
predicate,
|
||||
call_hir_id,
|
||||
);
|
||||
ensure_sufficient_stack(|| {
|
||||
self.note_obligation_cause_code(
|
||||
err,
|
||||
|
@ -2888,9 +2880,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
ObligationCauseCode::CompareImplItemObligation { trait_item_def_id, kind, .. } => {
|
||||
let item_name = self.tcx.item_name(trait_item_def_id);
|
||||
let msg = format!(
|
||||
"the requirement `{}` appears on the `impl`'s {kind} `{}` but not on the \
|
||||
corresponding trait's {kind}",
|
||||
predicate, item_name,
|
||||
"the requirement `{predicate}` appears on the `impl`'s {kind} \
|
||||
`{item_name}` but not on the corresponding trait's {kind}",
|
||||
);
|
||||
let sp = self
|
||||
.tcx
|
||||
|
@ -2900,7 +2891,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
let mut assoc_span: MultiSpan = sp.into();
|
||||
assoc_span.push_span_label(
|
||||
sp,
|
||||
format!("this trait's {kind} doesn't have the requirement `{}`", predicate),
|
||||
format!("this trait's {kind} doesn't have the requirement `{predicate}`"),
|
||||
);
|
||||
if let Some(ident) = self
|
||||
.tcx
|
||||
|
@ -2919,7 +2910,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
ObligationCauseCode::OpaqueReturnType(expr_info) => {
|
||||
if let Some((expr_ty, expr_span)) = expr_info {
|
||||
let expr_ty = self.resolve_vars_if_possible(expr_ty);
|
||||
let expr_ty = with_forced_trimmed_paths!(self.ty_to_string(expr_ty));
|
||||
err.span_label(
|
||||
expr_span,
|
||||
format!("return type was inferred to be `{expr_ty}` here"),
|
||||
|
@ -3099,6 +3090,298 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
);
|
||||
}
|
||||
}
|
||||
fn function_argument_obligation(
|
||||
&self,
|
||||
arg_hir_id: HirId,
|
||||
err: &mut Diagnostic,
|
||||
parent_code: &ObligationCauseCode<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
predicate: ty::Predicate<'tcx>,
|
||||
call_hir_id: HirId,
|
||||
) {
|
||||
let tcx = self.tcx;
|
||||
let hir = tcx.hir();
|
||||
if let Some(Node::Expr(expr)) = hir.find(arg_hir_id) {
|
||||
let parent_id = hir.get_parent_item(arg_hir_id);
|
||||
let typeck_results: &TypeckResults<'tcx> = match &self.typeck_results {
|
||||
Some(t) if t.hir_owner == parent_id => t,
|
||||
_ => self.tcx.typeck(parent_id.def_id),
|
||||
};
|
||||
if let hir::Expr { kind: hir::ExprKind::Block(..), .. } = expr {
|
||||
let expr = expr.peel_blocks();
|
||||
let ty = typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error());
|
||||
let span = expr.span;
|
||||
if Some(span) != err.span.primary_span() {
|
||||
err.span_label(
|
||||
span,
|
||||
if ty.references_error() {
|
||||
String::new()
|
||||
} else {
|
||||
let ty = with_forced_trimmed_paths!(self.ty_to_string(ty));
|
||||
format!("this tail expression is of type `{ty}`")
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: visit the ty to see if there's any closure involved, and if there is,
|
||||
// check whether its evaluated return type is the same as the one corresponding
|
||||
// to an associated type (as seen from `trait_pred`) in the predicate. Like in
|
||||
// trait_pred `S: Sum<<Self as Iterator>::Item>` and predicate `i32: Sum<&()>`
|
||||
let mut type_diffs = vec![];
|
||||
|
||||
if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = parent_code.deref()
|
||||
&& let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
|
||||
&& let Some(pred) = predicates.predicates.get(*idx)
|
||||
&& let Ok(trait_pred) = pred.kind().try_map_bound(|pred| match pred {
|
||||
ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) => Ok(trait_pred),
|
||||
_ => Err(()),
|
||||
})
|
||||
{
|
||||
let mut c = CollectAllMismatches {
|
||||
infcx: self.infcx,
|
||||
param_env,
|
||||
errors: vec![],
|
||||
};
|
||||
if let Ok(trait_predicate) = predicate.kind().try_map_bound(|pred| match pred {
|
||||
ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) => Ok(trait_pred),
|
||||
_ => Err(()),
|
||||
}) {
|
||||
if let Ok(_) = c.relate(trait_pred, trait_predicate) {
|
||||
type_diffs = c.errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
|
||||
&& let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
|
||||
&& let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
|
||||
&& let parent_hir_id = self.tcx.hir().get_parent_node(binding.hir_id)
|
||||
&& let Some(hir::Node::Local(local)) = self.tcx.hir().find(parent_hir_id)
|
||||
&& let Some(binding_expr) = local.init
|
||||
{
|
||||
// If the expression we're calling on is a binding, we want to point at the
|
||||
// `let` when talking about the type. Otherwise we'll point at every part
|
||||
// of the method chain with the type.
|
||||
self.point_at_chain(binding_expr, typeck_results, type_diffs, param_env, err);
|
||||
} else {
|
||||
self.point_at_chain(expr, typeck_results, type_diffs, param_env, err);
|
||||
}
|
||||
}
|
||||
let call_node = hir.find(call_hir_id);
|
||||
if let Some(Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::MethodCall(path, rcvr, ..), ..
|
||||
})) = call_node
|
||||
{
|
||||
if Some(rcvr.span) == err.span.primary_span() {
|
||||
err.replace_span_with(path.ident.span);
|
||||
}
|
||||
}
|
||||
if let Some(Node::Expr(hir::Expr {
|
||||
kind:
|
||||
hir::ExprKind::Call(hir::Expr { span, .. }, _)
|
||||
| hir::ExprKind::MethodCall(hir::PathSegment { ident: Ident { span, .. }, .. }, ..),
|
||||
..
|
||||
})) = hir.find(call_hir_id)
|
||||
{
|
||||
if Some(*span) != err.span.primary_span() {
|
||||
err.span_label(*span, "required by a bound introduced by this call");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn point_at_chain(
|
||||
&self,
|
||||
expr: &hir::Expr<'_>,
|
||||
typeck_results: &TypeckResults<'tcx>,
|
||||
type_diffs: Vec<TypeError<'tcx>>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
) {
|
||||
let mut primary_spans = vec![];
|
||||
let mut span_labels = vec![];
|
||||
|
||||
let tcx = self.tcx;
|
||||
|
||||
let mut assocs = vec![];
|
||||
// We still want to point at the different methods even if there hasn't
|
||||
// been a change of assoc type.
|
||||
let mut call_spans = vec![];
|
||||
let mut expr = expr;
|
||||
let mut prev_ty = self.resolve_vars_if_possible(
|
||||
typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()),
|
||||
);
|
||||
while let hir::ExprKind::MethodCall(_path_segment, rcvr_expr, _args, span) = expr.kind {
|
||||
// Point at every method call in the chain with the resulting type.
|
||||
// vec![1, 2, 3].iter().map(mapper).sum<i32>()
|
||||
// ^^^^^^ ^^^^^^^^^^^
|
||||
expr = rcvr_expr;
|
||||
let mut assocs_in_this_method = Vec::with_capacity(type_diffs.len());
|
||||
call_spans.push(span);
|
||||
|
||||
let ocx = ObligationCtxt::new_in_snapshot(self.infcx);
|
||||
for diff in &type_diffs {
|
||||
let Sorts(expected_found) = diff else { continue; };
|
||||
let ty::Projection(proj) = expected_found.expected.kind() else { continue; };
|
||||
|
||||
let origin =
|
||||
TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span };
|
||||
let trait_def_id = proj.trait_def_id(self.tcx);
|
||||
// Make `Self` be equivalent to the type of the call chain
|
||||
// expression we're looking at now, so that we can tell what
|
||||
// for example `Iterator::Item` is at this point in the chain.
|
||||
let substs = InternalSubsts::for_item(self.tcx, trait_def_id, |param, _| {
|
||||
match param.kind {
|
||||
ty::GenericParamDefKind::Type { .. } => {
|
||||
if param.index == 0 {
|
||||
return prev_ty.into();
|
||||
}
|
||||
}
|
||||
ty::GenericParamDefKind::Lifetime
|
||||
| ty::GenericParamDefKind::Const { .. } => {}
|
||||
}
|
||||
self.var_for_def(span, param)
|
||||
});
|
||||
// This will hold the resolved type of the associated type, if the
|
||||
// current expression implements the trait that associated type is
|
||||
// in. For example, this would be what `Iterator::Item` is here.
|
||||
let ty_var = self.infcx.next_ty_var(origin);
|
||||
// This corresponds to `<ExprTy as Iterator>::Item = _`.
|
||||
let trait_ref = ty::Binder::dummy(ty::PredicateKind::Clause(
|
||||
ty::Clause::Projection(ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy { substs, item_def_id: proj.item_def_id },
|
||||
term: ty_var.into(),
|
||||
}),
|
||||
));
|
||||
// Add `<ExprTy as Iterator>::Item = _` obligation.
|
||||
ocx.register_obligation(Obligation::misc(
|
||||
self.tcx,
|
||||
span,
|
||||
expr.hir_id,
|
||||
param_env,
|
||||
trait_ref,
|
||||
));
|
||||
if ocx.select_where_possible().is_empty() {
|
||||
// `ty_var` now holds the type that `Item` is for `ExprTy`.
|
||||
let ty_var = self.resolve_vars_if_possible(ty_var);
|
||||
assocs_in_this_method.push(Some((span, (proj.item_def_id, ty_var))));
|
||||
} else {
|
||||
// `<ExprTy as Iterator>` didn't select, so likely we've
|
||||
// reached the end of the iterator chain, like the originating
|
||||
// `Vec<_>`.
|
||||
// Keep the space consistent for later zipping.
|
||||
assocs_in_this_method.push(None);
|
||||
}
|
||||
}
|
||||
assocs.push(assocs_in_this_method);
|
||||
prev_ty = self.resolve_vars_if_possible(
|
||||
typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()),
|
||||
);
|
||||
|
||||
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
|
||||
&& let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
|
||||
&& let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
|
||||
&& let parent_hir_id = self.tcx.hir().get_parent_node(binding.hir_id)
|
||||
&& let Some(hir::Node::Local(local)) = self.tcx.hir().find(parent_hir_id)
|
||||
&& let Some(binding_expr) = local.init
|
||||
{
|
||||
// We've reached the root of the method call chain and it is a
|
||||
// binding. Get the binding creation and try to continue the chain.
|
||||
expr = binding_expr;
|
||||
}
|
||||
}
|
||||
// We want the type before deref coercions, otherwise we talk about `&[_]`
|
||||
// instead of `Vec<_>`.
|
||||
if let Some(ty) = typeck_results.expr_ty_opt(expr) {
|
||||
let ty = with_forced_trimmed_paths!(self.ty_to_string(ty));
|
||||
// Point at the root expression
|
||||
// vec![1, 2, 3].iter().map(mapper).sum<i32>()
|
||||
// ^^^^^^^^^^^^^
|
||||
span_labels.push((expr.span, format!("this expression has type `{ty}`")));
|
||||
};
|
||||
// Only show this if it is not a "trivial" expression (not a method
|
||||
// chain) and there are associated types to talk about.
|
||||
let mut assocs = assocs.into_iter().peekable();
|
||||
while let Some(assocs_in_method) = assocs.next() {
|
||||
let Some(prev_assoc_in_method) = assocs.peek() else {
|
||||
for entry in assocs_in_method {
|
||||
let Some((span, (assoc, ty))) = entry else { continue; };
|
||||
if type_diffs.iter().any(|diff| {
|
||||
let Sorts(expected_found) = diff else { return false; };
|
||||
self.can_eq(param_env, expected_found.found, ty).is_ok()
|
||||
}) {
|
||||
// FIXME: this doesn't quite work for `Iterator::collect`
|
||||
// because we have `Vec<i32>` and `()`, but we'd want `i32`
|
||||
// to point at the `.into_iter()` call, but as long as we
|
||||
// still point at the other method calls that might have
|
||||
// introduced the issue, this is fine for now.
|
||||
primary_spans.push(span);
|
||||
}
|
||||
span_labels.push((
|
||||
span,
|
||||
with_forced_trimmed_paths!(format!(
|
||||
"`{}` is `{ty}` here",
|
||||
self.tcx.def_path_str(assoc),
|
||||
)),
|
||||
));
|
||||
}
|
||||
break;
|
||||
};
|
||||
for (entry, prev_entry) in
|
||||
assocs_in_method.into_iter().zip(prev_assoc_in_method.into_iter())
|
||||
{
|
||||
match (entry, prev_entry) {
|
||||
(Some((span, (assoc, ty))), Some((_, (_, prev_ty)))) => {
|
||||
let ty_str = with_forced_trimmed_paths!(self.ty_to_string(ty));
|
||||
|
||||
let assoc = with_forced_trimmed_paths!(self.tcx.def_path_str(assoc));
|
||||
if ty != *prev_ty {
|
||||
if type_diffs.iter().any(|diff| {
|
||||
let Sorts(expected_found) = diff else { return false; };
|
||||
self.can_eq(param_env, expected_found.found, ty).is_ok()
|
||||
}) {
|
||||
primary_spans.push(span);
|
||||
}
|
||||
span_labels
|
||||
.push((span, format!("`{assoc}` changed to `{ty_str}` here")));
|
||||
} else {
|
||||
span_labels.push((span, format!("`{assoc}` remains `{ty_str}` here")));
|
||||
}
|
||||
}
|
||||
(Some((span, (assoc, ty))), None) => {
|
||||
span_labels.push((
|
||||
span,
|
||||
with_forced_trimmed_paths!(format!(
|
||||
"`{}` is `{}` here",
|
||||
self.tcx.def_path_str(assoc),
|
||||
self.ty_to_string(ty),
|
||||
)),
|
||||
));
|
||||
}
|
||||
(None, Some(_)) | (None, None) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
for span in call_spans {
|
||||
if span_labels.iter().find(|(s, _)| *s == span).is_none() {
|
||||
// Ensure we are showing the entire chain, even if the assoc types
|
||||
// haven't changed.
|
||||
span_labels.push((span, String::new()));
|
||||
}
|
||||
}
|
||||
if !primary_spans.is_empty() {
|
||||
let mut multi_span: MultiSpan = primary_spans.into();
|
||||
for (span, label) in span_labels {
|
||||
multi_span.push_span_label(span, label);
|
||||
}
|
||||
err.span_note(
|
||||
multi_span,
|
||||
format!(
|
||||
"the method call chain might not have had the expected \
|
||||
associated types",
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Collect all the returned expressions within the input expression.
|
||||
|
|
|
@ -14,7 +14,7 @@ LL | let p = Some(45).and_then({
|
|||
LL | |
|
||||
LL | | |x| println!("doubling {}", x);
|
||||
LL | | Some(x * 2)
|
||||
| | ----------- this tail expression is of type `std::option::Option<_>`
|
||||
| | ----------- this tail expression is of type `Option<_>`
|
||||
LL | |
|
||||
LL | | });
|
||||
| |_____^ expected an `FnOnce<({integer},)>` closure, found `Option<_>`
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: the trait bound `for<'a> &'a mut (): Foo<&'a mut ()>` is not satisfied
|
||||
--> $DIR/issue-101020.rs:31:5
|
||||
--> $DIR/issue-101020.rs:31:22
|
||||
|
|
||||
LL | (&mut EmptyIter).consume(());
|
||||
| ^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
|
||||
| |
|
||||
| the trait `for<'a> Foo<&'a mut ()>` is not implemented for `&'a mut ()`
|
||||
| ^^^^^^^ the trait `for<'a> Foo<&'a mut ()>` is not implemented for `&'a mut ()`
|
||||
|
|
||||
note: required for `&'a mut ()` to implement `for<'a> FuncInput<'a, &'a mut ()>`
|
||||
--> $DIR/issue-101020.rs:27:20
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: the trait bound `X: Ord` is not satisfied
|
||||
--> $DIR/issue-20162.rs:5:5
|
||||
--> $DIR/issue-20162.rs:5:7
|
||||
|
|
||||
LL | b.sort();
|
||||
| ^ ---- required by a bound introduced by this call
|
||||
| |
|
||||
| the trait `Ord` is not implemented for `X`
|
||||
| ^^^^ the trait `Ord` is not implemented for `X`
|
||||
|
|
||||
note: required by a bound in `slice::<impl [T]>::sort`
|
||||
--> $SRC_DIR/alloc/src/slice.rs:LL:COL
|
||||
|
|
|
@ -4,12 +4,11 @@ pub fn get_tok(it: &mut IntoIter<u8>) {
|
|||
let mut found_e = false;
|
||||
|
||||
let temp: Vec<u8> = it
|
||||
//~^ ERROR to be an iterator that yields `&_`, but it yields `u8`
|
||||
.take_while(|&x| {
|
||||
found_e = true;
|
||||
false
|
||||
})
|
||||
.cloned()
|
||||
.cloned() //~ ERROR to be an iterator that yields `&_`, but it yields `u8`
|
||||
.collect(); //~ ERROR the method
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
error[E0271]: expected `TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>` to be an iterator that yields `&_`, but it yields `u8`
|
||||
--> $DIR/issue-31173.rs:6:25
|
||||
error[E0271]: expected `TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>` to be an iterator that yields `&_`, but it yields `u8`
|
||||
--> $DIR/issue-31173.rs:11:10
|
||||
|
|
||||
LL | let temp: Vec<u8> = it
|
||||
| _________________________^
|
||||
LL | |
|
||||
LL | | .take_while(|&x| {
|
||||
LL | | found_e = true;
|
||||
LL | | false
|
||||
LL | | })
|
||||
| |__________^ expected reference, found `u8`
|
||||
LL | .cloned()
|
||||
| ------ required by a bound introduced by this call
|
||||
LL | .cloned()
|
||||
| ^^^^^^ expected reference, found `u8`
|
||||
|
|
||||
= note: expected reference `&_`
|
||||
found type `u8`
|
||||
|
@ -20,11 +12,11 @@ note: required by a bound in `cloned`
|
|||
LL | Self: Sized + Iterator<Item = &'a T>,
|
||||
| ^^^^^^^^^^^^ required by this bound in `Iterator::cloned`
|
||||
|
||||
error[E0599]: the method `collect` exists for struct `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>`, but its trait bounds were not satisfied
|
||||
--> $DIR/issue-31173.rs:13:10
|
||||
error[E0599]: the method `collect` exists for struct `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>`, but its trait bounds were not satisfied
|
||||
--> $DIR/issue-31173.rs:12:10
|
||||
|
|
||||
LL | .collect();
|
||||
| ^^^^^^^ method cannot be called on `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>` due to unsatisfied trait bounds
|
||||
| ^^^^^^^ method cannot be called on `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>` due to unsatisfied trait bounds
|
||||
|
|
||||
::: $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL
|
||||
|
|
||||
|
@ -37,10 +29,10 @@ LL | pub struct Cloned<I> {
|
|||
| -------------------- doesn't satisfy `_: Iterator`
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]> as Iterator>::Item = &_`
|
||||
which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator`
|
||||
`Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator`
|
||||
which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator`
|
||||
`<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]> as Iterator>::Item = &_`
|
||||
which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
|
||||
`Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
|
||||
which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0271]: expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
|
||||
--> $DIR/issue-33941.rs:6:14
|
||||
--> $DIR/issue-33941.rs:6:36
|
||||
|
|
||||
LL | for _ in HashMap::new().iter().cloned() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ ------ required by a bound introduced by this call
|
||||
| |
|
||||
| expected reference, found tuple
|
||||
| ^^^^^^ expected reference, found tuple
|
||||
|
|
||||
= note: expected reference `&_`
|
||||
found tuple `(&_, &_)`
|
||||
|
|
|
@ -13,15 +13,23 @@ LL | let sr: Vec<(u32, _, _)> = vec![];
|
|||
| +
|
||||
|
||||
error[E0277]: a value of type `Vec<(u32, _, _)>` cannot be built from an iterator over elements of type `()`
|
||||
--> $DIR/issue-34334.rs:5:33
|
||||
--> $DIR/issue-34334.rs:5:87
|
||||
|
|
||||
LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
|
||||
| |
|
||||
| value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator<Item=()>`
|
||||
| ^^^^^^^ value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator<Item=()>`
|
||||
|
|
||||
= help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>`
|
||||
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/issue-34334.rs:5:43
|
||||
|
|
||||
LL | let sr: Vec<(u32, _, _) = vec![];
|
||||
| ------ this expression has type `Vec<(_, _, _)>`
|
||||
...
|
||||
LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
|
||||
| ------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Iterator::Item` changed to `()` here
|
||||
| |
|
||||
| `Iterator::Item` is `&(_, _, _)` here
|
||||
note: required by a bound in `collect`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
error[E0277]: a value of type `Vec<f64>` cannot be built from an iterator over elements of type `&f64`
|
||||
--> $DIR/issue-66923-show-error-for-correct-call.rs:8:24
|
||||
--> $DIR/issue-66923-show-error-for-correct-call.rs:8:39
|
||||
|
|
||||
LL | let x2: Vec<f64> = x1.into_iter().collect();
|
||||
| ^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
|
||||
| |
|
||||
| value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
|
||||
| ^^^^^^^ value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
|
||||
|
|
||||
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
|
||||
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/issue-66923-show-error-for-correct-call.rs:8:27
|
||||
|
|
||||
LL | let x1: &[f64] = &v;
|
||||
| -- this expression has type `&Vec<f64>`
|
||||
LL | let x2: Vec<f64> = x1.into_iter().collect();
|
||||
| ^^^^^^^^^^^ `Iterator::Item` is `&f64` here
|
||||
note: required by a bound in `collect`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
|
@ -15,15 +20,21 @@ LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Iterator::collect`
|
||||
|
||||
error[E0277]: a value of type `Vec<f64>` cannot be built from an iterator over elements of type `&f64`
|
||||
--> $DIR/issue-66923-show-error-for-correct-call.rs:12:14
|
||||
--> $DIR/issue-66923-show-error-for-correct-call.rs:12:29
|
||||
|
|
||||
LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
|
||||
| ^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
|
||||
| |
|
||||
| value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
|
||||
| ^^^^^^^ value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
|
||||
|
|
||||
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
|
||||
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/issue-66923-show-error-for-correct-call.rs:12:17
|
||||
|
|
||||
LL | let x1: &[f64] = &v;
|
||||
| -- this expression has type `&Vec<f64>`
|
||||
...
|
||||
LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
|
||||
| ^^^^^^^^^^^ `Iterator::Item` is `&f64` here
|
||||
note: required by a bound in `collect`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
|
|
|
@ -3,5 +3,4 @@ fn main() {
|
|||
//~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator
|
||||
//~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()`
|
||||
//~| NOTE required by a bound in `collect`
|
||||
//~| NOTE required by a bound introduced by this call
|
||||
}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator
|
||||
--> $DIR/collect-into-array.rs:2:31
|
||||
--> $DIR/collect-into-array.rs:2:39
|
||||
|
|
||||
LL | let whatever: [u32; 10] = (0..10).collect();
|
||||
| ^^^^^^^ ------- required by a bound introduced by this call
|
||||
| |
|
||||
| try collecting into a `Vec<{integer}>`, then using `.try_into()`
|
||||
| ^^^^^^^ try collecting into a `Vec<{integer}>`, then using `.try_into()`
|
||||
|
|
||||
= help: the trait `FromIterator<{integer}>` is not implemented for `[u32; 10]`
|
||||
note: required by a bound in `collect`
|
||||
|
|
|
@ -13,6 +13,5 @@ fn main() {
|
|||
//~| NOTE all local variables must have a statically known size
|
||||
//~| NOTE doesn't have a size known at compile-time
|
||||
//~| NOTE doesn't have a size known at compile-time
|
||||
//~| NOTE required by a bound introduced by this call
|
||||
process_slice(&some_generated_vec);
|
||||
}
|
||||
|
|
|
@ -22,12 +22,10 @@ LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
|
|||
| ^ required by this bound in `Iterator::collect`
|
||||
|
||||
error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size
|
||||
--> $DIR/collect-into-slice.rs:6:30
|
||||
--> $DIR/collect-into-slice.rs:6:38
|
||||
|
|
||||
LL | let some_generated_vec = (0..10).collect();
|
||||
| ^^^^^^^ ------- required by a bound introduced by this call
|
||||
| |
|
||||
| try explicitly collecting into a `Vec<{integer}>`
|
||||
| ^^^^^^^ try explicitly collecting into a `Vec<{integer}>`
|
||||
|
|
||||
= help: the trait `FromIterator<{integer}>` is not implemented for `[i32]`
|
||||
note: required by a bound in `collect`
|
||||
|
|
41
src/test/ui/iterators/invalid-iterator-chain.rs
Normal file
41
src/test/ui/iterators/invalid-iterator-chain.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
fn main() {
|
||||
let scores = vec![(0, 0)]
|
||||
.iter()
|
||||
.map(|(a, b)| {
|
||||
a + b;
|
||||
});
|
||||
println!("{}", scores.sum::<i32>()); //~ ERROR E0277
|
||||
println!(
|
||||
"{}",
|
||||
vec![0, 1]
|
||||
.iter()
|
||||
.map(|x| x * 2)
|
||||
.map(|x| x as f64)
|
||||
.map(|x| x as i64)
|
||||
.filter(|x| *x > 0)
|
||||
.map(|x| { x + 1 })
|
||||
.map(|x| { x; })
|
||||
.sum::<i32>(), //~ ERROR E0277
|
||||
);
|
||||
println!(
|
||||
"{}",
|
||||
vec![0, 1]
|
||||
.iter()
|
||||
.map(|x| x * 2)
|
||||
.map(|x| x as f64)
|
||||
.filter(|x| *x > 0.0)
|
||||
.map(|x| { x + 1.0 })
|
||||
.sum::<i32>(), //~ ERROR E0277
|
||||
);
|
||||
println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>()); //~ ERROR E0277
|
||||
println!("{}", vec![(), ()].iter().sum::<i32>()); //~ ERROR E0277
|
||||
let a = vec![0];
|
||||
let b = a.into_iter();
|
||||
let c = b.map(|x| x + 1);
|
||||
let d = c.filter(|x| *x > 10 );
|
||||
let e = d.map(|x| {
|
||||
x + 1;
|
||||
});
|
||||
let f = e.filter(|_| false);
|
||||
let g: Vec<i32> = f.collect(); //~ ERROR E0277
|
||||
}
|
176
src/test/ui/iterators/invalid-iterator-chain.stderr
Normal file
176
src/test/ui/iterators/invalid-iterator-chain.stderr
Normal file
|
@ -0,0 +1,176 @@
|
|||
error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
|
||||
--> $DIR/invalid-iterator-chain.rs:7:27
|
||||
|
|
||||
LL | println!("{}", scores.sum::<i32>());
|
||||
| ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
|
||||
|
|
||||
= help: the trait `Sum<()>` is not implemented for `i32`
|
||||
= help: the following other types implement trait `Sum<A>`:
|
||||
<i32 as Sum<&'a i32>>
|
||||
<i32 as Sum>
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain.rs:4:10
|
||||
|
|
||||
LL | let scores = vec![(0, 0)]
|
||||
| ------------ this expression has type `Vec<({integer}, {integer})>`
|
||||
LL | .iter()
|
||||
| ------ `Iterator::Item` is `&({integer}, {integer})` here
|
||||
LL | .map(|(a, b)| {
|
||||
| __________^
|
||||
LL | | a + b;
|
||||
LL | | });
|
||||
| |__________^ `Iterator::Item` changed to `()` here
|
||||
note: required by a bound in `std::iter::Iterator::sum`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
LL | S: Sum<Self::Item>,
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `Iterator::sum`
|
||||
|
||||
error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
|
||||
--> $DIR/invalid-iterator-chain.rs:18:14
|
||||
|
|
||||
LL | .sum::<i32>(),
|
||||
| ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
|
||||
|
|
||||
= help: the trait `Sum<()>` is not implemented for `i32`
|
||||
= help: the following other types implement trait `Sum<A>`:
|
||||
<i32 as Sum<&'a i32>>
|
||||
<i32 as Sum>
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain.rs:12:14
|
||||
|
|
||||
LL | vec![0, 1]
|
||||
| ---------- this expression has type `Vec<{integer}>`
|
||||
LL | .iter()
|
||||
| ------ `Iterator::Item` is `&{integer}` here
|
||||
LL | .map(|x| x * 2)
|
||||
| ^^^^^^^^^^^^^^ `Iterator::Item` changed to `{integer}` here
|
||||
LL | .map(|x| x as f64)
|
||||
| ----------------- `Iterator::Item` changed to `f64` here
|
||||
LL | .map(|x| x as i64)
|
||||
| ----------------- `Iterator::Item` changed to `i64` here
|
||||
LL | .filter(|x| *x > 0)
|
||||
| ------------------ `Iterator::Item` remains `i64` here
|
||||
LL | .map(|x| { x + 1 })
|
||||
| ------------------ `Iterator::Item` remains `i64` here
|
||||
LL | .map(|x| { x; })
|
||||
| ^^^^^^^^^^^^^^^ `Iterator::Item` changed to `()` here
|
||||
note: required by a bound in `std::iter::Iterator::sum`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
LL | S: Sum<Self::Item>,
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `Iterator::sum`
|
||||
|
||||
error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `f64`
|
||||
--> $DIR/invalid-iterator-chain.rs:28:14
|
||||
|
|
||||
LL | .sum::<i32>(),
|
||||
| ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=f64>`
|
||||
|
|
||||
= help: the trait `Sum<f64>` is not implemented for `i32`
|
||||
= help: the following other types implement trait `Sum<A>`:
|
||||
<i32 as Sum<&'a i32>>
|
||||
<i32 as Sum>
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain.rs:24:14
|
||||
|
|
||||
LL | vec![0, 1]
|
||||
| ---------- this expression has type `Vec<{integer}>`
|
||||
LL | .iter()
|
||||
| ------ `Iterator::Item` is `&{integer}` here
|
||||
LL | .map(|x| x * 2)
|
||||
| ^^^^^^^^^^^^^^ `Iterator::Item` changed to `{integer}` here
|
||||
LL | .map(|x| x as f64)
|
||||
| ^^^^^^^^^^^^^^^^^ `Iterator::Item` changed to `f64` here
|
||||
LL | .filter(|x| *x > 0.0)
|
||||
| -------------------- `Iterator::Item` remains `f64` here
|
||||
LL | .map(|x| { x + 1.0 })
|
||||
| -------------------- `Iterator::Item` remains `f64` here
|
||||
note: required by a bound in `std::iter::Iterator::sum`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
LL | S: Sum<Self::Item>,
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `Iterator::sum`
|
||||
|
||||
error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
|
||||
--> $DIR/invalid-iterator-chain.rs:30:54
|
||||
|
|
||||
LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
|
||||
| ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
|
||||
|
|
||||
= help: the trait `Sum<()>` is not implemented for `i32`
|
||||
= help: the following other types implement trait `Sum<A>`:
|
||||
<i32 as Sum<&'a i32>>
|
||||
<i32 as Sum>
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain.rs:30:38
|
||||
|
|
||||
LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
|
||||
| ---------- ------ ^^^^^^^^^^^^^^^ `Iterator::Item` changed to `()` here
|
||||
| | |
|
||||
| | `Iterator::Item` is `&{integer}` here
|
||||
| this expression has type `Vec<{integer}>`
|
||||
note: required by a bound in `std::iter::Iterator::sum`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
LL | S: Sum<Self::Item>,
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `Iterator::sum`
|
||||
|
||||
error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `&()`
|
||||
--> $DIR/invalid-iterator-chain.rs:31:40
|
||||
|
|
||||
LL | println!("{}", vec![(), ()].iter().sum::<i32>());
|
||||
| ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=&()>`
|
||||
|
|
||||
= help: the trait `Sum<&()>` is not implemented for `i32`
|
||||
= help: the following other types implement trait `Sum<A>`:
|
||||
<i32 as Sum<&'a i32>>
|
||||
<i32 as Sum>
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain.rs:31:33
|
||||
|
|
||||
LL | println!("{}", vec![(), ()].iter().sum::<i32>());
|
||||
| ------------ ^^^^^^ `Iterator::Item` is `&()` here
|
||||
| |
|
||||
| this expression has type `Vec<()>`
|
||||
note: required by a bound in `std::iter::Iterator::sum`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
LL | S: Sum<Self::Item>,
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `Iterator::sum`
|
||||
|
||||
error[E0277]: a value of type `Vec<i32>` cannot be built from an iterator over elements of type `()`
|
||||
--> $DIR/invalid-iterator-chain.rs:40:25
|
||||
|
|
||||
LL | let g: Vec<i32> = f.collect();
|
||||
| ^^^^^^^ value of type `Vec<i32>` cannot be built from `std::iter::Iterator<Item=()>`
|
||||
|
|
||||
= help: the trait `FromIterator<()>` is not implemented for `Vec<i32>`
|
||||
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/invalid-iterator-chain.rs:36:15
|
||||
|
|
||||
LL | let a = vec![0];
|
||||
| ------- this expression has type `Vec<{integer}>`
|
||||
LL | let b = a.into_iter();
|
||||
| ----------- `Iterator::Item` is `{integer}` here
|
||||
LL | let c = b.map(|x| x + 1);
|
||||
| -------------- `Iterator::Item` remains `{integer}` here
|
||||
LL | let d = c.filter(|x| *x > 10 );
|
||||
| -------------------- `Iterator::Item` remains `{integer}` here
|
||||
LL | let e = d.map(|x| {
|
||||
| _______________^
|
||||
LL | | x + 1;
|
||||
LL | | });
|
||||
| |______^ `Iterator::Item` changed to `()` here
|
||||
LL | let f = e.filter(|_| false);
|
||||
| ----------------- `Iterator::Item` remains `()` here
|
||||
note: required by a bound in `collect`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Iterator::collect`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: a value of type `Bar` cannot be built from an iterator over elements of type `_`
|
||||
--> $DIR/branches.rs:19:9
|
||||
--> $DIR/branches.rs:19:28
|
||||
|
|
||||
LL | std::iter::empty().collect()
|
||||
| ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
|
||||
| |
|
||||
| value of type `Bar` cannot be built from `std::iter::Iterator<Item=_>`
|
||||
| ^^^^^^^ value of type `Bar` cannot be built from `std::iter::Iterator<Item=_>`
|
||||
|
|
||||
= help: the trait `FromIterator<_>` is not implemented for `Bar`
|
||||
note: required by a bound in `collect`
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: a value of type `Foo` cannot be built from an iterator over elements of type `_`
|
||||
--> $DIR/recursion4.rs:10:9
|
||||
--> $DIR/recursion4.rs:10:28
|
||||
|
|
||||
LL | x = std::iter::empty().collect();
|
||||
| ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
|
||||
| |
|
||||
| value of type `Foo` cannot be built from `std::iter::Iterator<Item=_>`
|
||||
| ^^^^^^^ value of type `Foo` cannot be built from `std::iter::Iterator<Item=_>`
|
||||
|
|
||||
= help: the trait `FromIterator<_>` is not implemented for `Foo`
|
||||
note: required by a bound in `collect`
|
||||
|
@ -14,12 +12,10 @@ LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Iterator::collect`
|
||||
|
||||
error[E0277]: a value of type `impl Debug` cannot be built from an iterator over elements of type `_`
|
||||
--> $DIR/recursion4.rs:19:9
|
||||
--> $DIR/recursion4.rs:19:28
|
||||
|
|
||||
LL | x = std::iter::empty().collect();
|
||||
| ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
|
||||
| |
|
||||
| value of type `impl Debug` cannot be built from `std::iter::Iterator<Item=_>`
|
||||
| ^^^^^^^ value of type `impl Debug` cannot be built from `std::iter::Iterator<Item=_>`
|
||||
|
|
||||
= help: the trait `FromIterator<_>` is not implemented for `impl Debug`
|
||||
note: required by a bound in `collect`
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: `Foo` doesn't implement `Debug`
|
||||
--> $DIR/method-help-unsatisfied-bound.rs:5:5
|
||||
--> $DIR/method-help-unsatisfied-bound.rs:5:7
|
||||
|
|
||||
LL | a.unwrap();
|
||||
| ^ ------ required by a bound introduced by this call
|
||||
| |
|
||||
| `Foo` cannot be formatted using `{:?}`
|
||||
| ^^^^^^ `Foo` cannot be formatted using `{:?}`
|
||||
|
|
||||
= help: the trait `Debug` is not implemented for `Foo`
|
||||
= note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo`
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | foo(panic!())
|
|||
| --- ^^^^^^^^
|
||||
| | |
|
||||
| | the trait `T` is not implemented for `()`
|
||||
| | this tail expression is of type `_`
|
||||
| | this tail expression is of type `()`
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `foo`
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
error[E0277]: the trait bound `S: Clone` is not satisfied in `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`
|
||||
--> $DIR/not-clone-closure.rs:11:17
|
||||
--> $DIR/not-clone-closure.rs:11:23
|
||||
|
|
||||
LL | let hello = move || {
|
||||
| ------- within this `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`
|
||||
...
|
||||
LL | let hello = hello.clone();
|
||||
| ^^^^^ ----- required by a bound introduced by this call
|
||||
| |
|
||||
| within `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`, the trait `Clone` is not implemented for `S`
|
||||
| ^^^^^ within `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`, the trait `Clone` is not implemented for `S`
|
||||
|
|
||||
note: required because it's used within this closure
|
||||
--> $DIR/not-clone-closure.rs:7:17
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `&()`
|
||||
--> $DIR/sum.rs:4:5
|
||||
--> $DIR/sum.rs:4:25
|
||||
|
|
||||
LL | vec![(), ()].iter().sum::<i32>();
|
||||
| ^^^^^^^^^^^^^^^^^^^ --- required by a bound introduced by this call
|
||||
| |
|
||||
| value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=&()>`
|
||||
| ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=&()>`
|
||||
|
|
||||
= help: the trait `Sum<&()>` is not implemented for `i32`
|
||||
= help: the following other types implement trait `Sum<A>`:
|
||||
<i32 as Sum<&'a i32>>
|
||||
<i32 as Sum>
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/sum.rs:4:18
|
||||
|
|
||||
LL | vec![(), ()].iter().sum::<i32>();
|
||||
| ------------ ^^^^^^ `Iterator::Item` is `&()` here
|
||||
| |
|
||||
| this expression has type `Vec<()>`
|
||||
note: required by a bound in `std::iter::Iterator::sum`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
|
@ -17,17 +22,22 @@ LL | S: Sum<Self::Item>,
|
|||
| ^^^^^^^^^^^^^^^ required by this bound in `Iterator::sum`
|
||||
|
||||
error[E0277]: a value of type `i32` cannot be made by multiplying all elements of type `&()` from an iterator
|
||||
--> $DIR/sum.rs:7:5
|
||||
--> $DIR/sum.rs:7:25
|
||||
|
|
||||
LL | vec![(), ()].iter().product::<i32>();
|
||||
| ^^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
|
||||
| |
|
||||
| value of type `i32` cannot be made by multiplying all elements from a `std::iter::Iterator<Item=&()>`
|
||||
| ^^^^^^^ value of type `i32` cannot be made by multiplying all elements from a `std::iter::Iterator<Item=&()>`
|
||||
|
|
||||
= help: the trait `Product<&()>` is not implemented for `i32`
|
||||
= help: the following other types implement trait `Product<A>`:
|
||||
<i32 as Product<&'a i32>>
|
||||
<i32 as Product>
|
||||
note: the method call chain might not have had the expected associated types
|
||||
--> $DIR/sum.rs:7:18
|
||||
|
|
||||
LL | vec![(), ()].iter().product::<i32>();
|
||||
| ------------ ^^^^^^ `Iterator::Item` is `&()` here
|
||||
| |
|
||||
| this expression has type `Vec<()>`
|
||||
note: required by a bound in `std::iter::Iterator::product`
|
||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
|
||||
--> $DIR/const-default-method-bodies.rs:24:5
|
||||
--> $DIR/const-default-method-bodies.rs:24:18
|
||||
|
|
||||
LL | NonConstImpl.a();
|
||||
| ^^^^^^^^^^^^ - required by a bound introduced by this call
|
||||
| |
|
||||
| the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl`
|
||||
| ^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl`
|
||||
|
|
||||
note: the trait `ConstDefaultFn` is implemented for `NonConstImpl`, but that implementation is not `const`
|
||||
--> $DIR/const-default-method-bodies.rs:24:5
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
|
||||
--> $DIR/cross-crate.rs:17:5
|
||||
--> $DIR/cross-crate.rs:17:14
|
||||
|
|
||||
LL | NonConst.func();
|
||||
| ^^^^^^^^ ---- required by a bound introduced by this call
|
||||
| |
|
||||
| the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
||||
| ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
||||
|
|
||||
note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const`
|
||||
--> $DIR/cross-crate.rs:17:5
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: the trait bound `cross_crate::NonConst: cross_crate::MyTrait` is not satisfied
|
||||
--> $DIR/cross-crate.rs:17:5
|
||||
--> $DIR/cross-crate.rs:17:14
|
||||
|
|
||||
LL | NonConst.func();
|
||||
| ^^^^^^^^ ---- required by a bound introduced by this call
|
||||
| |
|
||||
| the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
||||
| ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
||||
|
|
||||
note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const`
|
||||
--> $DIR/cross-crate.rs:17:5
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
|
||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:8:9
|
||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
|
||||
|
|
||||
LL | ().a()
|
||||
| ^^ - required by a bound introduced by this call
|
||||
| |
|
||||
| the trait `~const Tr` is not implemented for `()`
|
||||
| ^ the trait `~const Tr` is not implemented for `()`
|
||||
|
|
||||
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
|
||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:8:9
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: the trait bound `T: ~const Foo` is not satisfied
|
||||
--> $DIR/super-traits-fail-2.rs:15:5
|
||||
--> $DIR/super-traits-fail-2.rs:15:7
|
||||
|
|
||||
LL | x.a();
|
||||
| ^ - required by a bound introduced by this call
|
||||
| |
|
||||
| the trait `~const Foo` is not implemented for `T`
|
||||
| ^ the trait `~const Foo` is not implemented for `T`
|
||||
|
|
||||
note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
|
||||
--> $DIR/super-traits-fail-2.rs:15:5
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: the trait bound `T: ~const Foo` is not satisfied
|
||||
--> $DIR/super-traits-fail-2.rs:15:5
|
||||
--> $DIR/super-traits-fail-2.rs:15:7
|
||||
|
|
||||
LL | x.a();
|
||||
| ^ - required by a bound introduced by this call
|
||||
| |
|
||||
| the trait `~const Foo` is not implemented for `T`
|
||||
| ^ the trait `~const Foo` is not implemented for `T`
|
||||
|
|
||||
note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
|
||||
--> $DIR/super-traits-fail-2.rs:15:5
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: the trait bound `&[i8]: From<&[u8]>` is not satisfied
|
||||
--> $DIR/issue-71394-no-from-impl.rs:3:20
|
||||
--> $DIR/issue-71394-no-from-impl.rs:3:25
|
||||
|
|
||||
LL | let _: &[i8] = data.into();
|
||||
| ^^^^ ---- required by a bound introduced by this call
|
||||
| |
|
||||
| the trait `From<&[u8]>` is not implemented for `&[i8]`
|
||||
| ^^^^ the trait `From<&[u8]>` is not implemented for `&[i8]`
|
||||
|
|
||||
= help: the following other types implement trait `From<T>`:
|
||||
<[T; LANES] as From<Simd<T, LANES>>>
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: the trait bound `String: From<impl ToString>` is not satisfied
|
||||
--> $DIR/issue-97576.rs:8:18
|
||||
--> $DIR/issue-97576.rs:8:22
|
||||
|
|
||||
LL | bar: bar.into(),
|
||||
| ^^^ ---- required by a bound introduced by this call
|
||||
| |
|
||||
| the trait `From<impl ToString>` is not implemented for `String`
|
||||
| ^^^^ the trait `From<impl ToString>` is not implemented for `String`
|
||||
|
|
||||
= note: required for `impl ToString` to implement `Into<String>`
|
||||
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied
|
||||
--> $DIR/issue-71659.rs:30:13
|
||||
--> $DIR/issue-71659.rs:30:15
|
||||
|
|
||||
LL | let x = x.cast::<[i32]>();
|
||||
| ^ ---- required by a bound introduced by this call
|
||||
| |
|
||||
| the trait `CastTo<[i32]>` is not implemented for `dyn Foo`
|
||||
| ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo`
|
||||
|
|
||||
note: required by a bound in `Cast::cast`
|
||||
--> $DIR/issue-71659.rs:19:15
|
||||
|
|
Loading…
Add table
Reference in a new issue