mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Point at expressions where inference refines an unexpected type
Address #106355.
This commit is contained in:
parent
1d284af117
commit
ea43eb3721
@ -4,6 +4,7 @@ use rustc_errors::MultiSpan;
|
|||||||
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
|
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::CtorKind;
|
use rustc_hir::def::CtorKind;
|
||||||
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::{is_range_literal, Node};
|
use rustc_hir::{is_range_literal, Node};
|
||||||
use rustc_infer::infer::InferOk;
|
use rustc_infer::infer::InferOk;
|
||||||
@ -11,8 +12,11 @@ use rustc_middle::lint::in_external_macro;
|
|||||||
use rustc_middle::middle::stability::EvalResult;
|
use rustc_middle::middle::stability::EvalResult;
|
||||||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
use rustc_middle::ty::fold::TypeFolder;
|
||||||
use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut};
|
use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
|
||||||
|
use rustc_middle::ty::{
|
||||||
|
self, Article, AssocItem, Ty, TyCtxt, TypeAndMut, TypeSuperFoldable, TypeVisitable,
|
||||||
|
};
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
use rustc_span::{BytePos, Span};
|
use rustc_span::{BytePos, Span};
|
||||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||||
@ -53,7 +57,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|| self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
|
|| self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
|
||||||
|| self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
|
|| self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
|
||||||
|| self.suggest_into(err, expr, expr_ty, expected)
|
|| self.suggest_into(err, expr, expr_ty, expected)
|
||||||
|| self.suggest_floating_point_literal(err, expr, expected);
|
|| self.suggest_floating_point_literal(err, expr, expected)
|
||||||
|
|| self.point_inference_types(err, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn emit_coerce_suggestions(
|
pub fn emit_coerce_suggestions(
|
||||||
@ -205,6 +210,157 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
(expected, Some(err))
|
(expected, Some(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn point_inference_types(&self, err: &mut Diagnostic, expr: &hir::Expr<'_>) -> bool {
|
||||||
|
let tcx = self.tcx;
|
||||||
|
let map = self.tcx.hir();
|
||||||
|
|
||||||
|
// Hack to make equality checks on types with inference variables and regions useful.
|
||||||
|
struct TypeEraser<'tcx> {
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
}
|
||||||
|
impl<'tcx> TypeFolder<'tcx> for TypeEraser<'tcx> {
|
||||||
|
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||||
|
self.tcx
|
||||||
|
}
|
||||||
|
fn fold_region(&mut self, _r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
|
self.tcx().lifetimes.re_erased
|
||||||
|
}
|
||||||
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
|
if !t.needs_infer() && !t.has_erasable_regions() {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
match *t.kind() {
|
||||||
|
ty::Infer(ty::TyVar(_) | ty::FreshTy(_)) => {
|
||||||
|
self.tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0)))
|
||||||
|
}
|
||||||
|
ty::Infer(ty::IntVar(_) | ty::FreshIntTy(_)) => {
|
||||||
|
self.tcx.mk_ty_infer(ty::IntVar(ty::IntVid { index: 0 }))
|
||||||
|
}
|
||||||
|
ty::Infer(ty::FloatVar(_) | ty::FreshFloatTy(_)) => {
|
||||||
|
self.tcx.mk_ty_infer(ty::FloatVar(ty::FloatVid { index: 0 }))
|
||||||
|
}
|
||||||
|
_ => t.super_fold_with(self),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||||
|
ct.super_fold_with(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind else { return false; };
|
||||||
|
let [hir::PathSegment { ident, args: None, .. }] = p.segments else { return false; };
|
||||||
|
let hir::def::Res::Local(hir_id) = p.res else { return false; };
|
||||||
|
let Some(node) = map.find(hir_id) else { return false; };
|
||||||
|
let hir::Node::Pat(pat) = node else { return false; };
|
||||||
|
let parent = map.get_parent_node(pat.hir_id);
|
||||||
|
let Some(hir::Node::Local(hir::Local {
|
||||||
|
ty: None,
|
||||||
|
init: Some(init),
|
||||||
|
..
|
||||||
|
})) = map.find(parent) else { return false; };
|
||||||
|
|
||||||
|
let ty = self.node_ty(init.hir_id);
|
||||||
|
if ty.is_closure() || init.span.overlaps(expr.span) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let mut span_labels = vec![(
|
||||||
|
init.span,
|
||||||
|
with_forced_trimmed_paths!(format!(
|
||||||
|
"here the type of `{ident}` is inferred to be `{ty}`",
|
||||||
|
)),
|
||||||
|
)];
|
||||||
|
|
||||||
|
// Locate all the usages of the relevant binding.
|
||||||
|
struct FindExprs<'hir> {
|
||||||
|
hir_id: hir::HirId,
|
||||||
|
uses: Vec<&'hir hir::Expr<'hir>>,
|
||||||
|
}
|
||||||
|
impl<'v> Visitor<'v> for FindExprs<'v> {
|
||||||
|
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
|
||||||
|
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = ex.kind
|
||||||
|
&& let hir::def::Res::Local(hir_id) = path.res
|
||||||
|
&& hir_id == self.hir_id
|
||||||
|
{
|
||||||
|
self.uses.push(ex);
|
||||||
|
}
|
||||||
|
hir::intravisit::walk_expr(self, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut expr_finder = FindExprs { hir_id, uses: vec![] };
|
||||||
|
let id = map.get_parent_item(hir_id);
|
||||||
|
let hir_id: hir::HirId = id.into();
|
||||||
|
|
||||||
|
if let Some(node) = map.find(hir_id) && let Some(body_id) = node.body_id() {
|
||||||
|
let body = map.body(body_id);
|
||||||
|
expr_finder.visit_expr(body.value);
|
||||||
|
let mut eraser = TypeEraser { tcx };
|
||||||
|
let mut prev = eraser.fold_ty(ty);
|
||||||
|
|
||||||
|
for ex in expr_finder.uses {
|
||||||
|
if ex.span.overlaps(expr.span) { break; }
|
||||||
|
let parent = map.get_parent_node(ex.hir_id);
|
||||||
|
if let Some(hir::Node::Expr(expr))
|
||||||
|
| Some(hir::Node::Stmt(hir::Stmt {
|
||||||
|
kind: hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr),
|
||||||
|
..
|
||||||
|
})) = &map.find(parent)
|
||||||
|
&& let hir::ExprKind::MethodCall(s, rcvr, args, span) = expr.kind
|
||||||
|
&& rcvr.hir_id == ex.hir_id
|
||||||
|
{
|
||||||
|
let ty = if let Ok(m) = self.lookup_method(ty, s, span, expr, rcvr, args) {
|
||||||
|
// We get the self type from `lookup_method` because the `rcvr` node
|
||||||
|
// type will not have had any adjustments from the fn arguments.
|
||||||
|
let ty = m.sig.inputs_and_output[0];
|
||||||
|
match ty.kind() {
|
||||||
|
// Remove one layer of references to account for `&mut self` and
|
||||||
|
// `&self`, so that we can compare it against the binding.
|
||||||
|
ty::Ref(_, ty, _) => *ty,
|
||||||
|
_ => ty,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.node_ty(rcvr.hir_id)
|
||||||
|
};
|
||||||
|
let ty = eraser.fold_ty(ty);
|
||||||
|
if ty.references_error() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ty != prev {
|
||||||
|
span_labels.push((
|
||||||
|
s.ident.span,
|
||||||
|
with_forced_trimmed_paths!(format!(
|
||||||
|
"here the type of `{ident}` is inferred to be `{ty}`",
|
||||||
|
)),
|
||||||
|
));
|
||||||
|
prev = ty;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let ty = eraser.fold_ty(self.node_ty(ex.hir_id));
|
||||||
|
if ty.references_error() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ty != prev {
|
||||||
|
span_labels.push((
|
||||||
|
ex.span,
|
||||||
|
with_forced_trimmed_paths!(format!(
|
||||||
|
"here the type of `{ident}` is inferred to be `{ty}`",
|
||||||
|
)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
prev = ty;
|
||||||
|
}
|
||||||
|
if ex.hir_id == expr.hir_id {
|
||||||
|
// Stop showing spans after the error type was emitted.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (sp, label) in span_labels {
|
||||||
|
err.span_label(sp, &label);
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn annotate_expected_due_to_let_ty(
|
fn annotate_expected_due_to_let_ty(
|
||||||
&self,
|
&self,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
error[E0308]: arguments to this function are incorrect
|
error[E0308]: arguments to this function are incorrect
|
||||||
--> $DIR/two-mismatch-notes.rs:10:5
|
--> $DIR/two-mismatch-notes.rs:10:5
|
||||||
|
|
|
|
||||||
|
LL | let w = Wrapper::<isize>(1isize);
|
||||||
|
| ------------------------ here the type of `w` is inferred to be `Wrapper<isize>`
|
||||||
LL | foo(f, w);
|
LL | foo(f, w);
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/dont-suggest-missing-await.rs:14:18
|
--> $DIR/dont-suggest-missing-await.rs:14:18
|
||||||
|
|
|
|
||||||
|
LL | let x = make_u32();
|
||||||
|
| ---------- here the type of `x` is inferred to be `impl Future<Output = u32>`
|
||||||
LL | take_u32(x)
|
LL | take_u32(x)
|
||||||
| -------- ^ expected `u32`, found opaque type
|
| -------- ^ expected `u32`, found opaque type
|
||||||
| |
|
| |
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/suggest-missing-await-closure.rs:16:18
|
--> $DIR/suggest-missing-await-closure.rs:16:18
|
||||||
|
|
|
|
||||||
|
LL | let x = make_u32();
|
||||||
|
| ---------- here the type of `x` is inferred to be `impl Future<Output = u32>`
|
||||||
LL | take_u32(x)
|
LL | take_u32(x)
|
||||||
| -------- ^ expected `u32`, found opaque type
|
| -------- ^ expected `u32`, found opaque type
|
||||||
| |
|
| |
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/suggest-missing-await.rs:12:14
|
--> $DIR/suggest-missing-await.rs:12:14
|
||||||
|
|
|
|
||||||
|
LL | let x = make_u32();
|
||||||
|
| ---------- here the type of `x` is inferred to be `impl Future<Output = u32>`
|
||||||
LL | take_u32(x)
|
LL | take_u32(x)
|
||||||
| -------- ^ expected `u32`, found opaque type
|
| -------- ^ expected `u32`, found opaque type
|
||||||
| |
|
| |
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/closure-return-type-mismatch.rs:7:9
|
--> $DIR/closure-return-type-mismatch.rs:7:9
|
||||||
|
|
|
|
||||||
|
LL | let a = true;
|
||||||
|
| ---- here the type of `a` is inferred to be `bool`
|
||||||
LL | a
|
LL | a
|
||||||
| ^ expected `&str`, found `bool`
|
| ^ expected `&str`, found `bool`
|
||||||
|
|
|
|
||||||
|
@ -33,6 +33,9 @@ LL | fn foo(x: usize, y: !, z: usize) { }
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/coerce-to-bang.rs:26:12
|
--> $DIR/coerce-to-bang.rs:26:12
|
||||||
|
|
|
|
||||||
|
LL | let b = 22;
|
||||||
|
| -- here the type of `b` is inferred to be `{integer}`
|
||||||
|
LL | let c = 44;
|
||||||
LL | foo(a, b, c); // ... and hence a reference to `a` is expected to diverge.
|
LL | foo(a, b, c); // ... and hence a reference to `a` is expected to diverge.
|
||||||
| --- ^ expected `!`, found integer
|
| --- ^ expected `!`, found integer
|
||||||
| |
|
| |
|
||||||
@ -49,6 +52,9 @@ LL | fn foo(x: usize, y: !, z: usize) { }
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/coerce-to-bang.rs:36:12
|
--> $DIR/coerce-to-bang.rs:36:12
|
||||||
|
|
|
|
||||||
|
LL | let b = 22;
|
||||||
|
| -- here the type of `b` is inferred to be `{integer}`
|
||||||
|
LL | let c = 44;
|
||||||
LL | foo(a, b, c);
|
LL | foo(a, b, c);
|
||||||
| --- ^ expected `!`, found integer
|
| --- ^ expected `!`, found integer
|
||||||
| |
|
| |
|
||||||
@ -65,6 +71,9 @@ LL | fn foo(x: usize, y: !, z: usize) { }
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/coerce-to-bang.rs:45:12
|
--> $DIR/coerce-to-bang.rs:45:12
|
||||||
|
|
|
|
||||||
|
LL | let b = 22;
|
||||||
|
| -- here the type of `b` is inferred to be `{integer}`
|
||||||
|
LL | let c = 44;
|
||||||
LL | foo(a, b, c);
|
LL | foo(a, b, c);
|
||||||
| --- ^ expected `!`, found integer
|
| --- ^ expected `!`, found integer
|
||||||
| |
|
| |
|
||||||
|
@ -4,6 +4,9 @@ error[E0308]: mismatched types
|
|||||||
LL | fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
|
LL | fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
|
||||||
| ------------------------------------ expected `<C as Collection<i32>>::Sibling<f32>` because of return type
|
| ------------------------------------ expected `<C as Collection<i32>>::Sibling<f32>` because of return type
|
||||||
...
|
...
|
||||||
|
LL | let mut res = <C::Family as CollectionFamily>::Member::<f32>::empty();
|
||||||
|
| ------------------------------------------------------- here the type of `res` is inferred to be `<<C as Collection<i32>>::Family as CollectionFamily>::Member<f32>`
|
||||||
|
...
|
||||||
LL | res
|
LL | res
|
||||||
| ^^^ expected Collection::Sibling, found CollectionFamily::Member
|
| ^^^ expected Collection::Sibling, found CollectionFamily::Member
|
||||||
|
|
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/issue-15783.rs:8:19
|
--> $DIR/issue-15783.rs:8:19
|
||||||
|
|
|
|
||||||
|
LL | let x = Some(&[name]);
|
||||||
|
| ------------- here the type of `x` is inferred to be `Option<_>`
|
||||||
LL | let msg = foo(x);
|
LL | let msg = foo(x);
|
||||||
| --- ^ expected slice `[&str]`, found array `[&str; 1]`
|
| --- ^ expected slice `[&str]`, found array `[&str; 1]`
|
||||||
| |
|
| |
|
||||||
|
@ -19,6 +19,12 @@ LL | let Some(ref a): Option<&[u8]> = &some else { return };
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/let-else-ref-bindings.rs:24:34
|
--> $DIR/let-else-ref-bindings.rs:24:34
|
||||||
|
|
|
|
||||||
|
LL | let some = Some(bytes);
|
||||||
|
| ----------- here the type of `some` is inferred to be `Option<_>`
|
||||||
|
...
|
||||||
|
LL | let Some(ref a): Option<&[u8]> = some else { return };
|
||||||
|
| ---- here the type of `some` is inferred to be `Option<Vec<u8>>`
|
||||||
|
...
|
||||||
LL | let Some(a): Option<&[u8]> = some else { return };
|
LL | let Some(a): Option<&[u8]> = some else { return };
|
||||||
| ------------- ^^^^ expected `&[u8]`, found struct `Vec`
|
| ------------- ^^^^ expected `&[u8]`, found struct `Vec`
|
||||||
| |
|
| |
|
||||||
@ -59,6 +65,12 @@ LL | let Some(ref mut a): Option<&mut [u8]> = &mut some else { return };
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/let-else-ref-bindings.rs:52:38
|
--> $DIR/let-else-ref-bindings.rs:52:38
|
||||||
|
|
|
|
||||||
|
LL | let mut some = Some(bytes);
|
||||||
|
| ----------- here the type of `some` is inferred to be `Option<_>`
|
||||||
|
...
|
||||||
|
LL | let Some(ref mut a): Option<&mut [u8]> = some else { return };
|
||||||
|
| ---- here the type of `some` is inferred to be `Option<Vec<u8>>`
|
||||||
|
...
|
||||||
LL | let Some(a): Option<&mut [u8]> = some else { return };
|
LL | let Some(a): Option<&mut [u8]> = some else { return };
|
||||||
| ----------------- ^^^^ expected `&mut [u8]`, found struct `Vec`
|
| ----------------- ^^^^ expected `&mut [u8]`, found struct `Vec`
|
||||||
| |
|
| |
|
||||||
|
@ -10,6 +10,9 @@ LL | #![feature(unsized_locals, unsized_fn_params)]
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:87:24
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:87:24
|
||||||
|
|
|
|
||||||
|
LL | let z = x.foo();
|
||||||
|
| ------- here the type of `z` is inferred to be `u32`
|
||||||
|
...
|
||||||
LL | let _seetype: () = z;
|
LL | let _seetype: () = z;
|
||||||
| -- ^ expected `()`, found `u32`
|
| -- ^ expected `()`, found `u32`
|
||||||
| |
|
| |
|
||||||
@ -18,6 +21,9 @@ LL | let _seetype: () = z;
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:104:24
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:104:24
|
||||||
|
|
|
|
||||||
|
LL | let z = x.foo();
|
||||||
|
| ------- here the type of `z` is inferred to be `u64`
|
||||||
|
...
|
||||||
LL | let _seetype: () = z;
|
LL | let _seetype: () = z;
|
||||||
| -- ^ expected `()`, found `u64`
|
| -- ^ expected `()`, found `u64`
|
||||||
| |
|
| |
|
||||||
@ -60,6 +66,9 @@ LL | let z = FinalFoo::foo(x);
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:139:24
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:139:24
|
||||||
|
|
|
|
||||||
|
LL | let z = x.foo();
|
||||||
|
| ------- here the type of `z` is inferred to be `u8`
|
||||||
|
...
|
||||||
LL | let _seetype: () = z;
|
LL | let _seetype: () = z;
|
||||||
| -- ^ expected `()`, found `u8`
|
| -- ^ expected `()`, found `u8`
|
||||||
| |
|
| |
|
||||||
@ -68,6 +77,9 @@ LL | let _seetype: () = z;
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:157:24
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:157:24
|
||||||
|
|
|
|
||||||
|
LL | let z = x.foo();
|
||||||
|
| ------- here the type of `z` is inferred to be `u32`
|
||||||
|
...
|
||||||
LL | let _seetype: () = z;
|
LL | let _seetype: () = z;
|
||||||
| -- ^ expected `()`, found `u32`
|
| -- ^ expected `()`, found `u32`
|
||||||
| |
|
| |
|
||||||
@ -76,6 +88,9 @@ LL | let _seetype: () = z;
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:174:24
|
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:174:24
|
||||||
|
|
|
|
||||||
|
LL | let z = x.foo();
|
||||||
|
| ------- here the type of `z` is inferred to be `u32`
|
||||||
|
...
|
||||||
LL | let _seetype: () = z;
|
LL | let _seetype: () = z;
|
||||||
| -- ^ expected `()`, found `u32`
|
| -- ^ expected `()`, found `u32`
|
||||||
| |
|
| |
|
||||||
|
@ -53,11 +53,19 @@ LL | Ok(Foo { bar: 1 })
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/abridged.rs:39:5
|
--> $DIR/abridged.rs:39:5
|
||||||
|
|
|
|
||||||
LL | fn d() -> X<X<String, String>, String> {
|
LL | fn d() -> X<X<String, String>, String> {
|
||||||
| ---------------------------- expected `X<X<String, String>, String>` because of return type
|
| ---------------------------- expected `X<X<String, String>, String>` because of return type
|
||||||
...
|
LL | let x = X {
|
||||||
LL | x
|
| _____________-
|
||||||
| ^ expected struct `String`, found integer
|
LL | | x: X {
|
||||||
|
LL | | x: "".to_string(),
|
||||||
|
LL | | y: 2,
|
||||||
|
LL | | },
|
||||||
|
LL | | y: 3,
|
||||||
|
LL | | };
|
||||||
|
| |_____- here the type of `x` is inferred to be `X<_, _>`
|
||||||
|
LL | x
|
||||||
|
| ^ expected struct `String`, found integer
|
||||||
|
|
|
|
||||||
= note: expected struct `X<X<_, String>, String>`
|
= note: expected struct `X<X<_, String>, String>`
|
||||||
found struct `X<X<_, {integer}>, {integer}>`
|
found struct `X<X<_, {integer}>, {integer}>`
|
||||||
@ -65,11 +73,19 @@ LL | x
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/abridged.rs:50:5
|
--> $DIR/abridged.rs:50:5
|
||||||
|
|
|
|
||||||
LL | fn e() -> X<X<String, String>, String> {
|
LL | fn e() -> X<X<String, String>, String> {
|
||||||
| ---------------------------- expected `X<X<String, String>, String>` because of return type
|
| ---------------------------- expected `X<X<String, String>, String>` because of return type
|
||||||
...
|
LL | let x = X {
|
||||||
LL | x
|
| _____________-
|
||||||
| ^ expected struct `String`, found integer
|
LL | | x: X {
|
||||||
|
LL | | x: "".to_string(),
|
||||||
|
LL | | y: 2,
|
||||||
|
LL | | },
|
||||||
|
LL | | y: "".to_string(),
|
||||||
|
LL | | };
|
||||||
|
| |_____- here the type of `x` is inferred to be `X<_, _>`
|
||||||
|
LL | x
|
||||||
|
| ^ expected struct `String`, found integer
|
||||||
|
|
|
|
||||||
= note: expected struct `X<X<_, String>, _>`
|
= note: expected struct `X<X<_, String>, _>`
|
||||||
found struct `X<X<_, {integer}>, _>`
|
found struct `X<X<_, {integer}>, _>`
|
||||||
|
@ -51,6 +51,8 @@ LL | if x == E::V { field } {}
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/struct-literal-variant-in-if.rs:10:20
|
--> $DIR/struct-literal-variant-in-if.rs:10:20
|
||||||
|
|
|
|
||||||
|
LL | let field = true;
|
||||||
|
| ---- here the type of `field` is inferred to be `bool`
|
||||||
LL | if x == E::V { field } {}
|
LL | if x == E::V { field } {}
|
||||||
| ---------------^^^^^--
|
| ---------------^^^^^--
|
||||||
| | |
|
| | |
|
||||||
|
@ -100,6 +100,12 @@ LL | let Some(n) = opt && let another = n else {
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:9:19
|
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:9:19
|
||||||
|
|
|
|
||||||
|
LL | let opt = Some(1i32);
|
||||||
|
| ---------- here the type of `opt` is inferred to be `Option<_>`
|
||||||
|
LL |
|
||||||
|
LL | let Some(n) = opt else {
|
||||||
|
| --- here the type of `opt` is inferred to be `Option<i32>`
|
||||||
|
...
|
||||||
LL | let Some(n) = opt && n == 1 else {
|
LL | let Some(n) = opt && n == 1 else {
|
||||||
| ^^^ expected `bool`, found enum `Option`
|
| ^^^ expected `bool`, found enum `Option`
|
||||||
|
|
|
|
||||||
@ -120,6 +126,12 @@ LL | let Some(n) = opt && n == 1 else {
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:19
|
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:19
|
||||||
|
|
|
|
||||||
|
LL | let opt = Some(1i32);
|
||||||
|
| ---------- here the type of `opt` is inferred to be `Option<_>`
|
||||||
|
LL |
|
||||||
|
LL | let Some(n) = opt else {
|
||||||
|
| --- here the type of `opt` is inferred to be `Option<i32>`
|
||||||
|
...
|
||||||
LL | let Some(n) = opt && let another = n else {
|
LL | let Some(n) = opt && let another = n else {
|
||||||
| ^^^ expected `bool`, found enum `Option`
|
| ^^^ expected `bool`, found enum `Option`
|
||||||
|
|
|
|
||||||
|
@ -63,7 +63,10 @@ error[E0308]: mismatched types
|
|||||||
--> $DIR/coerce-suggestions.rs:21:9
|
--> $DIR/coerce-suggestions.rs:21:9
|
||||||
|
|
|
|
||||||
LL | s = format!("foo");
|
LL | s = format!("foo");
|
||||||
| ^^^^^^^^^^^^^^ expected `&mut String`, found struct `String`
|
| ^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| expected `&mut String`, found struct `String`
|
||||||
|
| here the type of `res` is inferred to be `String`
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
@ -2,7 +2,10 @@ error[E0308]: mismatched types
|
|||||||
--> $DIR/issue-33884.rs:6:22
|
--> $DIR/issue-33884.rs:6:22
|
||||||
|
|
|
|
||||||
LL | stream.write_fmt(format!("message received"))
|
LL | stream.write_fmt(format!("message received"))
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Arguments`, found struct `String`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| expected struct `Arguments`, found struct `String`
|
||||||
|
| here the type of `res` is inferred to be `String`
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ LL | static foo_i: Foo = Foo { a: 2, ..4 };
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/struct-base-wrong-type.rs:12:27
|
--> $DIR/struct-base-wrong-type.rs:12:27
|
||||||
|
|
|
|
||||||
|
LL | let b = Bar { x: 5 };
|
||||||
|
| ------------ here the type of `b` is inferred to be `Bar`
|
||||||
LL | let f = Foo { a: 2, ..b };
|
LL | let f = Foo { a: 2, ..b };
|
||||||
| ^ expected struct `Foo`, found struct `Bar`
|
| ^ expected struct `Foo`, found struct `Bar`
|
||||||
|
|
||||||
|
@ -4,7 +4,10 @@ error[E0308]: mismatched types
|
|||||||
LL | let mut x = 1i32;
|
LL | let mut x = 1i32;
|
||||||
| ---- expected due to this value
|
| ---- expected due to this value
|
||||||
LL | let y = Box::new(|| 1);
|
LL | let y = Box::new(|| 1);
|
||||||
| -- the found closure
|
| --------------
|
||||||
|
| | |
|
||||||
|
| | the found closure
|
||||||
|
| here the type of `y` is inferred to be `Box<_>`
|
||||||
LL | x = y;
|
LL | x = y;
|
||||||
| ^ expected `i32`, found struct `Box`
|
| ^ expected `i32`, found struct `Box`
|
||||||
|
|
|
|
||||||
|
@ -4,7 +4,10 @@ error[E0308]: mismatched types
|
|||||||
LL | / intrinsic_match! {
|
LL | / intrinsic_match! {
|
||||||
LL | | "abc"
|
LL | | "abc"
|
||||||
LL | | };
|
LL | | };
|
||||||
| |_____^ expected `&str`, found struct `String`
|
| | ^
|
||||||
|
| | |
|
||||||
|
| |_____expected `&str`, found struct `String`
|
||||||
|
| here the type of `res` is inferred to be `String`
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `format` which comes from the expansion of the macro `intrinsic_match` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `format` which comes from the expansion of the macro `intrinsic_match` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@ LL | let _s = S { _s: ("abc".to_string(),) };
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/issue-86100-tuple-paren-comma.rs:23:22
|
--> $DIR/issue-86100-tuple-paren-comma.rs:23:22
|
||||||
|
|
|
|
||||||
|
LL | let t = (1, 2);
|
||||||
|
| ------ here the type of `t` is inferred to be `({integer}, {integer})`
|
||||||
LL | let _x: (i32,) = (t);
|
LL | let _x: (i32,) = (t);
|
||||||
| ------ ^^^ expected a tuple with 1 element, found one with 2 elements
|
| ------ ^^^ expected a tuple with 1 element, found one with 2 elements
|
||||||
| |
|
| |
|
||||||
|
@ -4,6 +4,8 @@ error[E0308]: mismatched types
|
|||||||
LL | impl<F, Name, P> AddClass<Name, F> for Class<P>
|
LL | impl<F, Name, P> AddClass<Name, F> for Class<P>
|
||||||
| - this type parameter
|
| - this type parameter
|
||||||
...
|
...
|
||||||
|
LL | let output = builder.to_ref();
|
||||||
|
| ---------------- here the type of `output` is inferred to be `Class<P>`
|
||||||
LL | builder.push(output);
|
LL | builder.push(output);
|
||||||
| ---- ^^^^^^ expected type parameter `F`, found struct `Class`
|
| ---- ^^^^^^ expected type parameter `F`, found struct `Class`
|
||||||
| |
|
| |
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
error[E0061]: this method takes 1 argument but 2 arguments were supplied
|
error[E0061]: this method takes 1 argument but 2 arguments were supplied
|
||||||
--> $DIR/wrong_argument_ice-3.rs:9:16
|
--> $DIR/wrong_argument_ice-3.rs:9:16
|
||||||
|
|
|
|
||||||
|
LL | let new_group = vec![String::new()];
|
||||||
|
| ------------------- here the type of `new_group` is inferred to be `Vec<_, _>`
|
||||||
|
...
|
||||||
LL | groups.push(new_group, vec![process]);
|
LL | groups.push(new_group, vec![process]);
|
||||||
| ^^^^ ------------- argument of type `Vec<&Process>` unexpected
|
| ^^^^ ------------- argument of type `Vec<&Process>` unexpected
|
||||||
|
|
|
|
||||||
|
@ -67,6 +67,12 @@ LL | x == 5
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/assignment-in-if.rs:44:18
|
--> $DIR/assignment-in-if.rs:44:18
|
||||||
|
|
|
|
||||||
|
LL | let x = 1;
|
||||||
|
| - here the type of `x` is inferred to be `{integer}`
|
||||||
|
...
|
||||||
|
LL | println!("{}", x);
|
||||||
|
| - here the type of `x` is inferred to be `usize`
|
||||||
|
...
|
||||||
LL | if x == x && x = x && x == x {
|
LL | if x == x && x = x && x == x {
|
||||||
| ------ ^ expected `bool`, found `usize`
|
| ------ ^ expected `bool`, found `usize`
|
||||||
| |
|
| |
|
||||||
@ -75,6 +81,12 @@ LL | if x == x && x = x && x == x {
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/assignment-in-if.rs:44:22
|
--> $DIR/assignment-in-if.rs:44:22
|
||||||
|
|
|
|
||||||
|
LL | let x = 1;
|
||||||
|
| - here the type of `x` is inferred to be `{integer}`
|
||||||
|
...
|
||||||
|
LL | println!("{}", x);
|
||||||
|
| - here the type of `x` is inferred to be `usize`
|
||||||
|
...
|
||||||
LL | if x == x && x = x && x == x {
|
LL | if x == x && x = x && x == x {
|
||||||
| ^ expected `bool`, found `usize`
|
| ^ expected `bool`, found `usize`
|
||||||
|
|
||||||
@ -92,6 +104,12 @@ LL | if x == x && x == x && x == x {
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/assignment-in-if.rs:51:28
|
--> $DIR/assignment-in-if.rs:51:28
|
||||||
|
|
|
|
||||||
|
LL | let x = 1;
|
||||||
|
| - here the type of `x` is inferred to be `{integer}`
|
||||||
|
...
|
||||||
|
LL | println!("{}", x);
|
||||||
|
| - here the type of `x` is inferred to be `usize`
|
||||||
|
...
|
||||||
LL | if x == x && x == x && x = x {
|
LL | if x == x && x == x && x = x {
|
||||||
| ---------------- ^ expected `bool`, found `usize`
|
| ---------------- ^ expected `bool`, found `usize`
|
||||||
| |
|
| |
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/type-mismatch-same-crate-name.rs:16:20
|
--> $DIR/type-mismatch-same-crate-name.rs:16:20
|
||||||
|
|
|
|
||||||
|
LL | let foo2 = {extern crate crate_a2 as a; a::Foo};
|
||||||
|
| ------------------------------------ here the type of `foo2` is inferred to be `_`
|
||||||
|
...
|
||||||
LL | a::try_foo(foo2);
|
LL | a::try_foo(foo2);
|
||||||
| ---------- ^^^^ expected struct `main::a::Foo`, found a different struct `main::a::Foo`
|
| ---------- ^^^^ expected struct `main::a::Foo`, found a different struct `main::a::Foo`
|
||||||
| |
|
| |
|
||||||
@ -27,6 +30,9 @@ LL | pub fn try_foo(x: Foo){}
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/type-mismatch-same-crate-name.rs:20:20
|
--> $DIR/type-mismatch-same-crate-name.rs:20:20
|
||||||
|
|
|
|
||||||
|
LL | let bar2 = {extern crate crate_a2 as a; a::bar()};
|
||||||
|
| -------------------------------------- here the type of `bar2` is inferred to be `_`
|
||||||
|
...
|
||||||
LL | a::try_bar(bar2);
|
LL | a::try_bar(bar2);
|
||||||
| ---------- ^^^^ expected trait `main::a::Bar`, found a different trait `main::a::Bar`
|
| ---------- ^^^^ expected trait `main::a::Bar`, found a different trait `main::a::Bar`
|
||||||
| |
|
| |
|
||||||
|
Loading…
Reference in New Issue
Block a user