Rollup merge of #128110 - veera-sivarajan:bugfix-80173, r=cjgillot
Suggest Replacing Comma with Semicolon in Incorrect Repeat Expressions Fixes #80173 This PR detects typos in repeat expressions like `["_", 10]` and `vec![String::new(), 10]` and suggests replacing comma with semicolon. Also, improves code in other place by adding doc comments and making use of a helper function to check if a type implements `Clone`. References: 1. For `vec![T; N]`: https://doc.rust-lang.org/std/macro.vec.html 2. For `[T; N]`: https://doc.rust-lang.org/std/primitive.array.html
This commit is contained in:
commit
e4e2d9ceb8
9 changed files with 324 additions and 11 deletions
|
@ -7,7 +7,7 @@ use rustc_ast::token::CommentKind;
|
||||||
use rustc_ast::util::parser::{AssocOp, ExprPrecedence};
|
use rustc_ast::util::parser::{AssocOp, ExprPrecedence};
|
||||||
use rustc_ast::{
|
use rustc_ast::{
|
||||||
self as ast, AttrId, AttrStyle, DelimArgs, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece,
|
self as ast, AttrId, AttrStyle, DelimArgs, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece,
|
||||||
IntTy, Label, LitKind, MetaItemInner, MetaItemLit, TraitObjectSyntax, UintTy,
|
IntTy, Label, LitIntType, LitKind, MetaItemInner, MetaItemLit, TraitObjectSyntax, UintTy,
|
||||||
};
|
};
|
||||||
pub use rustc_ast::{
|
pub use rustc_ast::{
|
||||||
BinOp, BinOpKind, BindingMode, BorrowKind, BoundConstness, BoundPolarity, ByRef, CaptureBy,
|
BinOp, BinOpKind, BindingMode, BorrowKind, BoundConstness, BoundPolarity, ByRef, CaptureBy,
|
||||||
|
@ -2094,6 +2094,18 @@ impl Expr<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if expression is an integer literal that can be used
|
||||||
|
/// where `usize` is expected.
|
||||||
|
pub fn is_size_lit(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self.kind,
|
||||||
|
ExprKind::Lit(Lit {
|
||||||
|
node: LitKind::Int(_, LitIntType::Unsuffixed | LitIntType::Unsigned(UintTy::Usize)),
|
||||||
|
..
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// If `Self.kind` is `ExprKind::DropTemps(expr)`, drill down until we get a non-`DropTemps`
|
/// If `Self.kind` is `ExprKind::DropTemps(expr)`, drill down until we get a non-`DropTemps`
|
||||||
/// `Expr`. This is used in suggestions to ignore this `ExprKind` as it is semantically
|
/// `Expr`. This is used in suggestions to ignore this `ExprKind` as it is semantically
|
||||||
/// silent, only signaling the ownership system. By doing this, suggestions that check the
|
/// silent, only signaling the ownership system. By doing this, suggestions that check the
|
||||||
|
|
|
@ -165,6 +165,8 @@ hir_typeck_remove_semi_for_coerce_ret = the `match` arms can conform to this ret
|
||||||
hir_typeck_remove_semi_for_coerce_semi = the `match` is a statement because of this semicolon, consider removing it
|
hir_typeck_remove_semi_for_coerce_semi = the `match` is a statement because of this semicolon, consider removing it
|
||||||
hir_typeck_remove_semi_for_coerce_suggestion = remove this semicolon
|
hir_typeck_remove_semi_for_coerce_suggestion = remove this semicolon
|
||||||
|
|
||||||
|
hir_typeck_replace_comma_with_semicolon = replace the comma with a semicolon to create {$descr}
|
||||||
|
|
||||||
hir_typeck_return_stmt_outside_of_fn_body =
|
hir_typeck_return_stmt_outside_of_fn_body =
|
||||||
{$statement_kind} statement outside of function body
|
{$statement_kind} statement outside of function body
|
||||||
.encl_body_label = the {$statement_kind} is part of this body...
|
.encl_body_label = the {$statement_kind} is part of this body...
|
||||||
|
|
|
@ -30,7 +30,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
if expr_ty == expected {
|
if expr_ty == expected {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.annotate_alternative_method_deref(err, expr, error);
|
self.annotate_alternative_method_deref(err, expr, error);
|
||||||
self.explain_self_literal(err, expr, expected, expr_ty);
|
self.explain_self_literal(err, expr, expected, expr_ty);
|
||||||
|
|
||||||
|
@ -39,6 +38,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|| self.suggest_missing_unwrap_expect(err, expr, expected, expr_ty)
|
|| self.suggest_missing_unwrap_expect(err, expr, expected, expr_ty)
|
||||||
|| self.suggest_remove_last_method_call(err, expr, expected)
|
|| self.suggest_remove_last_method_call(err, expr, expected)
|
||||||
|| self.suggest_associated_const(err, expr, expected)
|
|| self.suggest_associated_const(err, expr, expected)
|
||||||
|
|| self.suggest_semicolon_in_repeat_expr(err, expr, expr_ty)
|
||||||
|| self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr)
|
|| self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr)
|
||||||
|| self.suggest_option_to_bool(err, expr, expr_ty, expected)
|
|| self.suggest_option_to_bool(err, expr, expr_ty, expected)
|
||||||
|| self.suggest_compatible_variants(err, expr, expected, expr_ty)
|
|| self.suggest_compatible_variants(err, expr, expected, expr_ty)
|
||||||
|
|
|
@ -846,3 +846,16 @@ pub(crate) struct PassFnItemToVariadicFunction {
|
||||||
pub sugg_span: Span,
|
pub sugg_span: Span,
|
||||||
pub replace: String,
|
pub replace: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
#[suggestion(
|
||||||
|
hir_typeck_replace_comma_with_semicolon,
|
||||||
|
applicability = "machine-applicable",
|
||||||
|
style = "verbose",
|
||||||
|
code = "; "
|
||||||
|
)]
|
||||||
|
pub(crate) struct ReplaceCommaWithSemicolon {
|
||||||
|
#[primary_span]
|
||||||
|
pub comma_span: Span,
|
||||||
|
pub descr: &'static str,
|
||||||
|
}
|
||||||
|
|
|
@ -1320,14 +1320,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let span = expr.span.shrink_to_hi();
|
let span = expr.span.shrink_to_hi();
|
||||||
let subdiag = if self.type_is_copy_modulo_regions(self.param_env, ty) {
|
let subdiag = if self.type_is_copy_modulo_regions(self.param_env, ty) {
|
||||||
errors::OptionResultRefMismatch::Copied { span, def_path }
|
errors::OptionResultRefMismatch::Copied { span, def_path }
|
||||||
} else if let Some(clone_did) = self.tcx.lang_items().clone_trait()
|
} else if self.type_is_clone_modulo_regions(self.param_env, ty) {
|
||||||
&& rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions(
|
|
||||||
self,
|
|
||||||
self.param_env,
|
|
||||||
ty,
|
|
||||||
clone_did,
|
|
||||||
)
|
|
||||||
{
|
|
||||||
errors::OptionResultRefMismatch::Cloned { span, def_path }
|
errors::OptionResultRefMismatch::Cloned { span, def_path }
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2182,6 +2175,87 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Suggest replacing comma with semicolon in incorrect repeat expressions
|
||||||
|
/// like `["_", 10]` or `vec![String::new(), 10]`.
|
||||||
|
pub(crate) fn suggest_semicolon_in_repeat_expr(
|
||||||
|
&self,
|
||||||
|
err: &mut Diag<'_>,
|
||||||
|
expr: &hir::Expr<'_>,
|
||||||
|
expr_ty: Ty<'tcx>,
|
||||||
|
) -> bool {
|
||||||
|
// Check if `expr` is contained in array of two elements
|
||||||
|
if let hir::Node::Expr(array_expr) = self.tcx.parent_hir_node(expr.hir_id)
|
||||||
|
&& let hir::ExprKind::Array(elements) = array_expr.kind
|
||||||
|
&& let [first, second] = &elements[..]
|
||||||
|
&& second.hir_id == expr.hir_id
|
||||||
|
{
|
||||||
|
// Span between the two elements of the array
|
||||||
|
let comma_span = first.span.between(second.span);
|
||||||
|
|
||||||
|
// Check if `expr` is a constant value of type `usize`.
|
||||||
|
// This can only detect const variable declarations and
|
||||||
|
// calls to const functions.
|
||||||
|
|
||||||
|
// Checking this here instead of rustc_hir::hir because
|
||||||
|
// this check needs access to `self.tcx` but rustc_hir
|
||||||
|
// has no access to `TyCtxt`.
|
||||||
|
let expr_is_const_usize = expr_ty.is_usize()
|
||||||
|
&& match expr.kind {
|
||||||
|
ExprKind::Path(QPath::Resolved(
|
||||||
|
None,
|
||||||
|
Path { res: Res::Def(DefKind::Const, _), .. },
|
||||||
|
)) => true,
|
||||||
|
ExprKind::Call(
|
||||||
|
Expr {
|
||||||
|
kind:
|
||||||
|
ExprKind::Path(QPath::Resolved(
|
||||||
|
None,
|
||||||
|
Path { res: Res::Def(DefKind::Fn, fn_def_id), .. },
|
||||||
|
)),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
_,
|
||||||
|
) => self.tcx.is_const_fn(*fn_def_id),
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Type of the first element is guaranteed to be checked
|
||||||
|
// when execution reaches here because `mismatched types`
|
||||||
|
// error occurs only when type of second element of array
|
||||||
|
// is not the same as type of first element.
|
||||||
|
let first_ty = self.typeck_results.borrow().expr_ty(first);
|
||||||
|
|
||||||
|
// `array_expr` is from a macro `vec!["a", 10]` if
|
||||||
|
// 1. array expression's span is imported from a macro
|
||||||
|
// 2. first element of array implements `Clone` trait
|
||||||
|
// 3. second element is an integer literal or is an expression of `usize` like type
|
||||||
|
if self.tcx.sess.source_map().is_imported(array_expr.span)
|
||||||
|
&& self.type_is_clone_modulo_regions(self.param_env, first_ty)
|
||||||
|
&& (expr.is_size_lit() || expr_ty.is_usize_like())
|
||||||
|
{
|
||||||
|
err.subdiagnostic(errors::ReplaceCommaWithSemicolon {
|
||||||
|
comma_span,
|
||||||
|
descr: "a vector",
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `array_expr` is from an array `["a", 10]` if
|
||||||
|
// 1. first element of array implements `Copy` trait
|
||||||
|
// 2. second element is an integer literal or is a const value of type `usize`
|
||||||
|
if self.type_is_copy_modulo_regions(self.param_env, first_ty)
|
||||||
|
&& (expr.is_size_lit() || expr_is_const_usize)
|
||||||
|
{
|
||||||
|
err.subdiagnostic(errors::ReplaceCommaWithSemicolon {
|
||||||
|
comma_span,
|
||||||
|
descr: "an array",
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// If the expected type is an enum (Issue #55250) with any variants whose
|
/// If the expected type is an enum (Issue #55250) with any variants whose
|
||||||
/// sole field is of the found type, suggest such variants. (Issue #42764)
|
/// sole field is of the found type, suggest such variants. (Issue #42764)
|
||||||
pub(crate) fn suggest_compatible_variants(
|
pub(crate) fn suggest_compatible_variants(
|
||||||
|
|
|
@ -27,7 +27,7 @@ use crate::infer::canonical::Canonical;
|
||||||
use crate::ty::InferTy::*;
|
use crate::ty::InferTy::*;
|
||||||
use crate::ty::{
|
use crate::ty::{
|
||||||
self, AdtDef, BoundRegionKind, Discr, GenericArg, GenericArgs, GenericArgsRef, List, ParamEnv,
|
self, AdtDef, BoundRegionKind, Discr, GenericArg, GenericArgs, GenericArgsRef, List, ParamEnv,
|
||||||
Region, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable, TypeVisitor,
|
Region, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here
|
// Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here
|
||||||
|
@ -1017,6 +1017,18 @@ impl<'tcx> Ty<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if type is an `usize`.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_usize(self) -> bool {
|
||||||
|
matches!(self.kind(), Uint(UintTy::Usize))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if type is an `usize` or an integral type variable.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_usize_like(self) -> bool {
|
||||||
|
matches!(self.kind(), Uint(UintTy::Usize) | Infer(IntVar(_)))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_never(self) -> bool {
|
pub fn is_never(self) -> bool {
|
||||||
matches!(self.kind(), Never)
|
matches!(self.kind(), Never)
|
||||||
|
|
|
@ -47,6 +47,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, copy_def_id)
|
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, copy_def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn type_is_clone_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
|
let ty = self.resolve_vars_if_possible(ty);
|
||||||
|
let clone_def_id = self.tcx.require_lang_item(LangItem::Clone, None);
|
||||||
|
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, clone_def_id)
|
||||||
|
}
|
||||||
|
|
||||||
fn type_is_sized_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
|
fn type_is_sized_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||||
let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
|
let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
|
||||||
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item)
|
traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item)
|
||||||
|
|
70
tests/ui/repeat-expr/typo-in-repeat-expr-issue-80173.rs
Normal file
70
tests/ui/repeat-expr/typo-in-repeat-expr-issue-80173.rs
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
struct Type;
|
||||||
|
|
||||||
|
struct NewType;
|
||||||
|
|
||||||
|
const fn get_size() -> usize {
|
||||||
|
10
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_dyn_size() -> usize {
|
||||||
|
10
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let a = ["a", 10];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| HELP replace the comma with a semicolon to create an array
|
||||||
|
|
||||||
|
const size_b: usize = 20;
|
||||||
|
let b = [Type, size_b];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| HELP replace the comma with a semicolon to create an array
|
||||||
|
|
||||||
|
let size_c: usize = 13;
|
||||||
|
let c = [Type, size_c];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
|
||||||
|
const size_d: bool = true;
|
||||||
|
let d = [Type, size_d];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
|
||||||
|
let e = [String::new(), 10];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| HELP try using a conversion method
|
||||||
|
|
||||||
|
let f = ["f", get_size()];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| HELP replace the comma with a semicolon to create an array
|
||||||
|
|
||||||
|
let m = ["m", get_dyn_size()];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
|
||||||
|
// is_vec, is_clone, is_usize_like
|
||||||
|
let g = vec![String::new(), 10];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| HELP replace the comma with a semicolon to create a vector
|
||||||
|
|
||||||
|
let dyn_size = 10;
|
||||||
|
let h = vec![Type, dyn_size];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| HELP replace the comma with a semicolon to create a vector
|
||||||
|
|
||||||
|
let i = vec![Type, get_dyn_size()];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| HELP replace the comma with a semicolon to create a vector
|
||||||
|
|
||||||
|
let k = vec!['c', 10];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| HELP replace the comma with a semicolon to create a vector
|
||||||
|
|
||||||
|
let j = vec![Type, 10_u8];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
|
||||||
|
let l = vec![NewType, 10];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
|
||||||
|
let byte_size: u8 = 10;
|
||||||
|
let h = vec![Type, byte_size];
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
124
tests/ui/repeat-expr/typo-in-repeat-expr-issue-80173.stderr
Normal file
124
tests/ui/repeat-expr/typo-in-repeat-expr-issue-80173.stderr
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:15:19
|
||||||
|
|
|
||||||
|
LL | let a = ["a", 10];
|
||||||
|
| ^^ expected `&str`, found integer
|
||||||
|
|
|
||||||
|
help: replace the comma with a semicolon to create an array
|
||||||
|
|
|
||||||
|
LL | let a = ["a"; 10];
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:20:20
|
||||||
|
|
|
||||||
|
LL | let b = [Type, size_b];
|
||||||
|
| ^^^^^^ expected `Type`, found `usize`
|
||||||
|
|
|
||||||
|
help: replace the comma with a semicolon to create an array
|
||||||
|
|
|
||||||
|
LL | let b = [Type; size_b];
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:25:20
|
||||||
|
|
|
||||||
|
LL | let c = [Type, size_c];
|
||||||
|
| ^^^^^^ expected `Type`, found `usize`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:29:20
|
||||||
|
|
|
||||||
|
LL | let d = [Type, size_d];
|
||||||
|
| ^^^^^^ expected `Type`, found `bool`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:32:29
|
||||||
|
|
|
||||||
|
LL | let e = [String::new(), 10];
|
||||||
|
| ^^- help: try using a conversion method: `.to_string()`
|
||||||
|
| |
|
||||||
|
| expected `String`, found integer
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:36:19
|
||||||
|
|
|
||||||
|
LL | let f = ["f", get_size()];
|
||||||
|
| ^^^^^^^^^^ expected `&str`, found `usize`
|
||||||
|
|
|
||||||
|
help: replace the comma with a semicolon to create an array
|
||||||
|
|
|
||||||
|
LL | let f = ["f"; get_size()];
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:40:19
|
||||||
|
|
|
||||||
|
LL | let m = ["m", get_dyn_size()];
|
||||||
|
| ^^^^^^^^^^^^^^ expected `&str`, found `usize`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:44:33
|
||||||
|
|
|
||||||
|
LL | let g = vec![String::new(), 10];
|
||||||
|
| ^^ expected `String`, found integer
|
||||||
|
|
|
||||||
|
help: replace the comma with a semicolon to create a vector
|
||||||
|
|
|
||||||
|
LL | let g = vec![String::new(); 10];
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:49:24
|
||||||
|
|
|
||||||
|
LL | let h = vec![Type, dyn_size];
|
||||||
|
| ^^^^^^^^ expected `Type`, found integer
|
||||||
|
|
|
||||||
|
help: replace the comma with a semicolon to create a vector
|
||||||
|
|
|
||||||
|
LL | let h = vec![Type; dyn_size];
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:53:24
|
||||||
|
|
|
||||||
|
LL | let i = vec![Type, get_dyn_size()];
|
||||||
|
| ^^^^^^^^^^^^^^ expected `Type`, found `usize`
|
||||||
|
|
|
||||||
|
help: replace the comma with a semicolon to create a vector
|
||||||
|
|
|
||||||
|
LL | let i = vec![Type; get_dyn_size()];
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:57:23
|
||||||
|
|
|
||||||
|
LL | let k = vec!['c', 10];
|
||||||
|
| ^^ expected `char`, found `u8`
|
||||||
|
|
|
||||||
|
help: replace the comma with a semicolon to create a vector
|
||||||
|
|
|
||||||
|
LL | let k = vec!['c'; 10];
|
||||||
|
| ~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:61:24
|
||||||
|
|
|
||||||
|
LL | let j = vec![Type, 10_u8];
|
||||||
|
| ^^^^^ expected `Type`, found `u8`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:64:27
|
||||||
|
|
|
||||||
|
LL | let l = vec![NewType, 10];
|
||||||
|
| ^^ expected `NewType`, found integer
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/typo-in-repeat-expr-issue-80173.rs:68:24
|
||||||
|
|
|
||||||
|
LL | let h = vec![Type, byte_size];
|
||||||
|
| ^^^^^^^^^ expected `Type`, found `u8`
|
||||||
|
|
||||||
|
error: aborting due to 14 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Add table
Add a link
Reference in a new issue