mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 15:01:51 +00:00
Auto merge of #105644 - matthiaskrgr:rollup-qc6hlzq, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #104864 (Account for item-local in inner scope for E0425) - #105332 (Point out the type of associated types in every method call of iterator chains) - #105620 (Remove unnecessary uses of `clone`) - #105625 (minor code cleanups) - #105629 (rustdoc: stop treating everything in a trait item as a method) - #105636 (Add check for local-storage value when changing "display line numbers" settings) - #105639 (rustdoc: remove `type="text/css" from stylesheet links) - #105640 (Adjust miri to still be optional) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
b96d9e0e20
@ -802,12 +802,9 @@ impl Integer {
|
||||
pub fn for_align<C: HasDataLayout>(cx: &C, wanted: Align) -> Option<Integer> {
|
||||
let dl = cx.data_layout();
|
||||
|
||||
for candidate in [I8, I16, I32, I64, I128] {
|
||||
if wanted == candidate.align(dl).abi && wanted.bytes() == candidate.size().bytes() {
|
||||
return Some(candidate);
|
||||
}
|
||||
}
|
||||
None
|
||||
[I8, I16, I32, I64, I128].into_iter().find(|&candidate| {
|
||||
wanted == candidate.align(dl).abi && wanted.bytes() == candidate.size().bytes()
|
||||
})
|
||||
}
|
||||
|
||||
/// Find the largest integer with the given alignment or less.
|
||||
|
@ -114,7 +114,7 @@ impl Lit {
|
||||
if let NtExpr(expr) | NtLiteral(expr) = &**nt
|
||||
&& let ast::ExprKind::Lit(token_lit) = expr.kind =>
|
||||
{
|
||||
Some(token_lit.clone())
|
||||
Some(token_lit)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
@ -630,7 +630,7 @@ fn check_incompatible_features(sess: &Session) {
|
||||
{
|
||||
let spans = vec![f1_span, f2_span];
|
||||
sess.struct_span_err(
|
||||
spans.clone(),
|
||||
spans,
|
||||
&format!(
|
||||
"features `{}` and `{}` are incompatible, using them at the same time \
|
||||
is not allowed",
|
||||
|
@ -745,7 +745,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_hi(),
|
||||
"consider cloning the value if the performance cost is acceptable",
|
||||
".clone()".to_string(),
|
||||
".clone()",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ pub fn expand(
|
||||
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
|
||||
} else {
|
||||
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "alloc_error_handler must be a function");
|
||||
return vec![orig_item.clone()];
|
||||
return vec![orig_item];
|
||||
};
|
||||
|
||||
// Generate a bunch of new items using the AllocFnFactory
|
||||
|
@ -196,7 +196,7 @@ pub fn expand_concat_bytes(
|
||||
}
|
||||
}
|
||||
if !missing_literals.is_empty() {
|
||||
let mut err = cx.struct_span_err(missing_literals.clone(), "expected a byte literal");
|
||||
let mut err = cx.struct_span_err(missing_literals, "expected a byte literal");
|
||||
err.note("only byte literals (like `b\"foo\"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`");
|
||||
err.emit();
|
||||
return base::MacEager::expr(DummyResult::raw_expr(sp, true));
|
||||
|
@ -210,7 +210,7 @@ pub(crate) fn run_thin(
|
||||
}
|
||||
|
||||
pub(crate) fn prepare_thin(module: ModuleCodegen<ModuleLlvm>) -> (String, ThinBuffer) {
|
||||
let name = module.name.clone();
|
||||
let name = module.name;
|
||||
let buffer = ThinBuffer::new(module.module_llvm.llmod(), true);
|
||||
(name, buffer)
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ pub const MAX_BASE: usize = 64;
|
||||
pub const ALPHANUMERIC_ONLY: usize = 62;
|
||||
pub const CASE_INSENSITIVE: usize = 36;
|
||||
|
||||
const BASE_64: &[u8; MAX_BASE as usize] =
|
||||
const BASE_64: &[u8; MAX_BASE] =
|
||||
b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@$";
|
||||
|
||||
#[inline]
|
||||
|
@ -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
|
||||
@ -802,7 +806,7 @@ impl Diagnostic {
|
||||
debug_assert!(
|
||||
!(suggestions
|
||||
.iter()
|
||||
.flat_map(|suggs| suggs)
|
||||
.flatten()
|
||||
.any(|(sp, suggestion)| sp.is_empty() && suggestion.is_empty())),
|
||||
"Span must not be empty and have no suggestion"
|
||||
);
|
||||
|
@ -1308,7 +1308,7 @@ impl EmitterWriter {
|
||||
// see how it *looks* with
|
||||
// very *weird* formats
|
||||
// see?
|
||||
for &(ref text, ref style) in msg.iter() {
|
||||
for (text, style) in msg.iter() {
|
||||
let text = self.translate_message(text, args);
|
||||
let lines = text.split('\n').collect::<Vec<_>>();
|
||||
if lines.len() > 1 {
|
||||
@ -1370,7 +1370,7 @@ impl EmitterWriter {
|
||||
buffer.append(0, ": ", header_style);
|
||||
label_width += 2;
|
||||
}
|
||||
for &(ref text, _) in msg.iter() {
|
||||
for (text, _) in msg.iter() {
|
||||
let text = self.translate_message(text, args);
|
||||
// Account for newlines to align output to its label.
|
||||
for (line, text) in normalize_whitespace(&text).lines().enumerate() {
|
||||
|
@ -548,12 +548,7 @@ impl<'hir> Generics<'hir> {
|
||||
}
|
||||
|
||||
pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'hir>> {
|
||||
for param in self.params {
|
||||
if name == param.name.ident().name {
|
||||
return Some(param);
|
||||
}
|
||||
}
|
||||
None
|
||||
self.params.iter().find(|¶m| name == param.name.ident().name)
|
||||
}
|
||||
|
||||
pub fn spans(&self) -> MultiSpan {
|
||||
|
@ -209,7 +209,7 @@ impl<T: Idx> BitSet<T> {
|
||||
self.words[start_word_index] |= !(start_mask - 1);
|
||||
// And all trailing bits (i.e. from 0..=end) in the end word,
|
||||
// including the end.
|
||||
self.words[end_word_index] |= end_mask | end_mask - 1;
|
||||
self.words[end_word_index] |= end_mask | (end_mask - 1);
|
||||
} else {
|
||||
self.words[start_word_index] |= end_mask | (end_mask - start_mask);
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ pub fn suggest_new_region_bound(
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
if let Some((param_span, param_ty)) = param.clone() {
|
||||
if let Some((param_span, ref param_ty)) = param {
|
||||
err.span_suggestion_verbose(
|
||||
param_span,
|
||||
add_static_bound,
|
||||
|
@ -204,14 +204,13 @@ fn scan_escape(chars: &mut Chars<'_>, is_byte: bool) -> Result<char, EscapeError
|
||||
})?;
|
||||
}
|
||||
Some(c) => {
|
||||
let digit =
|
||||
let digit: u32 =
|
||||
c.to_digit(16).ok_or(EscapeError::InvalidCharInUnicodeEscape)?;
|
||||
n_digits += 1;
|
||||
if n_digits > 6 {
|
||||
// Stop updating value since we're sure that it's incorrect already.
|
||||
continue;
|
||||
}
|
||||
let digit = digit as u32;
|
||||
value = value * 16 + digit;
|
||||
}
|
||||
};
|
||||
|
@ -566,6 +566,9 @@ struct LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
/// FIXME #4948: Reuse ribs to avoid allocation.
|
||||
ribs: PerNS<Vec<Rib<'a>>>,
|
||||
|
||||
/// Previous poped `rib`, only used for diagnostic.
|
||||
last_block_rib: Option<Rib<'a>>,
|
||||
|
||||
/// The current set of local scopes, for labels.
|
||||
label_ribs: Vec<Rib<'a, NodeId>>,
|
||||
|
||||
@ -873,6 +876,8 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
||||
// Ignore errors in function bodies if this is rustdoc
|
||||
// Be sure not to set this until the function signature has been resolved.
|
||||
let previous_state = replace(&mut this.in_func_body, true);
|
||||
// We only care block in the same function
|
||||
this.last_block_rib = None;
|
||||
// Resolve the function body, potentially inside the body of an async closure
|
||||
this.with_lifetime_rib(
|
||||
LifetimeRibKind::Elided(LifetimeRes::Infer),
|
||||
@ -1168,6 +1173,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
type_ns: vec![Rib::new(start_rib_kind)],
|
||||
macro_ns: vec![Rib::new(start_rib_kind)],
|
||||
},
|
||||
last_block_rib: None,
|
||||
label_ribs: Vec::new(),
|
||||
lifetime_ribs: Vec::new(),
|
||||
lifetime_elision_candidates: None,
|
||||
@ -3769,7 +3775,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
self.ribs[ValueNS].pop();
|
||||
self.label_ribs.pop();
|
||||
}
|
||||
self.ribs[ValueNS].pop();
|
||||
self.last_block_rib = self.ribs[ValueNS].pop();
|
||||
if anonymous_module.is_some() {
|
||||
self.ribs[TypeNS].pop();
|
||||
}
|
||||
|
@ -623,6 +623,22 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||
return (true, candidates);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to find in last block rib
|
||||
if let Some(rib) = &self.last_block_rib && let RibKind::NormalRibKind = rib.kind {
|
||||
for (ident, &res) in &rib.bindings {
|
||||
if let Res::Local(_) = res && path.len() == 1 &&
|
||||
ident.span.eq_ctxt(path[0].ident.span) &&
|
||||
ident.name == path[0].ident.name {
|
||||
err.span_help(
|
||||
ident.span,
|
||||
&format!("the binding `{}` is available in a different scope in the same function", path_str),
|
||||
);
|
||||
return (true, candidates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (false, candidates);
|
||||
}
|
||||
|
||||
|
@ -1150,7 +1150,7 @@ impl FilePathMapping {
|
||||
// NOTE: We are iterating over the mapping entries from last to first
|
||||
// because entries specified later on the command line should
|
||||
// take precedence.
|
||||
for &(ref from, ref to) in mapping.iter().rev() {
|
||||
for (from, to) in mapping.iter().rev() {
|
||||
debug!("Trying to apply {from:?} => {to:?}");
|
||||
|
||||
if let Ok(rest) = path.strip_prefix(from) {
|
||||
|
@ -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.
|
||||
|
@ -1470,7 +1470,7 @@ impl Step for Extended {
|
||||
|
||||
let xform = |p: &Path| {
|
||||
let mut contents = t!(fs::read_to_string(p));
|
||||
for tool in &["rust-demangler"] {
|
||||
for tool in &["rust-demangler", "miri"] {
|
||||
if !built_tools.contains(tool) {
|
||||
contents = filter(&contents, tool);
|
||||
}
|
||||
@ -1510,9 +1510,8 @@ impl Step for Extended {
|
||||
prepare("rust-std");
|
||||
prepare("rust-analysis");
|
||||
prepare("clippy");
|
||||
prepare("miri");
|
||||
prepare("rust-analyzer");
|
||||
for tool in &["rust-docs", "rust-demangler"] {
|
||||
for tool in &["rust-docs", "rust-demangler", "miri"] {
|
||||
if built_tools.contains(tool) {
|
||||
prepare(tool);
|
||||
}
|
||||
@ -1571,9 +1570,8 @@ impl Step for Extended {
|
||||
prepare("rust-docs");
|
||||
prepare("rust-std");
|
||||
prepare("clippy");
|
||||
prepare("miri");
|
||||
prepare("rust-analyzer");
|
||||
for tool in &["rust-demangler"] {
|
||||
for tool in &["rust-demangler", "miri"] {
|
||||
if built_tools.contains(tool) {
|
||||
prepare(tool);
|
||||
}
|
||||
@ -1710,23 +1708,25 @@ impl Step for Extended {
|
||||
.arg(etc.join("msi/remove-duplicates.xsl")),
|
||||
);
|
||||
}
|
||||
builder.run(
|
||||
Command::new(&heat)
|
||||
.current_dir(&exe)
|
||||
.arg("dir")
|
||||
.arg("miri")
|
||||
.args(&heat_flags)
|
||||
.arg("-cg")
|
||||
.arg("MiriGroup")
|
||||
.arg("-dr")
|
||||
.arg("Miri")
|
||||
.arg("-var")
|
||||
.arg("var.MiriDir")
|
||||
.arg("-out")
|
||||
.arg(exe.join("MiriGroup.wxs"))
|
||||
.arg("-t")
|
||||
.arg(etc.join("msi/remove-duplicates.xsl")),
|
||||
);
|
||||
if built_tools.contains("miri") {
|
||||
builder.run(
|
||||
Command::new(&heat)
|
||||
.current_dir(&exe)
|
||||
.arg("dir")
|
||||
.arg("miri")
|
||||
.args(&heat_flags)
|
||||
.arg("-cg")
|
||||
.arg("MiriGroup")
|
||||
.arg("-dr")
|
||||
.arg("Miri")
|
||||
.arg("-var")
|
||||
.arg("var.MiriDir")
|
||||
.arg("-out")
|
||||
.arg(exe.join("MiriGroup.wxs"))
|
||||
.arg("-t")
|
||||
.arg(etc.join("msi/remove-duplicates.xsl")),
|
||||
);
|
||||
}
|
||||
builder.run(
|
||||
Command::new(&heat)
|
||||
.current_dir(&exe)
|
||||
@ -1774,7 +1774,6 @@ impl Step for Extended {
|
||||
.arg("-dStdDir=rust-std")
|
||||
.arg("-dAnalysisDir=rust-analysis")
|
||||
.arg("-dClippyDir=clippy")
|
||||
.arg("-dMiriDir=miri")
|
||||
.arg("-arch")
|
||||
.arg(&arch)
|
||||
.arg("-out")
|
||||
@ -1788,6 +1787,9 @@ impl Step for Extended {
|
||||
if built_tools.contains("rust-analyzer") {
|
||||
cmd.arg("-dRustAnalyzerDir=rust-analyzer");
|
||||
}
|
||||
if built_tools.contains("miri") {
|
||||
cmd.arg("-dMiriDir=miri");
|
||||
}
|
||||
if target.ends_with("windows-gnu") {
|
||||
cmd.arg("-dGccDir=rust-mingw");
|
||||
}
|
||||
@ -1801,7 +1803,9 @@ impl Step for Extended {
|
||||
candle("CargoGroup.wxs".as_ref());
|
||||
candle("StdGroup.wxs".as_ref());
|
||||
candle("ClippyGroup.wxs".as_ref());
|
||||
candle("MiriGroup.wxs".as_ref());
|
||||
if built_tools.contains("miri") {
|
||||
candle("MiriGroup.wxs".as_ref());
|
||||
}
|
||||
if built_tools.contains("rust-demangler") {
|
||||
candle("RustDemanglerGroup.wxs".as_ref());
|
||||
}
|
||||
@ -1837,9 +1841,11 @@ impl Step for Extended {
|
||||
.arg("StdGroup.wixobj")
|
||||
.arg("AnalysisGroup.wixobj")
|
||||
.arg("ClippyGroup.wixobj")
|
||||
.arg("MiriGroup.wixobj")
|
||||
.current_dir(&exe);
|
||||
|
||||
if built_tools.contains("miri") {
|
||||
cmd.arg("MiriGroup.wixobj");
|
||||
}
|
||||
if built_tools.contains("rust-analyzer") {
|
||||
cmd.arg("RustAnalyzerGroup.wixobj");
|
||||
}
|
||||
|
@ -177,6 +177,9 @@ impl ItemType {
|
||||
ItemType::TraitAlias => "traitalias",
|
||||
}
|
||||
}
|
||||
pub(crate) fn is_method(&self) -> bool {
|
||||
matches!(*self, ItemType::Method | ItemType::TyMethod)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ItemType {
|
||||
|
@ -637,7 +637,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
||||
You need to enable Javascript be able to update your settings.\
|
||||
</section>\
|
||||
</noscript>\
|
||||
<link rel=\"stylesheet\" type=\"text/css\" \
|
||||
<link rel=\"stylesheet\" \
|
||||
href=\"{static_root_path}{settings_css}\">\
|
||||
<script defer src=\"{static_root_path}{settings_js}\"></script>",
|
||||
static_root_path = page.get_static_root_path(),
|
||||
|
@ -1512,8 +1512,7 @@ fn render_impl(
|
||||
|
||||
let toggled = !doc_buffer.is_empty();
|
||||
if toggled {
|
||||
let method_toggle_class =
|
||||
if item_type == ItemType::Method { " method-toggle" } else { "" };
|
||||
let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
|
||||
write!(w, "<details class=\"rustdoc-toggle{}\" open><summary>", method_toggle_class);
|
||||
}
|
||||
match &*item.kind {
|
||||
|
@ -732,7 +732,8 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
|
||||
document(&mut content, cx, m, Some(t), HeadingOffset::H5);
|
||||
let toggled = !content.is_empty();
|
||||
if toggled {
|
||||
write!(w, "<details class=\"rustdoc-toggle method-toggle\" open><summary>");
|
||||
let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
|
||||
write!(w, "<details class=\"rustdoc-toggle{method_toggle_class}\" open><summary>");
|
||||
}
|
||||
write!(w, "<section id=\"{}\" class=\"method has-srclink\">", id);
|
||||
render_rightside(w, cx, m, t, RenderMode::Normal);
|
||||
|
@ -184,7 +184,6 @@ function browserSupportsHistoryApi() {
|
||||
function loadCss(cssUrl) {
|
||||
const link = document.createElement("link");
|
||||
link.href = cssUrl;
|
||||
link.type = "text/css";
|
||||
link.rel = "stylesheet";
|
||||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ pub(crate) fn render<P: AsRef<Path>>(
|
||||
|
||||
let mut css = String::new();
|
||||
for name in &options.markdown_css {
|
||||
write!(css, r#"<link rel="stylesheet" type="text/css" href="{name}">"#)
|
||||
write!(css, r#"<link rel="stylesheet" href="{name}">"#)
|
||||
.expect("Writing to a String can't fail");
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,9 @@ assert-css: ("#settings", {"display": "block"})
|
||||
click: "input#line-numbers"
|
||||
wait-for: 100 // wait-for-false does not exist
|
||||
assert-false: "pre.example-line-numbers"
|
||||
assert-local-storage: {"rustdoc-line-numbers": "false" }
|
||||
|
||||
// Finally, turn it on again.
|
||||
click: "input#line-numbers"
|
||||
wait-for: "pre.example-line-numbers"
|
||||
assert-local-storage: {"rustdoc-line-numbers": "true" }
|
||||
|
@ -4,6 +4,8 @@
|
||||
// summary. Trait methods with no documentation should not be wrapped.
|
||||
//
|
||||
// @has foo/trait.Foo.html
|
||||
// @has - '//details[@class="rustdoc-toggle"]//summary//h4[@class="code-header"]' 'type Item'
|
||||
// @!has - '//details[@class="rustdoc-toggle"]//summary//h4[@class="code-header"]' 'type Item2'
|
||||
// @has - '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'is_documented()'
|
||||
// @!has - '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'not_documented()'
|
||||
// @has - '//details[@class="rustdoc-toggle method-toggle"]//*[@class="docblock"]' 'is_documented is documented'
|
||||
@ -11,6 +13,11 @@
|
||||
// @!has - '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'not_documented_optional()'
|
||||
// @has - '//details[@class="rustdoc-toggle method-toggle"]//*[@class="docblock"]' 'is_documented_optional is documented'
|
||||
pub trait Foo {
|
||||
/// is documented
|
||||
type Item;
|
||||
|
||||
type Item2;
|
||||
|
||||
fn not_documented();
|
||||
|
||||
/// is_documented is documented
|
||||
|
@ -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
|
||||
|
|
||||
|
11
src/test/ui/resolve/issue-104700-inner_scope.rs
Normal file
11
src/test/ui/resolve/issue-104700-inner_scope.rs
Normal file
@ -0,0 +1,11 @@
|
||||
fn main() {
|
||||
let foo = 1;
|
||||
{
|
||||
let bar = 2;
|
||||
let test_func = |x| x > 3;
|
||||
}
|
||||
if bar == 2 { //~ ERROR cannot find value
|
||||
println!("yes");
|
||||
}
|
||||
test_func(1); //~ ERROR cannot find function
|
||||
}
|
21
src/test/ui/resolve/issue-104700-inner_scope.stderr
Normal file
21
src/test/ui/resolve/issue-104700-inner_scope.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
error[E0425]: cannot find value `bar` in this scope
|
||||
--> $DIR/issue-104700-inner_scope.rs:7:8
|
||||
|
|
||||
LL | if bar == 2 {
|
||||
| ^^^
|
||||
|
|
||||
help: the binding `bar` is available in a different scope in the same function
|
||||
--> $DIR/issue-104700-inner_scope.rs:4:13
|
||||
|
|
||||
LL | let bar = 2;
|
||||
| ^^^
|
||||
|
||||
error[E0425]: cannot find function `test_func` in this scope
|
||||
--> $DIR/issue-104700-inner_scope.rs:10:5
|
||||
|
|
||||
LL | test_func(1);
|
||||
| ^^^^^^^^^ not found in this scope
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0425`.
|
@ -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…
Reference in New Issue
Block a user