diff options
393 files changed, 14043 insertions, 5242 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff3a8326315..451116f320d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: - name: disable git crlf conversion run: git config --global core.autocrlf false - name: checkout the source code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 2 - name: configure the PR in which the error message will be posted @@ -454,7 +454,7 @@ jobs: - name: disable git crlf conversion run: git config --global core.autocrlf false - name: checkout the source code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 2 - name: configure the PR in which the error message will be posted @@ -567,7 +567,7 @@ jobs: - name: disable git crlf conversion run: git config --global core.autocrlf false - name: checkout the source code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 2 - name: configure the PR in which the error message will be posted @@ -670,7 +670,7 @@ jobs: if: "github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust'" steps: - name: checkout the source code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 2 - name: publish toolstate diff --git a/Cargo.lock b/Cargo.lock index 325503a0e95..9eba61f8d29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ dependencies = [ [[package]] name = "cargo" -version = "0.62.0" +version = "0.63.0" dependencies = [ "anyhow", "atty", @@ -348,6 +348,7 @@ dependencies = [ "opener", "openssl", "os_info", + "pathdiff", "percent-encoding 2.1.0", "pretty_env_logger", "rustc-workspace-hack", @@ -453,7 +454,7 @@ dependencies = [ [[package]] name = "cargo-util" -version = "0.1.2" +version = "0.1.3" dependencies = [ "anyhow", "core-foundation", @@ -730,9 +731,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.70" +version = "0.1.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80873f979f0a344a4ade87c2f70d9ccf5720b83b10c97ec7cd745895d021e85a" +checksum = "163437f05ca8f29d7e9128ea728dedf5eb620e445fbca273641d3a3050305f23" dependencies = [ "cc", "rustc-std-workspace-core", @@ -2651,9 +2652,9 @@ dependencies = [ [[package]] name = "pathdiff" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877630b3de15c0b64cc52f659345724fbf6bdad9bd9566699fc53688f3c34a34" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "percent-encoding" diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 42ec206fc65..714f9383bb2 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2061,6 +2061,20 @@ impl InlineAsmTemplatePiece { } } +/// Inline assembly symbol operands get their own AST node that is somewhat +/// similar to `AnonConst`. +/// +/// The main difference is that we specifically don't assign it `DefId` in +/// `DefCollector`. Instead this is deferred until AST lowering where we +/// lower it to an `AnonConst` (for functions) or a `Path` (for statics) +/// depending on what the path resolves to. +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct InlineAsmSym { + pub id: NodeId, + pub qself: Option<QSelf>, + pub path: Path, +} + /// Inline assembly operand. /// /// E.g., `out("eax") result` as in `asm!("mov eax, 2", out("eax") result)`. @@ -2090,7 +2104,7 @@ pub enum InlineAsmOperand { anon_const: AnonConst, }, Sym { - expr: P<Expr>, + sym: InlineAsmSym, }, } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 15f7aceb83d..cba49835f69 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -280,6 +280,14 @@ pub trait MutVisitor: Sized { fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { noop_flat_map_pat_field(fp, self) } + + fn visit_inline_asm(&mut self, asm: &mut InlineAsm) { + noop_visit_inline_asm(asm, self) + } + + fn visit_inline_asm_sym(&mut self, sym: &mut InlineAsmSym) { + noop_visit_inline_asm_sym(sym, self) + } } /// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful @@ -1019,7 +1027,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) { } } ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), - ItemKind::GlobalAsm(asm) => noop_visit_inline_asm(asm, vis), + ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm), ItemKind::TyAlias(box TyAlias { defaultness, generics, where_clauses, bounds, ty, .. }) => { @@ -1237,13 +1245,12 @@ pub fn noop_visit_anon_const<T: MutVisitor>(AnonConst { id, value }: &mut AnonCo vis.visit_expr(value); } -fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) { +pub fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) { for (op, _) in &mut asm.operands { match op { InlineAsmOperand::In { expr, .. } | InlineAsmOperand::Out { expr: Some(expr), .. } - | InlineAsmOperand::InOut { expr, .. } - | InlineAsmOperand::Sym { expr, .. } => vis.visit_expr(expr), + | InlineAsmOperand::InOut { expr, .. } => vis.visit_expr(expr), InlineAsmOperand::Out { expr: None, .. } => {} InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => { vis.visit_expr(in_expr); @@ -1251,11 +1258,21 @@ fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) { vis.visit_expr(out_expr); } } - InlineAsmOperand::Const { anon_const, .. } => vis.visit_anon_const(anon_const), + InlineAsmOperand::Const { anon_const } => vis.visit_anon_const(anon_const), + InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym), } } } +pub fn noop_visit_inline_asm_sym<T: MutVisitor>( + InlineAsmSym { id, qself, path }: &mut InlineAsmSym, + vis: &mut T, +) { + vis.visit_id(id); + vis.visit_qself(qself); + vis.visit_path(path); +} + pub fn noop_visit_expr<T: MutVisitor>( Expr { kind, id, span, attrs, tokens }: &mut Expr, vis: &mut T, @@ -1374,7 +1391,7 @@ pub fn noop_visit_expr<T: MutVisitor>( ExprKind::Ret(expr) => { visit_opt(expr, |expr| vis.visit_expr(expr)); } - ExprKind::InlineAsm(asm) => noop_visit_inline_asm(asm, vis), + ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm), ExprKind::MacCall(mac) => vis.visit_mac_call(mac), ExprKind::Struct(se) => { let StructExpr { qself, path, fields, rest } = se.deref_mut(); diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 031c6cae793..5aa8011ca5e 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -722,7 +722,7 @@ impl NonterminalKind { Edition::Edition2015 | Edition::Edition2018 => { NonterminalKind::PatParam { inferred: true } } - Edition::Edition2021 => NonterminalKind::PatWithOr, + Edition::Edition2021 | Edition::Edition2024 => NonterminalKind::PatWithOr, }, sym::pat_param => NonterminalKind::PatParam { inferred: false }, sym::expr => NonterminalKind::Expr, diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ed16c25d921..3183612597d 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -214,6 +214,12 @@ pub trait Visitor<'ast>: Sized { fn visit_crate(&mut self, krate: &'ast Crate) { walk_crate(self, krate) } + fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) { + walk_inline_asm(self, asm) + } + fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) { + walk_inline_asm_sym(self, sym) + } } #[macro_export] @@ -717,13 +723,12 @@ pub fn walk_anon_const<'a, V: Visitor<'a>>(visitor: &mut V, constant: &'a AnonCo visitor.visit_expr(&constant.value); } -fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) { +pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) { for (op, _) in &asm.operands { match op { InlineAsmOperand::In { expr, .. } | InlineAsmOperand::Out { expr: Some(expr), .. } - | InlineAsmOperand::InOut { expr, .. } - | InlineAsmOperand::Sym { expr, .. } => visitor.visit_expr(expr), + | InlineAsmOperand::InOut { expr, .. } => visitor.visit_expr(expr), InlineAsmOperand::Out { expr: None, .. } => {} InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => { visitor.visit_expr(in_expr); @@ -732,10 +737,18 @@ fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) { } } InlineAsmOperand::Const { anon_const, .. } => visitor.visit_anon_const(anon_const), + InlineAsmOperand::Sym { sym } => visitor.visit_inline_asm_sym(sym), } } } +pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>(visitor: &mut V, sym: &'a InlineAsmSym) { + if let Some(ref qself) = sym.qself { + visitor.visit_ty(&qself.ty); + } + visitor.visit_path(&sym.path, sym.id); +} + pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { walk_list!(visitor, visit_attribute, expression.attrs.iter()); diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 171cc60dfd7..ae3e3675962 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -1,12 +1,17 @@ +use crate::{ImplTraitContext, ImplTraitPosition, ParamMode}; + use super::LoweringContext; +use rustc_ast::ptr::P; use rustc_ast::*; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_set::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::definitions::DefPathData; use rustc_session::parse::feature_err; -use rustc_span::{sym, Span}; +use rustc_span::{sym, ExpnId, Span}; use rustc_target::asm; use std::collections::hash_map::Entry; use std::fmt::Write; @@ -188,7 +193,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { anon_const: self.lower_anon_const(anon_const), } } - InlineAsmOperand::Sym { ref expr } => { + InlineAsmOperand::Sym { ref sym } => { if !self.sess.features_untracked().asm_sym { feature_err( &self.sess.parse_sess, @@ -198,7 +203,54 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) .emit(); } - hir::InlineAsmOperand::Sym { expr: self.lower_expr_mut(expr) } + + let static_def_id = self + .resolver + .get_partial_res(sym.id) + .filter(|res| res.unresolved_segments() == 0) + .and_then(|res| { + if let Res::Def(DefKind::Static(_), def_id) = res.base_res() { + Some(def_id) + } else { + None + } + }); + + if let Some(def_id) = static_def_id { + let path = self.lower_qpath( + sym.id, + &sym.qself, + &sym.path, + ParamMode::Optional, + ImplTraitContext::Disallowed(ImplTraitPosition::Path), + ); + hir::InlineAsmOperand::SymStatic { path, def_id } + } else { + // Replace the InlineAsmSym AST node with an + // Expr using the name node id. + let expr = Expr { + id: sym.id, + kind: ExprKind::Path(sym.qself.clone(), sym.path.clone()), + span: *op_sp, + attrs: AttrVec::new(), + tokens: None, + }; + + // Wrap the expression in an AnonConst. + let parent_def_id = self.current_hir_id_owner; + let node_id = self.resolver.next_node_id(); + self.resolver.create_def( + parent_def_id, + node_id, + DefPathData::AnonConst, + ExpnId::root(), + *op_sp, + ); + let anon_const = AnonConst { id: node_id, value: P(expr) }; + hir::InlineAsmOperand::SymFn { + anon_const: self.lower_anon_const(&anon_const), + } + } } }; (op, self.lower_span(*op_sp)) @@ -260,7 +312,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { err.span_label(op_sp, "argument"); err.emit(); } - hir::InlineAsmOperand::Sym { .. } => { + hir::InlineAsmOperand::SymFn { .. } + | hir::InlineAsmOperand::SymStatic { .. } => { let mut err = sess.struct_span_err( placeholder_span, "asm template modifiers are not allowed for `sym` arguments", @@ -308,7 +361,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::InlineAsmOperand::InOut { .. } | hir::InlineAsmOperand::SplitInOut { .. } => (true, true), - hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::Sym { .. } => { + hir::InlineAsmOperand::Const { .. } + | hir::InlineAsmOperand::SymFn { .. } + | hir::InlineAsmOperand::SymStatic { .. } => { unreachable!() } }; diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index 62935a2b1f7..5eab21bf79a 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -52,7 +52,9 @@ pub(super) fn index_hir<'hir>( }; match item { - OwnerNode::Crate(citem) => collector.visit_mod(&citem, citem.inner, hir::CRATE_HIR_ID), + OwnerNode::Crate(citem) => { + collector.visit_mod(&citem, citem.spans.inner_span, hir::CRATE_HIR_ID) + } OwnerNode::Item(item) => collector.visit_item(item), OwnerNode::TraitItem(item) => collector.visit_trait_item(item), OwnerNode::ImplItem(item) => collector.visit_impl_item(item), diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index c8fd96309a6..a8bd8c92a41 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -124,7 +124,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { debug_assert_eq!(self.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID); self.with_lctx(CRATE_NODE_ID, |lctx| { - let module = lctx.lower_mod(&c.items, c.spans.inner_span); + let module = lctx.lower_mod(&c.items, &c.spans); lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs); hir::OwnerNode::Crate(lctx.arena.alloc(module)) }) @@ -186,9 +186,12 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { } impl<'hir> LoweringContext<'_, 'hir> { - pub(super) fn lower_mod(&mut self, items: &[P<Item>], inner: Span) -> hir::Mod<'hir> { + pub(super) fn lower_mod(&mut self, items: &[P<Item>], spans: &ModSpans) -> hir::Mod<'hir> { hir::Mod { - inner: self.lower_span(inner), + spans: hir::ModSpans { + inner_span: self.lower_span(spans.inner_span), + inject_use_span: self.lower_span(spans.inject_use_span), + }, item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))), } } @@ -308,8 +311,8 @@ impl<'hir> LoweringContext<'_, 'hir> { }) } ItemKind::Mod(_, ref mod_kind) => match mod_kind { - ModKind::Loaded(items, _, ModSpans { inner_span, inject_use_span: _ }) => { - hir::ItemKind::Mod(self.lower_mod(items, *inner_span)) + ModKind::Loaded(items, _, spans) => { + hir::ItemKind::Mod(self.lower_mod(items, spans)) } ModKind::Unloaded => panic!("`mod` items should have been loaded by now"), }, diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 719fd271093..c2247150d09 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1266,10 +1266,14 @@ impl<'a> State<'a> { s.space(); s.print_expr(&anon_const.value); } - InlineAsmOperand::Sym { expr } => { + InlineAsmOperand::Sym { sym } => { s.word("sym"); s.space(); - s.print_expr(expr); + if let Some(qself) = &sym.qself { + s.print_qpath(&sym.path, qself, true); + } else { + s.print_path(&sym.path, true, 0); + } } } } diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 57ef46475dd..030295d3d8d 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -154,17 +154,19 @@ pub fn parse_asm_args<'a>( } else if p.eat_keyword(kw::Const) { let anon_const = p.parse_anon_const_expr()?; ast::InlineAsmOperand::Const { anon_const } - } else if !is_global_asm && p.eat_keyword(sym::sym) { + } else if p.eat_keyword(sym::sym) { let expr = p.parse_expr()?; - match expr.kind { - ast::ExprKind::Path(..) => {} - _ => { - let err = diag - .struct_span_err(expr.span, "argument to `sym` must be a path expression"); - return Err(err); - } - } - ast::InlineAsmOperand::Sym { expr } + let ast::ExprKind::Path(qself, path) = &expr.kind else { + let err = diag + .struct_span_err(expr.span, "expected a path for argument to `sym`"); + return Err(err); + }; + let sym = ast::InlineAsmSym { + id: ast::DUMMY_NODE_ID, + qself: qself.clone(), + path: path.clone(), + }; + ast::InlineAsmOperand::Sym { sym } } else if allow_templates { let template = p.parse_expr()?; // If it can't possibly expand to a string, provide diagnostics here to include other diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index ca83941f600..2c5260616c7 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -46,18 +46,7 @@ pub fn expand_deriving_default( StaticStruct(_, fields) => { default_struct_substructure(cx, trait_span, substr, fields) } - StaticEnum(enum_def, _) => { - if !cx.sess.features_untracked().derive_default_enum { - rustc_session::parse::feature_err( - cx.parse_sess(), - sym::derive_default_enum, - span, - "deriving `Default` on enums is experimental", - ) - .emit(); - } - default_enum_substructure(cx, trait_span, enum_def) - } + StaticEnum(enum_def, _) => default_enum_substructure(cx, trait_span, enum_def), _ => cx.span_bug(trait_span, "method in `derive(Default)`"), } })), diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs index 3571517d2b2..09ad5f9b3ea 100644 --- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs +++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs @@ -70,6 +70,7 @@ pub fn inject( Edition2015 => sym::rust_2015, Edition2018 => sym::rust_2018, Edition2021 => sym::rust_2021, + Edition2024 => sym::rust_2024, }]) .map(|&symbol| Ident::new(symbol, span)) .collect(); diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 8a74c4c07e0..2af050f0c75 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -258,9 +258,14 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } InlineAsmOperandRef::SymFn { instance } => { + // TODO(@Amanieu): Additional mangling is needed on + // some targets to add a leading underscore (Mach-O) + // or byte count suffixes (x86 Windows). constants_len += self.tcx.symbol_name(instance).name.len(); } InlineAsmOperandRef::SymStatic { def_id } => { + // TODO(@Amanieu): Additional mangling is needed on + // some targets to add a leading underscore (Mach-O). constants_len += self.tcx.symbol_name(Instance::mono(self.tcx, def_id)).name.len(); } } @@ -412,13 +417,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } InlineAsmOperandRef::SymFn { instance } => { + // TODO(@Amanieu): Additional mangling is needed on + // some targets to add a leading underscore (Mach-O) + // or byte count suffixes (x86 Windows). let name = self.tcx.symbol_name(instance).name; template_str.push_str(name); } InlineAsmOperandRef::SymStatic { def_id } => { - // TODO(@Commeownist): This may not be sufficient for all kinds of statics. - // Some statics may need the `@plt` suffix, like thread-local vars. + // TODO(@Amanieu): Additional mangling is needed on + // some targets to add a leading underscore (Mach-O). let instance = Instance::mono(self.tcx, def_id); let name = self.tcx.symbol_name(instance).name; template_str.push_str(name); @@ -656,8 +664,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl } } -impl<'gcc, 'tcx> AsmMethods for CodegenCx<'gcc, 'tcx> { - fn codegen_global_asm(&self, template: &[InlineAsmTemplatePiece], operands: &[GlobalAsmOperandRef], options: InlineAsmOptions, _line_spans: &[Span]) { +impl<'gcc, 'tcx> AsmMethods<'tcx> for CodegenCx<'gcc, 'tcx> { + fn codegen_global_asm(&self, template: &[InlineAsmTemplatePiece], operands: &[GlobalAsmOperandRef<'tcx>], options: InlineAsmOptions, _line_spans: &[Span]) { let asm_arch = self.tcx.sess.asm_arch.unwrap(); // Default to Intel syntax on x86 @@ -690,6 +698,22 @@ impl<'gcc, 'tcx> AsmMethods for CodegenCx<'gcc, 'tcx> { // here unlike normal inline assembly. template_str.push_str(string); } + + GlobalAsmOperandRef::SymFn { instance } => { + // TODO(@Amanieu): Additional mangling is needed on + // some targets to add a leading underscore (Mach-O) + // or byte count suffixes (x86 Windows). + let name = self.tcx.symbol_name(instance).name; + template_str.push_str(name); + } + + GlobalAsmOperandRef::SymStatic { def_id } => { + // TODO(@Amanieu): Additional mangling is needed on + // some targets to add a leading underscore (Mach-O). + let instance = Instance::mono(self.tcx, def_id); + let name = self.tcx.symbol_name(instance).name; + template_str.push_str(name); + } } } } diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 91d132eb343..dff32007918 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -312,11 +312,11 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } } -impl AsmMethods for CodegenCx<'_, '_> { +impl<'tcx> AsmMethods<'tcx> for CodegenCx<'_, 'tcx> { fn codegen_global_asm( &self, template: &[InlineAsmTemplatePiece], - operands: &[GlobalAsmOperandRef], + operands: &[GlobalAsmOperandRef<'tcx>], options: InlineAsmOptions, _line_spans: &[Span], ) { @@ -342,6 +342,29 @@ impl AsmMethods for CodegenCx<'_, '_> { // here unlike normal inline assembly. template_str.push_str(string); } + GlobalAsmOperandRef::SymFn { instance } => { + let llval = self.get_fn(instance); + self.add_compiler_used_global(llval); + let symbol = llvm::build_string(|s| unsafe { + llvm::LLVMRustGetMangledName(llval, s); + }) + .expect("symbol is not valid UTF-8"); + template_str.push_str(&symbol); + } + GlobalAsmOperandRef::SymStatic { def_id } => { + let llval = self + .renamed_statics + .borrow() + .get(&def_id) + .copied() + .unwrap_or_else(|| self.get_static(def_id)); + self.add_compiler_used_global(llval); + let symbol = llvm::build_string(|s| unsafe { + llvm::LLVMRustGetMangledName(llval, s); + }) + .expect("symbol is not valid UTF-8"); + template_str.push_str(&symbol); + } } } } diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index dd3ada44389..c163c7d8692 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -99,15 +99,6 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen attributes::apply_to_llfn(entry, llvm::AttributePlace::Function, &attrs); } - // Run replace-all-uses-with for statics that need it - for &(old_g, new_g) in cx.statics_to_rauw().borrow().iter() { - unsafe { - let bitcast = llvm::LLVMConstPointerCast(new_g, cx.val_ty(old_g)); - llvm::LLVMReplaceAllUsesWith(old_g, bitcast); - llvm::LLVMDeleteGlobal(old_g); - } - } - // Finalize code coverage by injecting the coverage map. Note, the coverage map will // also be added to the `llvm.compiler.used` variable, created next. if cx.sess().instrument_coverage() { @@ -122,6 +113,16 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen cx.create_compiler_used_variable() } + // Run replace-all-uses-with for statics that need it. This must + // happen after the llvm.used variables are created. + for &(old_g, new_g) in cx.statics_to_rauw().borrow().iter() { + unsafe { + let bitcast = llvm::LLVMConstPointerCast(new_g, cx.val_ty(old_g)); + llvm::LLVMReplaceAllUsesWith(old_g, bitcast); + llvm::LLVMDeleteGlobal(old_g); + } + } + // Finalize debuginfo if cx.sess().opts.debuginfo != DebugInfo::None { cx.debuginfo_finalize(); diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index cb4073528e1..4d3f3f318b8 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -412,6 +412,13 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> { llvm::LLVMRustSetLinkage(new_g, linkage); llvm::LLVMRustSetVisibility(new_g, visibility); + // The old global has had its name removed but is returned by + // get_static since it is in the instance cache. Provide an + // alternative lookup that points to the new global so that + // global_asm! can compute the correct mangled symbol name + // for the global. + self.renamed_statics.borrow_mut().insert(def_id, new_g); + // To avoid breaking any invariants, we leave around the old // global for the moment; we'll replace all references to it // with the new global later. (See base::codegen_backend.) diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 98cf873ebbd..d296ee3b42c 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -14,6 +14,7 @@ use rustc_codegen_ssa::traits::*; use rustc_data_structures::base_n; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::small_c_str::SmallCStr; +use rustc_hir::def_id::DefId; use rustc_middle::mir::mono::CodegenUnit; use rustc_middle::ty::layout::{ FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers, @@ -105,6 +106,12 @@ pub struct CodegenCx<'ll, 'tcx> { /// A counter that is used for generating local symbol names local_gen_sym_counter: Cell<usize>, + + /// `codegen_static` will sometimes create a second global variable with a + /// different type and clear the symbol name of the original global. + /// `global_asm!` needs to be able to find this new global so that it can + /// compute the correct mangled symbol name to insert into the asm. + pub renamed_statics: RefCell<FxHashMap<DefId, &'ll Value>>, } pub struct TypeLowering<'ll> { @@ -436,6 +443,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { rust_try_fn: Cell::new(None), intrinsics: Default::default(), local_gen_sym_counter: Cell::new(0), + renamed_statics: Default::default(), } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index 31bb9ed3185..d6e2c8ccdf4 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -372,7 +372,6 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>( // Build the type node for each field. let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_range - .clone() .map(|variant_index| { let variant_struct_type_di_node = super::build_generator_variant_struct_type_di_node( cx, diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 48840c76cac..cf9cf1b70aa 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1839,6 +1839,27 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, simd_neg: Int => neg, Float => fneg; } + if name == sym::simd_arith_offset { + // This also checks that the first operand is a ptr type. + let pointee = in_elem.builtin_deref(true).unwrap_or_else(|| { + span_bug!(span, "must be called with a vector of pointer types as first argument") + }); + let layout = bx.layout_of(pointee.ty); + let ptrs = args[0].immediate(); + // The second argument must be a ptr-sized integer. + // (We don't care about the signedness, this is wrapping anyway.) + let (_offsets_len, offsets_elem) = arg_tys[1].simd_size_and_type(bx.tcx()); + if !matches!(offsets_elem.kind(), ty::Int(ty::IntTy::Isize) | ty::Uint(ty::UintTy::Usize)) { + span_bug!( + span, + "must be called with a vector of pointer-sized integers as second argument" + ); + } + let offsets = args[1].immediate(); + + return Ok(bx.gep(bx.backend_type(layout), ptrs, &[offsets])); + } + if name == sym::simd_saturating_add || name == sym::simd_saturating_sub { let lhs = args[0].immediate(); let rhs = args[1].immediate(); diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 375b9927c86..7f533b0552a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2537,4 +2537,6 @@ extern "C" { remark_passes_len: usize, ); + #[allow(improper_ctypes)] + pub fn LLVMRustGetMangledName(V: &Value, out: &RustString); } diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index 5414c619dcb..5006a2157fc 100644 --- a/compiler/rustc_codegen_ssa/src/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -4,7 +4,9 @@ use crate::traits::*; use rustc_hir as hir; use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::{Linkage, Visibility}; +use rustc_middle::ty; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; +use rustc_middle::ty::Instance; pub trait MonoItemExt<'a, 'tcx> { fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx); @@ -56,7 +58,27 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { ); GlobalAsmOperandRef::Const { string } } - _ => span_bug!(*op_sp, "invalid operand type for global_asm!"), + hir::InlineAsmOperand::SymFn { ref anon_const } => { + let ty = cx + .tcx() + .typeck_body(anon_const.body) + .node_type(anon_const.hir_id); + let instance = match ty.kind() { + &ty::FnDef(def_id, substs) => Instance::new(def_id, substs), + _ => span_bug!(*op_sp, "asm sym is not a function"), + }; + + GlobalAsmOperandRef::SymFn { instance } + } + hir::InlineAsmOperand::SymStatic { path: _, def_id } => { + GlobalAsmOperandRef::SymStatic { def_id } + } + hir::InlineAsmOperand::In { .. } + | hir::InlineAsmOperand::Out { .. } + | hir::InlineAsmOperand::InOut { .. } + | hir::InlineAsmOperand::SplitInOut { .. } => { + span_bug!(*op_sp, "invalid operand type for global_asm!") + } }) .collect(); diff --git a/compiler/rustc_codegen_ssa/src/traits/asm.rs b/compiler/rustc_codegen_ssa/src/traits/asm.rs index 11111a79744..c2ae74b18d8 100644 --- a/compiler/rustc_codegen_ssa/src/traits/asm.rs +++ b/compiler/rustc_codegen_ssa/src/traits/asm.rs @@ -36,8 +36,10 @@ pub enum InlineAsmOperandRef<'tcx, B: BackendTypes + ?Sized> { } #[derive(Debug)] -pub enum GlobalAsmOperandRef { +pub enum GlobalAsmOperandRef<'tcx> { Const { string: String }, + SymFn { instance: Instance<'tcx> }, + SymStatic { def_id: DefId }, } pub trait AsmBuilderMethods<'tcx>: BackendTypes { @@ -53,11 +55,11 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes { ); } -pub trait AsmMethods { +pub trait AsmMethods<'tcx> { fn codegen_global_asm( &self, template: &[InlineAsmTemplatePiece], - operands: &[GlobalAsmOperandRef], + operands: &[GlobalAsmOperandRef<'tcx>], options: InlineAsmOptions, line_spans: &[Span], ); diff --git a/compiler/rustc_codegen_ssa/src/traits/mod.rs b/compiler/rustc_codegen_ssa/src/traits/mod.rs index c529fbbf518..396768e0a42 100644 --- a/compiler/rustc_codegen_ssa/src/traits/mod.rs +++ b/compiler/rustc_codegen_ssa/src/traits/mod.rs @@ -60,7 +60,7 @@ pub trait CodegenMethods<'tcx>: + StaticMethods + CoverageInfoMethods<'tcx> + DebugInfoMethods<'tcx> - + AsmMethods + + AsmMethods<'tcx> + PreDefineMethods<'tcx> + HasParamEnv<'tcx> + HasTyCtxt<'tcx> @@ -76,7 +76,7 @@ impl<'tcx, T> CodegenMethods<'tcx> for T where + StaticMethods + CoverageInfoMethods<'tcx> + DebugInfoMethods<'tcx> - + AsmMethods + + AsmMethods<'tcx> + PreDefineMethods<'tcx> + HasParamEnv<'tcx> + HasTyCtxt<'tcx> diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index eb1a184bf9b..e6dfdf54a32 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -196,27 +196,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_immediate(*val, &dest)?; } - Aggregate(ref kind, ref operands) => { - // active_field_index is for union initialization. - let (dest, active_field_index) = match **kind { - mir::AggregateKind::Adt(adt_did, variant_index, _, _, active_field_index) => { - self.write_discriminant(variant_index, &dest)?; - if self.tcx.adt_def(adt_did).is_enum() { - assert!(active_field_index.is_none()); - (self.place_downcast(&dest, variant_index)?, None) - } else { - if active_field_index.is_some() { - assert_eq!(operands.len(), 1); - } - (dest, active_field_index) - } - } - _ => (dest, None), - }; + Aggregate(box ref kind, ref operands) => { + assert!(matches!(kind, mir::AggregateKind::Array(..))); - for (i, operand) in operands.iter().enumerate() { + for (field_index, operand) in operands.iter().enumerate() { let op = self.eval_operand(operand, None)?; - let field_index = active_field_index.unwrap_or(i); let field_dest = self.place_field(&dest, field_index)?; self.copy_op(&op, &field_dest)?; } diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 01af9585135..79d427ccc44 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -315,9 +315,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { | ty::FnPtr(..) ) } - // None of the possible types have lifetimes, so we can just compare - // directly - if a != b { + // The function pointer types can have lifetimes + if !self.mir_assign_valid_types(a, b) { self.fail( location, format!("Cannot compare unequal types {:?} and {:?}", a, b), @@ -464,7 +463,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { }; // since CopyNonOverlapping is parametrized by 1 type, // we only need to check that they are equal and not keep an extra parameter. - if op_src_ty != op_dst_ty { + if !self.mir_assign_valid_types(op_src_ty, op_dst_ty) { self.fail(location, format!("bad arg ({:?} != {:?})", op_src_ty, op_dst_ty)); } diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 1a3fe652521..98d4870e645 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -27,7 +27,6 @@ #![feature(thread_id_value)] #![feature(vec_into_raw_parts)] #![allow(rustc::default_hash_types)] -#![deny(unaligned_references)] #![allow(rustc::potential_query_instability)] #[macro_use] diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index ecb3cdd627c..9cd072c8b4c 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -832,7 +832,7 @@ impl Diagnostic { name: impl Into<Cow<'static, str>>, arg: DiagnosticArgValue<'static>, ) -> &mut Self { - self.args.push((name.into(), arg.into())); + self.args.push((name.into(), arg)); self } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index cfad1fc01ab..416bc4e2e3b 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1208,7 +1208,7 @@ impl HandlerInner { (0, 0) => return, (0, _) => self.emitter.emit_diagnostic(&Diagnostic::new( Level::Warning, - DiagnosticMessage::Str(warnings.to_owned()), + DiagnosticMessage::Str(warnings), )), (_, 0) => { let _ = self.fatal(&errors); diff --git a/compiler/rustc_expand/src/mbe/macro_check.rs b/compiler/rustc_expand/src/mbe/macro_check.rs index 4298475767e..c6a6e3d125f 100644 --- a/compiler/rustc_expand/src/mbe/macro_check.rs +++ b/compiler/rustc_expand/src/mbe/macro_check.rs @@ -270,7 +270,7 @@ fn check_binders( MISSING_FRAGMENT_SPECIFIER, span, node_id, - &format!("missing fragment specifier"), + "missing fragment specifier", ); } if !macros.is_empty() { diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index 74b8450f756..8f260e1cdb5 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -77,7 +77,6 @@ use crate::mbe::{KleeneOp, TokenTree}; use rustc_ast::token::{self, DocComment, Nonterminal, NonterminalKind, Token}; use rustc_parse::parser::{NtOrTt, Parser}; -use rustc_session::parse::ParseSess; use rustc_span::symbol::MacroRulesNormalizedIdent; use rustc_span::Span; @@ -128,9 +127,8 @@ pub(super) enum MatcherLoc { Eof, } -pub(super) fn compute_locs(sess: &ParseSess, matcher: &[TokenTree]) -> Vec<MatcherLoc> { +pub(super) fn compute_locs(matcher: &[TokenTree]) -> Vec<MatcherLoc> { fn inner( - sess: &ParseSess, tts: &[TokenTree], locs: &mut Vec<MatcherLoc>, next_metavar: &mut usize, @@ -147,7 +145,7 @@ pub(super) fn compute_locs(sess: &ParseSess, matcher: &[TokenTree]) -> Vec<Match locs.push(MatcherLoc::Delimited); locs.push(MatcherLoc::Token { token: open_token }); - inner(sess, &delimited.tts, locs, next_metavar, seq_depth); + inner(&delimited.tts, locs, next_metavar, seq_depth); locs.push(MatcherLoc::Token { token: close_token }); } TokenTree::Sequence(_, seq) => { @@ -162,7 +160,7 @@ pub(super) fn compute_locs(sess: &ParseSess, matcher: &[TokenTree]) -> Vec<Match let op = seq.kleene.op; let idx_first = locs.len(); let idx_seq = idx_first - 1; - inner(sess, &seq.tts, locs, next_metavar, seq_depth + 1); + inner(&seq.tts, locs, next_metavar, seq_depth + 1); if let Some(separator) = &seq.separator { locs.push(MatcherLoc::SequenceSep { separator: separator.clone() }); @@ -197,7 +195,7 @@ pub(super) fn compute_locs(sess: &ParseSess, matcher: &[TokenTree]) -> Vec<Match let mut locs = vec![]; let mut next_metavar = 0; - inner(sess, matcher, &mut locs, &mut next_metavar, /* seq_depth */ 0); + inner(matcher, &mut locs, &mut next_metavar, /* seq_depth */ 0); // A final entry is needed for eof. locs.push(MatcherLoc::Eof); @@ -592,7 +590,7 @@ impl TtParser { (_, 0) => { // Dump all possible `next_mps` into `cur_mps` for the next iteration. Then // process the next token. - self.cur_mps.extend(self.next_mps.drain(..)); + self.cur_mps.append(&mut self.next_mps); parser.to_mut().bump(); } diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index ef174c3c45e..2cfd6968acc 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -435,7 +435,7 @@ pub fn compile_declarative_macro( ), ]; // Convert it into `MatcherLoc` form. - let argument_gram = mbe::macro_parser::compute_locs(&sess.parse_sess, &argument_gram); + let argument_gram = mbe::macro_parser::compute_locs(&argument_gram); let parser = Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS); let mut tt_parser = @@ -478,7 +478,7 @@ pub fn compile_declarative_macro( ) .pop() .unwrap(); - valid &= check_lhs_nt_follows(&sess.parse_sess, features, &def, &tt); + valid &= check_lhs_nt_follows(&sess.parse_sess, &def, &tt); return tt; } sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs") @@ -540,7 +540,7 @@ pub fn compile_declarative_macro( // Ignore the delimiters around the matcher. match lhs { mbe::TokenTree::Delimited(_, delimited) => { - mbe::macro_parser::compute_locs(&sess.parse_sess, &delimited.tts) + mbe::macro_parser::compute_locs(&delimited.tts) } _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "malformed macro lhs"), } @@ -563,16 +563,11 @@ pub fn compile_declarative_macro( })) } -fn check_lhs_nt_follows( - sess: &ParseSess, - features: &Features, - def: &ast::Item, - lhs: &mbe::TokenTree, -) -> bool { +fn check_lhs_nt_follows(sess: &ParseSess, def: &ast::Item, lhs: &mbe::TokenTree) -> bool { // lhs is going to be like TokenTree::Delimited(...), where the // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens. if let mbe::TokenTree::Delimited(_, delimited) = lhs { - check_matcher(sess, features, def, &delimited.tts) + check_matcher(sess, def, &delimited.tts) } else { let msg = "invalid macro matcher; matchers must be contained in balanced delimiters"; sess.span_diagnostic.span_err(lhs.span(), msg); @@ -632,16 +627,11 @@ fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool { false } -fn check_matcher( - sess: &ParseSess, - features: &Features, - def: &ast::Item, - matcher: &[mbe::TokenTree], -) -> bool { +fn check_matcher(sess: &ParseSess, def: &ast::Item, matcher: &[mbe::TokenTree]) -> bool { let first_sets = FirstSets::new(matcher); let empty_suffix = TokenSet::empty(); let err = sess.span_diagnostic.err_count(); - check_matcher_core(sess, features, def, &first_sets, matcher, &empty_suffix); + check_matcher_core(sess, def, &first_sets, matcher, &empty_suffix); err == sess.span_diagnostic.err_count() } @@ -955,7 +945,6 @@ impl<'tt> TokenSet<'tt> { // see `FirstSets::new`. fn check_matcher_core<'tt>( sess: &ParseSess, - features: &Features, def: &ast::Item, first_sets: &FirstSets<'tt>, matcher: &'tt [mbe::TokenTree], @@ -1008,7 +997,7 @@ fn check_matcher_core<'tt>( token::CloseDelim(d.delim), span.close, )); - check_matcher_core(sess, features, def, first_sets, &d.tts, &my_suffix); + check_matcher_core(sess, def, first_sets, &d.tts, &my_suffix); // don't track non NT tokens last.replace_with_irrelevant(); @@ -1040,8 +1029,7 @@ fn check_matcher_core<'tt>( // At this point, `suffix_first` is built, and // `my_suffix` is some TokenSet that we can use // for checking the interior of `seq_rep`. - let next = - check_matcher_core(sess, features, def, first_sets, &seq_rep.tts, my_suffix); + let next = check_matcher_core(sess, def, first_sets, &seq_rep.tts, my_suffix); if next.maybe_empty { last.add_all(&next); } else { @@ -1114,7 +1102,7 @@ fn check_matcher_core<'tt>( err.span_label(sp, format!("not allowed after `{}` fragments", kind)); if kind == NonterminalKind::PatWithOr - && sess.edition == Edition::Edition2021 + && sess.edition.rust_2021() && next_token.is_token(&BinOp(token::BinOpToken::Or)) { let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl( diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index e37251c9c24..048039343a7 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -126,6 +126,8 @@ declare_features! ( (accepted, default_type_params, "1.0.0", None, None), /// Allows `#[deprecated]` attribute. (accepted, deprecated, "1.9.0", Some(29935), None), + /// Allows `#[derive(Default)]` and `#[default]` on enums. + (accepted, derive_default_enum, "1.62.0", Some(86985), None), /// Allows the use of destructuring assignments. (accepted, destructuring_assignment, "1.59.0", Some(71126), None), /// Allows `#[doc(alias = "...")]`. diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 8340a0b360e..f3d4c8ab438 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -368,8 +368,6 @@ declare_features! ( (active, deprecated_safe, "1.61.0", Some(94978), None), /// Allows having using `suggestion` in the `#[deprecated]` attribute. (active, deprecated_suggestion, "1.61.0", Some(94785), None), - /// Allows `#[derive(Default)]` and `#[default]` on enums. - (active, derive_default_enum, "1.56.0", Some(86985), None), /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`. (active, doc_auto_cfg, "1.58.0", Some(43781), None), /// Allows `#[doc(cfg(...))]`. diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index bfc537cfae2..940c4ecdcc2 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -11,7 +11,7 @@ //! even if it is stabilized or removed, *do not remove it*. Instead, move the //! symbol to the `accepted` or `removed` modules respectively. -#![feature(derive_default_enum)] +#![cfg_attr(bootstrap, feature(derive_default_enum))] #![feature(once_cell)] mod accepted; diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index ff8b13d3112..83193746432 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2425,8 +2425,12 @@ pub enum InlineAsmOperand<'hir> { Const { anon_const: AnonConst, }, - Sym { - expr: Expr<'hir>, + SymFn { + anon_const: AnonConst, + }, + SymStatic { + path: QPath<'hir>, + def_id: DefId, }, } @@ -2437,7 +2441,7 @@ impl<'hir> InlineAsmOperand<'hir> { | Self::Out { reg, .. } | Self::InOut { reg, .. } | Self::SplitInOut { reg, .. } => Some(reg), - Self::Const { .. } | Self::Sym { .. } => None, + Self::Const { .. } | Self::SymFn { .. } | Self::SymStatic { .. } => None, } } @@ -2557,11 +2561,17 @@ impl FnRetTy<'_> { #[derive(Encodable, Debug, HashStable_Generic)] pub struct Mod<'hir> { + pub spans: ModSpans, + pub item_ids: &'hir [ItemId], +} + +#[derive(Copy, Clone, Debug, HashStable_Generic, Encodable)] +pub struct ModSpans { /// A span from the first token past `{` to the last token until `}`. /// For `mod foo;`, the inner span ranges from the first token /// to the last token in the external file. - pub inner: Span, - pub item_ids: &'hir [ItemId], + pub inner_span: Span, + pub inject_use_span: Span, } #[derive(Debug, HashStable_Generic)] @@ -3059,8 +3069,8 @@ impl<'hir> OwnerNode<'hir> { OwnerNode::Item(Item { span, .. }) | OwnerNode::ForeignItem(ForeignItem { span, .. }) | OwnerNode::ImplItem(ImplItem { span, .. }) - | OwnerNode::TraitItem(TraitItem { span, .. }) - | OwnerNode::Crate(Mod { inner: span, .. }) => *span, + | OwnerNode::TraitItem(TraitItem { span, .. }) => *span, + OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span, } } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 1b40f3d390e..445b856e513 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -484,6 +484,9 @@ pub trait Visitor<'v>: Sized { fn visit_defaultness(&mut self, defaultness: &'v Defaultness) { walk_defaultness(self, defaultness); } + fn visit_inline_asm(&mut self, asm: &'v InlineAsm<'v>, id: HirId) { + walk_inline_asm(self, asm, id); + } } pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod<'v>, mod_hir_id: HirId) { @@ -588,7 +591,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { } ItemKind::GlobalAsm(asm) => { visitor.visit_id(item.hir_id()); - walk_inline_asm(visitor, asm); + visitor.visit_inline_asm(asm, item.hir_id()); } ItemKind::TyAlias(ref ty, ref generics) => { visitor.visit_id(item.hir_id()); @@ -648,12 +651,12 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { } } -fn walk_inline_asm<'v, V: Visitor<'v>>(visitor: &mut V, asm: &'v InlineAsm<'v>) { - for (op, _op_sp) in asm.operands { +pub fn walk_inline_asm<'v, V: Visitor<'v>>(visitor: &mut V, asm: &'v InlineAsm<'v>, id: HirId) { + for (op, op_sp) in asm.operands { match op { - InlineAsmOperand::In { expr, .. } - | InlineAsmOperand::InOut { expr, .. } - | InlineAsmOperand::Sym { expr, .. } => visitor.visit_expr(expr), + InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => { + visitor.visit_expr(expr) + } InlineAsmOperand::Out { expr, .. } => { if let Some(expr) = expr { visitor.visit_expr(expr); @@ -665,7 +668,9 @@ fn walk_inline_asm<'v, V: Visitor<'v>>(visitor: &mut V, asm: &'v InlineAsm<'v>) visitor.visit_expr(out_expr); } } - InlineAsmOperand::Const { anon_const } => visitor.visit_anon_const(anon_const), + InlineAsmOperand::Const { anon_const, .. } + | InlineAsmOperand::SymFn { anon_const, .. } => visitor.visit_anon_const(anon_const), + InlineAsmOperand::SymStatic { path, .. } => visitor.visit_qpath(path, id, *op_sp), } } } @@ -1221,7 +1226,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) walk_list!(visitor, visit_expr, optional_expression); } ExprKind::InlineAsm(ref asm) => { - walk_inline_asm(visitor, asm); + visitor.visit_inline_asm(asm, expression.hir_id); } ExprKind::Yield(ref subexpression, _) => { visitor.visit_expr(subexpression); diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index b8df1632144..9318ebb40b0 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -326,6 +326,8 @@ language_item_table! { Range, sym::Range, range_struct, Target::Struct, GenericRequirement::None; RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, Target::Struct, GenericRequirement::None; RangeTo, sym::RangeTo, range_to_struct, Target::Struct, GenericRequirement::None; + + CStr, sym::CStr, c_str, Target::Struct, GenericRequirement::None; } pub enum GenericRequirement { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index b3042c61002..27f07a479b1 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1352,10 +1352,15 @@ impl<'a> State<'a> { s.space(); s.print_anon_const(anon_const); } - hir::InlineAsmOperand::Sym { expr } => { - s.word("sym"); + hir::InlineAsmOperand::SymFn { anon_const } => { + s.word("sym_fn"); s.space(); - s.print_expr(expr); + s.print_anon_const(anon_const); + } + hir::InlineAsmOperand::SymStatic { path, def_id: _ } => { + s.word("sym_static"); + s.space(); + s.print_qpath(path, true); } }, AsmArg::Options(opts) => { diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 09b02ba74a8..58c309a5c52 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -63,9 +63,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// common state. Used in coherence. pub fn fork(&self) -> Self { Self { - tcx: self.tcx.clone(), - defining_use_anchor: self.defining_use_anchor.clone(), - in_progress_typeck_results: self.in_progress_typeck_results.clone(), + tcx: self.tcx, + defining_use_anchor: self.defining_use_anchor, + in_progress_typeck_results: self.in_progress_typeck_results, inner: self.inner.clone(), skip_leak_check: self.skip_leak_check.clone(), lexical_region_resolutions: self.lexical_region_resolutions.clone(), diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index f25215fe813..f2dd4f5d5cb 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1448,6 +1448,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { mut values: Option<ValuePairs<'tcx>>, terr: &TypeError<'tcx>, swap_secondary_and_primary: bool, + force_label: bool, ) { let span = cause.span(self.tcx); debug!("note_type_err cause={:?} values={:?}, terr={:?}", cause, values, terr); @@ -1623,7 +1624,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { TypeError::ObjectUnsafeCoercion(_) => {} _ => { let mut label_or_note = |span: Span, msg: &str| { - if &[span] == diag.span.primary_spans() { + if force_label || &[span] == diag.span.primary_spans() { diag.span_label(span, msg); } else { diag.span_note(span, msg); @@ -2171,7 +2172,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { struct_span_err!(self.tcx.sess, span, E0644, "{}", failure_str) } }; - self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr, false); + self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr, false, false); diag } @@ -2765,7 +2766,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } -enum FailureCode { +pub enum FailureCode { Error0038(DefId), Error0317(&'static str), Error0580(&'static str), @@ -2773,7 +2774,7 @@ enum FailureCode { Error0644(&'static str), } -trait ObligationCauseExt<'tcx> { +pub trait ObligationCauseExt<'tcx> { fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode; fn as_requirement_str(&self) -> &'static str; } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 2524bd78355..919b89396d6 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -385,8 +385,8 @@ impl<'tcx> ValuePairs<'tcx> { /// See the `error_reporting` module for more details. #[derive(Clone, Debug)] pub struct TypeTrace<'tcx> { - cause: ObligationCause<'tcx>, - values: ValuePairs<'tcx>, + pub cause: ObligationCause<'tcx>, + pub values: ValuePairs<'tcx>, } /// The origin of a `r1 <= r2` constraint. diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 08e005364ce..e859bcaec12 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -17,7 +17,7 @@ #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(control_flow_enum)] -#![feature(derive_default_enum)] +#![cfg_attr(bootstrap, feature(derive_default_enum))] #![feature(extend_one)] #![feature(label_break_value)] #![feature(let_chains)] diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 2a01b677e33..08987dff660 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -629,11 +629,15 @@ fn write_out_deps( }); files.extend(extra_tracked_files); - if let Some(ref backend) = sess.opts.debugging_opts.codegen_backend { - files.push(backend.to_string()); - } - if sess.binary_dep_depinfo() { + if let Some(ref backend) = sess.opts.debugging_opts.codegen_backend { + if backend.contains('.') { + // If the backend name contain a `.`, it is the path to an external dynamic + // library. If not, it is not a path. + files.push(backend.to_string()); + } + } + boxed_resolver.borrow_mut().access(|resolver| { for cnum in resolver.cstore().crates_untracked() { let source = resolver.cstore().crate_source_untracked(cnum); diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 89ce307d12c..a42e3d5d957 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1110,8 +1110,6 @@ declare_lint! { /// ### Example /// /// ```rust,compile_fail - /// #![deny(unaligned_references)] - /// /// #[repr(packed)] /// pub struct Foo { /// field1: u64, @@ -1139,10 +1137,11 @@ declare_lint! { /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html /// [issue #82523]: https://github.com/rust-lang/rust/issues/82523 pub UNALIGNED_REFERENCES, - Warn, + Deny, "detects unaligned references to fields of packed structs", @future_incompatible = FutureIncompatibleInfo { reference: "issue #82523 <https://github.com/rust-lang/rust/issues/82523>", + reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow, }; report_in_external_macro } diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 51739df067f..3ed4396d1e9 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1835,3 +1835,9 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler( unwrap(C)->setDiagnosticHandler(std::make_unique<RustDiagnosticHandler>( DiagnosticHandlerCallback, DiagnosticHandlerContext, RemarkAllPasses, Passes)); } + +extern "C" void LLVMRustGetMangledName(LLVMValueRef V, RustStringRef Str) { + RawRustStringOstream OS(Str); + GlobalValue *GV = unwrap<GlobalValue>(V); + Mangler().getNameWithPrefix(OS, GV, true); +} diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 3589860eb0e..b53ef816135 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -44,7 +44,7 @@ pub fn symbols(input: TokenStream) -> TokenStream { #[proc_macro] #[allow_internal_unstable(step_trait, rustc_attrs, trusted_step)] pub fn newtype_index(input: TokenStream) -> TokenStream { - newtype::newtype(input).into() + newtype::newtype(input) } decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive); diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index a9e3b55aeee..566d27212d0 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -417,6 +417,7 @@ impl<'a> CrateLoader<'a> { let crate_metadata = CrateMetadata::new( self.sess, + &self.cstore, metadata, crate_root, raw_proc_macros, diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 3933a0d19a4..8d0e8467404 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1,6 +1,6 @@ // Decoding metadata from a single crate's metadata -use crate::creader::CrateMetadataRef; +use crate::creader::{CStore, CrateMetadataRef}; use crate::rmeta::table::{FixedSizeEncoding, Table}; use crate::rmeta::*; @@ -1737,6 +1737,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { impl CrateMetadata { crate fn new( sess: &Session, + cstore: &CStore, blob: MetadataBlob, root: CrateRoot<'static>, raw_proc_macros: Option<&'static [ProcMacro]>, @@ -1752,11 +1753,6 @@ impl CrateMetadata { .decode((&blob, sess)) .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls)) .collect(); - let incoherent_impls = root - .incoherent_impls - .decode((&blob, sess)) - .map(|incoherent_impls| (incoherent_impls.self_ty, incoherent_impls.impls)) - .collect(); let alloc_decoding_state = AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect()); let dependencies = Lock::new(cnum_map.iter().cloned().collect()); @@ -1765,11 +1761,11 @@ impl CrateMetadata { // that does not copy any data. It just does some data verification. let def_path_hash_map = root.def_path_hash_map.decode(&blob); - CrateMetadata { + let mut cdata = CrateMetadata { blob, root, trait_impls, - incoherent_impls, + incoherent_impls: Default::default(), raw_proc_macros, source_map_import_info: OnceCell::new(), def_path_hash_map, @@ -1786,7 +1782,17 @@ impl CrateMetadata { hygiene_context: Default::default(), def_key_cache: Default::default(), def_path_hash_cache: Default::default(), - } + }; + + // Need `CrateMetadataRef` to decode `DefId`s in simplified types. + cdata.incoherent_impls = cdata + .root + .incoherent_impls + .decode(CrateMetadataRef { cdata: &cdata, cstore }) + .map(|incoherent_impls| (incoherent_impls.self_ty, incoherent_impls.impls)) + .collect(); + + cdata } crate fn dependencies(&self) -> LockGuard<'_, Vec<CrateNum>> { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 65796fbc698..08cd40f38ef 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -584,7 +584,7 @@ impl<'hir> Map<'hir> { Some(OwnerNode::Item(&Item { span, kind: ItemKind::Mod(ref m), .. })) => { (m, span, hir_id) } - Some(OwnerNode::Crate(item)) => (item, item.inner, hir_id), + Some(OwnerNode::Crate(item)) => (item, item.spans.inner_span, hir_id), node => panic!("not a module: {:?}", node), } } @@ -1012,7 +1012,7 @@ impl<'hir> Map<'hir> { Node::Infer(i) => i.span, Node::Visibility(v) => bug!("unexpected Visibility {:?}", v), Node::Local(local) => local.span, - Node::Crate(item) => item.inner, + Node::Crate(item) => item.spans.inner_span, }; Some(span) } diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index fd2b5f5335f..199b5fa0314 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -30,7 +30,7 @@ #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(core_intrinsics)] -#![feature(derive_default_enum)] +#![cfg_attr(bootstrap, feature(derive_default_enum))] #![feature(discriminant_kind)] #![feature(exhaustive_patterns)] #![feature(get_mut_unchecked)] diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index 98da20baf02..af16e5e3fc8 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -362,12 +362,9 @@ impl ScopeTree { self.parent_map.get(&id).cloned().map(|(p, _)| p) } - /// Returns the lifetime of the local variable `var_id` - pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Scope { - self.var_map - .get(&var_id) - .cloned() - .unwrap_or_else(|| bug!("no enclosing scope for id {:?}", var_id)) + /// Returns the lifetime of the local variable `var_id`, if any. + pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Option<Scope> { + self.var_map.get(&var_id).cloned() } /// Returns the scope when the temp created by `expr_id` will be cleaned up. diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index db7e973fb62..49769b7ae3d 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2518,7 +2518,8 @@ pub enum Rvalue<'tcx> { /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second /// parameter may be a `usize` as well. /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats, - /// raw pointers, or function pointers of matching types and return a `bool`. + /// raw pointers, or function pointers and return a `bool`. The types of the operands must be + /// matching, up to the usual caveat of the lifetimes in function pointers. /// * Left and right shift operations accept signed or unsigned integers not necessarily of the /// same type and return a value of the same type as their LHS. Like in Rust, the RHS is /// truncated as needed. diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index b17343d7692..e56efb8d497 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -526,7 +526,8 @@ pub enum InlineAsmOperand<'tcx> { span: Span, }, SymFn { - expr: ExprId, + value: mir::ConstantKind<'tcx>, + span: Span, }, SymStatic { def_id: DefId, diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index ef7becde69a..f57569522d5 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -138,8 +138,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp match op { In { expr, reg: _ } | Out { expr: Some(expr), reg: _, late: _ } - | InOut { expr, reg: _, late: _ } - | SymFn { expr } => visitor.visit_expr(&visitor.thir()[*expr]), + | InOut { expr, reg: _, late: _ } => visitor.visit_expr(&visitor.thir()[*expr]), SplitInOut { in_expr, out_expr, reg: _, late: _ } => { visitor.visit_expr(&visitor.thir()[*in_expr]); if let Some(out_expr) = out_expr { @@ -148,6 +147,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp } Out { expr: None, reg: _, late: _ } | Const { value: _, span: _ } + | SymFn { value: _, span: _ } | SymStatic { def_id: _ } => {} } } diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 2c78c1f63d8..226456588e7 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -191,7 +191,7 @@ impl<'tcx> Ty<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> DefIdForest<'tcx> { - tcx.type_uninhabited_from(param_env.and(self)).clone() + tcx.type_uninhabited_from(param_env.and(self)) } } diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 8b9b1847e7f..3a6e59db90b 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -39,7 +39,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } }; - Constant { span, user_ty: None, literal: literal.into() } + Constant { span, user_ty: None, literal } } ExprKind::NonHirLiteral { lit, user_ty } => { let user_ty = user_ty.map(|user_ty| { diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index a8f623dbe46..a04ac338274 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -423,6 +423,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } thir::InlineAsmOperand::Const { value, span } => { mir::InlineAsmOperand::Const { + value: Box::new(Constant { span, user_ty: None, literal: value }), + } + } + thir::InlineAsmOperand::SymFn { value, span } => { + mir::InlineAsmOperand::SymFn { value: Box::new(Constant { span, user_ty: None, @@ -430,9 +435,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }), } } - thir::InlineAsmOperand::SymFn { expr } => mir::InlineAsmOperand::SymFn { - value: Box::new(this.as_constant(&this.thir[expr])), - }, thir::InlineAsmOperand::SymStatic { def_id } => { mir::InlineAsmOperand::SymStatic { def_id } } diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 219d101aa7c..d45ae19752e 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -701,8 +701,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let local_id = self.var_local_id(var, for_guard); let source_info = self.source_info(span); self.cfg.push(block, Statement { source_info, kind: StatementKind::StorageLive(local_id) }); - let region_scope = self.region_scope_tree.var_scope(var.local_id); - if schedule_drop { + // Altough there is almost always scope for given variable in corner cases + // like #92893 we might get variable with no scope. + if let Some(region_scope) = self.region_scope_tree.var_scope(var.local_id) && schedule_drop{ self.schedule_drop(span, region_scope, local_id, DropKind::Storage); } Place::from(local_id) @@ -710,8 +711,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { crate fn schedule_drop_for_binding(&mut self, var: HirId, span: Span, for_guard: ForGuard) { let local_id = self.var_local_id(var, for_guard); - let region_scope = self.region_scope_tree.var_scope(var.local_id); - self.schedule_drop(span, region_scope, local_id, DropKind::Value); + if let Some(region_scope) = self.region_scope_tree.var_scope(var.local_id) { + self.schedule_drop(span, region_scope, local_id, DropKind::Value); + } } /// Visit all of the primary bindings in a patterns, that is, visit the diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 806c260d110..0e9e9869376 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -441,7 +441,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Need to experiment. user_ty: None, - literal: method.into(), + literal: method, })), args: vec![val, expect], destination: Some((eq_result, eq_block)), diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 7ef33011234..f382f79af29 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -462,95 +462,56 @@ impl<'tcx> Cx<'tcx> { operands: asm .operands .iter() - .map(|(op, _op_sp)| { - match *op { - hir::InlineAsmOperand::In { reg, ref expr } => { - InlineAsmOperand::In { reg, expr: self.mirror_expr(expr) } - } - hir::InlineAsmOperand::Out { reg, late, ref expr } => { - InlineAsmOperand::Out { - reg, - late, - expr: expr.as_ref().map(|expr| self.mirror_expr(expr)), - } - } - hir::InlineAsmOperand::InOut { reg, late, ref expr } => { - InlineAsmOperand::InOut { reg, late, expr: self.mirror_expr(expr) } - } - hir::InlineAsmOperand::SplitInOut { - reg, - late, - ref in_expr, - ref out_expr, - } => InlineAsmOperand::SplitInOut { + .map(|(op, _op_sp)| match *op { + hir::InlineAsmOperand::In { reg, ref expr } => { + InlineAsmOperand::In { reg, expr: self.mirror_expr(expr) } + } + hir::InlineAsmOperand::Out { reg, late, ref expr } => { + InlineAsmOperand::Out { reg, late, - in_expr: self.mirror_expr(in_expr), - out_expr: out_expr.as_ref().map(|expr| self.mirror_expr(expr)), - }, - hir::InlineAsmOperand::Const { ref anon_const } => { - let anon_const_def_id = - self.tcx.hir().local_def_id(anon_const.hir_id); - let value = mir::ConstantKind::from_anon_const( - self.tcx, - anon_const_def_id, - self.param_env, - ); - let span = self.tcx.hir().span(anon_const.hir_id); - - InlineAsmOperand::Const { value, span } - } - hir::InlineAsmOperand::Sym { ref expr } => { - let hir::ExprKind::Path(ref qpath) = expr.kind else { - span_bug!( - expr.span, - "asm `sym` operand should be a path, found {:?}", - expr.kind - ); - }; - let temp_lifetime = - self.region_scope_tree.temporary_scope(expr.hir_id.local_id); - let res = self.typeck_results().qpath_res(qpath, expr.hir_id); - let ty; - match res { - Res::Def(DefKind::Fn, _) | Res::Def(DefKind::AssocFn, _) => { - ty = self.typeck_results().node_type(expr.hir_id); - let user_ty = - self.user_substs_applied_to_res(expr.hir_id, res); - InlineAsmOperand::SymFn { - expr: self.thir.exprs.push(Expr { - ty, - temp_lifetime, - span: expr.span, - kind: ExprKind::zero_sized_literal(user_ty), - }), - } - } - - Res::Def(DefKind::Static(_), def_id) => { - InlineAsmOperand::SymStatic { def_id } - } - - _ => { - self.tcx.sess.span_err( - expr.span, - "asm `sym` operand must point to a fn or static", - ); - - // Not a real fn, but we're not reaching codegen anyways... - ty = self.tcx.ty_error(); - InlineAsmOperand::SymFn { - expr: self.thir.exprs.push(Expr { - ty, - temp_lifetime, - span: expr.span, - kind: ExprKind::zero_sized_literal(None), - }), - } - } - } + expr: expr.as_ref().map(|expr| self.mirror_expr(expr)), } } + hir::InlineAsmOperand::InOut { reg, late, ref expr } => { + InlineAsmOperand::InOut { reg, late, expr: self.mirror_expr(expr) } + } + hir::InlineAsmOperand::SplitInOut { + reg, + late, + ref in_expr, + ref out_expr, + } => InlineAsmOperand::SplitInOut { + reg, + late, + in_expr: self.mirror_expr(in_expr), + out_expr: out_expr.as_ref().map(|expr| self.mirror_expr(expr)), + }, + hir::InlineAsmOperand::Const { ref anon_const } => { + let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id); + let value = mir::ConstantKind::from_anon_const( + self.tcx, + anon_const_def_id, + self.param_env, + ); + let span = self.tcx.hir().span(anon_const.hir_id); + + InlineAsmOperand::Const { value, span } + } + hir::InlineAsmOperand::SymFn { ref anon_const } => { + let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id); + let value = mir::ConstantKind::from_anon_const( + self.tcx, + anon_const_def_id, + self.param_env, + ); + let span = self.tcx.hir().span(anon_const.hir_id); + + InlineAsmOperand::SymFn { value, span } + } + hir::InlineAsmOperand::SymStatic { path: _, def_id } => { + InlineAsmOperand::SymStatic { def_id } + } }) .collect(), options: asm.options, diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 44caa2ac076..58e484e413d 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -844,7 +844,7 @@ fn non_exhaustive_match<'p, 'tcx>( format!( "{}{}{} => todo!()", comma, - snippet.strip_prefix(",").unwrap_or(&snippet), + snippet.strip_prefix(',').unwrap_or(&snippet), pattern ), )); diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index d1d6e7cfe2f..1b4510b6220 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -539,13 +539,13 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) { UnusedUnsafe::InUnsafeBlock(id) => { db.span_label( tcx.sess.source_map().guess_head_span(tcx.hir().span(id)), - format!("because it's nested under this `unsafe` block"), + "because it's nested under this `unsafe` block", ); } UnusedUnsafe::InUnsafeFn(id, usage_lint_root) => { db.span_label( tcx.sess.source_map().guess_head_span(tcx.hir().span(id)), - format!("because it's nested under this `unsafe` fn"), + "because it's nested under this `unsafe` fn", ) .note( "this `unsafe` block does contain unsafe operations, \ diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 2a659a97db5..fdb14e45d98 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -435,7 +435,27 @@ fn collect_items_rec<'tcx>( // are supported. Therefore the value should not // depend on any other items. } - _ => span_bug!(*op_sp, "invalid operand type for global_asm!"), + hir::InlineAsmOperand::SymFn { anon_const } => { + let def_id = tcx.hir().body_owner_def_id(anon_const.body).to_def_id(); + if let Ok(val) = tcx.const_eval_poly(def_id) { + rustc_data_structures::stack::ensure_sufficient_stack(|| { + collect_const_value(tcx, val, &mut neighbors); + }); + } + } + hir::InlineAsmOperand::SymStatic { path: _, def_id } => { + let instance = Instance::mono(tcx, *def_id); + if should_codegen_locally(tcx, &instance) { + trace!("collecting static {:?}", def_id); + neighbors.push(dummy_spanned(MonoItem::Static(*def_id))); + } + } + hir::InlineAsmOperand::In { .. } + | hir::InlineAsmOperand::Out { .. } + | hir::InlineAsmOperand::InOut { .. } + | hir::InlineAsmOperand::SplitInOut { .. } => { + span_bug!(*op_sp, "invalid operand type for global_asm!") + } } } } else { diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 5ab412dc777..bfa13ce79ba 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -182,16 +182,7 @@ impl<'a> StringReader<'a> { } rustc_lexer::TokenKind::BlockComment { doc_style, terminated } => { if !terminated { - let msg = match doc_style { - Some(_) => "unterminated block doc-comment", - None => "unterminated block comment", - }; - let last_bpos = self.pos; - self.sess.span_diagnostic.span_fatal_with_code( - self.mk_sp(start, last_bpos), - msg, - error_code!(E0758), - ); + self.report_unterminated_block_comment(start, doc_style); } // Skip non-doc comments @@ -234,13 +225,13 @@ impl<'a> StringReader<'a> { rustc_lexer::TokenKind::InvalidIdent // Do not recover an identifier with emoji if the codepoint is a confusable // with a recoverable substitution token, like `âž–`. - if UNICODE_ARRAY + if !UNICODE_ARRAY .iter() - .find(|&&(c, _, _)| { + .any(|&(c, _, _)| { let sym = self.str_from(start); sym.chars().count() == 1 && c == sym.chars().next().unwrap() }) - .is_none() => + => { let sym = nfc_normalize(self.str_from(start)); let span = self.mk_sp(start, self.pos); @@ -553,6 +544,55 @@ impl<'a> StringReader<'a> { err.emit() } + fn report_unterminated_block_comment(&self, start: BytePos, doc_style: Option<DocStyle>) { + let msg = match doc_style { + Some(_) => "unterminated block doc-comment", + None => "unterminated block comment", + }; + let last_bpos = self.pos; + let mut err = self.sess.span_diagnostic.struct_span_fatal_with_code( + self.mk_sp(start, last_bpos), + msg, + error_code!(E0758), + ); + let mut nested_block_comment_open_idxs = vec![]; + let mut last_nested_block_comment_idxs = None; + let mut content_chars = self.str_from(start).char_indices().peekable(); + + while let Some((idx, current_char)) = content_chars.next() { + match content_chars.peek() { + Some((_, '*')) if current_char == '/' => { + nested_block_comment_open_idxs.push(idx); + } + Some((_, '/')) if current_char == '*' => { + last_nested_block_comment_idxs = + nested_block_comment_open_idxs.pop().map(|open_idx| (open_idx, idx)); + } + _ => {} + }; + } + + if let Some((nested_open_idx, nested_close_idx)) = last_nested_block_comment_idxs { + err.span_label(self.mk_sp(start, start + BytePos(2)), msg) + .span_label( + self.mk_sp( + start + BytePos(nested_open_idx as u32), + start + BytePos(nested_open_idx as u32 + 2), + ), + "...as last nested comment starts here, maybe you want to close this instead?", + ) + .span_label( + self.mk_sp( + start + BytePos(nested_close_idx as u32), + start + BytePos(nested_close_idx as u32 + 2), + ), + "...and last nested comment terminates here.", + ); + } + + err.emit(); + } + // RFC 3101 introduced the idea of (reserved) prefixes. As of Rust 2021, // using a (unknown) prefix is an error. In earlier editions, however, they // only result in a (allowed by default) lint, and are treated as regular diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index c777074df46..261ea0b4deb 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -158,7 +158,6 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { #[allow(dead_code)] // FIXME(81658): should be used + lint reinstated after #83171 relands. fn check_for_self_assign(&mut self, assign: &'tcx hir::Expr<'tcx>) { fn check_for_self_assign_helper<'tcx>( - tcx: TyCtxt<'tcx>, typeck_results: &'tcx ty::TypeckResults<'tcx>, lhs: &'tcx hir::Expr<'tcx>, rhs: &'tcx hir::Expr<'tcx>, @@ -177,7 +176,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } (hir::ExprKind::Field(lhs_l, ident_l), hir::ExprKind::Field(lhs_r, ident_r)) => { if ident_l == ident_r { - return check_for_self_assign_helper(tcx, typeck_results, lhs_l, lhs_r); + return check_for_self_assign_helper(typeck_results, lhs_l, lhs_r); } return false; } @@ -188,7 +187,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } if let hir::ExprKind::Assign(lhs, rhs, _) = assign.kind { - if check_for_self_assign_helper(self.tcx, self.typeck_results(), lhs, rhs) + if check_for_self_assign_helper(self.typeck_results(), lhs, rhs) && !assign.span.from_expansion() { let is_field_assign = matches!(lhs.kind, hir::ExprKind::Field(..)); @@ -537,6 +536,10 @@ impl<'v, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'tcx> { .insert(self.tcx.hir().local_def_id(ctor_hir_id), item.def_id); } } + hir::ItemKind::GlobalAsm(_) => { + // global_asm! is always live. + self.worklist.push(item.def_id); + } _ => (), } } diff --git a/compiler/rustc_passes/src/intrinsicck.rs b/compiler/rustc_passes/src/intrinsicck.rs index 027eac16bad..7028fc44126 100644 --- a/compiler/rustc_passes/src/intrinsicck.rs +++ b/compiler/rustc_passes/src/intrinsicck.rs @@ -1,3 +1,4 @@ +use hir::intravisit::walk_inline_asm; use rustc_ast::InlineAsmTemplatePiece; use rustc_data_structures::stable_set::FxHashSet; use rustc_errors::struct_span_err; @@ -483,7 +484,10 @@ impl<'tcx> ExprVisitor<'tcx> { ); } } - hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::Sym { .. } => {} + // These are checked in ItemVisitor. + hir::InlineAsmOperand::Const { .. } + | hir::InlineAsmOperand::SymFn { .. } + | hir::InlineAsmOperand::SymStatic { .. } => {} } } } @@ -498,6 +502,42 @@ impl<'tcx> Visitor<'tcx> for ItemVisitor<'tcx> { ExprVisitor { tcx: self.tcx, param_env, typeck_results }.visit_body(body); self.visit_body(body); } + + fn visit_inline_asm(&mut self, asm: &'tcx hir::InlineAsm<'tcx>, id: hir::HirId) { + for (op, op_sp) in asm.operands.iter() { + match *op { + // These are checked in ExprVisitor. + hir::InlineAsmOperand::In { .. } + | hir::InlineAsmOperand::Out { .. } + | hir::InlineAsmOperand::InOut { .. } + | hir::InlineAsmOperand::SplitInOut { .. } => {} + // No special checking is needed for these: + // - Typeck has checked that Const operands are integers. + // - AST lowering guarantees that SymStatic points to a static. + hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::SymStatic { .. } => {} + // Check that sym actually points to a function. Later passes + // depend on this. + hir::InlineAsmOperand::SymFn { anon_const } => { + let ty = self.tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); + match ty.kind() { + ty::Never | ty::Error(_) => {} + ty::FnDef(..) => {} + _ => { + let mut err = + self.tcx.sess.struct_span_err(*op_sp, "invalid `sym` operand"); + err.span_label( + self.tcx.hir().span(anon_const.body.hir_id), + &format!("is {} `{}`", ty.kind().article(), ty), + ); + err.help("`sym` operands must refer to either a function or a static"); + err.emit(); + } + }; + } + } + } + walk_inline_asm(self, asm, id); + } } impl<'tcx> Visitor<'tcx> for ExprVisitor<'tcx> { diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 7298aba7e87..99ea73fe2fe 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1043,7 +1043,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { match op { hir::InlineAsmOperand::In { .. } | hir::InlineAsmOperand::Const { .. } - | hir::InlineAsmOperand::Sym { .. } => {} + | hir::InlineAsmOperand::SymFn { .. } + | hir::InlineAsmOperand::SymStatic { .. } => {} hir::InlineAsmOperand::Out { expr, .. } => { if let Some(expr) = expr { succ = self.write_place(expr, succ, ACC_WRITE); @@ -1064,8 +1065,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { let mut succ = succ; for (op, _op_sp) in asm.operands.iter().rev() { match op { - hir::InlineAsmOperand::In { expr, .. } - | hir::InlineAsmOperand::Sym { expr, .. } => { + hir::InlineAsmOperand::In { expr, .. } => { succ = self.propagate_through_expr(expr, succ) } hir::InlineAsmOperand::Out { expr, .. } => { @@ -1082,7 +1082,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } succ = self.propagate_through_expr(in_expr, succ); } - hir::InlineAsmOperand::Const { .. } => {} + hir::InlineAsmOperand::Const { .. } + | hir::InlineAsmOperand::SymFn { .. } + | hir::InlineAsmOperand::SymStatic { .. } => {} } } succ diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index af78fd5a6f2..e85720952da 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -252,7 +252,9 @@ impl<'tcx> CheckInlineAssembly<'tcx> { .operands .iter() .filter_map(|&(ref op, op_sp)| match op { - InlineAsmOperand::Const { .. } | InlineAsmOperand::Sym { .. } => None, + InlineAsmOperand::Const { .. } + | InlineAsmOperand::SymFn { .. } + | InlineAsmOperand::SymStatic { .. } => None, InlineAsmOperand::In { .. } | InlineAsmOperand::Out { .. } | InlineAsmOperand::InOut { .. } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index ff033cbb572..01ba9e35c24 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -133,9 +133,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { } // `Deprecation` is just two pointers, no need to intern it - let depr_entry = DeprecationEntry::local(depr.clone(), def_id); + let depr_entry = DeprecationEntry::local(*depr, def_id); self.index.depr_map.insert(def_id, depr_entry); - } else if let Some(parent_depr) = self.parent_depr.clone() { + } else if let Some(parent_depr) = self.parent_depr { if inherit_deprecation.yes() { is_deprecated = true; info!("tagging child {:?} as deprecated from parent", def_id); diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index d979311171b..f3b8c1e266c 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1012,6 +1012,12 @@ impl<'a> Resolver<'a> { err.span_label(trait_item_span, "item in trait"); err } + ResolutionError::InvalidAsmSym => { + let mut err = self.session.struct_span_err(span, "invalid `sym` operand"); + err.span_label(span, &format!("is a local variable")); + err.help("`sym` operands must refer to either a function or a static"); + err + } } } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 25ab3f7dacf..24b6d656981 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1182,6 +1182,12 @@ impl<'a> Resolver<'a> { } return Res::Err; } + InlineAsmSymRibKind => { + if let Some(span) = finalize { + self.report_error(span, InvalidAsmSym); + } + return Res::Err; + } } } if let Some((span, res_err)) = res_err { @@ -1242,6 +1248,22 @@ impl<'a> Resolver<'a> { } return Res::Err; } + InlineAsmSymRibKind => { + let features = self.session.features_untracked(); + if !features.generic_const_exprs { + if let Some(span) = finalize { + self.report_error( + span, + ResolutionError::ParamInNonTrivialAnonConst { + name: rib_ident.name, + is_type: true, + }, + ); + } + return Res::Err; + } + continue; + } }; if let Some(span) = finalize { @@ -1306,6 +1328,22 @@ impl<'a> Resolver<'a> { } return Res::Err; } + InlineAsmSymRibKind => { + let features = self.session.features_untracked(); + if !features.generic_const_exprs { + if let Some(span) = finalize { + self.report_error( + span, + ResolutionError::ParamInNonTrivialAnonConst { + name: rib_ident.name, + is_type: false, + }, + ); + } + return Res::Err; + } + continue; + } }; // This was an attempt to use a const parameter outside its scope. diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index aab0c1f9771..01dc727737a 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -310,18 +310,23 @@ impl<'a> Resolver<'a> { t } - // Define a "dummy" resolution containing a Res::Err as a placeholder for a - // failed resolution + // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed resolution, + // also mark such failed imports as used to avoid duplicate diagnostics. fn import_dummy_binding(&mut self, import: &'a Import<'a>) { - if let ImportKind::Single { target, .. } = import.kind { + if let ImportKind::Single { target, ref target_bindings, .. } = import.kind { + if target_bindings.iter().any(|binding| binding.get().is_some()) { + return; // Has resolution, do not create the dummy binding + } let dummy_binding = self.dummy_binding; let dummy_binding = self.import(dummy_binding, import); self.per_ns(|this, ns| { let key = this.new_key(target, ns); let _ = this.try_define(import.parent_scope.module, key, dummy_binding); }); - // Consider erroneous imports used to avoid duplicate diagnostics. self.record_use(target, dummy_binding, false); + } else if import.imported_module.get().is_none() { + import.used.set(true); + self.used_imports.insert(import.id); } } } @@ -386,7 +391,13 @@ impl<'a, 'b> ImportResolver<'a, 'b> { .map(|i| (false, i)) .chain(indeterminate_imports.into_iter().map(|i| (true, i))) { - if let Some(err) = self.finalize_import(import) { + let unresolved_import_error = self.finalize_import(import); + + // If this import is unresolved then create a dummy import + // resolution for it so that later resolve stages won't complain. + self.r.import_dummy_binding(import); + + if let Some(err) = unresolved_import_error { if let ImportKind::Single { source, ref source_bindings, .. } = import.kind { if source.name == kw::SelfLower { // Silence `unresolved import` error if E0429 is already emitted @@ -396,9 +407,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } } - // If the error is a single failed import then create a "fake" import - // resolution for it so that later resolve stages won't complain. - self.r.import_dummy_binding(import); if prev_root_id.as_u32() != 0 && prev_root_id.as_u32() != import.root_id.as_u32() && !errors.is_empty() @@ -418,8 +426,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> { prev_root_id = import.root_id; } } else if is_indeterminate { - // Consider erroneous imports used to avoid duplicate diagnostics. - self.r.used_imports.insert(import.id); let path = import_path_to_string( &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(), &import.kind, @@ -553,26 +559,23 @@ impl<'a, 'b> ImportResolver<'a, 'b> { Err(Undetermined) => indeterminate = true, // Don't update the resolution, because it was never added. Err(Determined) if target.name == kw::Underscore => {} - Err(Determined) => { + Ok(binding) if binding.is_importable() => { + let imported_binding = this.import(binding, import); + target_bindings[ns].set(Some(imported_binding)); + this.define(parent, target, ns, imported_binding); + } + source_binding @ (Ok(..) | Err(Determined)) => { + if source_binding.is_ok() { + let msg = format!("`{}` is not directly importable", target); + struct_span_err!(this.session, import.span, E0253, "{}", &msg) + .span_label(import.span, "cannot be imported directly") + .emit(); + } let key = this.new_key(target, ns); this.update_resolution(parent, key, |_, resolution| { resolution.single_imports.remove(&Interned::new_unchecked(import)); }); } - Ok(binding) if !binding.is_importable() => { - let msg = format!("`{}` is not directly importable", target); - struct_span_err!(this.session, import.span, E0253, "{}", &msg) - .span_label(import.span, "cannot be imported directly") - .emit(); - // Do not import this illegal binding. Import a dummy binding and pretend - // everything is fine - this.import_dummy_binding(import); - } - Ok(binding) => { - let imported_binding = this.import(binding, import); - target_bindings[ns].set(Some(imported_binding)); - this.define(parent, target, ns, imported_binding); - } } } }); @@ -605,10 +608,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> { ); let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len; import.vis.set(orig_vis); - if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res { - // Consider erroneous imports used to avoid duplicate diagnostics. - self.r.used_imports.insert(import.id); - } let module = match path_res { PathResult::Module(module) => { // Consistency checks, analogous to `finalize_macro_resolutions`. @@ -872,7 +871,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> { }) } else { // `resolve_ident_in_module` reported a privacy error. - self.r.import_dummy_binding(import); None }; } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f27b60e889f..763f31622bc 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -140,6 +140,10 @@ crate enum RibKind<'a> { /// We are inside of the type of a const parameter. Can't refer to any /// parameters. ConstParamTyRibKind, + + /// We are inside a `sym` inline assembly operand. Can only refer to + /// globals. + InlineAsmSymRibKind, } impl RibKind<'_> { @@ -153,7 +157,8 @@ impl RibKind<'_> { | ConstantItemRibKind(..) | ModuleRibKind(_) | MacroDefinition(_) - | ConstParamTyRibKind => false, + | ConstParamTyRibKind + | InlineAsmSymRibKind => false, AssocItemRibKind | ItemRibKind(_) | ForwardGenericParamBanRibKind => true, } } @@ -722,6 +727,23 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { visit::walk_where_predicate(self, p); self.diagnostic_metadata.current_where_predicate = previous_value; } + + fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) { + // This is similar to the code for AnonConst. + self.with_rib(ValueNS, InlineAsmSymRibKind, |this| { + this.with_rib(TypeNS, InlineAsmSymRibKind, |this| { + this.with_label_rib(InlineAsmSymRibKind, |this| { + this.smart_resolve_path( + sym.id, + sym.qself.as_ref(), + &sym.path, + PathSource::Expr(None), + ); + visit::walk_inline_asm_sym(this, sym); + }); + }) + }); + } } impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { @@ -909,7 +931,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { | ConstantItemRibKind(..) | ModuleRibKind(..) | ForwardGenericParamBanRibKind - | ConstParamTyRibKind => { + | ConstParamTyRibKind + | InlineAsmSymRibKind => { return false; } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b2c7a4d18de..0335c40d70d 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -260,6 +260,8 @@ enum ResolutionError<'a> { trait_item_span: Span, code: rustc_errors::DiagnosticId, }, + /// Inline asm `sym` operand must refer to a `fn` or `static`. + InvalidAsmSym, } enum VisResolutionError<'a> { diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs index 1eb575e0db2..22d0a20395e 100644 --- a/compiler/rustc_save_analysis/src/dump_visitor.rs +++ b/compiler/rustc_save_analysis/src/dump_visitor.rs @@ -1095,11 +1095,11 @@ impl<'tcx> DumpVisitor<'tcx> { let sm = self.tcx.sess.source_map(); let krate_mod = self.tcx.hir().root_module(); - let filename = sm.span_to_filename(krate_mod.inner); + let filename = sm.span_to_filename(krate_mod.spans.inner_span); let data_id = id_from_hir_id(id, &self.save_ctxt); let children = krate_mod.item_ids.iter().map(|i| id_from_def_id(i.def_id.to_def_id())).collect(); - let span = self.span_from_span(krate_mod.inner); + let span = self.span_from_span(krate_mod.spans.inner_span); let attrs = self.tcx.hir().attrs(id); self.dumper.dump_def( diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index 08a990c65ff..102268c6ca3 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -282,7 +282,7 @@ impl<'tcx> SaveContext<'tcx> { let qualname = format!("::{}", self.tcx.def_path_str(def_id)); let sm = self.tcx.sess.source_map(); - let filename = sm.span_to_filename(m.inner); + let filename = sm.span_to_filename(m.spans.inner_span); filter!(self.span_utils, item.ident.span); diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 3151b025fff..054b18b6b63 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -1,7 +1,7 @@ #![feature(crate_visibility_modifier)] -#![feature(derive_default_enum)] #![feature(if_let_guard)] #![feature(let_chains)] +#![cfg_attr(bootstrap, feature(derive_default_enum))] #![feature(let_else)] #![feature(min_specialization)] #![feature(never_type)] diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index c461b26788a..b4548129689 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -238,7 +238,7 @@ impl Session { } diag.emit(); // If we should err, make sure we did. - if must_err && !self.has_errors().is_some() { + if must_err && self.has_errors().is_none() { // We have skipped a feature gate, and not run into other errors... reject. self.err( "`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \ @@ -991,6 +991,11 @@ impl Session { self.opts.edition >= Edition::Edition2021 } + /// Are we allowed to use features from the Rust 2024 edition? + pub fn rust_2024(&self) -> bool { + self.opts.edition >= Edition::Edition2024 + } + pub fn edition(&self) -> Edition { self.opts.edition } diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs index 511c2e86626..065d3660e50 100644 --- a/compiler/rustc_span/src/edition.rs +++ b/compiler/rustc_span/src/edition.rs @@ -22,13 +22,15 @@ pub enum Edition { Edition2018, /// The 2021 edition Edition2021, + /// The 2024 edition + Edition2024, } // Must be in order from oldest to newest. pub const ALL_EDITIONS: &[Edition] = - &[Edition::Edition2015, Edition::Edition2018, Edition::Edition2021]; + &[Edition::Edition2015, Edition::Edition2018, Edition::Edition2021, Edition::Edition2024]; -pub const EDITION_NAME_LIST: &str = "2015|2018|2021"; +pub const EDITION_NAME_LIST: &str = "2015|2018|2021|2024"; pub const DEFAULT_EDITION: Edition = Edition::Edition2015; @@ -40,6 +42,7 @@ impl fmt::Display for Edition { Edition::Edition2015 => "2015", Edition::Edition2018 => "2018", Edition::Edition2021 => "2021", + Edition::Edition2024 => "2024", }; write!(f, "{}", s) } @@ -51,6 +54,7 @@ impl Edition { Edition::Edition2015 => "rust_2015_compatibility", Edition::Edition2018 => "rust_2018_compatibility", Edition::Edition2021 => "rust_2021_compatibility", + Edition::Edition2024 => "rust_2024_compatibility", } } @@ -59,6 +63,7 @@ impl Edition { Edition::Edition2015 => sym::rust_2015_preview, Edition::Edition2018 => sym::rust_2018_preview, Edition::Edition2021 => sym::rust_2021_preview, + Edition::Edition2024 => sym::rust_2024_preview, } } @@ -67,8 +72,28 @@ impl Edition { Edition::Edition2015 => true, Edition::Edition2018 => true, Edition::Edition2021 => true, + Edition::Edition2024 => false, } } + + pub fn rust_2015(&self) -> bool { + *self == Edition::Edition2015 + } + + /// Are we allowed to use features from the Rust 2018 edition? + pub fn rust_2018(&self) -> bool { + *self >= Edition::Edition2018 + } + + /// Are we allowed to use features from the Rust 2021 edition? + pub fn rust_2021(&self) -> bool { + *self >= Edition::Edition2021 + } + + /// Are we allowed to use features from the Rust 2024 edition? + pub fn rust_2024(&self) -> bool { + *self >= Edition::Edition2024 + } } impl FromStr for Edition { @@ -78,6 +103,7 @@ impl FromStr for Edition { "2015" => Ok(Edition::Edition2015), "2018" => Ok(Edition::Edition2018), "2021" => Ok(Edition::Edition2021), + "2024" => Ok(Edition::Edition2024), _ => Err(()), } } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 45b0e0c2dd1..b132c0a2132 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -684,6 +684,11 @@ impl Span { self.edition() >= edition::Edition::Edition2021 } + #[inline] + pub fn rust_2024(self) -> bool { + self.edition() >= edition::Edition::Edition2024 + } + /// Returns the source callee. /// /// Returns `None` if the supplied span has no expansion trace, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index dc4d10f699c..d9bada29589 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1149,6 +1149,8 @@ symbols! { rust_2018_preview, rust_2021, rust_2021_preview, + rust_2024, + rust_2024_preview, rust_begin_unwind, rust_eh_catch_typeinfo, rust_eh_personality, @@ -1245,6 +1247,7 @@ symbols! { simd, simd_add, simd_and, + simd_arith_offset, simd_as, simd_bitmask, simd_cast, diff --git a/compiler/rustc_target/src/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs index 5a92ebdd9e8..cc3a0a69999 100644 --- a/compiler/rustc_target/src/abi/call/sparc64.rs +++ b/compiler/rustc_target/src/abi/call/sparc64.rs @@ -113,11 +113,11 @@ where data = arg_scalar(cx, &scalar, offset, data); } abi::Abi::Aggregate { .. } => { - for i in 0..layout.fields.count().clone() { + for i in 0..layout.fields.count() { if offset < layout.fields.offset(i) { offset = layout.fields.offset(i); } - data = parse_structure(cx, layout.field(cx, i).clone(), data.clone(), offset); + data = parse_structure(cx, layout.field(cx, i), data.clone(), offset); } } _ => { @@ -161,7 +161,7 @@ where let mut data = parse_structure( cx, - arg.layout.clone(), + arg.layout, Sdata { prefix: [None; 8], prefix_index: 0, diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 7523b844101..2ae7f34a91e 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -16,7 +16,7 @@ #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(crate_visibility_modifier)] -#![feature(derive_default_enum)] +#![cfg_attr(bootstrap, feature(derive_default_enum))] #![feature(drain_filter)] #![feature(hash_drain_filter)] #![feature(label_break_value)] diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 0cb70de2415..50e4fafdd6c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1654,7 +1654,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { }), _ => None, }; - self.note_type_err(&mut diag, &obligation.cause, secondary_span, values, err, true); + self.note_type_err( + &mut diag, + &obligation.cause, + secondary_span, + values, + err, + true, + false, + ); self.note_obligation_cause(&mut diag, obligation); diag.emit(); }); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index ead1f0126c4..7485c082f4e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2724,9 +2724,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { &format!( "consider annotating `{}` with `#[derive({})]`", trait_pred.skip_binder().self_ty(), - diagnostic_name.to_string(), + diagnostic_name, ), - format!("#[derive({})]\n", diagnostic_name.to_string()), + format!("#[derive({})]\n", diagnostic_name), Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs index 38be28c07ff..ce0e0a21ff5 100644 --- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs @@ -258,7 +258,7 @@ impl<'tcx> OnUnimplementedDirective { enclosing_scope = Some(enclosing_scope_.clone()); } - append_const_msg = command.append_const_msg.clone(); + append_const_msg = command.append_const_msg; } OnUnimplementedNote { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 4734a843a9c..8ba390c71db 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -19,6 +19,7 @@ use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; use crate::traits::error_reporting::InferCtxtExt as _; +use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use crate::traits::select::ProjectionMatchesProjection; use rustc_data_structures::sso::SsoHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -1562,7 +1563,16 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // type parameters, opaques, and unnormalized projections have pointer // metadata if they're known (e.g. by the param_env) to be sized ty::Param(_) | ty::Projection(..) | ty::Opaque(..) - if tail.is_sized(selcx.tcx().at(obligation.cause.span), obligation.param_env) => + if selcx.infcx().predicate_must_hold_modulo_regions( + &obligation.with( + ty::Binder::dummy(ty::TraitRef::new( + selcx.tcx().require_lang_item(LangItem::Sized, None), + selcx.tcx().mk_substs_trait(self_ty, &[]), + )) + .without_const() + .to_predicate(selcx.tcx()), + ), + ) => { true } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 06f58240992..dbb6c54fcd9 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -231,8 +231,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // `Err(Unimplemented)` to `Ok(None)`. This helps us avoid // emitting additional spurious errors, since we're guaranteed // to have emitted at least one. - if stack.obligation.references_error() { - debug!("no results for error type, treating as ambiguous"); + if stack.obligation.predicate.references_error() { + debug!(?stack.obligation.predicate, "found error type in predicate, treating as ambiguous"); return Ok(None); } return Err(Unimplemented); diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index 26f7c267ed1..1c7e7c935c4 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -260,10 +260,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &mut |err| { if let Some((span, msg)) = &ret_reason { err.span_label(*span, msg.as_str()); - } else if let ExprKind::Block(block, _) = &then_expr.kind { - if let Some(expr) = &block.expr { - err.span_label(expr.span, "found here".to_string()); - } + } else if let ExprKind::Block(block, _) = &then_expr.kind + && let Some(expr) = &block.expr + { + err.span_label(expr.span, "found here".to_string()); } err.note("`if` expressions without `else` evaluate to `()`"); err.help("consider adding an `else` block that evaluates to the expected type"); @@ -293,7 +293,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return self.get_fn_decl(hir_id).and_then(|(fn_decl, _)| { let span = fn_decl.output.span(); let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok()?; - Some((span, format!("expected `{}` because of this return type", snippet))) + Some((span, format!("expected `{snippet}` because of this return type"))) }); } } diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index 2a5cf03e9d0..580fb7c3e0f 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -43,7 +43,7 @@ pub fn check_legal_trait_for_method_call( let (sp, suggestion) = receiver .and_then(|s| tcx.sess.source_map().span_to_snippet(s).ok()) .filter(|snippet| !snippet.is_empty()) - .map(|snippet| (expr_span, format!("drop({})", snippet))) + .map(|snippet| (expr_span, format!("drop({snippet})"))) .unwrap_or_else(|| (span, "drop".to_string())); err.span_suggestion( @@ -315,17 +315,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::ExprKind::Tup(exp), hir::ExprKind::Call(_, args), ) = (parent_node, &callee_expr.kind, &call_expr.kind) + && args.len() == exp.len() { - if args.len() == exp.len() { - let start = callee_expr.span.shrink_to_hi(); - err.span_suggestion( - start, - "consider separating array elements with a comma", - ",".to_string(), - Applicability::MaybeIncorrect, - ); - return true; - } + let start = callee_expr.span.shrink_to_hi(); + err.span_suggestion( + start, + "consider separating array elements with a comma", + ",".to_string(), + Applicability::MaybeIncorrect, + ); + return true; } false } @@ -373,15 +372,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ref t => { let mut unit_variant = None; let mut removal_span = call_expr.span; - if let ty::Adt(adt_def, ..) = t { - if adt_def.is_enum() { - if let hir::ExprKind::Call(expr, _) = call_expr.kind { - removal_span = - expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi()); - unit_variant = - self.tcx.sess.source_map().span_to_snippet(expr.span).ok(); - } - } + if let ty::Adt(adt_def, ..) = t + && adt_def.is_enum() + && let hir::ExprKind::Call(expr, _) = call_expr.kind + { + removal_span = + expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi()); + unit_variant = + self.tcx.sess.source_map().span_to_snippet(expr.span).ok(); } let callee_ty = self.resolve_vars_if_possible(callee_ty); @@ -392,8 +390,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { E0618, "expected function, found {}", match unit_variant { - Some(ref path) => format!("enum variant `{}`", path), - None => format!("`{}`", callee_ty), + Some(ref path) => format!("enum variant `{path}`"), + None => format!("`{callee_ty}`"), } ); @@ -408,8 +406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( removal_span, &format!( - "`{}` is a unit variant, you need to write it without the parentheses", - path + "`{path}` is a unit variant, you need to write it without the parentheses", ), String::new(), Applicability::MachineApplicable, @@ -452,14 +449,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(span) = self.tcx.hir().res_span(def) { let callee_ty = callee_ty.to_string(); let label = match (unit_variant, inner_callee_path) { - (Some(path), _) => Some(format!("`{}` defined here", path)), + (Some(path), _) => Some(format!("`{path}` defined here")), (_, Some(hir::QPath::Resolved(_, path))) => self .tcx .sess .source_map() .span_to_snippet(path.span) .ok() - .map(|p| format!("`{}` defined here returns `{}`", p, callee_ty)), + .map(|p| format!("`{p}` defined here returns `{callee_ty}`")), _ => { match def { // Emit a different diagnostic for local variables, as they are not @@ -475,7 +472,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.def_path_str(def_id), )) } - _ => Some(format!("`{}` defined here", callee_ty)), + _ => Some(format!("`{callee_ty}` defined here")), } } }; diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs index 47292b3e339..049940d19a6 100644 --- a/compiler/rustc_typeck/src/check/cast.rs +++ b/compiler/rustc_typeck/src/check/cast.rs @@ -322,7 +322,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { err.span_suggestion( self.span, "compare with zero instead", - format!("{} != 0", snippet), + format!("{snippet} != 0"), Applicability::MachineApplicable, ); } @@ -373,8 +373,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { let mut sugg = None; let mut sugg_mutref = false; if let ty::Ref(reg, cast_ty, mutbl) = *self.cast_ty.kind() { - if let ty::RawPtr(TypeAndMut { ty: expr_ty, .. }) = *self.expr_ty.kind() { - if fcx + if let ty::RawPtr(TypeAndMut { ty: expr_ty, .. }) = *self.expr_ty.kind() + && fcx .try_coerce( self.expr, fcx.tcx.mk_ref( @@ -386,27 +386,25 @@ impl<'a, 'tcx> CastCheck<'tcx> { None, ) .is_ok() - { - sugg = Some((format!("&{}*", mutbl.prefix_str()), cast_ty == expr_ty)); - } - } else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind() { - if expr_mutbl == Mutability::Not - && mutbl == Mutability::Mut - && fcx - .try_coerce( - self.expr, - fcx.tcx.mk_ref( - expr_reg, - TypeAndMut { ty: expr_ty, mutbl: Mutability::Mut }, - ), - self.cast_ty, - AllowTwoPhase::No, - None, - ) - .is_ok() - { - sugg_mutref = true; - } + { + sugg = Some((format!("&{}*", mutbl.prefix_str()), cast_ty == expr_ty)); + } else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind() + && expr_mutbl == Mutability::Not + && mutbl == Mutability::Mut + && fcx + .try_coerce( + self.expr, + fcx.tcx.mk_ref( + expr_reg, + TypeAndMut { ty: expr_ty, mutbl: Mutability::Mut }, + ), + self.cast_ty, + AllowTwoPhase::No, + None, + ) + .is_ok() + { + sugg_mutref = true; } if !sugg_mutref @@ -423,8 +421,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { { sugg = Some((format!("&{}", mutbl.prefix_str()), false)); } - } else if let ty::RawPtr(TypeAndMut { mutbl, .. }) = *self.cast_ty.kind() { - if fcx + } else if let ty::RawPtr(TypeAndMut { mutbl, .. }) = *self.cast_ty.kind() + && fcx .try_coerce( self.expr, fcx.tcx.mk_ref( @@ -436,9 +434,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { None, ) .is_ok() - { - sugg = Some((format!("&{}", mutbl.prefix_str()), false)); - } + { + sugg = Some((format!("&{}", mutbl.prefix_str()), false)); } if sugg_mutref { err.span_label(self.span, "invalid cast"); @@ -483,28 +480,28 @@ impl<'a, 'tcx> CastCheck<'tcx> { ) { let mut label = true; // Check `impl From<self.expr_ty> for self.cast_ty {}` for accurate suggestion: - if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr_span) { - if let Some(from_trait) = fcx.tcx.get_diagnostic_item(sym::From) { - let ty = fcx.resolve_vars_if_possible(self.cast_ty); - // Erase regions to avoid panic in `prove_value` when calling - // `type_implements_trait`. - let ty = fcx.tcx.erase_regions(ty); - let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); - let expr_ty = fcx.tcx.erase_regions(expr_ty); - let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]); - if fcx - .infcx - .type_implements_trait(from_trait, ty, ty_params, fcx.param_env) - .must_apply_modulo_regions() - { - label = false; - err.span_suggestion( - self.span, - "consider using the `From` trait instead", - format!("{}::from({})", self.cast_ty, snippet), - Applicability::MaybeIncorrect, - ); - } + if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr_span) + && let Some(from_trait) = fcx.tcx.get_diagnostic_item(sym::From) + { + let ty = fcx.resolve_vars_if_possible(self.cast_ty); + // Erase regions to avoid panic in `prove_value` when calling + // `type_implements_trait`. + let ty = fcx.tcx.erase_regions(ty); + let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); + let expr_ty = fcx.tcx.erase_regions(expr_ty); + let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]); + if fcx + .infcx + .type_implements_trait(from_trait, ty, ty_params, fcx.param_env) + .must_apply_modulo_regions() + { + label = false; + err.span_suggestion( + self.span, + "consider using the `From` trait instead", + format!("{}::from({})", self.cast_ty, snippet), + Applicability::MaybeIncorrect, + ); } } let msg = "an `as` expression can only be used to convert between primitive \ @@ -627,10 +624,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { } } } else { - let msg = &format!( - "consider using an implicit coercion to `&{}{}` instead", - mtstr, tstr - ); + let msg = + &format!("consider using an implicit coercion to `&{mtstr}{tstr}` instead"); err.span_help(self.span, msg); } } @@ -640,14 +635,14 @@ impl<'a, 'tcx> CastCheck<'tcx> { err.span_suggestion( self.cast_span, "you can cast to a `Box` instead", - format!("Box<{}>", s), + format!("Box<{s}>"), Applicability::MachineApplicable, ); } Err(_) => { err.span_help( self.cast_span, - &format!("you might have meant `Box<{}>`", tstr), + &format!("you might have meant `Box<{tstr}>`"), ); } } @@ -678,8 +673,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { )) .help(&format!( "cast can be replaced by coercion; this might \ - require {}a temporary variable", - type_asc_or + require {type_asc_or}a temporary variable" )) .emit(); }); @@ -969,21 +963,21 @@ impl<'a, 'tcx> CastCheck<'tcx> { } fn cenum_impl_drop_lint(&self, fcx: &FnCtxt<'a, 'tcx>) { - if let ty::Adt(d, _) = self.expr_ty.kind() { - if d.has_dtor(fcx.tcx) { - fcx.tcx.struct_span_lint_hir( - lint::builtin::CENUM_IMPL_DROP_CAST, - self.expr.hir_id, - self.span, - |err| { - err.build(&format!( - "cannot cast enum `{}` into integer `{}` because it implements `Drop`", - self.expr_ty, self.cast_ty - )) - .emit(); - }, - ); - } + if let ty::Adt(d, _) = self.expr_ty.kind() + && d.has_dtor(fcx.tcx) + { + fcx.tcx.struct_span_lint_hir( + lint::builtin::CENUM_IMPL_DROP_CAST, + self.expr.hir_id, + self.span, + |err| { + err.build(&format!( + "cannot cast enum `{}` into integer `{}` because it implements `Drop`", + self.expr_ty, self.cast_ty + )) + .emit(); + }, + ); } } @@ -1007,7 +1001,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { err.span_suggestion( self.span, msg, - format!("({}).addr(){}", snippet, scalar_cast), + format!("({snippet}).addr(){scalar_cast}"), Applicability::MaybeIncorrect ); } else { @@ -1038,7 +1032,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { err.span_suggestion( self.span, msg, - format!("(...).with_addr({})", snippet), + format!("(...).with_addr({snippet})"), Applicability::HasPlaceholders, ); } else { diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 1841451580f..314236b1cdf 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -43,8 +43,7 @@ pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab tcx.sess, span, E0570, - "`{}` is not a supported ABI for the current target", - abi + "`{abi}` is not a supported ABI for the current target", ) .emit(); } @@ -249,84 +248,84 @@ pub(super) fn check_fn<'a, 'tcx>( fcx.demand_suptype(span, declared_ret_ty, actual_return_ty); // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !` - if let Some(panic_impl_did) = tcx.lang_items().panic_impl() { - if panic_impl_did == hir.local_def_id(fn_id).to_def_id() { - if let Some(panic_info_did) = tcx.lang_items().panic_info() { - if *declared_ret_ty.kind() != ty::Never { - sess.span_err(decl.output.span(), "return type should be `!`"); - } + if let Some(panic_impl_did) = tcx.lang_items().panic_impl() + && panic_impl_did == hir.local_def_id(fn_id).to_def_id() + { + if let Some(panic_info_did) = tcx.lang_items().panic_info() { + if *declared_ret_ty.kind() != ty::Never { + sess.span_err(decl.output.span(), "return type should be `!`"); + } - let inputs = fn_sig.inputs(); - let span = hir.span(fn_id); - if inputs.len() == 1 { - let arg_is_panic_info = match *inputs[0].kind() { - ty::Ref(region, ty, mutbl) => match *ty.kind() { - ty::Adt(ref adt, _) => { - adt.did() == panic_info_did - && mutbl == hir::Mutability::Not - && !region.is_static() - } - _ => false, - }, + let inputs = fn_sig.inputs(); + let span = hir.span(fn_id); + if inputs.len() == 1 { + let arg_is_panic_info = match *inputs[0].kind() { + ty::Ref(region, ty, mutbl) => match *ty.kind() { + ty::Adt(ref adt, _) => { + adt.did() == panic_info_did + && mutbl == hir::Mutability::Not + && !region.is_static() + } _ => false, - }; - - if !arg_is_panic_info { - sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`"); - } + }, + _ => false, + }; - if let Node::Item(item) = hir.get(fn_id) - && let ItemKind::Fn(_, ref generics, _) = item.kind - && !generics.params.is_empty() - { - sess.span_err(span, "should have no type parameters"); - } - } else { - let span = sess.source_map().guess_head_span(span); - sess.span_err(span, "function should have one argument"); + if !arg_is_panic_info { + sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`"); } + + if let Node::Item(item) = hir.get(fn_id) + && let ItemKind::Fn(_, ref generics, _) = item.kind + && !generics.params.is_empty() + { + sess.span_err(span, "should have no type parameters"); + } } else { - sess.err("language item required, but not found: `panic_info`"); + let span = sess.source_map().guess_head_span(span); + sess.span_err(span, "function should have one argument"); } + } else { + sess.err("language item required, but not found: `panic_info`"); } } // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !` - if let Some(alloc_error_handler_did) = tcx.lang_items().oom() { - if alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() { - if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() { - if *declared_ret_ty.kind() != ty::Never { - sess.span_err(decl.output.span(), "return type should be `!`"); - } - - let inputs = fn_sig.inputs(); - let span = hir.span(fn_id); - if inputs.len() == 1 { - let arg_is_alloc_layout = match inputs[0].kind() { - ty::Adt(ref adt, _) => adt.did() == alloc_layout_did, - _ => false, - }; + if let Some(alloc_error_handler_did) = tcx.lang_items().oom() + && alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() + { + if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() { + if *declared_ret_ty.kind() != ty::Never { + sess.span_err(decl.output.span(), "return type should be `!`"); + } - if !arg_is_alloc_layout { - sess.span_err(decl.inputs[0].span, "argument should be `Layout`"); - } + let inputs = fn_sig.inputs(); + let span = hir.span(fn_id); + if inputs.len() == 1 { + let arg_is_alloc_layout = match inputs[0].kind() { + ty::Adt(ref adt, _) => adt.did() == alloc_layout_did, + _ => false, + }; - if let Node::Item(item) = hir.get(fn_id) - && let ItemKind::Fn(_, ref generics, _) = item.kind - && !generics.params.is_empty() - { - sess.span_err( - span, - "`#[alloc_error_handler]` function should have no type parameters", - ); - } - } else { - let span = sess.source_map().guess_head_span(span); - sess.span_err(span, "function should have one argument"); + if !arg_is_alloc_layout { + sess.span_err(decl.inputs[0].span, "argument should be `Layout`"); } + + if let Node::Item(item) = hir.get(fn_id) + && let ItemKind::Fn(_, ref generics, _) = item.kind + && !generics.params.is_empty() + { + sess.span_err( + span, + "`#[alloc_error_handler]` function should have no type parameters", + ); + } } else { - sess.err("language item required, but not found: `alloc_layout`"); + let span = sess.source_map().guess_head_span(span); + sess.span_err(span, "function should have one argument"); } + } else { + sess.err("language item required, but not found: `alloc_layout`"); } } @@ -670,7 +669,7 @@ fn check_opaque_meets_bounds<'tcx>( Err(ty_err) => { tcx.sess.delay_span_bug( span, - &format!("could not unify `{}` with revealed type:\n{}", hidden_type, ty_err,), + &format!("could not unify `{hidden_type}` with revealed type:\n{ty_err}"), ); } } @@ -817,10 +816,9 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) { tcx.sess, item.span, E0044, - "foreign items may not have {} parameters", - kinds, + "foreign items may not have {kinds} parameters", ) - .span_label(item.span, &format!("can't have {} parameters", kinds)) + .span_label(item.span, &format!("can't have {kinds} parameters")) .help( // FIXME: once we start storing spans for type arguments, turn this // into a suggestion. @@ -1065,68 +1063,67 @@ pub(super) fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalD pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { let t = tcx.type_of(def_id); - if let ty::Adt(def, substs) = t.kind() { - if def.is_struct() { - let fields = &def.non_enum_variant().fields; - if fields.is_empty() { + if let ty::Adt(def, substs) = t.kind() + && def.is_struct() + { + let fields = &def.non_enum_variant().fields; + if fields.is_empty() { + struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit(); + return; + } + let e = fields[0].ty(tcx, substs); + if !fields.iter().all(|f| f.ty(tcx, substs) == e) { + struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous") + .span_label(sp, "SIMD elements must have the same type") + .emit(); + return; + } + + let len = if let ty::Array(_ty, c) = e.kind() { + c.try_eval_usize(tcx, tcx.param_env(def.did())) + } else { + Some(fields.len() as u64) + }; + if let Some(len) = len { + if len == 0 { struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit(); return; - } - let e = fields[0].ty(tcx, substs); - if !fields.iter().all(|f| f.ty(tcx, substs) == e) { - struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous") - .span_label(sp, "SIMD elements must have the same type") - .emit(); + } else if len > MAX_SIMD_LANES { + struct_span_err!( + tcx.sess, + sp, + E0075, + "SIMD vector cannot have more than {MAX_SIMD_LANES} elements", + ) + .emit(); return; } + } - let len = if let ty::Array(_ty, c) = e.kind() { - c.try_eval_usize(tcx, tcx.param_env(def.did())) - } else { - Some(fields.len() as u64) - }; - if let Some(len) = len { - if len == 0 { - struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit(); - return; - } else if len > MAX_SIMD_LANES { - struct_span_err!( - tcx.sess, - sp, - E0075, - "SIMD vector cannot have more than {} elements", - MAX_SIMD_LANES, - ) - .emit(); - return; - } - } - - // Check that we use types valid for use in the lanes of a SIMD "vector register" - // These are scalar types which directly match a "machine" type - // Yes: Integers, floats, "thin" pointers - // No: char, "fat" pointers, compound types - match e.kind() { - ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors - ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok - ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors - ty::Array(t, _clen) - if matches!( - t.kind(), - ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) - ) => - { /* struct([f32; 4]) is ok */ } - _ => { - struct_span_err!( - tcx.sess, - sp, - E0077, - "SIMD vector element type should be a \ - primitive scalar (integer/float/pointer) type" - ) - .emit(); - return; - } + // Check that we use types valid for use in the lanes of a SIMD "vector register" + // These are scalar types which directly match a "machine" type + // Yes: Integers, floats, "thin" pointers + // No: char, "fat" pointers, compound types + match e.kind() { + ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors + ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok + ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors + ty::Array(t, _clen) + if matches!( + t.kind(), + ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) + ) => + { /* struct([f32; 4]) is ok */ } + _ => { + struct_span_err!( + tcx.sess, + sp, + E0077, + "SIMD vector element type should be a \ + primitive scalar (integer/float/pointer) type" + ) + .emit(); + return; } } } @@ -1189,7 +1186,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) { ident ) } else { - format!("...which contains a field of type `{}`", ident) + format!("...which contains a field of type `{ident}`") }, ); first = false; @@ -1215,13 +1212,12 @@ pub(super) fn check_packed_inner( stack.push(def_id); for field in &def.non_enum_variant().fields { - if let ty::Adt(def, _) = field.ty(tcx, substs).kind() { - if !stack.contains(&def.did()) { - if let Some(mut defs) = check_packed_inner(tcx, def.did(), stack) { - defs.push((def.did(), field.ident(tcx).span)); - return Some(defs); - } - } + if let ty::Adt(def, _) = field.ty(tcx, substs).kind() + && !stack.contains(&def.did()) + && let Some(mut defs) = check_packed_inner(tcx, def.did(), stack) + { + defs.push((def.did(), field.ident(tcx).span)); + return Some(defs); } } stack.pop(); @@ -1370,8 +1366,8 @@ fn check_enum<'tcx>( "discriminant value `{}` already exists", discr.val, ) - .span_label(i_span, format!("first use of {}", display_discr_i)) - .span_label(span, format!("enum already has {}", display_discr)) + .span_label(i_span, format!("first use of {display_discr_i}")) + .span_label(span, format!("enum already has {display_discr}")) .emit(); } disr_vals.push(discr); @@ -1393,7 +1389,7 @@ fn display_discriminant_value<'tcx>( && let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node && evaluated != *lit_value { - return format!("`{}` (overflowed from `{}`)", evaluated, lit_value); + return format!("`{evaluated}` (overflowed from `{lit_value}`)"); } } format!("`{}`", evaluated) @@ -1422,28 +1418,28 @@ pub(super) fn check_type_params_are_used<'tcx>( } for leaf in ty.walk() { - if let GenericArgKind::Type(leaf_ty) = leaf.unpack() { - if let ty::Param(param) = leaf_ty.kind() { - debug!("found use of ty param {:?}", param); - params_used.insert(param.index); - } + if let GenericArgKind::Type(leaf_ty) = leaf.unpack() + && let ty::Param(param) = leaf_ty.kind() + { + debug!("found use of ty param {:?}", param); + params_used.insert(param.index); } } for param in &generics.params { - if !params_used.contains(param.index) { - if let ty::GenericParamDefKind::Type { .. } = param.kind { - let span = tcx.def_span(param.def_id); - struct_span_err!( - tcx.sess, - span, - E0091, - "type parameter `{}` is unused", - param.name, - ) - .span_label(span, "unused type parameter") - .emit(); - } + if !params_used.contains(param.index) + && let ty::GenericParamDefKind::Type { .. } = param.kind + { + let span = tcx.def_span(param.def_id); + struct_span_err!( + tcx.sess, + span, + E0091, + "type parameter `{}` is unused", + param.name, + ) + .span_label(span, "unused type parameter") + .emit(); } } } @@ -1534,10 +1530,10 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> E for def_id in visitor.0 { let ty_span = tcx.def_span(def_id); if !seen.contains(&ty_span) { - err.span_label(ty_span, &format!("returning this opaque type `{}`", ty)); + err.span_label(ty_span, &format!("returning this opaque type `{ty}`")); seen.insert(ty_span); } - err.span_label(sp, &format!("returning here with type `{}`", ty)); + err.span_label(sp, &format!("returning here with type `{ty}`")); } } } diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 34fc177de6d..b44baf83cbe 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -632,11 +632,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let unsize_ty = trait_pred.trait_ref.substs[1].expect_ty(); if let (ty::Dynamic(ref data_a, ..), ty::Dynamic(ref data_b, ..)) = (self_ty.kind(), unsize_ty.kind()) + && data_a.principal_def_id() != data_b.principal_def_id() { - if data_a.principal_def_id() != data_b.principal_def_id() { - debug!("coerce_unsized: found trait upcasting coercion"); - has_trait_upcasting_coercion = true; - } + debug!("coerce_unsized: found trait upcasting coercion"); + has_trait_upcasting_coercion = true; } if let ty::Tuple(..) = unsize_ty.kind() { debug!("coerce_unsized: found unsized tuple coercion"); @@ -732,13 +731,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { F: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>, G: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>, { - if let ty::FnPtr(fn_ty_b) = b.kind() { - if let (hir::Unsafety::Normal, hir::Unsafety::Unsafe) = + if let ty::FnPtr(fn_ty_b) = b.kind() + && let (hir::Unsafety::Normal, hir::Unsafety::Unsafe) = (fn_ty_a.unsafety(), fn_ty_b.unsafety()) - { - let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a); - return self.unify_and(unsafe_a, b, to_unsafe); - } + { + let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a); + return self.unify_and(unsafe_a, b, to_unsafe); } self.unify_and(a, b, normal) } @@ -783,12 +781,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } // Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396). - if let ty::FnDef(def_id, _) = *a.kind() { - if b_sig.unsafety() == hir::Unsafety::Normal - && !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty() - { - return Err(TypeError::TargetFeatureCast(def_id)); - } + if let ty::FnDef(def_id, _) = *a.kind() + && b_sig.unsafety() == hir::Unsafety::Normal + && !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty() + { + return Err(TypeError::TargetFeatureCast(def_id)); } let InferOk { value: a_sig, obligations: o1 } = @@ -1502,7 +1499,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { found, expected, None, - coercion_error, + Some(coercion_error), ); } @@ -1540,11 +1537,11 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fcx.tcx.hir().get_if_cause(expr.hir_id), expected.is_unit(), pointing_at_return_type, - ) { + ) // If the block is from an external macro or try (`?`) desugaring, then // do not suggest adding a semicolon, because there's nowhere to put it. // See issues #81943 and #87051. - if matches!( + && matches!( cond_expr.span.desugaring_kind(), None | Some(DesugaringKind::WhileLoop) ) && !in_external_macro(fcx.tcx.sess, cond_expr.span) @@ -1552,11 +1549,10 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { cond_expr.kind, hir::ExprKind::Match(.., hir::MatchSource::TryDesugar) ) - { - err.span_label(cond_expr.span, "expected this to be `()`"); - if expr.can_have_side_effects() { - fcx.suggest_semicolon_at_end(cond_expr.span, &mut err); - } + { + err.span_label(cond_expr.span, "expected this to be `()`"); + if expr.can_have_side_effects() { + fcx.suggest_semicolon_at_end(cond_expr.span, &mut err); } } fcx.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main)) @@ -1636,28 +1632,27 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { let has_impl = snippet_iter.next().map_or(false, |s| s == "impl"); // Only suggest `Box<dyn Trait>` if `Trait` in `impl Trait` is object safe. let mut is_object_safe = false; - if let hir::FnRetTy::Return(ty) = fn_output { + if let hir::FnRetTy::Return(ty) = fn_output // Get the return type. - if let hir::TyKind::OpaqueDef(..) = ty.kind { - let ty = <dyn AstConv<'_>>::ast_ty_to_ty(fcx, ty); - // Get the `impl Trait`'s `DefId`. - if let ty::Opaque(def_id, _) = ty.kind() { - // Get the `impl Trait`'s `Item` so that we can get its trait bounds and - // get the `Trait`'s `DefId`. - if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }) = - fcx.tcx.hir().expect_item(def_id.expect_local()).kind - { - // Are of this `impl Trait`'s traits object safe? - is_object_safe = bounds.iter().all(|bound| { - bound - .trait_ref() - .and_then(|t| t.trait_def_id()) - .map_or(false, |def_id| { - fcx.tcx.object_safety_violations(def_id).is_empty() - }) + && let hir::TyKind::OpaqueDef(..) = ty.kind + { + let ty = <dyn AstConv<'_>>::ast_ty_to_ty(fcx, ty); + // Get the `impl Trait`'s `DefId`. + if let ty::Opaque(def_id, _) = ty.kind() + // Get the `impl Trait`'s `Item` so that we can get its trait bounds and + // get the `Trait`'s `DefId`. + && let hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }) = + fcx.tcx.hir().expect_item(def_id.expect_local()).kind + { + // Are of this `impl Trait`'s traits object safe? + is_object_safe = bounds.iter().all(|bound| { + bound + .trait_ref() + .and_then(|t| t.trait_def_id()) + .map_or(false, |def_id| { + fcx.tcx.object_safety_violations(def_id).is_empty() }) - } - } + }) } }; if has_impl { @@ -1703,7 +1698,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { && let ty = <dyn AstConv<'_>>::ast_ty_to_ty(fcx, ty) && let ty::Dynamic(..) = ty.kind() { - return true; + return true; } false } diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 0bd5e018f4a..4ab6f2cdafb 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -315,7 +315,7 @@ fn compare_predicate_entailment<'tcx>( ExplicitSelf::ByReference(_, hir::Mutability::Mut) => { "&mut self".to_owned() } - _ => format!("self: {}", ty), + _ => format!("self: {ty}"), }; // When the `impl` receiver is an arbitrary self type, like `self: Box<Self>`, the @@ -384,6 +384,7 @@ fn compare_predicate_entailment<'tcx>( })), &terr, false, + false, ); return Err(diag.emit()); @@ -526,7 +527,7 @@ fn compare_self_type<'tcx>( ExplicitSelf::ByValue => "self".to_owned(), ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(), ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(), - _ => format!("self: {}", self_arg_ty), + _ => format!("self: {self_arg_ty}"), } }) }; @@ -544,9 +545,9 @@ fn compare_self_type<'tcx>( trait_m.name, self_descr ); - err.span_label(impl_m_span, format!("`{}` used in impl", self_descr)); + err.span_label(impl_m_span, format!("`{self_descr}` used in impl")); if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) { - err.span_label(span, format!("trait method declared without `{}`", self_descr)); + err.span_label(span, format!("trait method declared without `{self_descr}`")); } else { err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx)); } @@ -564,9 +565,9 @@ fn compare_self_type<'tcx>( trait_m.name, self_descr ); - err.span_label(impl_m_span, format!("expected `{}` in impl", self_descr)); + err.span_label(impl_m_span, format!("expected `{self_descr}` in impl")); if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) { - err.span_label(span, format!("`{}` used in trait", self_descr)); + err.span_label(span, format!("`{self_descr}` used in trait")); } else { err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx)); } @@ -668,7 +669,7 @@ fn compare_number_of_generics<'tcx>( err.span_label(*span, ""); } } else { - suffix = Some(format!(", expected {}", trait_count)); + suffix = Some(format!(", expected {trait_count}")); } if let Some(span) = span { @@ -873,12 +874,10 @@ fn compare_synthetic_generics<'tcx>( intravisit::walk_ty(self, ty); if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = ty.kind + && let Res::Def(DefKind::TyParam, def_id) = path.res + && def_id == self.1 { - if let Res::Def(DefKind::TyParam, def_id) = path.res { - if def_id == self.1 { - self.0 = Some(ty.span); - } - } + self.0 = Some(ty.span); } } } @@ -908,7 +907,7 @@ fn compare_synthetic_generics<'tcx>( // delete generic parameters (impl_m.generics.span, String::new()), // replace param usage with `impl Trait` - (span, format!("impl {}", bounds)), + (span, format!("impl {bounds}")), ], Applicability::MaybeIncorrect, ); @@ -972,7 +971,7 @@ fn compare_const_param_types<'tcx>( &format!( "the const parameter{} has type `{}`, but the declaration \ in trait `{}` has type `{}`", - &impl_ident.map_or_else(|| "".to_string(), |ident| format!(" `{}`", ident)), + &impl_ident.map_or_else(|| "".to_string(), |ident| format!(" `{ident}`")), impl_ty, tcx.def_path_str(trait_m.def_id), trait_ty @@ -1074,6 +1073,7 @@ crate fn compare_const_impl<'tcx>( })), &terr, false, + false, ); diag.emit(); } diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index 83e535b3c32..f377cf3678e 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -28,7 +28,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr_ty: Ty<'tcx>, expected: Ty<'tcx>, expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, - error: TypeError<'tcx>, + error: Option<TypeError<'tcx>>, ) { self.annotate_expected_due_to_let_ty(err, expr, error); self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr); @@ -150,7 +150,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expr_ty = self.resolve_vars_with_obligations(checked_ty); let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e.clone()); - self.emit_coerce_suggestions(&mut err, expr, expr_ty, expected, expected_ty_expr, e); + self.emit_coerce_suggestions(&mut err, expr, expr_ty, expected, expected_ty_expr, Some(e)); (expected, Some(err)) } @@ -159,7 +159,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, err: &mut Diagnostic, expr: &hir::Expr<'_>, - error: TypeError<'_>, + error: Option<TypeError<'_>>, ) { let parent = self.tcx.hir().get_parent_node(expr.hir_id); match (self.tcx.hir().find(parent), error) { @@ -173,7 +173,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. })), - TypeError::Sorts(ExpectedFound { expected, .. }), + Some(TypeError::Sorts(ExpectedFound { expected, .. })), ) if rhs.hir_id == expr.hir_id && !expected.is_closure() => { // We ignore closures explicitly because we already point at them elsewhere. // Point at the assigned-to binding. @@ -241,13 +241,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We are pointing at the binding's type or initializer value, but it's pattern // is in a different line, so we point at both. err.span_label(secondary_span, "expected due to the type of this binding"); - err.span_label(primary_span, &format!("expected due to this{}", post_message)); + err.span_label(primary_span, &format!("expected due to this{post_message}")); } else if post_message == "" { // We are pointing at either the assignment lhs or the binding def pattern. err.span_label(primary_span, "expected due to the type of this binding"); } else { // We are pointing at the binding's type or initializer value. - err.span_label(primary_span, &format!("expected due to this{}", post_message)); + err.span_label(primary_span, &format!("expected due to this{post_message}")); } if !lhs.is_syntactic_place_expr() { @@ -321,7 +321,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "try adding an expression at the end of the block", return_suggestions .into_iter() - .map(|r| format!("{}\n{}{}", semicolon, indent, r)), + .map(|r| format!("{semicolon}\n{indent}{r}")), Applicability::MaybeIncorrect, ); } @@ -344,10 +344,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let variant_path = with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id)); // FIXME #56861: DRYer prelude filtering - if let Some(path) = variant_path.strip_prefix("std::prelude::") { - if let Some((_, path)) = path.split_once("::") { - return Some(path.to_string()); - } + if let Some(path) = variant_path.strip_prefix("std::prelude::") + && let Some((_, path)) = path.split_once("::") + { + return Some(path.to_string()); } Some(variant_path) } else { @@ -357,7 +357,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .collect(); let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) { - Some(ident) => format!("{}: ", ident), + Some(ident) => format!("{ident}: "), None => String::new(), }; @@ -366,9 +366,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { [variant] => { // Just a single matching variant. err.multipart_suggestion_verbose( - &format!("try wrapping the expression in `{}`", variant), + &format!("try wrapping the expression in `{variant}`"), vec![ - (expr.span.shrink_to_lo(), format!("{}{}(", prefix, variant)), + (expr.span.shrink_to_lo(), format!("{prefix}{variant}(")), (expr.span.shrink_to_hi(), ")".to_string()), ], Applicability::MaybeIncorrect, @@ -383,7 +383,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ), compatible_variants.into_iter().map(|variant| { vec![ - (expr.span.shrink_to_lo(), format!("{}{}(", prefix, variant)), + (expr.span.shrink_to_lo(), format!("{prefix}{variant}(")), (expr.span.shrink_to_hi(), ")".to_string()), ] }), @@ -680,7 +680,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ if is_range_literal(expr) => true, _ => false, }; - let sugg_expr = if needs_parens { format!("({})", src) } else { src }; + let sugg_expr = if needs_parens { format!("({src})") } else { src }; if let Some(sugg) = self.can_use_as_ref(expr) { return Some(( @@ -693,7 +693,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) { - Some(ident) => format!("{}: ", ident), + Some(ident) => format!("{ident}: "), None => String::new(), }; @@ -727,14 +727,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::Mutability::Mut => ( sp, "consider mutably borrowing here".to_string(), - format!("{}&mut {}", prefix, sugg_expr), + format!("{prefix}&mut {sugg_expr}"), Applicability::MachineApplicable, false, ), hir::Mutability::Not => ( sp, "consider borrowing here".to_string(), - format!("{}&{}", prefix, sugg_expr), + format!("{prefix}&{sugg_expr}"), Applicability::MachineApplicable, false, ), @@ -758,29 +758,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(call_span) = iter::successors(Some(expr.span), |s| s.parent_callsite()) .find(|&s| sp.contains(s)) + && sm.span_to_snippet(call_span).is_ok() { - if sm.span_to_snippet(call_span).is_ok() { - return Some(( - sp.with_hi(call_span.lo()), - "consider removing the borrow".to_string(), - String::new(), - Applicability::MachineApplicable, - true, - )); - } - } - return None; - } - if sp.contains(expr.span) { - if sm.span_to_snippet(expr.span).is_ok() { return Some(( - sp.with_hi(expr.span.lo()), + sp.with_hi(call_span.lo()), "consider removing the borrow".to_string(), String::new(), Applicability::MachineApplicable, true, )); } + return None; + } + if sp.contains(expr.span) + && sm.span_to_snippet(expr.span).is_ok() + { + return Some(( + sp.with_hi(expr.span.lo()), + "consider removing the borrow".to_string(), + String::new(), + Applicability::MachineApplicable, + true, + )); } } ( @@ -788,66 +787,65 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &ty::RawPtr(TypeAndMut { ty: ty_b, mutbl: mutbl_b }), &ty::Ref(_, ty_a, mutbl_a), ) => { - if let Some(steps) = self.deref_steps(ty_a, ty_b) { + if let Some(steps) = self.deref_steps(ty_a, ty_b) // Only suggest valid if dereferencing needed. - if steps > 0 { - // The pointer type implements `Copy` trait so the suggestion is always valid. - if let Ok(src) = sm.span_to_snippet(sp) { - let derefs = "*".repeat(steps); - if let Some((span, src, applicability)) = match mutbl_b { + && steps > 0 + // The pointer type implements `Copy` trait so the suggestion is always valid. + && let Ok(src) = sm.span_to_snippet(sp) + { + let derefs = "*".repeat(steps); + if let Some((span, src, applicability)) = match mutbl_b { + hir::Mutability::Mut => { + let new_prefix = "&mut ".to_owned() + &derefs; + match mutbl_a { hir::Mutability::Mut => { - let new_prefix = "&mut ".to_owned() + &derefs; - match mutbl_a { - hir::Mutability::Mut => { - replace_prefix(&src, "&mut ", &new_prefix).map(|_| { - let pos = sp.lo() + BytePos(5); - let sp = sp.with_lo(pos).with_hi(pos); - (sp, derefs, Applicability::MachineApplicable) - }) - } - hir::Mutability::Not => { - replace_prefix(&src, "&", &new_prefix).map(|_| { - let pos = sp.lo() + BytePos(1); - let sp = sp.with_lo(pos).with_hi(pos); - ( - sp, - format!("mut {}", derefs), - Applicability::Unspecified, - ) - }) - } - } + replace_prefix(&src, "&mut ", &new_prefix).map(|_| { + let pos = sp.lo() + BytePos(5); + let sp = sp.with_lo(pos).with_hi(pos); + (sp, derefs, Applicability::MachineApplicable) + }) } hir::Mutability::Not => { - let new_prefix = "&".to_owned() + &derefs; - match mutbl_a { - hir::Mutability::Mut => { - replace_prefix(&src, "&mut ", &new_prefix).map(|_| { - let lo = sp.lo() + BytePos(1); - let hi = sp.lo() + BytePos(5); - let sp = sp.with_lo(lo).with_hi(hi); - (sp, derefs, Applicability::MachineApplicable) - }) - } - hir::Mutability::Not => { - replace_prefix(&src, "&", &new_prefix).map(|_| { - let pos = sp.lo() + BytePos(1); - let sp = sp.with_lo(pos).with_hi(pos); - (sp, derefs, Applicability::MachineApplicable) - }) - } - } + replace_prefix(&src, "&", &new_prefix).map(|_| { + let pos = sp.lo() + BytePos(1); + let sp = sp.with_lo(pos).with_hi(pos); + ( + sp, + format!("mut {derefs}"), + Applicability::Unspecified, + ) + }) } - } { - return Some(( - span, - "consider dereferencing".to_string(), - src, - applicability, - true, - )); } } + hir::Mutability::Not => { + let new_prefix = "&".to_owned() + &derefs; + match mutbl_a { + hir::Mutability::Mut => { + replace_prefix(&src, "&mut ", &new_prefix).map(|_| { + let lo = sp.lo() + BytePos(1); + let hi = sp.lo() + BytePos(5); + let sp = sp.with_lo(lo).with_hi(hi); + (sp, derefs, Applicability::MachineApplicable) + }) + } + hir::Mutability::Not => { + replace_prefix(&src, "&", &new_prefix).map(|_| { + let pos = sp.lo() + BytePos(1); + let sp = sp.with_lo(pos).with_hi(pos); + (sp, derefs, Applicability::MachineApplicable) + }) + } + } + } + } { + return Some(( + span, + "consider dereferencing".to_string(), + src, + applicability, + true, + )); } } } @@ -908,7 +906,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Suggest removing `&` if we have removed any, otherwise suggest just // dereferencing the remaining number of steps. let message = if remove.is_empty() { - format!("consider {}", deref_kind) + format!("consider {deref_kind}") } else { format!( "consider removing the `{}` and {} instead", @@ -918,7 +916,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) { - Some(ident) => format!("{}: ", ident), + Some(ident) => format!("{ident}: "), None => String::new(), }; @@ -994,35 +992,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - if let hir::ExprKind::Call(path, args) = &expr.kind { - if let (hir::ExprKind::Path(hir::QPath::TypeRelative(base_ty, path_segment)), 1) = + if let hir::ExprKind::Call(path, args) = &expr.kind + && let (hir::ExprKind::Path(hir::QPath::TypeRelative(base_ty, path_segment)), 1) = (&path.kind, args.len()) - { - // `expr` is a conversion like `u32::from(val)`, do not suggest anything (#63697). - if let (hir::TyKind::Path(hir::QPath::Resolved(None, base_ty_path)), sym::from) = - (&base_ty.kind, path_segment.ident.name) - { - if let Some(ident) = &base_ty_path.segments.iter().map(|s| s.ident).next() { - match ident.name { - sym::i128 - | sym::i64 - | sym::i32 - | sym::i16 - | sym::i8 - | sym::u128 - | sym::u64 - | sym::u32 - | sym::u16 - | sym::u8 - | sym::isize - | sym::usize - if base_ty_path.segments.len() == 1 => - { - return false; - } - _ => {} - } + // `expr` is a conversion like `u32::from(val)`, do not suggest anything (#63697). + && let (hir::TyKind::Path(hir::QPath::Resolved(None, base_ty_path)), sym::from) = + (&base_ty.kind, path_segment.ident.name) + { + if let Some(ident) = &base_ty_path.segments.iter().map(|s| s.ident).next() { + match ident.name { + sym::i128 + | sym::i64 + | sym::i32 + | sym::i16 + | sym::i8 + | sym::u128 + | sym::u64 + | sym::u32 + | sym::u16 + | sym::u8 + | sym::isize + | sym::usize + if base_ty_path.segments.len() == 1 => + { + return false; } + _ => {} } } } @@ -1042,8 +1037,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty, ); let lit_msg = format!( - "change the type of the numeric literal from `{}` to `{}`", - checked_ty, expected_ty, + "change the type of the numeric literal from `{checked_ty}` to `{expected_ty}`", ); let close_paren = if expr.precedence().order() < PREC_POSTFIX { @@ -1054,10 +1048,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let mut cast_suggestion = sugg.clone(); - cast_suggestion - .push((expr.span.shrink_to_hi(), format!("{} as {}", close_paren, expected_ty))); + cast_suggestion.push((expr.span.shrink_to_hi(), format!("{close_paren} as {expected_ty}"))); let mut into_suggestion = sugg.clone(); - into_suggestion.push((expr.span.shrink_to_hi(), format!("{}.into()", close_paren))); + into_suggestion.push((expr.span.shrink_to_hi(), format!("{close_paren}.into()"))); let mut suffix_suggestion = sugg.clone(); suffix_suggestion.push(( if matches!( @@ -1074,7 +1067,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, if expr.precedence().order() < PREC_POSTFIX { // Readd `)` - format!("{})", expected_ty) + format!("{expected_ty})") } else { expected_ty.to_string() }, @@ -1108,20 +1101,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (lhs_expr_and_src, exp_to_found_is_fallible) { let msg = format!( - "you can convert `{}` from `{}` to `{}`, matching the type of `{}`", - lhs_src, expected_ty, checked_ty, src + "you can convert `{lhs_src}` from `{expected_ty}` to `{checked_ty}`, matching the type of `{src}`", ); let suggestion = vec![ - (lhs_expr.span.shrink_to_lo(), format!("{}::from(", checked_ty)), + (lhs_expr.span.shrink_to_lo(), format!("{checked_ty}::from(")), (lhs_expr.span.shrink_to_hi(), ")".to_string()), ]; (msg, suggestion) } else { - let msg = format!("{} and panic if the converted value doesn't fit", msg); + let msg = format!("{msg} and panic if the converted value doesn't fit"); let mut suggestion = sugg.clone(); suggestion.push(( expr.span.shrink_to_hi(), - format!("{}.try_into().unwrap()", close_paren), + format!("{close_paren}.try_into().unwrap()"), )); (msg, suggestion) }; @@ -1151,7 +1143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We now know that converting either the lhs or rhs is fallible. Before we // suggest a fallible conversion, check if the value can never fit in the // expected type. - let msg = format!("`{}` cannot fit into type `{}`", src, expected_ty); + let msg = format!("`{src}` cannot fit into type `{expected_ty}`"); err.note(&msg); return; } else if in_const_context { @@ -1229,7 +1221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if can_cast { // Missing try_into implementation for `f64` to `f32` err.multipart_suggestion_verbose( - &format!("{}, producing the closest possible value", cast_msg), + &format!("{cast_msg}, producing the closest possible value"), cast_suggestion, Applicability::MaybeIncorrect, // lossy conversion ); @@ -1246,7 +1238,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if can_cast { // Missing try_into implementation for `{float}` to `{integer}` err.multipart_suggestion_verbose( - &format!("{}, rounding the float towards zero", msg), + &format!("{msg}, rounding the float towards zero"), cast_suggestion, Applicability::MaybeIncorrect, // lossy conversion ); @@ -1258,8 +1250,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if exp.bit_width() > found.bit_width().unwrap_or(256) { err.multipart_suggestion_verbose( &format!( - "{}, producing the floating point representation of the integer", - msg, + "{msg}, producing the floating point representation of the integer", ), into_suggestion, Applicability::MachineApplicable, @@ -1274,9 +1265,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Missing try_into implementation for `{integer}` to `{float}` err.multipart_suggestion_verbose( &format!( - "{}, producing the floating point representation of the integer, \ + "{cast_msg}, producing the floating point representation of the integer, \ rounded if necessary", - cast_msg, ), cast_suggestion, Applicability::MaybeIncorrect, // lossy conversion @@ -1321,7 +1311,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &ty::Char, ) => { err.multipart_suggestion_verbose( - &format!("{}, since a `char` always occupies 4 bytes", cast_msg,), + &format!("{cast_msg}, since a `char` always occupies 4 bytes"), cast_suggestion, Applicability::MachineApplicable, ); @@ -1333,22 +1323,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Report the type inferred by the return statement. fn report_closure_inferred_return_type(&self, err: &mut Diagnostic, expected: Ty<'tcx>) { - if let Some(sp) = self.ret_coercion_span.get() { + if let Some(sp) = self.ret_coercion_span.get() // If the closure has an explicit return type annotation, or if // the closure's return type has been inferred from outside // requirements (such as an Fn* trait bound), then a type error // may occur at the first return expression we see in the closure // (if it conflicts with the declared return type). Skip adding a // note in this case, since it would be incorrect. - if !self.return_type_pre_known { - err.span_note( - sp, - &format!( - "return type inferred to be `{}` here", - self.resolve_vars_if_possible(expected) - ), - ); - } + && !self.return_type_pre_known + { + err.span_note( + sp, + &format!( + "return type inferred to be `{}` here", + self.resolve_vars_if_possible(expected) + ), + ); } } } diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs index 4ab94f39357..3bc92166543 100644 --- a/compiler/rustc_typeck/src/check/dropck.rs +++ b/compiler/rustc_typeck/src/check/dropck.rs @@ -57,7 +57,7 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro let span = tcx.def_span(drop_impl_did); let reported = tcx.sess.delay_span_bug( span, - &format!("should have been rejected by coherence check: {}", dtor_self_type), + &format!("should have been rejected by coherence check: {dtor_self_type}"), ); Err(reported) } @@ -104,8 +104,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( item_span, &format!( "use the same sequence of generic type, lifetime and const parameters \ - as the {} definition", - self_descr, + as the {self_descr} definition", ), ) .emit(); @@ -262,9 +261,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( tcx.sess, predicate_sp, E0367, - "`Drop` impl requires `{}` but the {} it is implemented for does not", - predicate, - self_descr, + "`Drop` impl requires `{predicate}` but the {self_descr} it is implemented for does not", ) .span_note(item_span, "the implementor must specify the same requirement") .emit(); diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 669521bc472..e88082dbb97 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -181,13 +181,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // make this code only run with -Zverbose because it is probably slow if let Ok(lint_str) = self.tcx.sess.source_map().span_to_snippet(expr.span) { if !lint_str.contains('\n') { - debug!("expr text: {}", lint_str); + debug!("expr text: {lint_str}"); } else { let mut lines = lint_str.lines(); if let Some(line0) = lines.next() { let remaining_lines = lines.count(); - debug!("expr text: {}", line0); - debug!("expr text: ...(and {} more lines)", remaining_lines); + debug!("expr text: {line0}"); + debug!("expr text: ...(and {remaining_lines} more lines)"); } } } @@ -259,7 +259,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } #[instrument(skip(self, expr), level = "debug")] - fn check_expr_kind( + pub(super) fn check_expr_kind( &self, expr: &'tcx hir::Expr<'tcx>, expected: Expectation<'tcx>, @@ -375,8 +375,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr.span, oprnd_t, E0614, - "type `{}` cannot be dereferenced", - oprnd_t, + "type `{oprnd_t}` cannot be dereferenced", ); let sp = tcx.sess.source_map().start_point(expr.span); if let Some(sp) = @@ -652,7 +651,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( expr.span, "give it a value of the expected type", - format!("break{} {}", label, val), + format!("break{label} {val}"), Applicability::HasPlaceholders, ); } @@ -780,7 +779,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { db.span_label( span, - format!("expected `{}` because of this return type", snippet), + format!("expected `{snippet}` because of this return type"), ); } }, @@ -1367,11 +1366,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let tcx = self.tcx; - let adt_ty_hint = self - .expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty]) - .get(0) - .cloned() - .unwrap_or(adt_ty); + let expected_inputs = + self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty]); + let adt_ty_hint = if let Some(expected_inputs) = expected_inputs { + expected_inputs.get(0).cloned().unwrap_or(adt_ty) + } else { + adt_ty + }; // re-link the regions that EIfEO can erase. self.demand_eqtype(span, adt_ty_hint, adt_ty); @@ -1611,15 +1612,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut truncated_fields_error = String::new(); let remaining_fields_names = match &displayable_field_names[..] { [field1] => format!("`{}`", field1), - [field1, field2] => format!("`{}` and `{}`", field1, field2), - [field1, field2, field3] => format!("`{}`, `{}` and `{}`", field1, field2, field3), + [field1, field2] => format!("`{field1}` and `{field2}`"), + [field1, field2, field3] => format!("`{field1}`, `{field2}` and `{field3}`"), _ => { truncated_fields_error = format!(" and {} other field{}", len - 3, pluralize!(len - 3)); displayable_field_names .iter() .take(3) - .map(|n| format!("`{}`", n)) + .map(|n| format!("`{n}`")) .collect::<Vec<_>>() .join(", ") } @@ -1635,10 +1636,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { truncated_fields_error, adt_ty ); - err.span_label( - span, - format!("missing {}{}", remaining_fields_names, truncated_fields_error), - ); + err.span_label(span, format!("missing {remaining_fields_names}{truncated_fields_error}")); // If the last field is a range literal, but it isn't supposed to be, then they probably // meant to use functional update syntax. @@ -1693,8 +1691,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.sess.span_err( span, &format!( - "cannot construct `{}` with struct literal syntax due to inaccessible fields", - adt_ty, + "cannot construct `{adt_ty}` with struct literal syntax due to inaccessible fields", ), ); } @@ -1807,7 +1804,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { err.span_label( field.ident.span, - format!("`{}` does not have this field", ty), + format!("`{ty}` does not have this field"), ); } let available_field_names = @@ -1973,8 +1970,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field.span, expr_t, E0610, - "`{}` is a primitive type and therefore doesn't have fields", - expr_t + "`{expr_t}` is a primitive type and therefore doesn't have fields", ) .emit(); } @@ -2018,7 +2014,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } if add_label { - err.span_label(field_ident.span, &format!("field not found in `{}`", ty)); + err.span_label(field_ident.span, &format!("field not found in `{ty}`")); } } @@ -2077,10 +2073,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx().sess, field.span, E0616, - "field `{}` of {} `{}` is private", - field, - kind_name, - struct_path + "field `{field}` of {kind_name} `{struct_path}` is private", ); err.span_label(field.span, "private field"); // Also check if an accessible method exists, which is often what is meant. @@ -2088,7 +2081,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { self.suggest_method_call( &mut err, - &format!("a method `{}` also exists, call it with parentheses", field), + &format!("a method `{field}` also exists, call it with parentheses"), field, expr_t, expr, @@ -2104,9 +2097,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field.span, expr_t, E0615, - "attempted to take value of method `{}` on type `{}`", - field, - expr_t + "attempted to take value of method `{field}` on type `{expr_t}`", ); err.span_label(field.span, "method, not a field"); let expr_is_call = @@ -2150,27 +2141,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { let mut found = false; - if let ty::RawPtr(ty_and_mut) = expr_t.kind() { - if let ty::Adt(adt_def, _) = ty_and_mut.ty.kind() { - if adt_def.variants().len() == 1 - && adt_def - .variants() - .iter() - .next() - .unwrap() - .fields - .iter() - .any(|f| f.ident(self.tcx) == field) - { - if let Some(dot_loc) = expr_snippet.rfind('.') { - found = true; - err.span_suggestion( - expr.span.with_hi(expr.span.lo() + BytePos::from_usize(dot_loc)), - "to access the field, dereference first", - format!("(*{})", &expr_snippet[0..dot_loc]), - Applicability::MaybeIncorrect, - ); - } + if let ty::RawPtr(ty_and_mut) = expr_t.kind() + && let ty::Adt(adt_def, _) = ty_and_mut.ty.kind() + { + if adt_def.variants().len() == 1 + && adt_def + .variants() + .iter() + .next() + .unwrap() + .fields + .iter() + .any(|f| f.ident(self.tcx) == field) + { + if let Some(dot_loc) = expr_snippet.rfind('.') { + found = true; + err.span_suggestion( + expr.span.with_hi(expr.span.lo() + BytePos::from_usize(dot_loc)), + "to access the field, dereference first", + format!("(*{})", &expr_snippet[0..dot_loc]), + Applicability::MaybeIncorrect, + ); } } } @@ -2197,7 +2188,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let param_span = self.tcx.hir().span(param_hir_id); let param_name = self.tcx.hir().ty_param_name(param_def_id.expect_local()); - err.span_label(param_span, &format!("type parameter '{}' declared here", param_name)); + err.span_label(param_span, &format!("type parameter '{param_name}' declared here")); } fn suggest_fields_on_recordish( @@ -2239,17 +2230,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { if let (Some(len), Ok(user_index)) = (len.try_eval_usize(self.tcx, self.param_env), field.as_str().parse::<u64>()) + && let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) { - if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) { - let help = "instead of using tuple indexing, use array indexing"; - let suggestion = format!("{}[{}]", base, field); - let applicability = if len < user_index { - Applicability::MachineApplicable - } else { - Applicability::MaybeIncorrect - }; - err.span_suggestion(expr.span, help, suggestion, applicability); - } + let help = "instead of using tuple indexing, use array indexing"; + let suggestion = format!("{base}[{field}]"); + let applicability = if len < user_index { + Applicability::MachineApplicable + } else { + Applicability::MaybeIncorrect + }; + err.span_suggestion(expr.span, help, suggestion, applicability); } } @@ -2261,8 +2251,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field: Ident, ) { if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) { - let msg = format!("`{}` is a raw pointer; try dereferencing it", base); - let suggestion = format!("(*{}).{}", base, field); + let msg = format!("`{base}` is a raw pointer; try dereferencing it"); + let suggestion = format!("(*{base}).{field}"); err.span_suggestion(expr.span, &msg, suggestion, Applicability::MaybeIncorrect); } } @@ -2281,9 +2271,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field.span, expr_t, E0609, - "no field `{}` on type `{}`", - field, - expr_t + "no field `{field}` on type `{expr_t}`", ); // try to add a suggestion in case the field is a nested field of a field of the Adt @@ -2307,7 +2295,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( field.span.shrink_to_lo(), "one of the expressions' fields has a field of the same name", - format!("{}.", field_path_str), + format!("{field_path_str}."), Applicability::MaybeIncorrect, ); } @@ -2419,8 +2407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr.span, base_t, E0608, - "cannot index into a value of type `{}`", - base_t + "cannot index into a value of type `{base_t}`", ); // Try to give some advice about indexing tuples. if let ty::Tuple(..) = base_t.kind() { @@ -2434,7 +2421,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( expr.span, "to access tuple elements, use", - format!("{}.{}", snip, i), + format!("{snip}.{i}"), Applicability::MachineApplicable, ); needs_note = false; @@ -2535,12 +2522,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_expr_asm_operand(out_expr, false); } } - hir::InlineAsmOperand::Const { anon_const } => { + hir::InlineAsmOperand::Const { anon_const } + | hir::InlineAsmOperand::SymFn { anon_const } => { self.to_const(anon_const); } - hir::InlineAsmOperand::Sym { expr } => { - self.check_expr(expr); - } + hir::InlineAsmOperand::SymStatic { .. } => {} } } if asm.options.contains(ast::InlineAsmOptions::NORETURN) { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index d403d6e3f33..152be4bd538 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -755,9 +755,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ret: Expectation<'tcx>, formal_ret: Ty<'tcx>, formal_args: &[Ty<'tcx>], - ) -> Vec<Ty<'tcx>> { + ) -> Option<Vec<Ty<'tcx>>> { let formal_ret = self.resolve_vars_with_obligations(formal_ret); - let Some(ret_ty) = expected_ret.only_has_type(self) else { return Vec::new() }; + let Some(ret_ty) = expected_ret.only_has_type(self) else { return None }; // HACK(oli-obk): This is a hack to keep RPIT and TAIT in sync wrt their behaviour. // Without it, the inference @@ -779,7 +779,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::subst::GenericArgKind::Type(ty) = ty.unpack() { if let ty::Opaque(def_id, _) = *ty.kind() { if self.infcx.opaque_type_origin(def_id, DUMMY_SP).is_some() { - return Vec::new(); + return None; } } } @@ -820,7 +820,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Record all the argument types, with the substitutions // produced from the above subtyping unification. - Ok(formal_args.iter().map(|&ty| self.resolve_vars_if_possible(ty)).collect()) + Ok(Some(formal_args.iter().map(|&ty| self.resolve_vars_if_possible(ty)).collect())) }) .unwrap_or_default(); debug!(?formal_args, ?formal_ret, ?expect_args, ?expected_ret); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs b/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs new file mode 100644 index 00000000000..48a66e8026b --- /dev/null +++ b/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs @@ -0,0 +1,343 @@ +use std::cmp; + +use rustc_middle::ty::error::TypeError; + +// An issue that might be found in the compatibility matrix +enum Issue { + /// The given argument is the invalid type for the input + Invalid(usize), + /// There is a missing input + Missing(usize), + /// There's a superfluous argument + Extra(usize), + /// Two arguments should be swapped + Swap(usize, usize), + /// Several arguments should be reordered + Permutation(Vec<Option<usize>>), +} + +#[derive(Clone, Debug)] +pub(crate) enum Compatibility<'tcx> { + Compatible, + Incompatible(Option<TypeError<'tcx>>), +} + +/// Similar to `Issue`, but contains some extra information +pub(crate) enum Error<'tcx> { + /// The given argument is the invalid type for the input + Invalid(usize, Compatibility<'tcx>), + /// There is a missing input + Missing(usize), + /// There's a superfluous argument + Extra(usize), + /// Two arguments should be swapped + Swap(usize, usize, usize, usize), + /// Several arguments should be reordered + Permutation(Vec<(usize, usize)>), // dest_arg, dest_input +} + +pub(crate) struct ArgMatrix<'tcx> { + input_indexes: Vec<usize>, + arg_indexes: Vec<usize>, + compatibility_matrix: Vec<Vec<Compatibility<'tcx>>>, +} + +impl<'tcx> ArgMatrix<'tcx> { + pub(crate) fn new<F: FnMut(usize, usize) -> Compatibility<'tcx>>( + minimum_input_count: usize, + provided_arg_count: usize, + mut is_compatible: F, + ) -> Self { + let compatibility_matrix = (0..provided_arg_count) + .map(|i| (0..minimum_input_count).map(|j| is_compatible(i, j)).collect()) + .collect(); + ArgMatrix { + input_indexes: (0..minimum_input_count).collect(), + arg_indexes: (0..provided_arg_count).collect(), + compatibility_matrix, + } + } + + /// Remove a given input from consideration + fn eliminate_input(&mut self, idx: usize) { + self.input_indexes.remove(idx); + for row in &mut self.compatibility_matrix { + row.remove(idx); + } + } + + /// Remove a given argument from consideration + fn eliminate_arg(&mut self, idx: usize) { + self.arg_indexes.remove(idx); + self.compatibility_matrix.remove(idx); + } + + /// "satisfy" an input with a given arg, removing both from consideration + fn satisfy_input(&mut self, input_idx: usize, arg_idx: usize) { + self.eliminate_input(input_idx); + self.eliminate_arg(arg_idx); + } + + fn eliminate_satisfied(&mut self) -> Vec<(usize, usize)> { + let mut i = cmp::min(self.input_indexes.len(), self.arg_indexes.len()); + let mut eliminated = vec![]; + while i > 0 { + let idx = i - 1; + if matches!(self.compatibility_matrix[idx][idx], Compatibility::Compatible) { + eliminated.push((self.arg_indexes[idx], self.input_indexes[idx])); + self.satisfy_input(idx, idx); + } + i -= 1; + } + return eliminated; + } + + // Check for the above mismatch cases + fn find_issue(&self) -> Option<Issue> { + let mat = &self.compatibility_matrix; + let ai = &self.arg_indexes; + let ii = &self.input_indexes; + + for i in 0..cmp::max(ai.len(), ii.len()) { + // If we eliminate the last row, any left-over inputs are considered missing + if i >= mat.len() { + return Some(Issue::Missing(i)); + } + // If we eliminate the last column, any left-over arguments are extra + if mat[i].len() == 0 { + return Some(Issue::Extra(i)); + } + + // Make sure we don't pass the bounds of our matrix + let is_arg = i < ai.len(); + let is_input = i < ii.len(); + if is_arg && is_input && matches!(mat[i][i], Compatibility::Compatible) { + // This is a satisfied input, so move along + continue; + } + + let mut useless = true; + let mut unsatisfiable = true; + if is_arg { + for j in 0..ii.len() { + // If we find at least one input this argument could satisfy + // this argument isn't completely useless + if matches!(mat[i][j], Compatibility::Compatible) { + useless = false; + break; + } + } + } + if is_input { + for j in 0..ai.len() { + // If we find at least one argument that could satisfy this input + // this argument isn't unsatisfiable + if matches!(mat[j][i], Compatibility::Compatible) { + unsatisfiable = false; + break; + } + } + } + + match (is_arg, is_input, useless, unsatisfiable) { + // If an input is unsatisfied, and the argument in its position is useless + // then the most likely explanation is that we just got the types wrong + (true, true, true, true) => return Some(Issue::Invalid(i)), + // Otherwise, if an input is useless, then indicate that this is an extra argument + (true, _, true, _) => return Some(Issue::Extra(i)), + // Otherwise, if an argument is unsatisfiable, indicate that it's missing + (_, true, _, true) => return Some(Issue::Missing(i)), + (true, true, _, _) => { + // The argument isn't useless, and the input isn't unsatisfied, + // so look for a parameter we might swap it with + // We look for swaps explicitly, instead of just falling back on permutations + // so that cases like (A,B,C,D) given (B,A,D,C) show up as two swaps, + // instead of a large permutation of 4 elements. + for j in 0..cmp::min(ai.len(), ii.len()) { + if i == j || matches!(mat[j][j], Compatibility::Compatible) { + continue; + } + if matches!(mat[i][j], Compatibility::Compatible) + && matches!(mat[j][i], Compatibility::Compatible) + { + return Some(Issue::Swap(i, j)); + } + } + } + _ => { + continue; + } + }; + } + + // We didn't find any of the individual issues above, but + // there might be a larger permutation of parameters, so we now check for that + // by checking for cycles + // We use a double option at position i in this vec to represent: + // - None: We haven't computed anything about this argument yet + // - Some(None): This argument definitely doesn't participate in a cycle + // - Some(Some(x)): the i-th argument could permute to the x-th position + let mut permutation: Vec<Option<Option<usize>>> = vec![None; mat.len()]; + let mut permutation_found = false; + for i in 0..mat.len() { + if permutation[i].is_some() { + // We've already decided whether this argument is or is not in a loop + continue; + } + + let mut stack = vec![]; + let mut j = i; + let mut last = i; + let mut is_cycle = true; + loop { + stack.push(j); + // Look for params this one could slot into + let compat: Vec<_> = + mat[j] + .iter() + .enumerate() + .filter_map(|(i, c)| { + if matches!(c, Compatibility::Compatible) { Some(i) } else { None } + }) + .collect(); + if compat.len() != 1 { + // this could go into multiple slots, don't bother exploring both + is_cycle = false; + break; + } + j = compat[0]; + if stack.contains(&j) { + last = j; + break; + } + } + if stack.len() <= 2 { + // If we encounter a cycle of 1 or 2 elements, we'll let the + // "satisfy" and "swap" code above handle those + is_cycle = false; + } + // We've built up some chain, some of which might be a cycle + // ex: [1,2,3,4]; last = 2; j = 2; + // So, we want to mark 4, 3, and 2 as part of a permutation + permutation_found = is_cycle; + while let Some(x) = stack.pop() { + if is_cycle { + permutation[x] = Some(Some(j)); + j = x; + if j == last { + // From here on out, we're a tail leading into a cycle, + // not the cycle itself + is_cycle = false; + } + } else { + // Some(None) ensures we save time by skipping this argument again + permutation[x] = Some(None); + } + } + } + + if permutation_found { + // Map unwrap to remove the first layer of Some + let final_permutation: Vec<Option<usize>> = + permutation.into_iter().map(|x| x.unwrap()).collect(); + return Some(Issue::Permutation(final_permutation)); + } + return None; + } + + // Obviously, detecting exact user intention is impossible, so the goal here is to + // come up with as likely of a story as we can to be helpful. + // + // We'll iteratively removed "satisfied" input/argument pairs, + // then check for the cases above, until we've eliminated the entire grid + // + // We'll want to know which arguments and inputs these rows and columns correspond to + // even after we delete them. + pub(crate) fn find_errors(mut self) -> (Vec<Error<'tcx>>, Vec<Option<usize>>) { + let provided_arg_count = self.arg_indexes.len(); + + let mut errors: Vec<Error<'tcx>> = vec![]; + // For each expected argument, the matched *actual* input + let mut matched_inputs: Vec<Option<usize>> = vec![None; self.input_indexes.len()]; + + // Before we start looking for issues, eliminate any arguments that are already satisfied, + // so that an argument which is already spoken for by the input it's in doesn't + // spill over into another similarly typed input + // ex: + // fn some_func(_a: i32, _b: i32) {} + // some_func(1, ""); + // Without this elimination, the first argument causes the second argument + // to show up as both a missing input and extra argument, rather than + // just an invalid type. + for (arg, inp) in self.eliminate_satisfied() { + matched_inputs[inp] = Some(arg); + } + + while self.input_indexes.len() > 0 || self.arg_indexes.len() > 0 { + // Check for the first relevant issue + match self.find_issue() { + Some(Issue::Invalid(idx)) => { + let compatibility = self.compatibility_matrix[idx][idx].clone(); + let input_idx = self.input_indexes[idx]; + self.satisfy_input(idx, idx); + errors.push(Error::Invalid(input_idx, compatibility)); + } + Some(Issue::Extra(idx)) => { + let arg_idx = self.arg_indexes[idx]; + self.eliminate_arg(idx); + errors.push(Error::Extra(arg_idx)); + } + Some(Issue::Missing(idx)) => { + let input_idx = self.input_indexes[idx]; + self.eliminate_input(idx); + errors.push(Error::Missing(input_idx)); + } + Some(Issue::Swap(idx, other)) => { + let input_idx = self.input_indexes[idx]; + let other_input_idx = self.input_indexes[other]; + let arg_idx = self.arg_indexes[idx]; + let other_arg_idx = self.arg_indexes[other]; + let (min, max) = (cmp::min(idx, other), cmp::max(idx, other)); + self.satisfy_input(min, max); + // Subtract 1 because we already removed the "min" row + self.satisfy_input(max - 1, min); + errors.push(Error::Swap(input_idx, other_input_idx, arg_idx, other_arg_idx)); + matched_inputs[input_idx] = Some(other_arg_idx); + matched_inputs[other_input_idx] = Some(arg_idx); + } + Some(Issue::Permutation(args)) => { + // FIXME: If satisfy_input ever did anything non-trivial (emit obligations to help type checking, for example) + // we'd want to call this function with the correct arg/input pairs, but for now, we just throw them in a bucket. + // This works because they force a cycle, so each row is guaranteed to also be a column + let mut idxs: Vec<usize> = args.iter().filter_map(|&a| a).collect(); + + let mut real_idxs = vec![None; provided_arg_count]; + for (src, dst) in + args.iter().enumerate().filter_map(|(src, dst)| dst.map(|dst| (src, dst))) + { + let src_arg = self.arg_indexes[src]; + let dst_arg = self.arg_indexes[dst]; + let dest_input = self.input_indexes[dst]; + real_idxs[src_arg] = Some((dst_arg, dest_input)); + matched_inputs[dest_input] = Some(src_arg); + } + idxs.sort(); + idxs.reverse(); + for i in idxs { + self.satisfy_input(i, i); + } + errors.push(Error::Permutation(real_idxs.into_iter().flatten().collect())); + } + None => { + // We didn't find any issues, so we need to push the algorithm forward + // First, eliminate any arguments that currently satisfy their inputs + for (arg, inp) in self.eliminate_satisfied() { + matched_inputs[inp] = Some(arg); + } + } + }; + } + + return (errors, matched_inputs); + } +} diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index f6a5243274c..80f6190732a 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1,5 +1,6 @@ use crate::astconv::AstConv; use crate::check::coercion::CoerceMany; +use crate::check::fn_ctxt::arg_matrix::{ArgMatrix, Compatibility, Error}; use crate::check::gather_locals::Declaration; use crate::check::method::MethodCallee; use crate::check::Expectation::*; @@ -8,6 +9,7 @@ use crate::check::{ potentially_plural_count, struct_span_err, BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, Needs, TupleArgumentsFlag, }; +use crate::structured_errors::StructuredDiagnostic; use rustc_ast as ast; use rustc_data_structures::sync::Lrc; @@ -16,7 +18,11 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{ExprKind, Node, QPath}; +use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt}; +use rustc_infer::infer::InferOk; +use rustc_infer::infer::TypeTrace; use rustc_middle::ty::adjustment::AllowTwoPhase; +use rustc_middle::ty::error::TypeError; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, Ty}; use rustc_session::Session; @@ -24,15 +30,15 @@ use rustc_span::symbol::Ident; use rustc_span::{self, Span}; use rustc_trait_selection::traits::{self, ObligationCauseCode, StatementAsExpression}; -use crate::structured_errors::StructuredDiagnostic; use std::iter; use std::slice; -struct FnArgsAsTuple<'hir> { - first: &'hir hir::Expr<'hir>, - last: &'hir hir::Expr<'hir>, +enum TupleMatchFound { + None, + Single, + /// Beginning and end Span + Multiple(Span, Span), } - impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn check_casts(&self) { let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut(); @@ -67,7 +73,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sp, expr, &err_inputs, - vec![], + None, args_no_rcvr, false, tuple_arguments, @@ -108,7 +114,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Types (as defined in the *signature* of the target function) formal_input_tys: &[Ty<'tcx>], // More specific expected types, after unifying with caller output types - expected_input_tys: Vec<Ty<'tcx>>, + expected_input_tys: Option<Vec<Ty<'tcx>>>, // The expressions for each provided argument provided_args: &'tcx [hir::Expr<'tcx>], // Whether the function is variadic, for example when imported from C @@ -119,10 +125,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_def_id: Option<DefId>, ) { let tcx = self.tcx; - // Grab the argument types, supplying fresh type variables - // if the wrong number of arguments were supplied - let supplied_arg_count = - if tuple_arguments == DontTupleArguments { provided_args.len() } else { 1 }; + + // Conceptually, we've got some number of expected inputs, and some number of provided aguments + // and we can form a grid of whether each argument could satisfy a given input: + // in1 | in2 | in3 | ... + // arg1 ? | | | + // arg2 | ? | | + // arg3 | | ? | + // ... + // Initially, we just check the diagonal, because in the case of correct code + // these are the only checks that matter + // However, in the unhappy path, we'll fill in this whole grid to attempt to provide + // better error messages about invalid method calls. // All the input types from the fn signature must outlive the call // so as to validate implied bounds. @@ -130,11 +144,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation); } - let expected_arg_count = formal_input_tys.len(); - - // expected_count, arg_count, error_code, sugg_unit, sugg_tuple_wrap_args - let mut arg_count_error: Option<(usize, usize, &str, bool, Option<FnArgsAsTuple<'_>>)> = - None; + let mut err_code = "E0061"; // If the arguments should be wrapped in a tuple (ex: closures), unwrap them here let (formal_input_tys, expected_input_tys) = if tuple_arguments == TupleArguments { @@ -144,15 +154,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Tuple(arg_types) => { // Argument length differs if arg_types.len() != provided_args.len() { - arg_count_error = - Some((arg_types.len(), provided_args.len(), "E0057", false, None)); + err_code = "E0057"; } - let expected_input_tys = match expected_input_tys.get(0) { - Some(&ty) => match ty.kind() { - ty::Tuple(tys) => tys.iter().collect(), - _ => vec![], + let expected_input_tys = match expected_input_tys { + Some(expected_input_tys) => match expected_input_tys.get(0) { + Some(ty) => match ty.kind() { + ty::Tuple(tys) => Some(tys.iter().collect()), + _ => None, + }, + None => None, }, - None => vec![], + None => None, }; (arg_types.iter().collect(), expected_input_tys) } @@ -167,67 +179,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for the function trait is neither a tuple nor unit" ) .emit(); - (self.err_args(provided_args.len()), vec![]) + (self.err_args(provided_args.len()), None) } } - } else if expected_arg_count == supplied_arg_count { - (formal_input_tys.to_vec(), expected_input_tys) - } else if c_variadic { - if supplied_arg_count >= expected_arg_count { - (formal_input_tys.to_vec(), expected_input_tys) - } else { - arg_count_error = - Some((expected_arg_count, supplied_arg_count, "E0060", false, None)); - (self.err_args(supplied_arg_count), vec![]) - } } else { - // is the missing argument of type `()`? - let sugg_unit = if expected_input_tys.len() == 1 && supplied_arg_count == 0 { - self.resolve_vars_if_possible(expected_input_tys[0]).is_unit() - } else if formal_input_tys.len() == 1 && supplied_arg_count == 0 { - self.resolve_vars_if_possible(formal_input_tys[0]).is_unit() - } else { - false - }; - - // are we passing elements of a tuple without the tuple parentheses? - let expected_input_tys = if expected_input_tys.is_empty() { - // In most cases we can use expected_input_tys, but some callers won't have the type - // information, in which case we fall back to the types from the input expressions. - formal_input_tys - } else { - &*expected_input_tys - }; - - let sugg_tuple_wrap_args = self.suggested_tuple_wrap(expected_input_tys, provided_args); - - arg_count_error = Some(( - expected_arg_count, - supplied_arg_count, - "E0061", - sugg_unit, - sugg_tuple_wrap_args, - )); - (self.err_args(supplied_arg_count), vec![]) + (formal_input_tys.to_vec(), expected_input_tys) }; - debug!( - "check_argument_types: formal_input_tys={:?}", - formal_input_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>() - ); - - // If there is no expectation, expect formal_input_tys. - let expected_input_tys = if !expected_input_tys.is_empty() { + // If there are no external expectations at the call site, just use the types from the function defn + let expected_input_tys = if let Some(expected_input_tys) = expected_input_tys { + assert_eq!(expected_input_tys.len(), formal_input_tys.len()); expected_input_tys } else { formal_input_tys.clone() }; - assert_eq!(expected_input_tys.len(), formal_input_tys.len()); - - let provided_arg_count: usize = provided_args.len(); + let minimum_input_count = expected_input_tys.len(); + let provided_arg_count = provided_args.len(); - // Keep track of the fully coerced argument types + // We'll also want to keep track of the fully coerced argument types, for an awkward hack near the end let mut final_arg_types: Vec<Option<(Ty<'_>, Ty<'_>)>> = vec![None; provided_arg_count]; // We introduce a helper function to demand that a given argument satisfy a given input @@ -240,8 +210,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("checking argument {}: {:?} = {:?}", idx, provided_arg, formal_input_ty); - // The special-cased logic below has three functions: - // 1. Provide as good of an expected type as possible. + // We're on the happy path here, so we'll do a more involved check and write back types + // To check compatibility, we'll do 3 things: + // 1. Unify the provided argument with the expected type let expectation = Expectation::rvalue_hint(self, expected_input_ty); let checked_ty = self.check_expr_with_expectation(provided_arg, expectation); @@ -255,8 +226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { final_arg_types[idx] = Some((checked_ty, coerced_ty)); // Cause selection errors caused by resolving a single argument to point at the - // argument and not the call. This is otherwise redundant with the `demand_coerce` - // call immediately after, but it lets us customize the span pointed to in the + // argument and not the call. This lets us customize the span pointed to in the // fulfillment error to be more accurate. let coerced_ty = self.resolve_vars_with_obligations_and_mutate_fulfillment(coerced_ty, |errors| { @@ -270,18 +240,95 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); }); + // Make sure we store the resolved type final_arg_types[idx] = Some((checked_ty, coerced_ty)); - // We're processing function arguments so we definitely want to use - // two-phase borrows. - self.demand_coerce(&provided_arg, checked_ty, coerced_ty, None, AllowTwoPhase::Yes); + let coerce_error = self + .try_coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None) + .err(); + + if coerce_error.is_some() { + return Compatibility::Incompatible(coerce_error); + } + + // 3. Check if the formal type is a supertype of the checked one + // and register any such obligations for future type checks + let supertype_error = self + .at(&self.misc(provided_arg.span), self.param_env) + .sup(formal_input_ty, coerced_ty); + let subtyping_error = match supertype_error { + Ok(InferOk { obligations, value: () }) => { + self.register_predicates(obligations); + None + } + Err(err) => Some(err), + }; - // 3. Relate the expected type and the formal one, - // if the expected type was used for the coercion. - self.demand_suptype(provided_arg.span, formal_input_ty, coerced_ty); + // If neither check failed, the types are compatible + match subtyping_error { + None => Compatibility::Compatible, + Some(_) => Compatibility::Incompatible(subtyping_error), + } }; - let minimum_input_count = formal_input_tys.len(); + // A "softer" version of the helper above, which checks types without persisting them, + // and treats error types differently + // This will allow us to "probe" for other argument orders that would likely have been correct + let check_compatible = |arg_idx, input_idx| { + let formal_input_ty: Ty<'tcx> = formal_input_tys[input_idx]; + let expected_input_ty: Ty<'tcx> = expected_input_tys[input_idx]; + + // If either is an error type, we defy the usual convention and consider them to *not* be + // coercible. This prevents our error message heuristic from trying to pass errors into + // every argument. + if formal_input_ty.references_error() || expected_input_ty.references_error() { + return Compatibility::Incompatible(None); + } + + let provided_arg: &hir::Expr<'tcx> = &provided_args[arg_idx]; + let expectation = Expectation::rvalue_hint(self, expected_input_ty); + // FIXME: check that this is safe; I don't believe this commits any of the obligations, but I can't be sure. + // + // I had another method of "soft" type checking before, + // but it was failing to find the type of some expressions (like "") + // so I prodded this method and made it pub(super) so I could call it, and it seems to work well. + let checked_ty = self.check_expr_kind(provided_arg, expectation); + + let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty); + let can_coerce = self.can_coerce(checked_ty, coerced_ty); + + if !can_coerce { + return Compatibility::Incompatible(None); + } + + let subtyping_result = self + .at(&self.misc(provided_arg.span), self.param_env) + .sup(formal_input_ty, coerced_ty); + + // Same as above: if either the coerce type or the checked type is an error type, + // consider them *not* compatible. + let coercible = + !coerced_ty.references_error() && !checked_ty.references_error() && can_coerce; + + match (coercible, &subtyping_result) { + (true, Ok(_)) => Compatibility::Compatible, + _ => Compatibility::Incompatible(subtyping_result.err()), + } + }; + + // To start, we only care "along the diagonal", where we expect every + // provided arg to be in the right spot + let mut compatibility = vec![Compatibility::Incompatible(None); provided_args.len()]; + + // Keep track of whether we *could possibly* be satisfied, i.e. whether we're on the happy path + // if the wrong number of arguments were supplied, we CAN'T be satisfied, + // and if we're c_variadic, the supplied arguments must be >= the minimum count from the function + // otherwise, they need to be identical, because rust doesn't currently support variadic functions + let mut call_appears_satisfied = if c_variadic { + provided_arg_count >= minimum_input_count + } else { + provided_arg_count == minimum_input_count + }; // Check the arguments. // We do this in a pretty awful way: first we type-check any arguments @@ -305,6 +352,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) } + // Check each argument, to satisfy the input it was provided for + // Visually, we're traveling down the diagonal of the compatibility matrix for (idx, arg) in provided_args.iter().enumerate() { // Warn only for the first loop (the "no closures" one). // Closure arguments themselves can't be diverging, but @@ -327,15 +376,82 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { continue; } - demand_compatible(idx, &mut final_arg_types); + let compatible = demand_compatible(idx, &mut final_arg_types); + let is_compatible = matches!(compatible, Compatibility::Compatible); + compatibility[idx] = compatible; + + if !is_compatible { + call_appears_satisfied = false; + } } } - // If there was an error in parameter count, emit that here - if let Some((expected_count, arg_count, err_code, sugg_unit, sugg_tuple_wrap_args)) = - arg_count_error - { - let (span, start_span, args, ctor_of) = match &call_expr.kind { + // Logic here is a bit hairy + 'errors: { + // If something above didn't typecheck, we've fallen off the happy path + // and we should make some effort to provide better error messages + if call_appears_satisfied { + break 'errors; + } + + // The algorithm here is inspired by levenshtein distance and longest common subsequence. + // We'll try to detect 4 different types of mistakes: + // - An extra parameter has been provided that doesn't satisfy *any* of the other inputs + // - An input is missing, which isn't satisfied by *any* of the other arguments + // - Some number of arguments have been provided in the wrong order + // - A type is straight up invalid + + // First, let's find the errors + let mut compatibility: Vec<_> = compatibility.into_iter().map(Some).collect(); + let (mut errors, matched_inputs) = + ArgMatrix::new(minimum_input_count, provided_arg_count, |i, j| { + if i == j { compatibility[i].take().unwrap() } else { check_compatible(i, j) } + }) + .find_errors(); + + // Okay, so here's where it gets complicated in regards to what errors + // we emit and how. + // There are 3 different "types" of errors we might encounter. + // 1) Missing/extra/swapped arguments + // 2) Valid but incorrect arguments + // 3) Invalid arguments + // - Currently I think this only comes up with `CyclicTy` + // + // We first need to go through, remove those from (3) and emit those + // as their own error, particularly since they're error code and + // message is special. From what I can tell, we *must* emit these + // here (vs somewhere prior to this function) since the arguments + // become invalid *because* of how they get used in the function. + // It is what it is. + + let found_errors = !errors.is_empty(); + + errors.drain_filter(|error| { + let Error::Invalid(input_idx, Compatibility::Incompatible(error)) = error else { return false }; + let expected_ty = expected_input_tys[*input_idx]; + let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap(); + let cause = &self.misc(provided_args[*input_idx].span); + let trace = TypeTrace::types(cause, true, expected_ty, provided_ty); + if let Some(e) = error { + if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) { + self.report_and_explain_type_error(trace, e).emit(); + return true; + } + } + false + }); + + // We're done if we found errors, but we already emitted them. + // I don't think we *should* be able to enter this bit of code + // (`!call_appears_satisfied`) without *also* finding errors, but we + // don't want to accidentally not emit an error if there is some + // logic bug in the `ArgMatrix` code. + if found_errors && errors.is_empty() { + break 'errors; + } + + // Next, let's construct the error + let (error_span, full_call_span, ctor_of) = match &call_expr.kind { hir::ExprKind::Call( hir::Expr { span, @@ -346,67 +462,484 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )), .. }, - args, - ) => (*span, *span, &args[..], Some(of)), - hir::ExprKind::Call(hir::Expr { span, .. }, args) => { - (*span, *span, &args[..], None) + _, + ) => (call_span, *span, Some(of)), + hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None), + hir::ExprKind::MethodCall(path_segment, _, span) => { + let ident_span = path_segment.ident.span; + let ident_span = if let Some(args) = path_segment.args { + ident_span.with_hi(args.span_ext.hi()) + } else { + ident_span + }; + ( + *span, ident_span, None, // methods are never ctors + ) } - hir::ExprKind::MethodCall(path_segment, args, _) => ( - path_segment.ident.span, - // `sp` doesn't point at the whole `foo.bar()`, only at `bar`. - path_segment - .args - .and_then(|args| args.args.iter().last()) - // Account for `foo.bar::<T>()`. - .map(|arg| { - // Skip the closing `>`. - tcx.sess - .source_map() - .next_point(tcx.sess.source_map().next_point(arg.span())) - }) - .unwrap_or(path_segment.ident.span), - &args[1..], // Skip the receiver. - None, // methods are never ctors - ), k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k), }; - let arg_spans = if provided_args.is_empty() { - // foo() - // ^^^-- supplied 0 arguments - // | - // expected 2 arguments - vec![tcx.sess.source_map().next_point(start_span).with_hi(call_span.hi())] - } else { - // foo(1, 2, 3) - // ^^^ - - - supplied 3 arguments - // | - // expected 2 arguments - args.iter().map(|arg| arg.span).collect::<Vec<Span>>() - }; + let args_span = error_span.trim_start(full_call_span).unwrap_or(error_span); let call_name = match ctor_of { Some(CtorOf::Struct) => "struct", Some(CtorOf::Variant) => "enum variant", None => "function", }; - let mut err = tcx.sess.struct_span_err_with_code( - span, - &format!( - "this {} takes {}{} but {} {} supplied", + if c_variadic && provided_arg_count < minimum_input_count { + err_code = "E0060"; + } + + // Next special case: The case where we expect a single tuple and + // wrapping all the args in parentheses (or adding a comma to + // already existing parentheses) will result in a tuple that + // satisfies the call. + // This isn't super ideal code, because we copy code from elsewhere + // and somewhat duplicate this. We also delegate to the general type + // mismatch suggestions for the single arg case. + let sugg_tuple_wrap_args = + self.suggested_tuple_wrap(&expected_input_tys, provided_args); + match sugg_tuple_wrap_args { + TupleMatchFound::None => {} + TupleMatchFound::Single => { + let expected_ty = expected_input_tys[0]; + let provided_ty = final_arg_types[0].map(|ty| ty.0).unwrap(); + let cause = &self.misc(provided_args[0].span); + let compatibility = demand_compatible(0, &mut final_arg_types); + let type_error = match compatibility { + Compatibility::Incompatible(Some(error)) => error, + _ => TypeError::Mismatch, + }; + let trace = TypeTrace::types(cause, true, expected_ty, provided_ty); + let mut err = self.report_and_explain_type_error(trace, &type_error); + self.emit_coerce_suggestions( + &mut err, + &provided_args[0], + final_arg_types[0].map(|ty| ty.0).unwrap(), + final_arg_types[0].map(|ty| ty.1).unwrap(), + None, + None, + ); + err.span_label( + full_call_span, + format!("arguments to this {} are incorrect", call_name), + ); + // Call out where the function is defined + if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) { + let mut spans: MultiSpan = def_span.into(); + + let params = tcx + .hir() + .get_if_local(def_id) + .and_then(|node| node.body_id()) + .into_iter() + .map(|id| tcx.hir().body(id).params) + .flatten(); + + for param in params { + spans.push_span_label(param.span, String::new()); + } + + let def_kind = tcx.def_kind(def_id); + err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id))); + } + err.emit(); + break 'errors; + } + TupleMatchFound::Multiple(start, end) => { + let mut err = tcx.sess.struct_span_err_with_code( + full_call_span, + &format!( + "this {} takes {}{} but {} {} supplied", + call_name, + if c_variadic { "at least " } else { "" }, + potentially_plural_count(minimum_input_count, "argument"), + potentially_plural_count(provided_arg_count, "argument"), + if provided_arg_count == 1 { "was" } else { "were" } + ), + DiagnosticId::Error(err_code.to_owned()), + ); + // Call out where the function is defined + if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) { + let mut spans: MultiSpan = def_span.into(); + + let params = tcx + .hir() + .get_if_local(def_id) + .and_then(|node| node.body_id()) + .into_iter() + .map(|id| tcx.hir().body(id).params) + .flatten(); + + for param in params { + spans.push_span_label(param.span, String::new()); + } + + let def_kind = tcx.def_kind(def_id); + err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id))); + } + err.multipart_suggestion( + "use parentheses to construct a tuple", + vec![(start, '('.to_string()), (end, ')'.to_string())], + Applicability::MachineApplicable, + ); + err.emit(); + break 'errors; + } + } + + // Okay, now that we've emitted the special errors separately, we + // are only left missing/extra/swapped and mismatched arguments, both + // can be collated pretty easily if needed. + + // Next special case: if there is only one "Incompatible" error, just emit that + if errors.len() == 1 { + if let Some(Error::Invalid(input_idx, Compatibility::Incompatible(Some(error)))) = + errors.iter().next() + { + let expected_ty = expected_input_tys[*input_idx]; + let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap(); + let cause = &self.misc(provided_args[*input_idx].span); + let trace = TypeTrace::types(cause, true, expected_ty, provided_ty); + let mut err = self.report_and_explain_type_error(trace, error); + self.emit_coerce_suggestions( + &mut err, + &provided_args[*input_idx], + final_arg_types[*input_idx].map(|ty| ty.0).unwrap(), + final_arg_types[*input_idx].map(|ty| ty.1).unwrap(), + None, + None, + ); + err.span_label( + full_call_span, + format!("arguments to this {} are incorrect", call_name), + ); + // Call out where the function is defined + if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) { + let mut spans: MultiSpan = def_span.into(); + + let params = tcx + .hir() + .get_if_local(def_id) + .and_then(|node| node.body_id()) + .into_iter() + .map(|id| tcx.hir().body(id).params) + .flatten(); + + for param in params { + spans.push_span_label(param.span, String::new()); + } + + let def_kind = tcx.def_kind(def_id); + err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id))); + } + err.emit(); + break 'errors; + } + } + + let mut err = if minimum_input_count == provided_arg_count { + struct_span_err!( + tcx.sess, + full_call_span, + E0308, + "arguments to this {} are incorrect", call_name, - if c_variadic { "at least " } else { "" }, - potentially_plural_count(expected_count, "argument"), - potentially_plural_count(arg_count, "argument"), - if arg_count == 1 { "was" } else { "were" } - ), - DiagnosticId::Error(err_code.to_owned()), - ); - let label = format!("supplied {}", potentially_plural_count(arg_count, "argument")); - for (i, span) in arg_spans.into_iter().enumerate() { - err.span_label( - span, - if arg_count == 0 || i + 1 == arg_count { &label } else { "" }, - ); + ) + } else { + tcx.sess.struct_span_err_with_code( + full_call_span, + &format!( + "this {} takes {}{} but {} {} supplied", + call_name, + if c_variadic { "at least " } else { "" }, + potentially_plural_count(minimum_input_count, "argument"), + potentially_plural_count(provided_arg_count, "argument"), + if provided_arg_count == 1 { "was" } else { "were" } + ), + DiagnosticId::Error(err_code.to_owned()), + ) + }; + + // As we encounter issues, keep track of what we want to provide for the suggestion + let mut labels = vec![]; + // If there is a single error, we give a specific suggestion; otherwise, we change to + // "did you mean" with the suggested function call + enum SuggestionText { + None, + Provide(bool), + Remove(bool), + Swap, + Reorder, + DidYouMean, } + let mut suggestion_text = SuggestionText::None; + + let mut errors = errors.into_iter().peekable(); + while let Some(error) = errors.next() { + match error { + Error::Invalid(input_idx, compatibility) => { + let expected_ty = expected_input_tys[input_idx]; + if let Compatibility::Incompatible(error) = &compatibility { + let provided_ty = final_arg_types[input_idx].map(|ty| ty.0).unwrap(); + let cause = &self.misc(provided_args[input_idx].span); + let trace = TypeTrace::types(cause, true, expected_ty, provided_ty); + if let Some(e) = error { + self.note_type_err( + &mut err, + &trace.cause, + None, + Some(trace.values), + e, + false, + true, + ); + } + } + + self.emit_coerce_suggestions( + &mut err, + &provided_args[input_idx], + final_arg_types[input_idx].map(|ty| ty.0).unwrap(), + final_arg_types[input_idx].map(|ty| ty.1).unwrap(), + None, + None, + ); + } + Error::Extra(arg_idx) => { + let arg_type = if let Some((_, ty)) = final_arg_types[arg_idx] { + if ty.references_error() || ty.has_infer_types() { + "".into() + } else { + format!(" of type `{}`", ty) + } + } else { + "".into() + }; + labels.push(( + provided_args[arg_idx].span, + format!("argument{} unexpected", arg_type), + )); + suggestion_text = match suggestion_text { + SuggestionText::None => SuggestionText::Remove(false), + SuggestionText::Remove(_) => SuggestionText::Remove(true), + _ => SuggestionText::DidYouMean, + }; + } + Error::Missing(input_idx) => { + // If there are multiple missing arguments adjacent to each other, + // then we can provide a single error. + + let mut missing_idxs = vec![input_idx]; + while let Some(e) = errors.next_if(|e| matches!(e, Error::Missing(input_idx) if *input_idx == (missing_idxs.last().unwrap() + 1))) { + match e { + Error::Missing(input_idx) => missing_idxs.push(input_idx), + _ => unreachable!(), + } + } + + // NOTE: Because we might be re-arranging arguments, might have extra + // arguments, etc. it's hard to *really* know where we should provide + // this error label, so as a heuristic, we point to the provided arg, or + // to the call if the missing inputs pass the provided args. + match &missing_idxs[..] { + &[input_idx] => { + let expected_ty = expected_input_tys[input_idx]; + let input_ty = self.resolve_vars_if_possible(expected_ty); + let span = if input_idx < provided_arg_count { + let arg_span = provided_args[input_idx].span; + Span::new(arg_span.lo(), arg_span.hi(), arg_span.ctxt(), None) + } else { + args_span + }; + let arg_type = + if input_ty.references_error() || input_ty.has_infer_types() { + "".into() + } else { + format!(" of type `{}`", input_ty) + }; + labels.push((span, format!("an argument{} is missing", arg_type))); + suggestion_text = match suggestion_text { + SuggestionText::None => SuggestionText::Provide(false), + SuggestionText::Provide(_) => SuggestionText::Provide(true), + _ => SuggestionText::DidYouMean, + }; + } + &[first_idx, second_idx] => { + let first_input_ty = + self.resolve_vars_if_possible(expected_input_tys[first_idx]); + let second_input_ty = + self.resolve_vars_if_possible(expected_input_tys[second_idx]); + + let span = if second_idx < provided_arg_count { + let first_arg_span = provided_args[first_idx].span; + let second_arg_span = provided_args[second_idx].span; + Span::new( + first_arg_span.lo(), + second_arg_span.hi(), + first_arg_span.ctxt(), + None, + ) + } else { + args_span + }; + let any_unnameable = false + || first_input_ty.references_error() + || first_input_ty.has_infer_types() + || second_input_ty.references_error() + || second_input_ty.has_infer_types(); + let arg_type = if any_unnameable { + "".into() + } else { + format!( + " of type `{}` and `{}`", + first_input_ty, second_input_ty + ) + }; + labels + .push((span, format!("two arguments{} are missing", arg_type))); + suggestion_text = match suggestion_text { + SuggestionText::None | SuggestionText::Provide(_) => { + SuggestionText::Provide(true) + } + _ => SuggestionText::DidYouMean, + }; + } + &[first_idx, second_idx, third_idx] => { + let first_input_ty = + self.resolve_vars_if_possible(expected_input_tys[first_idx]); + let second_input_ty = + self.resolve_vars_if_possible(expected_input_tys[second_idx]); + let third_input_ty = + self.resolve_vars_if_possible(expected_input_tys[second_idx]); + let span = if third_idx < provided_arg_count { + let first_arg_span = provided_args[first_idx].span; + let third_arg_span = provided_args[third_idx].span; + Span::new( + first_arg_span.lo(), + third_arg_span.hi(), + first_arg_span.ctxt(), + None, + ) + } else { + args_span + }; + let any_unnameable = false + || first_input_ty.references_error() + || first_input_ty.has_infer_types() + || second_input_ty.references_error() + || second_input_ty.has_infer_types() + || third_input_ty.references_error() + || third_input_ty.has_infer_types(); + let arg_type = if any_unnameable { + "".into() + } else { + format!( + " of type `{}`, `{}`, and `{}`", + first_input_ty, second_input_ty, third_input_ty + ) + }; + labels.push(( + span, + format!("three arguments{} are missing", arg_type), + )); + suggestion_text = match suggestion_text { + SuggestionText::None | SuggestionText::Provide(_) => { + SuggestionText::Provide(true) + } + _ => SuggestionText::DidYouMean, + }; + } + missing_idxs => { + let first_idx = *missing_idxs.first().unwrap(); + let second_idx = *missing_idxs.last().unwrap(); + // NOTE: Because we might be re-arranging arguments, might have extra arguments, etc. + // It's hard to *really* know where we should provide this error label, so this is a + // decent heuristic + let span = if first_idx < provided_arg_count { + let first_arg_span = provided_args[first_idx].span; + let second_arg_span = provided_args[second_idx].span; + Span::new( + first_arg_span.lo(), + second_arg_span.hi(), + first_arg_span.ctxt(), + None, + ) + } else { + // Otherwise just label the whole function + args_span + }; + labels.push((span, format!("multiple arguments are missing"))); + suggestion_text = match suggestion_text { + SuggestionText::None | SuggestionText::Provide(_) => { + SuggestionText::Provide(true) + } + _ => SuggestionText::DidYouMean, + }; + } + } + } + Error::Swap(input_idx, other_input_idx, arg_idx, other_arg_idx) => { + let first_span = provided_args[arg_idx].span; + let second_span = provided_args[other_arg_idx].span; + + let first_expected_ty = + self.resolve_vars_if_possible(expected_input_tys[input_idx]); + let first_provided_ty = if let Some((ty, _)) = final_arg_types[arg_idx] { + format!(",found `{}`", ty) + } else { + "".into() + }; + labels.push(( + first_span, + format!("expected `{}`{}", first_expected_ty, first_provided_ty), + )); + let other_expected_ty = + self.resolve_vars_if_possible(expected_input_tys[other_input_idx]); + let other_provided_ty = + if let Some((ty, _)) = final_arg_types[other_arg_idx] { + format!(",found `{}`", ty) + } else { + "".into() + }; + labels.push(( + second_span, + format!("expected `{}`{}", other_expected_ty, other_provided_ty), + )); + suggestion_text = match suggestion_text { + SuggestionText::None => SuggestionText::Swap, + _ => SuggestionText::DidYouMean, + }; + } + Error::Permutation(args) => { + for (dst_arg, dest_input) in args { + let expected_ty = + self.resolve_vars_if_possible(expected_input_tys[dest_input]); + let provided_ty = if let Some((ty, _)) = final_arg_types[dst_arg] { + format!(",found `{}`", ty) + } else { + "".into() + }; + labels.push(( + provided_args[dst_arg].span, + format!("expected `{}`{}", expected_ty, provided_ty), + )); + } + + suggestion_text = match suggestion_text { + SuggestionText::None => SuggestionText::Reorder, + _ => SuggestionText::DidYouMean, + }; + } + } + } + + // If we have less than 5 things to say, it would be useful to call out exactly what's wrong + if labels.len() <= 5 { + for (span, label) in labels { + err.span_label(span, label); + } + } + + // Call out where the function is defined if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) { let mut spans: MultiSpan = def_span.into(); @@ -415,8 +948,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .get_if_local(def_id) .and_then(|node| node.body_id()) .into_iter() - .map(|id| tcx.hir().body(id).params) - .flatten(); + .flat_map(|id| tcx.hir().body(id).params) + ; for param in params { spans.push_span_label(param.span, String::new()); @@ -425,33 +958,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let def_kind = tcx.def_kind(def_id); err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id))); } - if sugg_unit { - let sugg_span = tcx.sess.source_map().end_point(call_expr.span); - // remove closing `)` from the span - let sugg_span = sugg_span.shrink_to_lo(); - err.span_suggestion( - sugg_span, - "expected the unit value `()`; create it with empty parentheses", - String::from("()"), - Applicability::MachineApplicable, - ); - } else if let Some(FnArgsAsTuple { first, last }) = sugg_tuple_wrap_args { - err.multipart_suggestion( - "use parentheses to construct a tuple", - vec![ - (first.span.shrink_to_lo(), '('.to_string()), - (last.span.shrink_to_hi(), ')'.to_string()), - ], - Applicability::MachineApplicable, + + // And add a suggestion block for all of the parameters + let suggestion_text = match suggestion_text { + SuggestionText::None => None, + SuggestionText::Provide(plural) => { + Some(format!("provide the argument{}", if plural { "s" } else { "" })) + } + SuggestionText::Remove(plural) => { + Some(format!("remove the extra argument{}", if plural { "s" } else { "" })) + } + SuggestionText::Swap => Some(format!("swap these arguments")), + SuggestionText::Reorder => Some(format!("reorder these arguments")), + SuggestionText::DidYouMean => Some(format!("did you mean")), + }; + if let Some(suggestion_text) = suggestion_text { + let source_map = self.sess().source_map(); + let mut suggestion = format!( + "{}(", + source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| String::new()) ); - } else { - err.span_label( - span, - format!( - "expected {}{}", - if c_variadic { "at least " } else { "" }, - potentially_plural_count(expected_count, "argument") - ), + for (idx, arg) in matched_inputs.iter().enumerate() { + let suggestion_text = if let Some(arg) = arg { + let arg_span = provided_args[*arg].span; + let arg_text = source_map.span_to_snippet(arg_span).unwrap(); + arg_text + } else { + // Propose a placeholder of the correct type + let expected_ty = expected_input_tys[idx]; + let input_ty = self.resolve_vars_if_possible(expected_ty); + if input_ty.is_unit() { + "()".to_string() + } else { + format!("{{{}}}", input_ty) + } + }; + suggestion += &suggestion_text; + if idx < minimum_input_count - 1 { + suggestion += ", "; + } + } + suggestion += ")"; + err.span_suggestion_verbose( + error_span, + &suggestion_text, + suggestion, + Applicability::HasPlaceholders, ); } err.emit(); @@ -460,10 +1012,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for arg in provided_args.iter().skip(minimum_input_count) { let arg_ty = self.check_expr(&arg); + // If the function is c-style variadic, we skipped a bunch of arguments + // so we need to check those, and write out the types + // Ideally this would be folded into the above, for uniform style + // but c-variadic is already a corner case if c_variadic { - // We also need to make sure we at least write the ty of the other - // arguments which we skipped above, either because they were additional - // c_variadic args, or because we had an argument count mismatch. fn variadic_error<'tcx>(sess: &Session, span: Span, ty: Ty<'tcx>, cast_ty: &str) { use crate::structured_errors::MissingCastForVariadicArg; @@ -498,27 +1051,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, expected_input_tys: &[Ty<'tcx>], provided_args: &'tcx [hir::Expr<'tcx>], - ) -> Option<FnArgsAsTuple<'_>> { - let [expected_arg_type] = expected_input_tys[..] else { return None }; - + ) -> TupleMatchFound { + // Only handle the case where we expect only one tuple arg + let [expected_arg_type] = expected_input_tys[..] else { return TupleMatchFound::None }; let &ty::Tuple(expected_types) = self.resolve_vars_if_possible(expected_arg_type).kind() - else { return None }; + else { return TupleMatchFound::None }; + + // First check that there are the same number of types. + if expected_types.len() != provided_args.len() { + return TupleMatchFound::None; + } let supplied_types: Vec<_> = provided_args.iter().map(|arg| self.check_expr(arg)).collect(); let all_match = iter::zip(expected_types, supplied_types) .all(|(expected, supplied)| self.can_eq(self.param_env, expected, supplied).is_ok()); - if all_match { - match provided_args { - [] => None, - [_] => unreachable!( - "shouldn't reach here - need count mismatch between 1-tuple and 1-argument" - ), - [first, .., last] => Some(FnArgsAsTuple { first, last }), + if !all_match { + return TupleMatchFound::None; + } + match provided_args { + [] => TupleMatchFound::None, + [_] => TupleMatchFound::Single, + [first, .., last] => { + TupleMatchFound::Multiple(first.span.shrink_to_lo(), last.span.shrink_to_hi()) } - } else { - None } } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index 77cba1c22c4..ce9ff61bd9e 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -1,9 +1,9 @@ mod _impl; +mod arg_matrix; mod checks; mod suggestions; pub use _impl::*; -pub use checks::*; pub use suggestions::*; use crate::astconv::AstConv; diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 93a0900c7e8..62518408b8b 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -646,7 +646,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // now get all predicates in the same types as the where bounds, so we can chain them let predicates_from_where = - where_predicates.iter().flatten().map(|bounds| bounds.iter()).flatten(); + where_predicates.iter().flatten().flat_map(|bounds| bounds.iter()); // extract all bounds from the source code using their spans let all_matching_bounds_strs = expected_generic_param diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index e584c9ad201..15edc11a497 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -319,7 +319,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> { self.expr_count += 1; if let PatKind::Binding(..) = pat.kind { - let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id); + let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id).unwrap(); let ty = self.fcx.typeck_results.borrow().pat_ty(pat); self.record(ty, pat.hir_id, Some(scope), None, pat.span, false); } @@ -567,7 +567,7 @@ pub fn check_must_not_suspend_ty<'tcx>( _ => None, }; for (i, ty) in fields.iter().enumerate() { - let descr_post = &format!(" in tuple element {}", i); + let descr_post = &format!(" in tuple element {i}"); let span = comps.and_then(|c| c.get(i)).map(|e| e.span).unwrap_or(data.source_span); if check_must_not_suspend_ty( fcx, diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index cd6b1115ed8..0dd8ee88ca2 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -437,6 +437,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) | sym::simd_fpow | sym::simd_saturating_add | sym::simd_saturating_sub => (1, vec![param(0), param(0)], param(0)), + sym::simd_arith_offset => (2, vec![param(0), param(1)], param(0)), sym::simd_neg | sym::simd_fsqrt | sym::simd_fsin @@ -484,14 +485,14 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) } Err(_) => { let msg = - format!("unrecognized platform-specific intrinsic function: `{}`", name); + format!("unrecognized platform-specific intrinsic function: `{name}`"); tcx.sess.struct_span_err(it.span, &msg).emit(); return; } } } _ => { - let msg = format!("unrecognized platform-specific intrinsic function: `{}`", name); + let msg = format!("unrecognized platform-specific intrinsic function: `{name}`"); tcx.sess.struct_span_err(it.span, &msg).emit(); return; } diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 83474bd7e72..e04cc42b6d7 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -644,7 +644,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.assemble_inherent_impl_candidates_for_type(p.def_id()); } ty::Adt(def, _) => { - self.assemble_inherent_impl_candidates_for_type(def.did()); + let def_id = def.did(); + self.assemble_inherent_impl_candidates_for_type(def_id); + if Some(def_id) == self.tcx.lang_items().c_str() { + self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty); + } } ty::Foreign(did) => { self.assemble_inherent_impl_candidates_for_type(did); diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index e6560ca4d9b..2921176ca4b 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -8,7 +8,7 @@ use rustc_errors::{ MultiSpan, }; use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; @@ -1473,12 +1473,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn suggest_use_candidates( - &self, - err: &mut Diagnostic, - mut msg: String, - candidates: Vec<DefId>, - ) { + fn suggest_use_candidates(&self, err: &mut Diagnostic, msg: String, candidates: Vec<DefId>) { let parent_map = self.tcx.visible_parent_map(()); // Separate out candidates that must be imported with a glob, because they are named `_` @@ -1502,80 +1497,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); let module_did = self.tcx.parent_module(self.body_id); - let (span, found_use) = find_use_placement(self.tcx, module_did); - if let Some(span) = span { - let path_strings = candidates.iter().map(|trait_did| { - // Produce an additional newline to separate the new use statement - // from the directly following item. - let additional_newline = if found_use { "" } else { "\n" }; - format!( - "use {};\n{}", - with_crate_prefix!(self.tcx.def_path_str(*trait_did)), - additional_newline - ) - }); + let (module, _, _) = self.tcx.hir().get_module(module_did); + let span = module.spans.inject_use_span; - let glob_path_strings = globs.iter().map(|trait_did| { - let parent_did = parent_map.get(trait_did).unwrap(); + let path_strings = candidates.iter().map(|trait_did| { + format!("use {};\n", with_crate_prefix!(self.tcx.def_path_str(*trait_did)),) + }); - // Produce an additional newline to separate the new use statement - // from the directly following item. - let additional_newline = if found_use { "" } else { "\n" }; - format!( - "use {}::*; // trait {}\n{}", - with_crate_prefix!(self.tcx.def_path_str(*parent_did)), - self.tcx.item_name(*trait_did), - additional_newline - ) - }); + let glob_path_strings = globs.iter().map(|trait_did| { + let parent_did = parent_map.get(trait_did).unwrap(); + format!( + "use {}::*; // trait {}\n", + with_crate_prefix!(self.tcx.def_path_str(*parent_did)), + self.tcx.item_name(*trait_did), + ) + }); - err.span_suggestions( - span, - &msg, - path_strings.chain(glob_path_strings), - Applicability::MaybeIncorrect, - ); - } else { - let limit = if candidates.len() + globs.len() == 5 { 5 } else { 4 }; - for (i, trait_did) in candidates.iter().take(limit).enumerate() { - if candidates.len() + globs.len() > 1 { - msg.push_str(&format!( - "\ncandidate #{}: `use {};`", - i + 1, - with_crate_prefix!(self.tcx.def_path_str(*trait_did)) - )); - } else { - msg.push_str(&format!( - "\n`use {};`", - with_crate_prefix!(self.tcx.def_path_str(*trait_did)) - )); - } - } - for (i, trait_did) in - globs.iter().take(limit.saturating_sub(candidates.len())).enumerate() - { - let parent_did = parent_map.get(trait_did).unwrap(); - - if candidates.len() + globs.len() > 1 { - msg.push_str(&format!( - "\ncandidate #{}: `use {}::*; // trait {}`", - candidates.len() + i + 1, - with_crate_prefix!(self.tcx.def_path_str(*parent_did)), - self.tcx.item_name(*trait_did), - )); - } else { - msg.push_str(&format!( - "\n`use {}::*; // trait {}`", - with_crate_prefix!(self.tcx.def_path_str(*parent_did)), - self.tcx.item_name(*trait_did), - )); - } - } - if candidates.len() > limit { - msg.push_str(&format!("\nand {} others", candidates.len() + globs.len() - limit)); - } - err.note(&msg); - } + err.span_suggestions( + span, + &msg, + path_strings.chain(glob_path_strings), + Applicability::MaybeIncorrect, + ); } fn suggest_valid_traits( @@ -2106,53 +2049,6 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> { tcx.all_traits().map(|def_id| TraitInfo { def_id }).collect() } -fn find_use_placement<'tcx>(tcx: TyCtxt<'tcx>, target_module: LocalDefId) -> (Option<Span>, bool) { - // FIXME(#94854): this code uses an out-of-date method for inferring a span - // to suggest. It would be better to thread the ModSpans from the AST into - // the HIR, and then use that to drive the suggestion here. - - let mut span = None; - let mut found_use = false; - let (module, _, _) = tcx.hir().get_module(target_module); - - // Find a `use` statement. - for &item_id in module.item_ids { - let item = tcx.hir().item(item_id); - match item.kind { - hir::ItemKind::Use(..) => { - // Don't suggest placing a `use` before the prelude - // import or other generated ones. - if !item.span.from_expansion() { - span = Some(item.span.shrink_to_lo()); - found_use = true; - break; - } - } - // Don't place `use` before `extern crate`... - hir::ItemKind::ExternCrate(_) => {} - // ...but do place them before the first other item. - _ => { - if span.map_or(true, |span| item.span < span) { - if !item.span.from_expansion() { - span = Some(item.span.shrink_to_lo()); - // Don't insert between attributes and an item. - let attrs = tcx.hir().attrs(item.hir_id()); - // Find the first attribute on the item. - // FIXME: This is broken for active attributes. - for attr in attrs { - if !attr.span.is_dummy() && span.map_or(true, |span| attr.span < span) { - span = Some(attr.span.shrink_to_lo()); - } - } - } - } - } - } - } - - (span, found_use) -} - fn print_disambiguation_help<'tcx>( item_name: Ident, args: Option<&'tcx [hir::Expr<'tcx>]>, diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index 19d52f430fc..0d5e7b28a4e 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -427,16 +427,29 @@ fn typeck_with_fallback<'tcx>( span, }), Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. }) - | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) - if asm.operands.iter().any(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } => { - anon_const.hir_id == id - } - _ => false, - }) => - { - // Inline assembly constants must be integers. - fcx.next_int_var() + | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => { + let operand_ty = asm + .operands + .iter() + .filter_map(|(op, _op_sp)| match op { + hir::InlineAsmOperand::Const { anon_const } + if anon_const.hir_id == id => + { + // Inline assembly constants must be integers. + Some(fcx.next_int_var()) + } + hir::InlineAsmOperand::SymFn { anon_const } + if anon_const.hir_id == id => + { + Some(fcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::MiscVariable, + span, + })) + } + _ => None, + }) + .next(); + operand_ty.unwrap_or_else(fallback) } _ => fallback(), }, @@ -553,13 +566,13 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: S // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is // the consumer's responsibility to ensure all bytes that have been read // have defined values. - if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id()) { - if alloc.inner().relocations().len() != 0 { - let msg = "statics with a custom `#[link_section]` must be a \ - simple list of bytes on the wasm target with no \ - extra levels of indirection such as references"; - tcx.sess.span_err(span, msg); - } + if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id()) + && alloc.inner().relocations().len() != 0 + { + let msg = "statics with a custom `#[link_section]` must be a \ + simple list of bytes on the wasm target with no \ + extra levels of indirection such as references"; + tcx.sess.span_err(span, msg); } } @@ -587,7 +600,7 @@ fn report_forbidden_specialization( )); } Err(cname) => { - err.note(&format!("parent implementation is in crate `{}`", cname)); + err.note(&format!("parent implementation is in crate `{cname}`")); } } @@ -610,10 +623,9 @@ fn missing_items_err( tcx.sess, impl_span, E0046, - "not all trait items implemented, missing: `{}`", - missing_items_msg + "not all trait items implemented, missing: `{missing_items_msg}`", ); - err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg)); + err.span_label(impl_span, format!("missing `{missing_items_msg}` in implementation")); // `Span` before impl block closing brace. let hi = full_impl_span.hi() - BytePos(1); @@ -628,7 +640,7 @@ fn missing_items_err( for trait_item in missing_items { let snippet = suggestion_signature(trait_item, tcx); let code = format!("{}{}\n{}", padding, snippet, padding); - let msg = format!("implement the missing item: `{}`", snippet); + let msg = format!("implement the missing item: `{snippet}`"); let appl = Applicability::HasPlaceholders; if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) { err.span_label(span, format!("`{}` from trait", trait_item.name)); @@ -653,10 +665,9 @@ fn missing_items_must_implement_one_of_err( tcx.sess, impl_span, E0046, - "not all trait items implemented, missing one of: `{}`", - missing_items_msg + "not all trait items implemented, missing one of: `{missing_items_msg}`", ); - err.span_label(impl_span, format!("missing one of `{}` in implementation", missing_items_msg)); + err.span_label(impl_span, format!("missing one of `{missing_items_msg}` in implementation")); if let Some(annotation_span) = annotation_span { err.span_note(annotation_span, "required because of this annotation"); @@ -749,9 +760,10 @@ fn fn_sig_suggestion<'tcx>( Some(match ty.kind() { ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(), ty::Ref(reg, ref_ty, mutability) if i == 0 => { - let reg = match &format!("{}", reg)[..] { - "'_" | "" => String::new(), - reg => format!("{} ", reg), + let reg = format!("{reg} "); + let reg = match ®[..] { + "'_ " | " " => "", + reg => reg, }; if assoc.fn_has_self_parameter { match ref_ty.kind() { @@ -759,17 +771,17 @@ fn fn_sig_suggestion<'tcx>( format!("&{}{}self", reg, mutability.prefix_str()) } - _ => format!("self: {}", ty), + _ => format!("self: {ty}"), } } else { - format!("_: {}", ty) + format!("_: {ty}") } } _ => { if assoc.fn_has_self_parameter && i == 0 { - format!("self: {}", ty) + format!("self: {ty}") } else { - format!("_: {}", ty) + format!("_: {ty}") } } }) @@ -779,7 +791,7 @@ fn fn_sig_suggestion<'tcx>( .collect::<Vec<String>>() .join(", "); let output = sig.output(); - let output = if !output.is_unit() { format!(" -> {}", output) } else { String::new() }; + let output = if !output.is_unit() { format!(" -> {output}") } else { String::new() }; let unsafety = sig.unsafety.prefix_str(); let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates); @@ -789,10 +801,7 @@ fn fn_sig_suggestion<'tcx>( // lifetimes between the `impl` and the `trait`, but this should be good enough to // fill in a significant portion of the missing code, and other subsequent // suggestions can help the user fix the code. - format!( - "{}fn {}{}({}){}{} {{ todo!() }}", - unsafety, ident, generics, args, output, where_clauses - ) + format!("{unsafety}fn {ident}{generics}({args}){output}{where_clauses} {{ todo!() }}") } /// Return placeholder code for the given associated item. @@ -830,7 +839,7 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>, sp: Span, d .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap()) .collect(); let msg = format!("needs exactly one variant, but has {}", adt.variants().len(),); - let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg); + let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {msg}"); err.span_label(sp, &msg); if let [start @ .., end] = &*variant_spans { for variant_span in start { @@ -850,7 +859,7 @@ fn bad_non_zero_sized_fields<'tcx>( field_spans: impl Iterator<Item = Span>, sp: Span, ) { - let msg = format!("needs at most one non-zero-sized field, but has {}", field_count); + let msg = format!("needs at most one non-zero-sized field, but has {field_count}"); let mut err = struct_span_err!( tcx.sess, sp, @@ -877,7 +886,7 @@ fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) { tcx.sess .source_map() .span_to_snippet(span) - .map_or_else(|_| String::new(), |s| format!(" `{}`", s)), + .map_or_else(|_| String::new(), |s| format!(" `{s}`",)), ) .emit(); } diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 0baca9048b4..f3dcf5fff74 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -405,16 +405,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut pat_ty = ty; if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(_), .. }) = lt.kind { let expected = self.structurally_resolved_type(span, expected); - if let ty::Ref(_, inner_ty, _) = expected.kind() { - if matches!(inner_ty.kind(), ty::Slice(_)) { - let tcx = self.tcx; - trace!(?lt.hir_id.local_id, "polymorphic byte string lit"); - self.typeck_results - .borrow_mut() - .treat_byte_string_as_slice - .insert(lt.hir_id.local_id); - pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_slice(tcx.types.u8)); - } + if let ty::Ref(_, inner_ty, _) = expected.kind() + && matches!(inner_ty.kind(), ty::Slice(_)) + { + let tcx = self.tcx; + trace!(?lt.hir_id.local_id, "polymorphic byte string lit"); + self.typeck_results + .borrow_mut() + .treat_byte_string_as_slice + .insert(lt.hir_id.local_id); + pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_slice(tcx.types.u8)); } } @@ -481,14 +481,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Unify each side with `expected`. // Subtyping doesn't matter here, as the value is some kind of scalar. let demand_eqtype = |x: &mut _, y| { - if let Some((ref mut fail, x_ty, x_span)) = *x { - if let Some(mut err) = self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti) { - if let Some((_, y_ty, y_span)) = y { - self.endpoint_has_type(&mut err, y_span, y_ty); - } - err.emit(); - *fail = true; - }; + if let Some((ref mut fail, x_ty, x_span)) = *x + && let Some(mut err) = self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti) + { + if let Some((_, y_ty, y_span)) = y { + self.endpoint_has_type(&mut err, y_span, y_ty); + } + err.emit(); + *fail = true; } }; demand_eqtype(&mut lhs, rhs); @@ -630,7 +630,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) { let hir = self.tcx.hir(); let var_ty = self.resolve_vars_with_obligations(var_ty); - let msg = format!("first introduced with type `{}` here", var_ty); + let msg = format!("first introduced with type `{var_ty}` here"); err.span_label(hir.span(var_id), msg); let in_match = hir.parent_iter(var_id).any(|(_, n)| { matches!( @@ -665,8 +665,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { err.span_suggestion( *span, - &format!("did you mean `{}`", snippet), - format!(" &{}", expected), + &format!("did you mean `{snippet}`"), + format!(" &{expected}"), Applicability::MachineApplicable, ); } @@ -701,7 +701,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "type `{}` cannot be dereferenced", type_str ); - err.span_label(span, format!("type `{}` cannot be dereferenced", type_str)); + err.span_label(span, format!("type `{type_str}` cannot be dereferenced")); if self.tcx.sess.teach(&err.get_code().unwrap()) { err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ); } @@ -918,7 +918,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { path_str ); - let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg); + let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{msg}"); match res { Res::Def(DefKind::Fn | DefKind::AssocFn, _) => { err.span_label(pat.span, "`fn` calls are not allowed in patterns"); @@ -1396,8 +1396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.sess, pat.span, E0769, - "tuple variant `{}` written as struct variant", - path + "tuple variant `{path}` written as struct variant", ); err.span_suggestion_verbose( qpath.span().shrink_to_hi().to(pat.span.shrink_to_hi()), @@ -1422,8 +1421,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sess, pat.span, E0638, - "`..` required with {} marked as non-exhaustive", - descr + "`..` required with {descr} marked as non-exhaustive", ); err.span_suggestion_verbose( sp_comma, @@ -1442,8 +1440,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "field `{}` bound multiple times in the pattern", ident ) - .span_label(span, format!("multiple uses of `{}` in pattern", ident)) - .span_label(other_field, format!("first use of `{}`", ident)) + .span_label(span, format!("multiple uses of `{ident}` in pattern")) + .span_label(other_field, format!("first use of `{ident}`")) .emit(); } diff --git a/compiler/rustc_typeck/src/check/place_op.rs b/compiler/rustc_typeck/src/check/place_op.rs index 5dab0bb7a13..2e0f37eba23 100644 --- a/compiler/rustc_typeck/src/check/place_op.rs +++ b/compiler/rustc_typeck/src/check/place_op.rs @@ -74,9 +74,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.resolve_vars_if_possible(ty); let mut err = self.tcx.sess.struct_span_err( span, - &format!("negative integers cannot be used to index on a `{}`", ty), + &format!("negative integers cannot be used to index on a `{ty}`"), ); - err.span_label(span, &format!("cannot use a negative integer for indexing on `{}`", ty)); + err.span_label(span, &format!("cannot use a negative integer for indexing on `{ty}`")); if let (hir::ExprKind::Path(..), Ok(snippet)) = (&base_expr.kind, self.tcx.sess.source_map().span_to_snippet(base_expr.span)) { @@ -84,10 +84,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( span.shrink_to_lo(), &format!( - "to access an element starting from the end of the `{}`, compute the index", - ty, + "to access an element starting from the end of the `{ty}`, compute the index", ), - format!("{}.len() ", snippet), + format!("{snippet}.len() "), Applicability::MachineApplicable, ); } @@ -314,32 +313,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.typeck_results.borrow_mut().adjustments_mut().remove(expr.hir_id); if let Some(mut adjustments) = previous_adjustments { for adjustment in &mut adjustments { - if let Adjust::Deref(Some(ref mut deref)) = adjustment.kind { - if let Some(ok) = self.try_mutable_overloaded_place_op( + if let Adjust::Deref(Some(ref mut deref)) = adjustment.kind + && let Some(ok) = self.try_mutable_overloaded_place_op( expr.span, source, &[], PlaceOp::Deref, - ) { - let method = self.register_infer_ok_obligations(ok); - if let ty::Ref(region, _, mutbl) = *method.sig.output().kind() { - *deref = OverloadedDeref { region, mutbl, span: deref.span }; - } - // If this is a union field, also throw an error for `DerefMut` of `ManuallyDrop` (see RFC 2514). - // This helps avoid accidental drops. - if inside_union - && source.ty_adt_def().map_or(false, |adt| adt.is_manually_drop()) - { - let mut err = self.tcx.sess.struct_span_err( - expr.span, - "not automatically applying `DerefMut` on `ManuallyDrop` union field", - ); - err.help( - "writing to this reference calls the destructor for the old value", - ); - err.help("add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor"); - err.emit(); - } + ) + { + let method = self.register_infer_ok_obligations(ok); + if let ty::Ref(region, _, mutbl) = *method.sig.output().kind() { + *deref = OverloadedDeref { region, mutbl, span: deref.span }; + } + // If this is a union field, also throw an error for `DerefMut` of `ManuallyDrop` (see RFC 2514). + // This helps avoid accidental drops. + if inside_union + && source.ty_adt_def().map_or(false, |adt| adt.is_manually_drop()) + { + let mut err = self.tcx.sess.struct_span_err( + expr.span, + "not automatically applying `DerefMut` on `ManuallyDrop` union field", + ); + err.help( + "writing to this reference calls the destructor for the old value", + ); + err.help("add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor"); + err.emit(); } } source = adjustment.target; diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs index e18cb31acbd..e37e83e7487 100644 --- a/compiler/rustc_typeck/src/check/regionck.rs +++ b/compiler/rustc_typeck/src/check/regionck.rs @@ -317,13 +317,8 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { self.body_id = body_id.hir_id; self.body_owner = self.tcx.hir().body_owner_def_id(body_id); - let fn_sig = { - match self.typeck_results.borrow().liberated_fn_sigs().get(id) { - Some(f) => *f, - None => { - bug!("No fn-sig entry for id={:?}", id); - } - } + let Some(fn_sig) = self.typeck_results.borrow().liberated_fn_sigs().get(id) else { + bug!("No fn-sig entry for id={:?}", id); }; // Collect the types from which we create inferred bounds. @@ -642,12 +637,9 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { ignore_err!(self.with_mc(|mc| { mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, hir::Pat { kind, span, hir_id, .. }| { // `ref x` pattern - if let PatKind::Binding(..) = kind { - if let Some(ty::BindByReference(mutbl)) = - mc.typeck_results.extract_binding_mode(self.tcx.sess, *hir_id, *span) - { - self.link_region_from_node_type(*span, *hir_id, mutbl, sub_cmt); - } + if let PatKind::Binding(..) = kind + && let Some(ty::BindByReference(mutbl)) = mc.typeck_results.extract_binding_mode(self.tcx.sess, *hir_id, *span) { + self.link_region_from_node_type(*span, *hir_id, mutbl, sub_cmt); } }) })); diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 1118e967707..9dbb8132932 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -862,7 +862,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { diagnostics_builder.span_suggestion( closure_body_span.with_lo(closure_body_span.lo() + BytePos::from_usize(line1.len())).shrink_to_lo(), &diagnostic_msg, - format!("\n{}{};", indent, migration_string), + format!("\n{indent}{migration_string};"), Applicability::MachineApplicable, ); } else if line1.starts_with('{') { @@ -873,7 +873,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { diagnostics_builder.span_suggestion( closure_body_span.with_lo(closure_body_span.lo() + BytePos(1)).shrink_to_lo(), &diagnostic_msg, - format!(" {};", migration_string), + format!(" {migration_string};"), Applicability::MachineApplicable, ); } else { @@ -882,7 +882,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { diagnostics_builder.multipart_suggestion( &diagnostic_msg, vec![ - (closure_body_span.shrink_to_lo(), format!("{{ {}; ", migration_string)), + (closure_body_span.shrink_to_lo(), format!("{{ {migration_string}; ")), (closure_body_span.shrink_to_hi(), " }".to_string()), ], Applicability::MachineApplicable @@ -1527,7 +1527,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.sess.struct_span_err(closure_span, "First Pass analysis includes:"); for (place, capture_info) in capture_information { let capture_str = construct_capture_info_string(self.tcx, place, capture_info); - let output_str = format!("Capturing {}", capture_str); + let output_str = format!("Capturing {capture_str}"); let span = capture_info.path_expr_id.map_or(closure_span, |e| self.tcx.hir().span(e)); @@ -1552,7 +1552,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let capture_str = construct_capture_info_string(self.tcx, place, capture_info); - let output_str = format!("Min Capture {}", capture_str); + let output_str = format!("Min Capture {capture_str}"); if capture.info.path_expr_id != capture.info.capture_kind_expr_id { let path_span = capture_info @@ -1969,7 +1969,7 @@ fn construct_place_string<'tcx>(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String projections_str.push_str(proj.as_str()); } - format!("{}[{}]", variable_name, projections_str) + format!("{variable_name}[{projections_str}]") } fn construct_capture_kind_reason_string<'tcx>( @@ -1984,13 +1984,13 @@ fn construct_capture_kind_reason_string<'tcx>( ty::UpvarCapture::ByRef(kind) => format!("{:?}", kind), }; - format!("{} captured as {} here", place_str, capture_kind_str) + format!("{place_str} captured as {capture_kind_str} here") } fn construct_path_string<'tcx>(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String { let place_str = construct_place_string(tcx, place); - format!("{} used here", place_str) + format!("{place_str} used here") } fn construct_capture_info_string<'tcx>( @@ -2004,7 +2004,7 @@ fn construct_capture_info_string<'tcx>( ty::UpvarCapture::ByValue => "ByValue".into(), ty::UpvarCapture::ByRef(kind) => format!("{:?}", kind), }; - format!("{} -> {}", place_str, capture_kind_str) + format!("{place_str} -> {capture_kind_str}") } fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol { @@ -2035,16 +2035,16 @@ fn migration_suggestion_for_2229( .collect::<Vec<_>>(); let migration_ref_concat = - need_migrations_variables.iter().map(|v| format!("&{}", v)).collect::<Vec<_>>().join(", "); + need_migrations_variables.iter().map(|v| format!("&{v}")).collect::<Vec<_>>().join(", "); let migration_string = if 1 == need_migrations.len() { - format!("let _ = {}", migration_ref_concat) + format!("let _ = {migration_ref_concat}") } else { - format!("let _ = ({})", migration_ref_concat) + format!("let _ = ({migration_ref_concat})") }; let migrated_variables_concat = - need_migrations_variables.iter().map(|v| format!("`{}`", v)).collect::<Vec<_>>().join(", "); + need_migrations_variables.iter().map(|v| format!("`{v}`")).collect::<Vec<_>>().join(", "); (migration_string, migrated_variables_concat) } diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index f9664a9b991..4e3e32670e9 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -230,8 +230,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { .struct_span_err( self_ty.span, &format!( - "first argument of `call` in `{}` lang item must be a reference", - fn_lang_item_name + "first argument of `call` in `{fn_lang_item_name}` lang item must be a reference", ), ) .emit(); @@ -241,8 +240,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { .struct_span_err( *span, &format!( - "`call` function in `{}` lang item takes exactly two arguments", - fn_lang_item_name + "`call` function in `{fn_lang_item_name}` lang item takes exactly two arguments", ), ) .emit(); @@ -252,8 +250,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { .struct_span_err( trait_item.span, &format!( - "`call` trait item in `{}` lang item must be a function", - fn_lang_item_name + "`call` trait item in `{fn_lang_item_name}` lang item must be a function", ), ) .emit(); @@ -432,7 +429,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe ); err.span_suggestion( gat_item_hir.generics.where_clause.tail_span_for_suggestion(), - &format!("add the required where clause{}", plural), + &format!("add the required where clause{plural}"), suggestion, Applicability::MachineApplicable, ); @@ -523,7 +520,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>( // In our example, requires that `Self: 'a` if ty_known_to_outlive(tcx, item_hir, param_env, &wf_tys, *ty, *region_a) { debug!(?ty_idx, ?region_a_idx); - debug!("required clause: {} must outlive {}", ty, region_a); + debug!("required clause: {ty} must outlive {region_a}"); // Translate into the generic parameters of the GAT. In // our example, the type was `Self`, which will also be // `Self` in the GAT. @@ -560,7 +557,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>( } if region_known_to_outlive(tcx, item_hir, param_env, &wf_tys, *region_a, *region_b) { debug!(?region_a_idx, ?region_b_idx); - debug!("required clause: {} must outlive {}", region_a, region_b); + debug!("required clause: {region_a} must outlive {region_b}"); // Translate into the generic parameters of the GAT. let region_a_param = gat_generics.param_at(*region_a_idx, tcx); let region_a_param = @@ -869,7 +866,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { ) .span_label( hir_ty.span, - format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty), + format!("`{ty}` doesn't derive both `PartialEq` and `Eq`"), ) .emit(); } @@ -884,7 +881,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { ty::RawPtr(_) => Some("raw pointers"), _ => { is_ptr = false; - err_ty_str = format!("`{}`", ty); + err_ty_str = format!("`{ty}`"); Some(err_ty_str.as_str()) } }; @@ -894,16 +891,14 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { tcx.sess.span_err( hir_ty.span, &format!( - "using {} as const generic parameters is forbidden", - unsupported_type + "using {unsupported_type} as const generic parameters is forbidden", ), ); } else { let mut err = tcx.sess.struct_span_err( hir_ty.span, &format!( - "{} is forbidden as the type of a const generic parameter", - unsupported_type + "{unsupported_type} is forbidden as the type of a const generic parameter", ), ); err.note("the only supported types are integers, `bool` and `char`"); @@ -1567,9 +1562,8 @@ fn check_method_receiver<'fcx, 'tcx>( sym::arbitrary_self_types, span, &format!( - "`{}` cannot be used as the type of `self` without \ + "`{receiver_ty}` cannot be used as the type of `self` without \ the `arbitrary_self_types` feature", - receiver_ty, ), ) .help(HELP_FOR_SELF_TYPE) @@ -1587,8 +1581,7 @@ fn e0307<'tcx>(fcx: &FnCtxt<'_, 'tcx>, span: Span, receiver_ty: Ty<'_>) { fcx.tcx.sess.diagnostic(), span, E0307, - "invalid `self` parameter type: {}", - receiver_ty, + "invalid `self` parameter type: {receiver_ty}" ) .note("type of `self` must be `Self` or a type that dereferences to it") .help(HELP_FOR_SELF_TYPE) @@ -1793,7 +1786,7 @@ fn report_bivariance( tcx.def_path_str(def_id), ) } else { - format!("consider removing `{}` or referring to it in a field", param_name) + format!("consider removing `{param_name}` or referring to it in a field") }; err.help(&msg); @@ -1993,8 +1986,7 @@ fn error_392( span: Span, param_name: Symbol, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut err = - struct_span_err!(tcx.sess, span, E0392, "parameter `{}` is never used", param_name); + let mut err = struct_span_err!(tcx.sess, span, E0392, "parameter `{param_name}` is never used"); err.span_label(span, "unused parameter"); err } diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs index e11bd9355eb..5ad0c4ac52d 100644 --- a/compiler/rustc_typeck/src/coherence/inherent_impls.rs +++ b/compiler/rustc_typeck/src/coherence/inherent_impls.rs @@ -55,7 +55,12 @@ impl<'tcx> ItemLikeVisitor<'_> for InherentCollect<'tcx> { let self_ty = self.tcx.type_of(item.def_id); match *self_ty.kind() { ty::Adt(def, _) => { - self.check_def_id(item, def.did()); + let def_id = def.did(); + if !def_id.is_local() && Some(def_id) == self.tcx.lang_items().c_str() { + self.check_primitive_impl(item.def_id, self_ty, items, ty.span) + } else { + self.check_def_id(item, def_id); + } } ty::Foreign(did) => { self.check_def_id(item, did); diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 785538ab0df..fa06ec09fce 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -450,7 +450,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) if asm.operands.iter().any(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } => anon_const.hir_id == hir_id, + hir::InlineAsmOperand::Const { anon_const } + | hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id, _ => false, }) => { diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index 055e391d706..2bcf2d3b2ed 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -358,8 +358,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { hir::ExprKind::InlineAsm(asm) => { for (op, _op_sp) in asm.operands { match op { - hir::InlineAsmOperand::In { expr, .. } - | hir::InlineAsmOperand::Sym { expr, .. } => self.consume_expr(expr), + hir::InlineAsmOperand::In { expr, .. } => self.consume_expr(expr), hir::InlineAsmOperand::Out { expr: Some(expr), .. } | hir::InlineAsmOperand::InOut { expr, .. } => { self.mutate_expr(expr); @@ -371,7 +370,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } } hir::InlineAsmOperand::Out { expr: None, .. } - | hir::InlineAsmOperand::Const { .. } => {} + | hir::InlineAsmOperand::Const { .. } + | hir::InlineAsmOperand::SymFn { .. } + | hir::InlineAsmOperand::SymStatic { .. } => {} } } } diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index d0c4726bb0a..9fb9652b849 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -61,9 +61,11 @@ This API is completely unstable and subject to change. #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(crate_visibility_modifier)] +#![feature(drain_filter)] #![feature(hash_drain_filter)] #![feature(if_let_guard)] #![feature(is_sorted)] +#![feature(label_break_value)] #![feature(let_chains)] #![feature(let_else)] #![feature(min_specialization)] diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index cc986e93698..47ba1777ae9 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -1879,6 +1879,96 @@ fn test_first_last_entry() { } #[test] +fn test_pop_first_last() { + let mut map = BTreeMap::new(); + assert_eq!(map.pop_first(), None); + assert_eq!(map.pop_last(), None); + + map.insert(1, 10); + map.insert(2, 20); + map.insert(3, 30); + map.insert(4, 40); + + assert_eq!(map.len(), 4); + + let (key, val) = map.pop_first().unwrap(); + assert_eq!(key, 1); + assert_eq!(val, 10); + assert_eq!(map.len(), 3); + + let (key, val) = map.pop_first().unwrap(); + assert_eq!(key, 2); + assert_eq!(val, 20); + assert_eq!(map.len(), 2); + let (key, val) = map.pop_last().unwrap(); + assert_eq!(key, 4); + assert_eq!(val, 40); + assert_eq!(map.len(), 1); + + map.insert(5, 50); + map.insert(6, 60); + assert_eq!(map.len(), 3); + + let (key, val) = map.pop_first().unwrap(); + assert_eq!(key, 3); + assert_eq!(val, 30); + assert_eq!(map.len(), 2); + + let (key, val) = map.pop_last().unwrap(); + assert_eq!(key, 6); + assert_eq!(val, 60); + assert_eq!(map.len(), 1); + + let (key, val) = map.pop_last().unwrap(); + assert_eq!(key, 5); + assert_eq!(val, 50); + assert_eq!(map.len(), 0); + + assert_eq!(map.pop_first(), None); + assert_eq!(map.pop_last(), None); + + map.insert(7, 70); + map.insert(8, 80); + + let (key, val) = map.pop_last().unwrap(); + assert_eq!(key, 8); + assert_eq!(val, 80); + assert_eq!(map.len(), 1); + + let (key, val) = map.pop_last().unwrap(); + assert_eq!(key, 7); + assert_eq!(val, 70); + assert_eq!(map.len(), 0); + + assert_eq!(map.pop_first(), None); + assert_eq!(map.pop_last(), None); +} + +#[test] +fn test_get_key_value() { + let mut map = BTreeMap::new(); + + assert!(map.is_empty()); + assert_eq!(map.get_key_value(&1), None); + assert_eq!(map.get_key_value(&2), None); + + map.insert(1, 10); + map.insert(2, 20); + map.insert(3, 30); + + assert_eq!(map.len(), 3); + assert_eq!(map.get_key_value(&1), Some((&1, &10))); + assert_eq!(map.get_key_value(&3), Some((&3, &30))); + assert_eq!(map.get_key_value(&4), None); + + map.remove(&3); + + assert_eq!(map.len(), 2); + assert_eq!(map.get_key_value(&3), None); + assert_eq!(map.get_key_value(&2), Some((&2, &20))); +} + +#[test] fn test_insert_into_full_height_0() { let size = node::CAPACITY; for pos in 0..=size { @@ -1904,6 +1994,21 @@ fn test_insert_into_full_height_1() { } } +#[test] +fn test_try_insert() { + let mut map = BTreeMap::new(); + + assert!(map.is_empty()); + + assert_eq!(map.try_insert(1, 10).unwrap(), &10); + assert_eq!(map.try_insert(2, 20).unwrap(), &20); + + let err = map.try_insert(2, 200).unwrap_err(); + assert_eq!(err.entry.key(), &2); + assert_eq!(err.entry.get(), &20); + assert_eq!(err.value, 200); +} + macro_rules! create_append_test { ($name:ident, $len:expr) => { #[test] diff --git a/library/alloc/src/collections/btree/set/tests.rs b/library/alloc/src/collections/btree/set/tests.rs index 00a2a0aaa14..429b1644976 100644 --- a/library/alloc/src/collections/btree/set/tests.rs +++ b/library/alloc/src/collections/btree/set/tests.rs @@ -320,6 +320,42 @@ fn test_is_subset() { } #[test] +fn test_is_superset() { + fn is_superset(a: &[i32], b: &[i32]) -> bool { + let set_a = BTreeSet::from_iter(a.iter()); + let set_b = BTreeSet::from_iter(b.iter()); + set_a.is_superset(&set_b) + } + + assert_eq!(is_superset(&[], &[]), true); + assert_eq!(is_superset(&[], &[1, 2]), false); + assert_eq!(is_superset(&[0], &[1, 2]), false); + assert_eq!(is_superset(&[1], &[1, 2]), false); + assert_eq!(is_superset(&[4], &[1, 2]), false); + assert_eq!(is_superset(&[1, 4], &[1, 2]), false); + assert_eq!(is_superset(&[1, 2], &[1, 2]), true); + assert_eq!(is_superset(&[1, 2, 3], &[1, 3]), true); + assert_eq!(is_superset(&[1, 2, 3], &[]), true); + assert_eq!(is_superset(&[-1, 1, 2, 3], &[-1, 3]), true); + + if cfg!(miri) { + // Miri is too slow + return; + } + + let large = Vec::from_iter(0..100); + assert_eq!(is_superset(&[], &large), false); + assert_eq!(is_superset(&large, &[]), true); + assert_eq!(is_superset(&large, &[1]), true); + assert_eq!(is_superset(&large, &[50, 99]), true); + assert_eq!(is_superset(&large, &[100]), false); + assert_eq!(is_superset(&large, &[0, 99]), true); + assert_eq!(is_superset(&[-1], &large), false); + assert_eq!(is_superset(&[0], &large), false); + assert_eq!(is_superset(&[99, 100], &large), false); +} + +#[test] fn test_retain() { let mut set = BTreeSet::from([1, 2, 3, 4, 5, 6]); set.retain(|&k| k % 2 == 0); @@ -391,6 +427,26 @@ fn test_clear() { x.clear(); assert!(x.is_empty()); } +#[test] +fn test_remove() { + let mut x = BTreeSet::new(); + assert!(x.is_empty()); + + x.insert(1); + x.insert(2); + x.insert(3); + x.insert(4); + + assert_eq!(x.remove(&2), true); + assert_eq!(x.remove(&0), false); + assert_eq!(x.remove(&5), false); + assert_eq!(x.remove(&1), true); + assert_eq!(x.remove(&2), false); + assert_eq!(x.remove(&3), true); + assert_eq!(x.remove(&4), true); + assert_eq!(x.remove(&4), false); + assert!(x.is_empty()); +} #[test] fn test_zip() { diff --git a/library/std/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index a68def1e83d..172a008e89a 100644 --- a/library/std/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -1,25 +1,25 @@ -#![deny(unsafe_op_in_unsafe_fn)] - #[cfg(test)] mod tests; -use crate::ascii; -use crate::borrow::{Borrow, Cow}; -use crate::cmp::Ordering; -use crate::error::Error; -use crate::fmt::{self, Write}; -use crate::io; -use crate::mem; -use crate::num::NonZeroU8; -use crate::ops; -use crate::os::raw::c_char; -use crate::ptr; +use crate::borrow::{Cow, ToOwned}; +use crate::boxed::Box; use crate::rc::Rc; -use crate::slice; -use crate::str::{self, Utf8Error}; +use crate::slice::hack::into_vec; +use crate::string::String; +use crate::vec::Vec; +use core::borrow::Borrow; +use core::ffi::{c_char, CStr}; +use core::fmt; +use core::mem; +use core::num::NonZeroU8; +use core::ops; +use core::ptr; +use core::slice; +use core::slice::memchr; +use core::str::{self, Utf8Error}; + +#[cfg(target_has_atomic = "ptr")] use crate::sync::Arc; -use crate::sys; -use crate::sys_common::memchr; /// A type representing an owned, C-compatible, nul-terminated string with no nul bytes in the /// middle. @@ -108,7 +108,7 @@ use crate::sys_common::memchr; /// and other memory errors. #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)] #[cfg_attr(not(test), rustc_diagnostic_item = "cstring_type")] -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "alloc_c_string", issue = "94079")] pub struct CString { // Invariant 1: the slice ends with a zero byte and has a length of at least one. // Invariant 2: the slice contains only one zero byte. @@ -116,90 +116,6 @@ pub struct CString { inner: Box<[u8]>, } -/// Representation of a borrowed C string. -/// -/// This type represents a borrowed reference to a nul-terminated -/// array of bytes. It can be constructed safely from a <code>&[[u8]]</code> -/// slice, or unsafely from a raw `*const c_char`. It can then be -/// converted to a Rust <code>&[str]</code> by performing UTF-8 validation, or -/// into an owned [`CString`]. -/// -/// `&CStr` is to [`CString`] as <code>&[str]</code> is to [`String`]: the former -/// in each pair are borrowed references; the latter are owned -/// strings. -/// -/// Note that this structure is **not** `repr(C)` and is not recommended to be -/// placed in the signatures of FFI functions. Instead, safe wrappers of FFI -/// functions may leverage the unsafe [`CStr::from_ptr`] constructor to provide -/// a safe interface to other consumers. -/// -/// # Examples -/// -/// Inspecting a foreign C string: -/// -/// ```ignore (extern-declaration) -/// use std::ffi::CStr; -/// use std::os::raw::c_char; -/// -/// extern "C" { fn my_string() -> *const c_char; } -/// -/// unsafe { -/// let slice = CStr::from_ptr(my_string()); -/// println!("string buffer size without nul terminator: {}", slice.to_bytes().len()); -/// } -/// ``` -/// -/// Passing a Rust-originating C string: -/// -/// ```ignore (extern-declaration) -/// use std::ffi::{CString, CStr}; -/// use std::os::raw::c_char; -/// -/// fn work(data: &CStr) { -/// extern "C" { fn work_with(data: *const c_char); } -/// -/// unsafe { work_with(data.as_ptr()) } -/// } -/// -/// let s = CString::new("data data data data").expect("CString::new failed"); -/// work(&s); -/// ``` -/// -/// Converting a foreign C string into a Rust [`String`]: -/// -/// ```ignore (extern-declaration) -/// use std::ffi::CStr; -/// use std::os::raw::c_char; -/// -/// extern "C" { fn my_string() -> *const c_char; } -/// -/// fn my_string_safe() -> String { -/// unsafe { -/// CStr::from_ptr(my_string()).to_string_lossy().into_owned() -/// } -/// } -/// -/// println!("string: {}", my_string_safe()); -/// ``` -/// -/// [str]: prim@str "str" -#[derive(Hash)] -#[cfg_attr(not(test), rustc_diagnostic_item = "CStr")] -#[stable(feature = "rust1", since = "1.0.0")] -// FIXME: -// `fn from` in `impl From<&CStr> for Box<CStr>` current implementation relies -// on `CStr` being layout-compatible with `[u8]`. -// When attribute privacy is implemented, `CStr` should be annotated as `#[repr(transparent)]`. -// Anyway, `CStr` representation and layout are considered implementation detail, are -// not documented and must not be relied upon. -pub struct CStr { - // FIXME: this should not be represented with a DST slice but rather with - // just a raw `c_char` along with some form of marker to make - // this an unsized type. Essentially `sizeof(&CStr)` should be the - // same as `sizeof(&c_char)` but `CStr` should be an unsized type. - inner: [c_char], -} - /// An error indicating that an interior nul byte was found. /// /// While Rust strings may contain nul bytes in the middle, C strings @@ -216,28 +132,13 @@ pub struct CStr { /// let _: NulError = CString::new(b"f\0oo".to_vec()).unwrap_err(); /// ``` #[derive(Clone, PartialEq, Eq, Debug)] -#[stable(feature = "rust1", since = "1.0.0")] +#[unstable(feature = "alloc_c_string", issue = "94079")] pub struct NulError(usize, Vec<u8>); -/// An error indicating that a nul byte was not in the expected position. -/// -/// The slice used to create a [`CStr`] must have one and only one nul byte, -/// positioned at the end. -/// -/// This error is created by the [`CStr::from_bytes_with_nul`] method. -/// See its documentation for more. -/// -/// # Examples -/// -/// ``` -/// use std::ffi::{CStr, FromBytesWithNulError}; -/// -/// let _: FromBytesWithNulError = CStr::from_bytes_with_nul(b"f\0oo").unwrap_err(); -/// ``` #[derive(Clone, PartialEq, Eq, Debug)] -#[stable(feature = "cstr_from_bytes", since = "1.10.0")] -pub struct FromBytesWithNulError { - kind: FromBytesWithNulErrorKind, +enum FromBytesWithNulErrorKind { + InteriorNul(usize), + NotNulTerminated, } /// An error indicating that a nul byte was not in the expected position. @@ -256,27 +157,12 @@ pub struct FromBytesWithNulError { /// let _: FromVecWithNulError = CString::from_vec_with_nul(b"f\0oo".to_vec()).unwrap_err(); /// ``` #[derive(Clone, PartialEq, Eq, Debug)] -#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")] +#[unstable(feature = "alloc_c_string", issue = "94079")] pub struct FromVecWithNulError { error_kind: FromBytesWithNulErrorKind, bytes: Vec<u8>, } -#[derive(Clone, PartialEq, Eq, Debug)] -enum FromBytesWithNulErrorKind { - InteriorNul(usize), - NotNulTerminated, -} - -impl FromBytesWithNulError { - fn interior_nul(pos: usize) -> FromBytesWithNulError { - FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) } - } - fn not_nul_terminated() -> FromBytesWithNulError { - FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated } - } -} - #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")] impl FromVecWithNulError { /// Returns a slice of [`u8`]s bytes that were attempted to convert to a [`CString`]. @@ -328,27 +214,6 @@ impl FromVecWithNulError { } } -/// An error indicating that no nul byte was present. -/// -/// A slice used to create a [`CStr`] must contain a nul byte somewhere -/// within the slice. -/// -/// This error is created by the [`CStr::from_bytes_until_nul`] method. -/// -#[derive(Clone, PartialEq, Eq, Debug)] -#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")] -pub struct FromBytesUntilNulError(()); - -#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")] -impl Error for FromBytesUntilNulError {} - -#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")] -impl fmt::Display for FromBytesUntilNulError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "data provided does not contain a nul") - } -} - /// An error indicating invalid UTF-8 when converting a [`CString`] into a [`String`]. /// /// `CString` is just a wrapper over a buffer of bytes with a nul terminator; @@ -358,7 +223,7 @@ impl fmt::Display for FromBytesUntilNulError { /// This `struct` is created by [`CString::into_string()`]. See /// its documentation for more. #[derive(Clone, PartialEq, Eq, Debug)] -#[stable(feature = "cstring_into", since = "1.7.0")] +#[unstable(feature = "alloc_c_string", issue = "94079")] pub struct IntoStringError { inner: CString, error: Utf8Error, @@ -536,7 +401,11 @@ impl CString { // information about the size of the allocation is correct on Rust's // side. unsafe { - let len = sys::strlen(ptr) + 1; // Including the NUL byte + extern "C" { + /// Provided by libc or compiler_builtins. + fn strlen(s: *const c_char) -> usize; + } + let len = strlen(ptr) + 1; // Including the NUL byte let slice = slice::from_raw_parts_mut(ptr, len as usize); CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) } } @@ -626,7 +495,7 @@ impl CString { #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "cstring_into", since = "1.7.0")] pub fn into_bytes(self) -> Vec<u8> { - let mut vec = self.into_inner().into_vec(); + let mut vec = into_vec(self.into_inner()); let _nul = vec.pop(); debug_assert_eq!(_nul, Some(0u8)); vec @@ -647,7 +516,7 @@ impl CString { #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "cstring_into", since = "1.7.0")] pub fn into_bytes_with_nul(self) -> Vec<u8> { - self.into_inner().into_vec() + into_vec(self.into_inner()) } /// Returns the contents of this `CString` as a slice of bytes. @@ -842,7 +711,7 @@ impl ops::Deref for CString { #[inline] fn deref(&self) -> &CStr { - unsafe { CStr::_from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) } + unsafe { CStr::from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) } } } @@ -864,25 +733,6 @@ impl From<CString> for Vec<u8> { } } -#[stable(feature = "cstr_debug", since = "1.3.0")] -impl fmt::Debug for CStr { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "\"")?; - for byte in self.to_bytes().iter().flat_map(|&b| ascii::escape_default(b)) { - f.write_char(byte as char)?; - } - write!(f, "\"") - } -} - -#[stable(feature = "cstr_default", since = "1.10.0")] -impl Default for &CStr { - fn default() -> Self { - const SLICE: &[c_char] = &[0]; - unsafe { CStr::from_ptr(SLICE.as_ptr()) } - } -} - #[stable(feature = "cstr_default", since = "1.10.0")] impl Default for CString { /// Creates an empty `CString`. @@ -910,6 +760,7 @@ impl<'a> From<Cow<'a, CStr>> for CString { } } +#[cfg(not(test))] #[stable(feature = "box_from_c_str", since = "1.17.0")] impl From<&CStr> for Box<CStr> { /// Converts a `&CStr` into a `Box<CStr>`, @@ -938,7 +789,8 @@ impl From<Box<CStr>> for CString { /// Converts a <code>[Box]<[CStr]></code> into a [`CString`] without copying or allocating. #[inline] fn from(s: Box<CStr>) -> CString { - s.into_c_string() + let raw = Box::into_raw(s) as *mut [u8]; + CString { inner: unsafe { Box::from_raw(raw) } } } } @@ -964,6 +816,7 @@ impl From<Vec<NonZeroU8>> for CString { } } +#[cfg(not(test))] #[stable(feature = "more_box_slice_clone", since = "1.29.0")] impl Clone for Box<CStr> { #[inline] @@ -1008,6 +861,7 @@ impl<'a> From<&'a CString> for Cow<'a, CStr> { } } +#[cfg(target_has_atomic = "ptr")] #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From<CString> for Arc<CStr> { /// Converts a [`CString`] into an <code>[Arc]<[CStr]></code> by moving the [`CString`] @@ -1019,6 +873,7 @@ impl From<CString> for Arc<CStr> { } } +#[cfg(target_has_atomic = "ptr")] #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From<&CStr> for Arc<CStr> { /// Converts a `&CStr` into a `Arc<CStr>`, @@ -1052,6 +907,7 @@ impl From<&CStr> for Rc<CStr> { } } +#[cfg(not(test))] #[stable(feature = "default_box_extra", since = "1.17.0")] impl Default for Box<CStr> { fn default() -> Box<CStr> { @@ -1100,56 +956,12 @@ impl NulError { } #[stable(feature = "rust1", since = "1.0.0")] -impl Error for NulError { - #[allow(deprecated)] - fn description(&self) -> &str { - "nul byte found in data" - } -} - -#[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for NulError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "nul byte found in provided data at position: {}", self.0) } } -#[stable(feature = "rust1", since = "1.0.0")] -impl From<NulError> for io::Error { - /// Converts a [`NulError`] into a [`io::Error`]. - fn from(_: NulError) -> io::Error { - io::const_io_error!(io::ErrorKind::InvalidInput, "data provided contains a nul byte") - } -} - -#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")] -impl Error for FromBytesWithNulError { - #[allow(deprecated)] - fn description(&self) -> &str { - match self.kind { - FromBytesWithNulErrorKind::InteriorNul(..) => { - "data provided contains an interior nul byte" - } - FromBytesWithNulErrorKind::NotNulTerminated => "data provided is not nul terminated", - } - } -} - -#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")] -impl fmt::Display for FromBytesWithNulError { - #[allow(deprecated, deprecated_in_future)] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.description())?; - if let FromBytesWithNulErrorKind::InteriorNul(pos) = self.kind { - write!(f, " at byte pos {pos}")?; - } - Ok(()) - } -} - -#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")] -impl Error for FromVecWithNulError {} - #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")] impl fmt::Display for FromVecWithNulError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -1179,18 +991,18 @@ impl IntoStringError { pub fn utf8_error(&self) -> Utf8Error { self.error } + + #[doc(hidden)] + #[unstable(feature = "cstr_internals", issue = "none")] + pub fn __source(&self) -> &Utf8Error { + &self.error + } } -#[stable(feature = "cstring_into", since = "1.7.0")] -impl Error for IntoStringError { - #[allow(deprecated)] +impl IntoStringError { fn description(&self) -> &str { "C string contained non-utf8 bytes" } - - fn source(&self) -> Option<&(dyn Error + 'static)> { - Some(&self.error) - } } #[stable(feature = "cstring_into", since = "1.7.0")] @@ -1201,327 +1013,126 @@ impl fmt::Display for IntoStringError { } } -impl CStr { - /// Wraps a raw C string with a safe C string wrapper. - /// - /// This function will wrap the provided `ptr` with a `CStr` wrapper, which - /// allows inspection and interoperation of non-owned C strings. The total - /// size of the raw C string must be smaller than `isize::MAX` **bytes** - /// in memory due to calling the `slice::from_raw_parts` function. - /// This method is unsafe for a number of reasons: - /// - /// * There is no guarantee to the validity of `ptr`. - /// * The returned lifetime is not guaranteed to be the actual lifetime of - /// `ptr`. - /// * There is no guarantee that the memory pointed to by `ptr` contains a - /// valid nul terminator byte at the end of the string. - /// * It is not guaranteed that the memory pointed by `ptr` won't change - /// before the `CStr` has been destroyed. - /// - /// > **Note**: This operation is intended to be a 0-cost cast but it is - /// > currently implemented with an up-front calculation of the length of - /// > the string. This is not guaranteed to always be the case. - /// - /// # Examples - /// - /// ```ignore (extern-declaration) - /// # fn main() { - /// use std::ffi::CStr; - /// use std::os::raw::c_char; - /// - /// extern "C" { - /// fn my_string() -> *const c_char; - /// } - /// - /// unsafe { - /// let slice = CStr::from_ptr(my_string()); - /// println!("string returned: {}", slice.to_str().unwrap()); - /// } - /// # } - /// ``` - #[inline] - #[must_use] - #[stable(feature = "rust1", since = "1.0.0")] - pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr { - // SAFETY: The caller has provided a pointer that points to a valid C - // string with a NUL terminator of size less than `isize::MAX`, whose - // content remain valid and doesn't change for the lifetime of the - // returned `CStr`. - // - // Thus computing the length is fine (a NUL byte exists), the call to - // from_raw_parts is safe because we know the length is at most `isize::MAX`, meaning - // the call to `from_bytes_with_nul_unchecked` is correct. - // - // The cast from c_char to u8 is ok because a c_char is always one byte. - unsafe { - let len = sys::strlen(ptr); - let ptr = ptr as *const u8; - Self::_from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1)) - } - } +#[stable(feature = "cstr_borrow", since = "1.3.0")] +impl ToOwned for CStr { + type Owned = CString; - /// Creates a C string wrapper from a byte slice. - /// - /// This method will create a `CStr` from any byte slice that contains at - /// least one nul byte. The caller does not need to know or specify where - /// the nul byte is located. - /// - /// If the first byte is a nul character, this method will return an - /// empty `CStr`. If multiple nul characters are present, the `CStr` will - /// end at the first one. - /// - /// If the slice only has a single nul byte at the end, this method is - /// equivalent to [`CStr::from_bytes_with_nul`]. - /// - /// # Examples - /// ``` - /// #![feature(cstr_from_bytes_until_nul)] - /// - /// use std::ffi::CStr; - /// - /// let mut buffer = [0u8; 16]; - /// unsafe { - /// // Here we might call an unsafe C function that writes a string - /// // into the buffer. - /// let buf_ptr = buffer.as_mut_ptr(); - /// buf_ptr.write_bytes(b'A', 8); - /// } - /// // Attempt to extract a C nul-terminated string from the buffer. - /// let c_str = CStr::from_bytes_until_nul(&buffer[..]).unwrap(); - /// assert_eq!(c_str.to_str().unwrap(), "AAAAAAAA"); - /// ``` - /// - #[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")] - pub fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> { - let nul_pos = memchr::memchr(0, bytes); - match nul_pos { - Some(nul_pos) => { - // SAFETY: We know there is a nul byte at nul_pos, so this slice - // (ending at the nul byte) is a well-formed C string. - let subslice = &bytes[..nul_pos + 1]; - Ok(unsafe { CStr::from_bytes_with_nul_unchecked(subslice) }) - } - None => Err(FromBytesUntilNulError(())), - } + fn to_owned(&self) -> CString { + CString { inner: self.to_bytes_with_nul().into() } } - /// Creates a C string wrapper from a byte slice. - /// - /// This function will cast the provided `bytes` to a `CStr` - /// wrapper after ensuring that the byte slice is nul-terminated - /// and does not contain any interior nul bytes. - /// - /// If the nul byte may not be at the end, - /// [`CStr::from_bytes_until_nul`] can be used instead. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::CStr; - /// - /// let cstr = CStr::from_bytes_with_nul(b"hello\0"); - /// assert!(cstr.is_ok()); - /// ``` - /// - /// Creating a `CStr` without a trailing nul terminator is an error: - /// - /// ``` - /// use std::ffi::CStr; - /// - /// let cstr = CStr::from_bytes_with_nul(b"hello"); - /// assert!(cstr.is_err()); - /// ``` - /// - /// Creating a `CStr` with an interior nul byte is an error: - /// - /// ``` - /// use std::ffi::CStr; - /// - /// let cstr = CStr::from_bytes_with_nul(b"he\0llo\0"); - /// assert!(cstr.is_err()); - /// ``` - #[stable(feature = "cstr_from_bytes", since = "1.10.0")] - pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> { - let nul_pos = memchr::memchr(0, bytes); - match nul_pos { - Some(nul_pos) if nul_pos + 1 == bytes.len() => { - // SAFETY: We know there is only one nul byte, at the end - // of the byte slice. - Ok(unsafe { Self::_from_bytes_with_nul_unchecked(bytes) }) - } - Some(nul_pos) => Err(FromBytesWithNulError::interior_nul(nul_pos)), - None => Err(FromBytesWithNulError::not_nul_terminated()), - } + fn clone_into(&self, target: &mut CString) { + let mut b = into_vec(mem::take(&mut target.inner)); + self.to_bytes_with_nul().clone_into(&mut b); + target.inner = b.into_boxed_slice(); } +} - /// Unsafely creates a C string wrapper from a byte slice. - /// - /// This function will cast the provided `bytes` to a `CStr` wrapper without - /// performing any sanity checks. The provided slice **must** be nul-terminated - /// and not contain any interior nul bytes. - /// - /// # Examples - /// - /// ``` - /// use std::ffi::{CStr, CString}; - /// - /// unsafe { - /// let cstring = CString::new("hello").expect("CString::new failed"); - /// let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul()); - /// assert_eq!(cstr, &*cstring); - /// } - /// ``` - #[inline] - #[must_use] - #[stable(feature = "cstr_from_bytes", since = "1.10.0")] - #[rustc_const_stable(feature = "const_cstr_unchecked", since = "1.59.0")] - pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr { - // We're in a const fn, so this is the best we can do - debug_assert!(!bytes.is_empty() && bytes[bytes.len() - 1] == 0); - unsafe { Self::_from_bytes_with_nul_unchecked(bytes) } +#[stable(feature = "cstring_asref", since = "1.7.0")] +impl From<&CStr> for CString { + fn from(s: &CStr) -> CString { + s.to_owned() } +} + +#[stable(feature = "cstring_asref", since = "1.7.0")] +impl ops::Index<ops::RangeFull> for CString { + type Output = CStr; #[inline] - const unsafe fn _from_bytes_with_nul_unchecked(bytes: &[u8]) -> &Self { - // SAFETY: Casting to CStr is safe because its internal representation - // is a [u8] too (safe only inside std). - // Dereferencing the obtained pointer is safe because it comes from a - // reference. Making a reference is then safe because its lifetime - // is bound by the lifetime of the given `bytes`. - unsafe { &*(bytes as *const [u8] as *const Self) } + fn index(&self, _index: ops::RangeFull) -> &CStr { + self } +} - /// Returns the inner pointer to this C string. - /// - /// The returned pointer will be valid for as long as `self` is, and points - /// to a contiguous region of memory terminated with a 0 byte to represent - /// the end of the string. - /// - /// **WARNING** - /// - /// The returned pointer is read-only; writing to it (including passing it - /// to C code that writes to it) causes undefined behavior. - /// - /// It is your responsibility to make sure that the underlying memory is not - /// freed too early. For example, the following code will cause undefined - /// behavior when `ptr` is used inside the `unsafe` block: - /// - /// ```no_run - /// # #![allow(unused_must_use)] #![allow(temporary_cstring_as_ptr)] - /// use std::ffi::CString; - /// - /// let ptr = CString::new("Hello").expect("CString::new failed").as_ptr(); - /// unsafe { - /// // `ptr` is dangling - /// *ptr; - /// } - /// ``` - /// - /// This happens because the pointer returned by `as_ptr` does not carry any - /// lifetime information and the [`CString`] is deallocated immediately after - /// the `CString::new("Hello").expect("CString::new failed").as_ptr()` - /// expression is evaluated. - /// To fix the problem, bind the `CString` to a local variable: - /// - /// ```no_run - /// # #![allow(unused_must_use)] - /// use std::ffi::CString; - /// - /// let hello = CString::new("Hello").expect("CString::new failed"); - /// let ptr = hello.as_ptr(); - /// unsafe { - /// // `ptr` is valid because `hello` is in scope - /// *ptr; - /// } - /// ``` - /// - /// This way, the lifetime of the [`CString`] in `hello` encompasses - /// the lifetime of `ptr` and the `unsafe` block. +#[stable(feature = "cstring_asref", since = "1.7.0")] +impl AsRef<CStr> for CString { #[inline] - #[must_use] - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0")] - pub const fn as_ptr(&self) -> *const c_char { - self.inner.as_ptr() + fn as_ref(&self) -> &CStr { + self } +} - /// Converts this C string to a byte slice. +#[cfg(bootstrap)] +#[doc(hidden)] +#[unstable(feature = "cstr_internals", issue = "none")] +pub trait CStrExt { + /// Converts a `CStr` into a <code>[Cow]<[str]></code>. /// - /// The returned slice will **not** contain the trailing nul terminator that this C - /// string has. + /// If the contents of the `CStr` are valid UTF-8 data, this + /// function will return a <code>[Cow]::[Borrowed]\(&[str])</code> + /// with the corresponding <code>&[str]</code> slice. Otherwise, it will + /// replace any invalid UTF-8 sequences with + /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a + /// <code>[Cow]::[Owned]\(&[str])</code> with the result. /// - /// > **Note**: This method is currently implemented as a constant-time - /// > cast, but it is planned to alter its definition in the future to - /// > perform the length calculation whenever this method is called. + /// [str]: prim@str "str" + /// [Borrowed]: Cow::Borrowed + /// [Owned]: Cow::Owned + /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER "std::char::REPLACEMENT_CHARACTER" /// /// # Examples /// + /// Calling `to_string_lossy` on a `CStr` containing valid UTF-8: + /// /// ``` + /// use std::borrow::Cow; /// use std::ffi::CStr; /// - /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); - /// assert_eq!(cstr.to_bytes(), b"foo"); + /// let cstr = CStr::from_bytes_with_nul(b"Hello World\0") + /// .expect("CStr::from_bytes_with_nul failed"); + /// assert_eq!(cstr.to_string_lossy(), Cow::Borrowed("Hello World")); /// ``` - #[inline] - #[must_use = "this returns the result of the operation, \ - without modifying the original"] - #[stable(feature = "rust1", since = "1.0.0")] - pub fn to_bytes(&self) -> &[u8] { - let bytes = self.to_bytes_with_nul(); - // SAFETY: to_bytes_with_nul returns slice with length at least 1 - unsafe { bytes.get_unchecked(..bytes.len() - 1) } - } - - /// Converts this C string to a byte slice containing the trailing 0 byte. /// - /// This function is the equivalent of [`CStr::to_bytes`] except that it - /// will retain the trailing nul terminator instead of chopping it off. - /// - /// > **Note**: This method is currently implemented as a 0-cost cast, but - /// > it is planned to alter its definition in the future to perform the - /// > length calculation whenever this method is called. - /// - /// # Examples + /// Calling `to_string_lossy` on a `CStr` containing invalid UTF-8: /// /// ``` + /// use std::borrow::Cow; /// use std::ffi::CStr; /// - /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); - /// assert_eq!(cstr.to_bytes_with_nul(), b"foo\0"); + /// let cstr = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0") + /// .expect("CStr::from_bytes_with_nul failed"); + /// assert_eq!( + /// cstr.to_string_lossy(), + /// Cow::Owned(String::from("Hello �World")) as Cow<'_, str> + /// ); /// ``` - #[inline] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[stable(feature = "rust1", since = "1.0.0")] - pub fn to_bytes_with_nul(&self) -> &[u8] { - unsafe { &*(&self.inner as *const [c_char] as *const [u8]) } - } + #[stable(feature = "cstr_to_str", since = "1.4.0")] + fn to_string_lossy(&self) -> Cow<'_, str>; - /// Yields a <code>&[str]</code> slice if the `CStr` contains valid UTF-8. - /// - /// If the contents of the `CStr` are valid UTF-8 data, this - /// function will return the corresponding <code>&[str]</code> slice. Otherwise, - /// it will return an error with details of where UTF-8 validation failed. - /// - /// [str]: prim@str "str" + /// Converts a <code>[Box]<[CStr]></code> into a [`CString`] without copying or allocating. /// /// # Examples /// /// ``` - /// use std::ffi::CStr; + /// use std::ffi::CString; /// - /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); - /// assert_eq!(cstr.to_str(), Ok("foo")); + /// let c_string = CString::new(b"foo".to_vec()).expect("CString::new failed"); + /// let boxed = c_string.into_boxed_c_str(); + /// assert_eq!(boxed.into_c_string(), CString::new("foo").expect("CString::new failed")); /// ``` - #[stable(feature = "cstr_to_str", since = "1.4.0")] - pub fn to_str(&self) -> Result<&str, str::Utf8Error> { - // N.B., when `CStr` is changed to perform the length check in `.to_bytes()` - // instead of in `from_ptr()`, it may be worth considering if this should - // be rewritten to do the UTF-8 check inline with the length calculation - // instead of doing it afterwards. - str::from_utf8(self.to_bytes()) + #[must_use = "`self` will be dropped if the result is not used"] + #[stable(feature = "into_boxed_c_str", since = "1.20.0")] + fn into_c_string(self: Box<Self>) -> CString; +} + +#[cfg(bootstrap)] +#[unstable(feature = "cstr_internals", issue = "none")] +impl CStrExt for CStr { + fn to_string_lossy(&self) -> Cow<'_, str> { + String::from_utf8_lossy(self.to_bytes()) } + fn into_c_string(self: Box<Self>) -> CString { + CString::from(self) + } +} + +#[cfg(not(bootstrap))] +#[cfg(not(test))] +impl CStr { /// Converts a `CStr` into a <code>[Cow]<[str]></code>. /// /// If the contents of the `CStr` are valid UTF-8 data, this @@ -1534,7 +1145,7 @@ impl CStr { /// [str]: prim@str "str" /// [Borrowed]: Cow::Borrowed /// [Owned]: Cow::Owned - /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER "std::char::REPLACEMENT_CHARACTER" + /// [U+FFFD]: core::char::REPLACEMENT_CHARACTER "std::char::REPLACEMENT_CHARACTER" /// /// # Examples /// @@ -1562,6 +1173,7 @@ impl CStr { /// Cow::Owned(String::from("Hello �World")) as Cow<'_, str> /// ); /// ``` + #[rustc_allow_incoherent_impl] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "cstr_to_str", since = "1.4.0")] @@ -1580,101 +1192,10 @@ impl CStr { /// let boxed = c_string.into_boxed_c_str(); /// assert_eq!(boxed.into_c_string(), CString::new("foo").expect("CString::new failed")); /// ``` + #[rustc_allow_incoherent_impl] #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "into_boxed_c_str", since = "1.20.0")] - pub fn into_c_string(self: Box<CStr>) -> CString { - let raw = Box::into_raw(self) as *mut [u8]; - CString { inner: unsafe { Box::from_raw(raw) } } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for CStr { - fn eq(&self, other: &CStr) -> bool { - self.to_bytes().eq(other.to_bytes()) - } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl Eq for CStr {} -#[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for CStr { - fn partial_cmp(&self, other: &CStr) -> Option<Ordering> { - self.to_bytes().partial_cmp(&other.to_bytes()) - } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl Ord for CStr { - fn cmp(&self, other: &CStr) -> Ordering { - self.to_bytes().cmp(&other.to_bytes()) - } -} - -#[stable(feature = "cstr_borrow", since = "1.3.0")] -impl ToOwned for CStr { - type Owned = CString; - - fn to_owned(&self) -> CString { - CString { inner: self.to_bytes_with_nul().into() } - } - - fn clone_into(&self, target: &mut CString) { - let mut b = Vec::from(mem::take(&mut target.inner)); - self.to_bytes_with_nul().clone_into(&mut b); - target.inner = b.into_boxed_slice(); - } -} - -#[stable(feature = "cstring_asref", since = "1.7.0")] -impl From<&CStr> for CString { - /// Copies the contents of the `&CStr` into a newly allocated `CString`. - fn from(s: &CStr) -> CString { - s.to_owned() - } -} - -#[stable(feature = "cstring_asref", since = "1.7.0")] -impl ops::Index<ops::RangeFull> for CString { - type Output = CStr; - - #[inline] - fn index(&self, _index: ops::RangeFull) -> &CStr { - self - } -} - -#[stable(feature = "cstr_range_from", since = "1.47.0")] -impl ops::Index<ops::RangeFrom<usize>> for CStr { - type Output = CStr; - - fn index(&self, index: ops::RangeFrom<usize>) -> &CStr { - let bytes = self.to_bytes_with_nul(); - // we need to manually check the starting index to account for the null - // byte, since otherwise we could get an empty string that doesn't end - // in a null. - if index.start < bytes.len() { - unsafe { CStr::_from_bytes_with_nul_unchecked(&bytes[index.start..]) } - } else { - panic!( - "index out of bounds: the len is {} but the index is {}", - bytes.len(), - index.start - ); - } - } -} - -#[stable(feature = "cstring_asref", since = "1.7.0")] -impl AsRef<CStr> for CStr { - #[inline] - fn as_ref(&self) -> &CStr { - self - } -} - -#[stable(feature = "cstring_asref", since = "1.7.0")] -impl AsRef<CStr> for CString { - #[inline] - fn as_ref(&self) -> &CStr { - self + pub fn into_c_string(self: Box<Self>) -> CString { + CString::from(self) } } diff --git a/library/std/src/ffi/c_str/tests.rs b/library/alloc/src/ffi/c_str/tests.rs index c20da138a18..0b7476d5cc7 100644 --- a/library/std/src/ffi/c_str/tests.rs +++ b/library/alloc/src/ffi/c_str/tests.rs @@ -1,10 +1,12 @@ use super::*; -use crate::borrow::Cow::{Borrowed, Owned}; -use crate::collections::hash_map::DefaultHasher; -use crate::hash::{Hash, Hasher}; -use crate::os::raw::c_char; use crate::rc::Rc; use crate::sync::Arc; +use core::assert_matches::assert_matches; +use core::ffi::FromBytesUntilNulError; +use core::hash::{Hash, Hasher}; + +#[allow(deprecated)] +use core::hash::SipHasher13 as DefaultHasher; #[test] fn c_to_rust() { @@ -48,22 +50,6 @@ fn borrowed() { } #[test] -fn to_str() { - let data = b"123\xE2\x80\xA6\0"; - let ptr = data.as_ptr() as *const c_char; - unsafe { - assert_eq!(CStr::from_ptr(ptr).to_str(), Ok("123…")); - assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Borrowed("123…")); - } - let data = b"123\xE2\0"; - let ptr = data.as_ptr() as *const c_char; - unsafe { - assert!(CStr::from_ptr(ptr).to_str().is_err()); - assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Owned::<str>(format!("123\u{FFFD}"))); - } -} - -#[test] fn to_owned() { let data = b"123\0"; let ptr = data.as_ptr() as *const c_char; @@ -78,9 +64,11 @@ fn equal_hash() { let ptr = data.as_ptr() as *const c_char; let cstr: &'static CStr = unsafe { CStr::from_ptr(ptr) }; + #[allow(deprecated)] let mut s = DefaultHasher::new(); cstr.hash(&mut s); let cstr_hash = s.finish(); + #[allow(deprecated)] let mut s = DefaultHasher::new(); CString::new(&data[..data.len() - 1]).unwrap().hash(&mut s); let cstring_hash = s.finish(); @@ -122,11 +110,11 @@ fn cstr_from_bytes_until_nul() { // Test an empty slice. This should fail because it // does not contain a nul byte. let b = b""; - assert_eq!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError(()))); + assert_matches!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError { .. })); // Test a non-empty slice, that does not contain a nul byte. let b = b"hello"; - assert_eq!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError(()))); + assert_matches!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError { .. })); // Test an empty nul-terminated string let b = b"\0"; diff --git a/library/alloc/src/ffi/mod.rs b/library/alloc/src/ffi/mod.rs new file mode 100644 index 00000000000..eed2851c153 --- /dev/null +++ b/library/alloc/src/ffi/mod.rs @@ -0,0 +1,91 @@ +//! Utilities related to FFI bindings. +//! +//! This module provides utilities to handle data across non-Rust +//! interfaces, like other programming languages and the underlying +//! operating system. It is mainly of use for FFI (Foreign Function +//! Interface) bindings and code that needs to exchange C-like strings +//! with other languages. +//! +//! # Overview +//! +//! Rust represents owned strings with the [`String`] type, and +//! borrowed slices of strings with the [`str`] primitive. Both are +//! always in UTF-8 encoding, and may contain nul bytes in the middle, +//! i.e., if you look at the bytes that make up the string, there may +//! be a `\0` among them. Both `String` and `str` store their length +//! explicitly; there are no nul terminators at the end of strings +//! like in C. +//! +//! C strings are different from Rust strings: +//! +//! * **Encodings** - Rust strings are UTF-8, but C strings may use +//! other encodings. If you are using a string from C, you should +//! check its encoding explicitly, rather than just assuming that it +//! is UTF-8 like you can do in Rust. +//! +//! * **Character size** - C strings may use `char` or `wchar_t`-sized +//! characters; please **note** that C's `char` is different from Rust's. +//! The C standard leaves the actual sizes of those types open to +//! interpretation, but defines different APIs for strings made up of +//! each character type. Rust strings are always UTF-8, so different +//! Unicode characters will be encoded in a variable number of bytes +//! each. The Rust type [`char`] represents a '[Unicode scalar +//! value]', which is similar to, but not the same as, a '[Unicode +//! code point]'. +//! +//! * **Nul terminators and implicit string lengths** - Often, C +//! strings are nul-terminated, i.e., they have a `\0` character at the +//! end. The length of a string buffer is not stored, but has to be +//! calculated; to compute the length of a string, C code must +//! manually call a function like `strlen()` for `char`-based strings, +//! or `wcslen()` for `wchar_t`-based ones. Those functions return +//! the number of characters in the string excluding the nul +//! terminator, so the buffer length is really `len+1` characters. +//! Rust strings don't have a nul terminator; their length is always +//! stored and does not need to be calculated. While in Rust +//! accessing a string's length is an *O*(1) operation (because the +//! length is stored); in C it is an *O*(*n*) operation because the +//! length needs to be computed by scanning the string for the nul +//! terminator. +//! +//! * **Internal nul characters** - When C strings have a nul +//! terminator character, this usually means that they cannot have nul +//! characters in the middle — a nul character would essentially +//! truncate the string. Rust strings *can* have nul characters in +//! the middle, because nul does not have to mark the end of the +//! string in Rust. +//! +//! # Representations of non-Rust strings +//! +//! [`CString`] and [`CStr`] are useful when you need to transfer +//! UTF-8 strings to and from languages with a C ABI, like Python. +//! +//! * **From Rust to C:** [`CString`] represents an owned, C-friendly +//! string: it is nul-terminated, and has no internal nul characters. +//! Rust code can create a [`CString`] out of a normal string (provided +//! that the string doesn't have nul characters in the middle), and +//! then use a variety of methods to obtain a raw <code>\*mut [u8]</code> that can +//! then be passed as an argument to functions which use the C +//! conventions for strings. +//! +//! * **From C to Rust:** [`CStr`] represents a borrowed C string; it +//! is what you would use to wrap a raw <code>\*const [u8]</code> that you got from +//! a C function. A [`CStr`] is guaranteed to be a nul-terminated array +//! of bytes. Once you have a [`CStr`], you can convert it to a Rust +//! <code>&[str]</code> if it's valid UTF-8, or lossily convert it by adding +//! replacement characters. +//! +//! [`String`]: crate::string::String +//! [`CStr`]: core::ffi::CStr + +#![unstable(feature = "alloc_ffi", issue = "94079")] + +#[cfg(bootstrap)] +#[unstable(feature = "cstr_internals", issue = "none")] +pub use self::c_str::CStrExt; +#[unstable(feature = "alloc_c_string", issue = "94079")] +pub use self::c_str::FromVecWithNulError; +#[unstable(feature = "alloc_c_string", issue = "94079")] +pub use self::c_str::{CString, IntoStringError, NulError}; + +mod c_str; diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index c54001dceea..4d2dc4ecee0 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -86,11 +86,13 @@ #![allow(explicit_outlives_requirements)] // // Library features: +#![cfg_attr(not(no_global_oom_handling), feature(alloc_c_string))] #![feature(alloc_layout_extra)] #![feature(allocator_api)] #![feature(array_chunks)] #![feature(array_methods)] #![feature(array_windows)] +#![feature(assert_matches)] #![feature(async_iterator)] #![feature(coerce_unsized)] #![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))] @@ -104,9 +106,12 @@ #![feature(const_maybe_uninit_write)] #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_refs_to_cell)] +#![feature(core_c_str)] #![feature(core_intrinsics)] +#![feature(core_ffi_c)] #![feature(const_eval_select)] #![feature(const_pin)] +#![feature(cstr_from_bytes_until_nul)] #![feature(dispatch_from_dyn)] #![feature(exact_size_is_empty)] #![feature(extend_one)] @@ -152,6 +157,7 @@ #![feature(exclusive_range_pattern)] #![feature(fundamental)] #![cfg_attr(not(test), feature(generator_trait))] +#![feature(hashmap_internals)] #![feature(lang_items)] #![feature(let_else)] #![feature(min_specialization)] @@ -160,6 +166,7 @@ #![feature(nll)] // Not necessary, but here to test the `nll` feature. #![feature(rustc_allow_const_fn_unstable)] #![feature(rustc_attrs)] +#![feature(slice_internals)] #![feature(staged_api)] #![cfg_attr(test, feature(test))] #![feature(unboxed_closures)] @@ -205,6 +212,8 @@ mod boxed { } pub mod borrow; pub mod collections; +#[cfg(not(no_global_oom_handling))] +pub mod ffi; pub mod fmt; pub mod rc; pub mod slice; diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index d0d37c08d13..a42f1c3b4bb 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2511,14 +2511,23 @@ trait RcInnerPtr { fn inc_strong(&self) { let strong = self.strong(); + // We insert an `assume` here to hint LLVM at an otherwise + // missed optimization. + // SAFETY: The reference count will never be zero when this is + // called. + unsafe { + core::intrinsics::assume(strong != 0); + } + + let strong = strong.wrapping_add(1); + self.strong_ref().set(strong); + // We want to abort on overflow instead of dropping the value. - // The reference count will never be zero when this is called; - // nevertheless, we insert an abort here to hint LLVM at - // an otherwise missed optimization. - if strong == 0 || strong == usize::MAX { + // Checking for overflow after the store instead of before + // allows for slightly better code generation. + if core::intrinsics::unlikely(strong == 0) { abort(); } - self.strong_ref().set(strong + 1); } #[inline] @@ -2535,14 +2544,23 @@ trait RcInnerPtr { fn inc_weak(&self) { let weak = self.weak(); + // We insert an `assume` here to hint LLVM at an otherwise + // missed optimization. + // SAFETY: The reference count will never be zero when this is + // called. + unsafe { + core::intrinsics::assume(weak != 0); + } + + let weak = weak.wrapping_add(1); + self.weak_ref().set(weak); + // We want to abort on overflow instead of dropping the value. - // The reference count will never be zero when this is called; - // nevertheless, we insert an abort here to hint LLVM at - // an otherwise missed optimization. - if weak == 0 || weak == usize::MAX { + // Checking for overflow after the store instead of before + // allows for slightly better code generation. + if core::intrinsics::unlikely(weak == 0) { abort(); } - self.weak_ref().set(weak + 1); } #[inline] diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 31edbe0c5af..02a47c57b8a 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -153,7 +153,7 @@ pub use hack::to_vec; // functions are actually methods that are in `impl [T]` but not in // `core::slice::SliceExt` - we need to supply these functions for the // `test_permutations` test -mod hack { +pub(crate) mod hack { use core::alloc::Allocator; use crate::boxed::Box; diff --git a/library/alloc/tests/c_str.rs b/library/alloc/tests/c_str.rs new file mode 100644 index 00000000000..8fbb10e1d5c --- /dev/null +++ b/library/alloc/tests/c_str.rs @@ -0,0 +1,18 @@ +use std::borrow::Cow::{Borrowed, Owned}; +use std::ffi::{c_char, CStr}; + +#[test] +fn to_str() { + let data = b"123\xE2\x80\xA6\0"; + let ptr = data.as_ptr() as *const c_char; + unsafe { + assert_eq!(CStr::from_ptr(ptr).to_str(), Ok("123…")); + assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Borrowed("123…")); + } + let data = b"123\xE2\0"; + let ptr = data.as_ptr() as *const c_char; + unsafe { + assert!(CStr::from_ptr(ptr).to_str().is_err()); + assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Owned::<str>(format!("123\u{FFFD}"))); + } +} diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 16d3b368595..8de159246c6 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -12,6 +12,8 @@ #![feature(const_nonnull_slice_from_raw_parts)] #![feature(const_ptr_write)] #![feature(const_try)] +#![feature(core_c_str)] +#![feature(core_ffi_c)] #![feature(core_intrinsics)] #![feature(drain_filter)] #![feature(exact_size_is_empty)] @@ -49,6 +51,7 @@ mod binary_heap; mod borrow; mod boxed; mod btree_set_hash; +mod c_str; mod const_fns; mod cow_str; mod fmt; diff --git a/library/core/src/default.rs b/library/core/src/default.rs index fb862f7df94..1ce00828bf3 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -52,6 +52,23 @@ /// This trait can be used with `#[derive]` if all of the type's fields implement /// `Default`. When `derive`d, it will use the default value for each field's type. /// +/// ### `enum`s +/// +/// When using `#[derive(Default)]` on an `enum`, you need to choose which unit variant will be +/// default. You do this by placing the `#[default]` attribute on the variant. +/// +/// ``` +/// #[derive(Default)] +/// enum Kind { +/// #[default] +/// A, +/// B, +/// C, +/// } +/// ``` +/// +/// You cannot use the `#[default]` attribute on non-unit or non-exhaustive variants. +/// /// ## How can I implement `Default`? /// /// Provide an implementation for the `default()` method that returns the value of diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs new file mode 100644 index 00000000000..15d9d013997 --- /dev/null +++ b/library/core/src/ffi/c_str.rs @@ -0,0 +1,570 @@ +use crate::ascii; +use crate::cmp::Ordering; +use crate::ffi::c_char; +use crate::fmt::{self, Write}; +use crate::ops; +use crate::slice; +use crate::slice::memchr; +use crate::str; + +/// Representation of a borrowed C string. +/// +/// This type represents a borrowed reference to a nul-terminated +/// array of bytes. It can be constructed safely from a <code>&[[u8]]</code> +/// slice, or unsafely from a raw `*const c_char`. It can then be +/// converted to a Rust <code>&[str]</code> by performing UTF-8 validation, or +/// into an owned `CString`. +/// +/// `&CStr` is to `CString` as <code>&[str]</code> is to `String`: the former +/// in each pair are borrowed references; the latter are owned +/// strings. +/// +/// Note that this structure is **not** `repr(C)` and is not recommended to be +/// placed in the signatures of FFI functions. Instead, safe wrappers of FFI +/// functions may leverage the unsafe [`CStr::from_ptr`] constructor to provide +/// a safe interface to other consumers. +/// +/// # Examples +/// +/// Inspecting a foreign C string: +/// +/// ```ignore (extern-declaration) +/// use std::ffi::CStr; +/// use std::os::raw::c_char; +/// +/// extern "C" { fn my_string() -> *const c_char; } +/// +/// unsafe { +/// let slice = CStr::from_ptr(my_string()); +/// println!("string buffer size without nul terminator: {}", slice.to_bytes().len()); +/// } +/// ``` +/// +/// Passing a Rust-originating C string: +/// +/// ```ignore (extern-declaration) +/// use std::ffi::{CString, CStr}; +/// use std::os::raw::c_char; +/// +/// fn work(data: &CStr) { +/// extern "C" { fn work_with(data: *const c_char); } +/// +/// unsafe { work_with(data.as_ptr()) } +/// } +/// +/// let s = CString::new("data data data data").expect("CString::new failed"); +/// work(&s); +/// ``` +/// +/// Converting a foreign C string into a Rust `String`: +/// +/// ```ignore (extern-declaration) +/// use std::ffi::CStr; +/// use std::os::raw::c_char; +/// +/// extern "C" { fn my_string() -> *const c_char; } +/// +/// fn my_string_safe() -> String { +/// unsafe { +/// CStr::from_ptr(my_string()).to_string_lossy().into_owned() +/// } +/// } +/// +/// println!("string: {}", my_string_safe()); +/// ``` +/// +/// [str]: prim@str "str" +#[derive(Hash)] +#[cfg_attr(not(test), rustc_diagnostic_item = "CStr")] +#[unstable(feature = "core_c_str", issue = "94079")] +#[cfg_attr(not(bootstrap), lang = "CStr")] +// FIXME: +// `fn from` in `impl From<&CStr> for Box<CStr>` current implementation relies +// on `CStr` being layout-compatible with `[u8]`. +// When attribute privacy is implemented, `CStr` should be annotated as `#[repr(transparent)]`. +// Anyway, `CStr` representation and layout are considered implementation detail, are +// not documented and must not be relied upon. +pub struct CStr { + // FIXME: this should not be represented with a DST slice but rather with + // just a raw `c_char` along with some form of marker to make + // this an unsized type. Essentially `sizeof(&CStr)` should be the + // same as `sizeof(&c_char)` but `CStr` should be an unsized type. + inner: [c_char], +} + +/// An error indicating that a nul byte was not in the expected position. +/// +/// The slice used to create a [`CStr`] must have one and only one nul byte, +/// positioned at the end. +/// +/// This error is created by the [`CStr::from_bytes_with_nul`] method. +/// See its documentation for more. +/// +/// # Examples +/// +/// ``` +/// use std::ffi::{CStr, FromBytesWithNulError}; +/// +/// let _: FromBytesWithNulError = CStr::from_bytes_with_nul(b"f\0oo").unwrap_err(); +/// ``` +#[derive(Clone, PartialEq, Eq, Debug)] +#[unstable(feature = "core_c_str", issue = "94079")] +pub struct FromBytesWithNulError { + kind: FromBytesWithNulErrorKind, +} + +#[derive(Clone, PartialEq, Eq, Debug)] +enum FromBytesWithNulErrorKind { + InteriorNul(usize), + NotNulTerminated, +} + +impl FromBytesWithNulError { + fn interior_nul(pos: usize) -> FromBytesWithNulError { + FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) } + } + fn not_nul_terminated() -> FromBytesWithNulError { + FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated } + } + + #[doc(hidden)] + #[unstable(feature = "cstr_internals", issue = "none")] + pub fn __description(&self) -> &str { + match self.kind { + FromBytesWithNulErrorKind::InteriorNul(..) => { + "data provided contains an interior nul byte" + } + FromBytesWithNulErrorKind::NotNulTerminated => "data provided is not nul terminated", + } + } +} + +/// An error indicating that no nul byte was present. +/// +/// A slice used to create a [`CStr`] must contain a nul byte somewhere +/// within the slice. +/// +/// This error is created by the [`CStr::from_bytes_until_nul`] method. +/// +#[derive(Clone, PartialEq, Eq, Debug)] +#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")] +pub struct FromBytesUntilNulError(()); + +#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")] +impl fmt::Display for FromBytesUntilNulError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "data provided does not contain a nul") + } +} + +#[stable(feature = "cstr_debug", since = "1.3.0")] +impl fmt::Debug for CStr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "\"")?; + for byte in self.to_bytes().iter().flat_map(|&b| ascii::escape_default(b)) { + f.write_char(byte as char)?; + } + write!(f, "\"") + } +} + +#[stable(feature = "cstr_default", since = "1.10.0")] +impl Default for &CStr { + fn default() -> Self { + const SLICE: &[c_char] = &[0]; + // SAFETY: `SLICE` is indeed pointing to a valid nul-terminated string. + unsafe { CStr::from_ptr(SLICE.as_ptr()) } + } +} + +#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")] +impl fmt::Display for FromBytesWithNulError { + #[allow(deprecated, deprecated_in_future)] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.__description())?; + if let FromBytesWithNulErrorKind::InteriorNul(pos) = self.kind { + write!(f, " at byte pos {pos}")?; + } + Ok(()) + } +} + +impl CStr { + /// Wraps a raw C string with a safe C string wrapper. + /// + /// This function will wrap the provided `ptr` with a `CStr` wrapper, which + /// allows inspection and interoperation of non-owned C strings. The total + /// size of the raw C string must be smaller than `isize::MAX` **bytes** + /// in memory due to calling the `slice::from_raw_parts` function. + /// This method is unsafe for a number of reasons: + /// + /// * There is no guarantee to the validity of `ptr`. + /// * The returned lifetime is not guaranteed to be the actual lifetime of + /// `ptr`. + /// * There is no guarantee that the memory pointed to by `ptr` contains a + /// valid nul terminator byte at the end of the string. + /// * It is not guaranteed that the memory pointed by `ptr` won't change + /// before the `CStr` has been destroyed. + /// + /// > **Note**: This operation is intended to be a 0-cost cast but it is + /// > currently implemented with an up-front calculation of the length of + /// > the string. This is not guaranteed to always be the case. + /// + /// # Examples + /// + /// ```ignore (extern-declaration) + /// # fn main() { + /// use std::ffi::CStr; + /// use std::os::raw::c_char; + /// + /// extern "C" { + /// fn my_string() -> *const c_char; + /// } + /// + /// unsafe { + /// let slice = CStr::from_ptr(my_string()); + /// println!("string returned: {}", slice.to_str().unwrap()); + /// } + /// # } + /// ``` + #[inline] + #[must_use] + #[stable(feature = "rust1", since = "1.0.0")] + pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr { + // SAFETY: The caller has provided a pointer that points to a valid C + // string with a NUL terminator of size less than `isize::MAX`, whose + // content remain valid and doesn't change for the lifetime of the + // returned `CStr`. + // + // Thus computing the length is fine (a NUL byte exists), the call to + // from_raw_parts is safe because we know the length is at most `isize::MAX`, meaning + // the call to `from_bytes_with_nul_unchecked` is correct. + // + // The cast from c_char to u8 is ok because a c_char is always one byte. + unsafe { + extern "C" { + /// Provided by libc or compiler_builtins. + fn strlen(s: *const c_char) -> usize; + } + let len = strlen(ptr); + let ptr = ptr as *const u8; + CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1)) + } + } + + /// Creates a C string wrapper from a byte slice. + /// + /// This method will create a `CStr` from any byte slice that contains at + /// least one nul byte. The caller does not need to know or specify where + /// the nul byte is located. + /// + /// If the first byte is a nul character, this method will return an + /// empty `CStr`. If multiple nul characters are present, the `CStr` will + /// end at the first one. + /// + /// If the slice only has a single nul byte at the end, this method is + /// equivalent to [`CStr::from_bytes_with_nul`]. + /// + /// # Examples + /// ``` + /// #![feature(cstr_from_bytes_until_nul)] + /// + /// use std::ffi::CStr; + /// + /// let mut buffer = [0u8; 16]; + /// unsafe { + /// // Here we might call an unsafe C function that writes a string + /// // into the buffer. + /// let buf_ptr = buffer.as_mut_ptr(); + /// buf_ptr.write_bytes(b'A', 8); + /// } + /// // Attempt to extract a C nul-terminated string from the buffer. + /// let c_str = CStr::from_bytes_until_nul(&buffer[..]).unwrap(); + /// assert_eq!(c_str.to_str().unwrap(), "AAAAAAAA"); + /// ``` + /// + #[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")] + pub fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> { + let nul_pos = memchr::memchr(0, bytes); + match nul_pos { + Some(nul_pos) => { + let subslice = &bytes[..nul_pos + 1]; + // SAFETY: We know there is a nul byte at nul_pos, so this slice + // (ending at the nul byte) is a well-formed C string. + Ok(unsafe { CStr::from_bytes_with_nul_unchecked(subslice) }) + } + None => Err(FromBytesUntilNulError(())), + } + } + + /// Creates a C string wrapper from a byte slice. + /// + /// This function will cast the provided `bytes` to a `CStr` + /// wrapper after ensuring that the byte slice is nul-terminated + /// and does not contain any interior nul bytes. + /// + /// If the nul byte may not be at the end, + /// [`CStr::from_bytes_until_nul`] can be used instead. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::CStr; + /// + /// let cstr = CStr::from_bytes_with_nul(b"hello\0"); + /// assert!(cstr.is_ok()); + /// ``` + /// + /// Creating a `CStr` without a trailing nul terminator is an error: + /// + /// ``` + /// use std::ffi::CStr; + /// + /// let cstr = CStr::from_bytes_with_nul(b"hello"); + /// assert!(cstr.is_err()); + /// ``` + /// + /// Creating a `CStr` with an interior nul byte is an error: + /// + /// ``` + /// use std::ffi::CStr; + /// + /// let cstr = CStr::from_bytes_with_nul(b"he\0llo\0"); + /// assert!(cstr.is_err()); + /// ``` + #[stable(feature = "cstr_from_bytes", since = "1.10.0")] + pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> { + let nul_pos = memchr::memchr(0, bytes); + match nul_pos { + Some(nul_pos) if nul_pos + 1 == bytes.len() => { + // SAFETY: We know there is only one nul byte, at the end + // of the byte slice. + Ok(unsafe { Self::from_bytes_with_nul_unchecked(bytes) }) + } + Some(nul_pos) => Err(FromBytesWithNulError::interior_nul(nul_pos)), + None => Err(FromBytesWithNulError::not_nul_terminated()), + } + } + + /// Unsafely creates a C string wrapper from a byte slice. + /// + /// This function will cast the provided `bytes` to a `CStr` wrapper without + /// performing any sanity checks. The provided slice **must** be nul-terminated + /// and not contain any interior nul bytes. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::{CStr, CString}; + /// + /// unsafe { + /// let cstring = CString::new("hello").expect("CString::new failed"); + /// let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul()); + /// assert_eq!(cstr, &*cstring); + /// } + /// ``` + #[inline] + #[must_use] + #[stable(feature = "cstr_from_bytes", since = "1.10.0")] + #[rustc_const_stable(feature = "const_cstr_unchecked", since = "1.59.0")] + pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr { + // We're in a const fn, so this is the best we can do + debug_assert!(!bytes.is_empty() && bytes[bytes.len() - 1] == 0); + // SAFETY: Calling an inner function with the same prerequisites. + unsafe { Self::_from_bytes_with_nul_unchecked(bytes) } + } + + #[inline] + const unsafe fn _from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr { + // SAFETY: Casting to CStr is safe because its internal representation + // is a [u8] too (safe only inside std). + // Dereferencing the obtained pointer is safe because it comes from a + // reference. Making a reference is then safe because its lifetime + // is bound by the lifetime of the given `bytes`. + unsafe { &*(bytes as *const [u8] as *const CStr) } + } + + /// Returns the inner pointer to this C string. + /// + /// The returned pointer will be valid for as long as `self` is, and points + /// to a contiguous region of memory terminated with a 0 byte to represent + /// the end of the string. + /// + /// **WARNING** + /// + /// The returned pointer is read-only; writing to it (including passing it + /// to C code that writes to it) causes undefined behavior. + /// + /// It is your responsibility to make sure that the underlying memory is not + /// freed too early. For example, the following code will cause undefined + /// behavior when `ptr` is used inside the `unsafe` block: + /// + /// ```no_run + /// # #![allow(unused_must_use)] #![allow(temporary_cstring_as_ptr)] + /// use std::ffi::CString; + /// + /// let ptr = CString::new("Hello").expect("CString::new failed").as_ptr(); + /// unsafe { + /// // `ptr` is dangling + /// *ptr; + /// } + /// ``` + /// + /// This happens because the pointer returned by `as_ptr` does not carry any + /// lifetime information and the `CString` is deallocated immediately after + /// the `CString::new("Hello").expect("CString::new failed").as_ptr()` + /// expression is evaluated. + /// To fix the problem, bind the `CString` to a local variable: + /// + /// ```no_run + /// # #![allow(unused_must_use)] + /// use std::ffi::CString; + /// + /// let hello = CString::new("Hello").expect("CString::new failed"); + /// let ptr = hello.as_ptr(); + /// unsafe { + /// // `ptr` is valid because `hello` is in scope + /// *ptr; + /// } + /// ``` + /// + /// This way, the lifetime of the `CString` in `hello` encompasses + /// the lifetime of `ptr` and the `unsafe` block. + #[inline] + #[must_use] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0")] + pub const fn as_ptr(&self) -> *const c_char { + self.inner.as_ptr() + } + + /// Converts this C string to a byte slice. + /// + /// The returned slice will **not** contain the trailing nul terminator that this C + /// string has. + /// + /// > **Note**: This method is currently implemented as a constant-time + /// > cast, but it is planned to alter its definition in the future to + /// > perform the length calculation whenever this method is called. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::CStr; + /// + /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); + /// assert_eq!(cstr.to_bytes(), b"foo"); + /// ``` + #[inline] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn to_bytes(&self) -> &[u8] { + let bytes = self.to_bytes_with_nul(); + // SAFETY: to_bytes_with_nul returns slice with length at least 1 + unsafe { bytes.get_unchecked(..bytes.len() - 1) } + } + + /// Converts this C string to a byte slice containing the trailing 0 byte. + /// + /// This function is the equivalent of [`CStr::to_bytes`] except that it + /// will retain the trailing nul terminator instead of chopping it off. + /// + /// > **Note**: This method is currently implemented as a 0-cost cast, but + /// > it is planned to alter its definition in the future to perform the + /// > length calculation whenever this method is called. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::CStr; + /// + /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); + /// assert_eq!(cstr.to_bytes_with_nul(), b"foo\0"); + /// ``` + #[inline] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn to_bytes_with_nul(&self) -> &[u8] { + // SAFETY: Transmuting a slice of `c_char`s to a slice of `u8`s + // is safe on all supported targets. + unsafe { &*(&self.inner as *const [c_char] as *const [u8]) } + } + + /// Yields a <code>&[str]</code> slice if the `CStr` contains valid UTF-8. + /// + /// If the contents of the `CStr` are valid UTF-8 data, this + /// function will return the corresponding <code>&[str]</code> slice. Otherwise, + /// it will return an error with details of where UTF-8 validation failed. + /// + /// [str]: prim@str "str" + /// + /// # Examples + /// + /// ``` + /// use std::ffi::CStr; + /// + /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); + /// assert_eq!(cstr.to_str(), Ok("foo")); + /// ``` + #[stable(feature = "cstr_to_str", since = "1.4.0")] + pub fn to_str(&self) -> Result<&str, str::Utf8Error> { + // N.B., when `CStr` is changed to perform the length check in `.to_bytes()` + // instead of in `from_ptr()`, it may be worth considering if this should + // be rewritten to do the UTF-8 check inline with the length calculation + // instead of doing it afterwards. + str::from_utf8(self.to_bytes()) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl PartialEq for CStr { + fn eq(&self, other: &CStr) -> bool { + self.to_bytes().eq(other.to_bytes()) + } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl Eq for CStr {} +#[stable(feature = "rust1", since = "1.0.0")] +impl PartialOrd for CStr { + fn partial_cmp(&self, other: &CStr) -> Option<Ordering> { + self.to_bytes().partial_cmp(&other.to_bytes()) + } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl Ord for CStr { + fn cmp(&self, other: &CStr) -> Ordering { + self.to_bytes().cmp(&other.to_bytes()) + } +} + +#[stable(feature = "cstr_range_from", since = "1.47.0")] +impl ops::Index<ops::RangeFrom<usize>> for CStr { + type Output = CStr; + + fn index(&self, index: ops::RangeFrom<usize>) -> &CStr { + let bytes = self.to_bytes_with_nul(); + // we need to manually check the starting index to account for the null + // byte, since otherwise we could get an empty string that doesn't end + // in a null. + if index.start < bytes.len() { + // SAFETY: Non-empty tail of a valid `CStr` is still a valid `CStr`. + unsafe { CStr::from_bytes_with_nul_unchecked(&bytes[index.start..]) } + } else { + panic!( + "index out of bounds: the len is {} but the index is {}", + bytes.len(), + index.start + ); + } + } +} + +#[stable(feature = "cstring_asref", since = "1.7.0")] +impl AsRef<CStr> for CStr { + #[inline] + fn as_ref(&self) -> &CStr { + self + } +} diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index e61ea9ce87f..6c49521c223 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -14,6 +14,11 @@ use crate::marker::PhantomData; use crate::num::*; use crate::ops::{Deref, DerefMut}; +#[unstable(feature = "core_c_str", issue = "94079")] +pub use self::c_str::{CStr, FromBytesUntilNulError, FromBytesWithNulError}; + +mod c_str; + macro_rules! type_alias_no_nz { { $Docfile:tt, $Alias:ident = $Real:ty; diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 53fbe4cbc42..69f06fb06ef 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -470,6 +470,10 @@ pub trait Iterator { /// it will first try to advance the first iterator at most one time and if it still yielded an item /// try to advance the second iterator at most one time. /// + /// To 'undo' the result of zipping up two iterators, see [`unzip`]. + /// + /// [`unzip`]: Iterator::unzip + /// /// # Examples /// /// Basic usage: diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 6546a5244fd..dafd07b1617 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -20,7 +20,7 @@ // FIXME: Fill me in with more detail when the interface settles //! This library is built on the assumption of a few existing symbols: //! -//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are +//! * `memcpy`, `memcmp`, `memset`, `strlen` - These are core memory routines which are //! often generated by LLVM. Additionally, this library can make explicit //! calls to these functions. Their signatures are the same as found in C. //! These functions are often provided by the system libc, but can also be @@ -117,6 +117,7 @@ #![feature(const_intrinsic_copy)] #![feature(const_intrinsic_forget)] #![feature(const_likely)] +#![feature(const_maybe_uninit_uninit_array)] #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_assume_init)] #![feature(const_num_from_num)] @@ -167,7 +168,7 @@ #![feature(const_precise_live_drops)] #![feature(const_refs_to_cell)] #![feature(decl_macro)] -#![feature(derive_default_enum)] +#![cfg_attr(bootstrap, feature(derive_default_enum))] #![feature(deprecated_suggestion)] #![feature(doc_cfg)] #![feature(doc_notable_trait)] diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 58d682fc4c8..cac7f435573 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -350,13 +350,13 @@ impl<T> MaybeUninit<T> { /// let mut buf: [MaybeUninit<u8>; 32] = MaybeUninit::uninit_array(); /// let data = read(&mut buf); /// ``` - #[unstable(feature = "maybe_uninit_uninit_array", issue = "none")] - #[rustc_const_unstable(feature = "maybe_uninit_uninit_array", issue = "none")] + #[unstable(feature = "maybe_uninit_uninit_array", issue = "96097")] + #[rustc_const_unstable(feature = "const_maybe_uninit_uninit_array", issue = "96097")] #[must_use] #[inline(always)] - pub const fn uninit_array<const LEN: usize>() -> [Self; LEN] { + pub const fn uninit_array<const N: usize>() -> [Self; N] { // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid. - unsafe { MaybeUninit::<[MaybeUninit<T>; LEN]>::uninit().assume_init() } + unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() } } /// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being @@ -942,19 +942,24 @@ impl<T> MaybeUninit<T> { /// /// assert_eq!(array, [0, 1, 2]); /// ``` - #[unstable(feature = "maybe_uninit_array_assume_init", issue = "80908")] + #[unstable(feature = "maybe_uninit_array_assume_init", issue = "96097")] + #[rustc_const_unstable(feature = "const_maybe_uninit_array_assume_init", issue = "96097")] #[inline(always)] #[track_caller] - pub unsafe fn array_assume_init<const N: usize>(array: [Self; N]) -> [T; N] { + pub const unsafe fn array_assume_init<const N: usize>(array: [Self; N]) -> [T; N] { // SAFETY: // * The caller guarantees that all elements of the array are initialized // * `MaybeUninit<T>` and T are guaranteed to have the same layout // * `MaybeUninit` does not drop, so there are no double-frees // And thus the conversion is safe - unsafe { + let ret = unsafe { intrinsics::assert_inhabited::<[T; N]>(); (&array as *const _ as *const [T; N]).read() - } + }; + + // FIXME: required to avoid `~const Destruct` bound + super::forget(array); + ret } /// Assuming all the elements are initialized, get a slice to them. diff --git a/library/core/src/prelude/mod.rs b/library/core/src/prelude/mod.rs index ccd36a428e2..3cd3a3b780e 100644 --- a/library/core/src/prelude/mod.rs +++ b/library/core/src/prelude/mod.rs @@ -45,3 +45,13 @@ pub mod rust_2021 { #[doc(no_inline)] pub use crate::convert::{TryFrom, TryInto}; } + +/// The 2024 edition of the core prelude. +/// +/// See the [module-level documentation](self) for more. +#[unstable(feature = "prelude_2024", issue = "none")] +pub mod rust_2024 { + #[unstable(feature = "prelude_2024", issue = "none")] + #[doc(no_inline)] + pub use super::rust_2021::*; +} diff --git a/library/portable-simd/crates/core_simd/src/intrinsics.rs b/library/portable-simd/crates/core_simd/src/intrinsics.rs index 426c4de6ab1..82508c6882d 100644 --- a/library/portable-simd/crates/core_simd/src/intrinsics.rs +++ b/library/portable-simd/crates/core_simd/src/intrinsics.rs @@ -61,6 +61,10 @@ extern "platform-intrinsic" { /// xor pub(crate) fn simd_xor<T>(x: T, y: T) -> T; + /// getelementptr (without inbounds) + #[cfg(not(bootstrap))] + pub(crate) fn simd_arith_offset<T, U>(ptrs: T, offsets: U) -> T; + /// fptoui/fptosi/uitofp/sitofp /// casting floats to integers is truncating, so it is safe to convert values like e.g. 1.5 /// but the truncated value must fit in the target type or the result is poison. diff --git a/library/portable-simd/crates/core_simd/src/vector/ptr.rs b/library/portable-simd/crates/core_simd/src/vector/ptr.rs index 417d255c28d..68a9c67f795 100644 --- a/library/portable-simd/crates/core_simd/src/vector/ptr.rs +++ b/library/portable-simd/crates/core_simd/src/vector/ptr.rs @@ -1,5 +1,8 @@ //! Private implementation details of public gather/scatter APIs. +#[cfg(not(bootstrap))] +use crate::simd::intrinsics; use crate::simd::{LaneCount, Simd, SupportedLaneCount}; +#[cfg(bootstrap)] use core::mem; /// A vector of *const T. @@ -21,12 +24,16 @@ where #[inline] #[must_use] pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self { + #[cfg(bootstrap)] // Safety: converting pointers to usize and vice-versa is safe // (even if using that pointer is not) unsafe { let x: Simd<usize, LANES> = mem::transmute_copy(&self); mem::transmute_copy(&{ x + (addend * Simd::splat(mem::size_of::<T>())) }) } + #[cfg(not(bootstrap))] + // Safety: this intrinsic doesn't have a precondition + unsafe { intrinsics::simd_arith_offset(self, addend) } } } @@ -49,11 +56,15 @@ where #[inline] #[must_use] pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self { + #[cfg(bootstrap)] // Safety: converting pointers to usize and vice-versa is safe // (even if using that pointer is not) unsafe { let x: Simd<usize, LANES> = mem::transmute_copy(&self); mem::transmute_copy(&{ x + (addend * Simd::splat(mem::size_of::<T>())) }) } + #[cfg(not(bootstrap))] + // Safety: this intrinsic doesn't have a precondition + unsafe { intrinsics::simd_arith_offset(self, addend) } } } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index dd9b035e86d..f2d65832060 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -16,7 +16,7 @@ panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core" } libc = { version = "0.2.116", default-features = false, features = ['rustc-dep-of-std'] } -compiler_builtins = { version = "0.1.69" } +compiler_builtins = { version = "0.1.71" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } hashbrown = { version = "0.12", default-features = false, features = ['rustc-dep-of-std'] } diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 4fb94908c80..3f85c2095cb 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -26,6 +26,7 @@ use crate::borrow::Cow; use crate::cell; use crate::char; use crate::fmt::{self, Debug, Display, Write}; +use crate::io; use crate::mem::transmute; use crate::num; use crate::str; @@ -612,6 +613,48 @@ impl Error for alloc::collections::TryReserveError {} #[unstable(feature = "duration_checked_float", issue = "83400")] impl Error for time::FromFloatSecsError {} +#[stable(feature = "rust1", since = "1.0.0")] +impl Error for alloc::ffi::NulError { + #[allow(deprecated)] + fn description(&self) -> &str { + "nul byte found in data" + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl From<alloc::ffi::NulError> for io::Error { + /// Converts a [`alloc::ffi::NulError`] into a [`io::Error`]. + fn from(_: alloc::ffi::NulError) -> io::Error { + io::const_io_error!(io::ErrorKind::InvalidInput, "data provided contains a nul byte") + } +} + +#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")] +impl Error for core::ffi::FromBytesWithNulError { + #[allow(deprecated)] + fn description(&self) -> &str { + self.__description() + } +} + +#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")] +impl Error for core::ffi::FromBytesUntilNulError {} + +#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")] +impl Error for alloc::ffi::FromVecWithNulError {} + +#[stable(feature = "cstring_into", since = "1.7.0")] +impl Error for alloc::ffi::IntoStringError { + #[allow(deprecated)] + fn description(&self) -> &str { + "C string contained non-utf8 bytes" + } + + fn source(&self) -> Option<&(dyn Error + 'static)> { + Some(self.__source()) + } +} + // Copied from `any.rs`. impl dyn Error + 'static { /// Returns `true` if the inner type is the same as `T`. diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs index 13e3dacc30d..0141a2bccdf 100644 --- a/library/std/src/ffi/mod.rs +++ b/library/std/src/ffi/mod.rs @@ -146,12 +146,24 @@ #![stable(feature = "rust1", since = "1.0.0")] -#[stable(feature = "cstr_from_bytes", since = "1.10.0")] -pub use self::c_str::FromBytesWithNulError; +/// See [alloc::ffi::FromVecWithNulError]. #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")] -pub use self::c_str::FromVecWithNulError; +pub type FromVecWithNulError = alloc::ffi::FromVecWithNulError; +/// See [alloc::ffi::CString]. +#[stable(feature = "rust1", since = "1.0.0")] +pub type CString = alloc::ffi::CString; +/// See [alloc::ffi::IntoStringError]. +#[stable(feature = "rust1", since = "1.0.0")] +pub type IntoStringError = alloc::ffi::IntoStringError; +/// See [alloc::ffi::NulError]. #[stable(feature = "rust1", since = "1.0.0")] -pub use self::c_str::{CStr, CString, IntoStringError, NulError}; +pub type NulError = alloc::ffi::NulError; +/// See [core::ffi::CStr]. +#[stable(feature = "rust1", since = "1.0.0")] +pub type CStr = core::ffi::CStr; +/// See [core::ffi::FromBytesWithNulError]. +#[stable(feature = "cstr_from_bytes", since = "1.10.0")] +pub type FromBytesWithNulError = core::ffi::FromBytesWithNulError; #[stable(feature = "rust1", since = "1.0.0")] pub use self::os_str::{OsStr, OsString}; @@ -176,5 +188,4 @@ pub use core::ffi::{c_ptrdiff_t, c_size_t, c_ssize_t}; )] pub use core::ffi::{VaList, VaListImpl}; -mod c_str; mod os_str; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 60e7c2af8e4..da7753216d0 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -260,7 +260,10 @@ #![feature(atomic_mut_ptr)] #![feature(char_error_internals)] #![feature(char_internals)] +#![feature(core_c_str)] #![feature(core_intrinsics)] +#![feature(cstr_from_bytes_until_nul)] +#![feature(cstr_internals)] #![feature(duration_checked_float)] #![feature(duration_constants)] #![feature(exact_size_is_empty)] @@ -276,6 +279,7 @@ #![feature(panic_info_message)] #![feature(panic_internals)] #![feature(portable_simd)] +#![feature(prelude_2024)] #![feature(ptr_as_uninit)] #![feature(raw_os_nonzero)] #![feature(slice_internals)] @@ -286,6 +290,7 @@ // // Library features (alloc): #![feature(alloc_layout_extra)] +#![feature(alloc_c_string)] #![feature(allocator_api)] #![feature(get_mut_unchecked)] #![feature(map_try_insert)] diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs index d4bf6aeefee..c314bbbb68e 100644 --- a/library/std/src/prelude/mod.rs +++ b/library/std/src/prelude/mod.rs @@ -132,3 +132,17 @@ pub mod rust_2021 { #[doc(no_inline)] pub use core::prelude::rust_2021::*; } + +/// The 2024 version of the prelude of The Rust Standard Library. +/// +/// See the [module-level documentation](self) for more. +#[unstable(feature = "prelude_2024", issue = "none")] +pub mod rust_2024 { + #[unstable(feature = "prelude_2024", issue = "none")] + #[doc(no_inline)] + pub use super::v1::*; + + #[unstable(feature = "prelude_2024", issue = "none")] + #[doc(no_inline)] + pub use core::prelude::rust_2024::*; +} diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index 0226c4d7a25..f7533696df4 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -95,3 +95,7 @@ pub use crate::string::{String, ToString}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use crate::vec::Vec; + +#[cfg(bootstrap)] +#[unstable(feature = "cstr_internals", issue = "none")] +pub use alloc::ffi::CStrExt; diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs index 08eca423802..60b7a973cc2 100644 --- a/library/std/src/sys/hermit/mod.rs +++ b/library/std/src/sys/hermit/mod.rs @@ -71,16 +71,6 @@ pub fn unsupported_err() -> crate::io::Error { ) } -pub unsafe fn strlen(start: *const c_char) -> usize { - let mut str = start; - - while *str != 0 { - str = str.offset(1); - } - - (str as usize) - (start as usize) -} - #[no_mangle] pub extern "C" fn floor(x: f64) -> f64 { unsafe { intrinsics::floorf64(x) } diff --git a/library/std/src/sys/sgx/mod.rs b/library/std/src/sys/sgx/mod.rs index 1333edb9881..696400670e0 100644 --- a/library/std/src/sys/sgx/mod.rs +++ b/library/std/src/sys/sgx/mod.rs @@ -5,7 +5,6 @@ #![deny(unsafe_op_in_unsafe_fn)] use crate::io::ErrorKind; -use crate::os::raw::c_char; use crate::sync::atomic::{AtomicBool, Ordering}; pub mod abi; @@ -130,15 +129,6 @@ pub fn decode_error_kind(code: i32) -> ErrorKind { } } -pub unsafe fn strlen(mut s: *const c_char) -> usize { - let mut n = 0; - while unsafe { *s } != 0 { - n += 1; - s = unsafe { s.offset(1) }; - } - return n; -} - pub fn abort_internal() -> ! { abi::usercalls::exit(true) } diff --git a/library/std/src/sys/solid/mod.rs b/library/std/src/sys/solid/mod.rs index 492b1a55475..5ffa381f2e5 100644 --- a/library/std/src/sys/solid/mod.rs +++ b/library/std/src/sys/solid/mod.rs @@ -99,5 +99,3 @@ pub fn hashmap_random_keys() -> (u64, u64) { (x1, x2) } } - -pub use libc::strlen; diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs index b45d1c0149c..62760373a6a 100644 --- a/library/std/src/sys/unix/futex.rs +++ b/library/std/src/sys/unix/futex.rs @@ -4,7 +4,7 @@ all(target_os = "emscripten", target_feature = "atomics") ))] -use crate::sync::atomic::AtomicI32; +use crate::sync::atomic::AtomicU32; use crate::time::Duration; /// Wait for a futex_wake operation to wake us. @@ -13,7 +13,7 @@ use crate::time::Duration; /// /// Returns false on timeout, and true in all other cases. #[cfg(any(target_os = "linux", target_os = "android"))] -pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) -> bool { +pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool { use super::time::Timespec; use crate::ptr::null; use crate::sync::atomic::Ordering::Relaxed; @@ -35,7 +35,7 @@ pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) - let r = unsafe { libc::syscall( libc::SYS_futex, - futex as *const AtomicI32, + futex as *const AtomicU32, libc::FUTEX_WAIT_BITSET | libc::FUTEX_PRIVATE_FLAG, expected, timespec.as_ref().map_or(null(), |t| &t.t as *const libc::timespec), @@ -53,10 +53,10 @@ pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) - } #[cfg(target_os = "emscripten")] -pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) { +pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) { extern "C" { fn emscripten_futex_wait( - addr: *const AtomicI32, + addr: *const AtomicU32, val: libc::c_uint, max_wait_ms: libc::c_double, ) -> libc::c_int; @@ -64,10 +64,8 @@ pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) { unsafe { emscripten_futex_wait( - futex as *const AtomicI32, - // `val` is declared unsigned to match the Emscripten headers, but since it's used as - // an opaque value, we can ignore the meaning of signed vs. unsigned and cast here. - expected as libc::c_uint, + futex, + expected, timeout.map_or(crate::f64::INFINITY, |d| d.as_secs_f64() * 1000.0), ); } @@ -78,11 +76,11 @@ pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) { /// Returns true if this actually woke up such a thread, /// or false if no thread was waiting on this futex. #[cfg(any(target_os = "linux", target_os = "android"))] -pub fn futex_wake(futex: &AtomicI32) -> bool { +pub fn futex_wake(futex: &AtomicU32) -> bool { unsafe { libc::syscall( libc::SYS_futex, - futex as *const AtomicI32, + futex as *const AtomicU32, libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG, 1, ) > 0 @@ -91,11 +89,11 @@ pub fn futex_wake(futex: &AtomicI32) -> bool { /// Wake up all threads that are waiting on futex_wait on this futex. #[cfg(any(target_os = "linux", target_os = "android"))] -pub fn futex_wake_all(futex: &AtomicI32) { +pub fn futex_wake_all(futex: &AtomicU32) { unsafe { libc::syscall( libc::SYS_futex, - futex as *const AtomicI32, + futex as *const AtomicU32, libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG, i32::MAX, ); @@ -103,10 +101,10 @@ pub fn futex_wake_all(futex: &AtomicI32) { } #[cfg(target_os = "emscripten")] -pub fn futex_wake(futex: &AtomicI32) -> bool { +pub fn futex_wake(futex: &AtomicU32) -> bool { extern "C" { - fn emscripten_futex_wake(addr: *const AtomicI32, count: libc::c_int) -> libc::c_int; + fn emscripten_futex_wake(addr: *const AtomicU32, count: libc::c_int) -> libc::c_int; } - unsafe { emscripten_futex_wake(futex as *const AtomicI32, 1) > 0 } + unsafe { emscripten_futex_wake(futex, 1) > 0 } } diff --git a/library/std/src/sys/unix/locks/futex.rs b/library/std/src/sys/unix/locks/futex.rs index d97777e4da2..b166e7c453c 100644 --- a/library/std/src/sys/unix/locks/futex.rs +++ b/library/std/src/sys/unix/locks/futex.rs @@ -1,6 +1,6 @@ use crate::cell::UnsafeCell; use crate::sync::atomic::{ - AtomicI32, AtomicUsize, + AtomicU32, AtomicUsize, Ordering::{Acquire, Relaxed, Release}, }; use crate::sys::futex::{futex_wait, futex_wake, futex_wake_all}; @@ -13,13 +13,13 @@ pub struct Mutex { /// 0: unlocked /// 1: locked, no other threads waiting /// 2: locked, and other threads waiting (contended) - futex: AtomicI32, + futex: AtomicU32, } impl Mutex { #[inline] pub const fn new() -> Self { - Self { futex: AtomicI32::new(0) } + Self { futex: AtomicU32::new(0) } } #[inline] @@ -71,7 +71,7 @@ impl Mutex { } } - fn spin(&self) -> i32 { + fn spin(&self) -> u32 { let mut spin = 100; loop { // We only use `load` (and not `swap` or `compare_exchange`) @@ -110,13 +110,13 @@ pub struct Condvar { // The value of this atomic is simply incremented on every notification. // This is used by `.wait()` to not miss any notifications after // unlocking the mutex and before waiting for notifications. - futex: AtomicI32, + futex: AtomicU32, } impl Condvar { #[inline] pub const fn new() -> Self { - Self { futex: AtomicI32::new(0) } + Self { futex: AtomicU32::new(0) } } #[inline] diff --git a/library/std/src/sys/unix/locks/futex_rwlock.rs b/library/std/src/sys/unix/locks/futex_rwlock.rs index aa16da97e4c..e42edb25858 100644 --- a/library/std/src/sys/unix/locks/futex_rwlock.rs +++ b/library/std/src/sys/unix/locks/futex_rwlock.rs @@ -1,5 +1,5 @@ use crate::sync::atomic::{ - AtomicI32, + AtomicU32, Ordering::{Acquire, Relaxed, Release}, }; use crate::sys::futex::{futex_wait, futex_wake, futex_wake_all}; @@ -14,36 +14,36 @@ pub struct RwLock { // 0x3FFF_FFFF: Write locked // Bit 30: Readers are waiting on this futex. // Bit 31: Writers are waiting on the writer_notify futex. - state: AtomicI32, + state: AtomicU32, // The 'condition variable' to notify writers through. // Incremented on every signal. - writer_notify: AtomicI32, + writer_notify: AtomicU32, } -const READ_LOCKED: i32 = 1; -const MASK: i32 = (1 << 30) - 1; -const WRITE_LOCKED: i32 = MASK; -const MAX_READERS: i32 = MASK - 1; -const READERS_WAITING: i32 = 1 << 30; -const WRITERS_WAITING: i32 = 1 << 31; +const READ_LOCKED: u32 = 1; +const MASK: u32 = (1 << 30) - 1; +const WRITE_LOCKED: u32 = MASK; +const MAX_READERS: u32 = MASK - 1; +const READERS_WAITING: u32 = 1 << 30; +const WRITERS_WAITING: u32 = 1 << 31; -fn is_unlocked(state: i32) -> bool { +fn is_unlocked(state: u32) -> bool { state & MASK == 0 } -fn is_write_locked(state: i32) -> bool { +fn is_write_locked(state: u32) -> bool { state & MASK == WRITE_LOCKED } -fn has_readers_waiting(state: i32) -> bool { +fn has_readers_waiting(state: u32) -> bool { state & READERS_WAITING != 0 } -fn has_writers_waiting(state: i32) -> bool { +fn has_writers_waiting(state: u32) -> bool { state & WRITERS_WAITING != 0 } -fn is_read_lockable(state: i32) -> bool { +fn is_read_lockable(state: u32) -> bool { // This also returns false if the counter could overflow if we tried to read lock it. // // We don't allow read-locking if there's readers waiting, even if the lock is unlocked @@ -53,14 +53,14 @@ fn is_read_lockable(state: i32) -> bool { state & MASK < MAX_READERS && !has_readers_waiting(state) && !has_writers_waiting(state) } -fn has_reached_max_readers(state: i32) -> bool { +fn has_reached_max_readers(state: u32) -> bool { state & MASK == MAX_READERS } impl RwLock { #[inline] pub const fn new() -> Self { - Self { state: AtomicI32::new(0), writer_notify: AtomicI32::new(0) } + Self { state: AtomicU32::new(0), writer_notify: AtomicU32::new(0) } } #[inline] @@ -227,7 +227,7 @@ impl RwLock { /// If both are waiting, this will wake up only one writer, but will fall /// back to waking up readers if there was no writer to wake up. #[cold] - fn wake_writer_or_readers(&self, mut state: i32) { + fn wake_writer_or_readers(&self, mut state: u32) { assert!(is_unlocked(state)); // The readers waiting bit might be turned on at any point now, @@ -287,7 +287,7 @@ impl RwLock { } /// Spin for a while, but stop directly at the given condition. - fn spin_until(&self, f: impl Fn(i32) -> bool) -> i32 { + fn spin_until(&self, f: impl Fn(u32) -> bool) -> u32 { let mut spin = 100; // Chosen by fair dice roll. loop { let state = self.state.load(Relaxed); @@ -299,12 +299,12 @@ impl RwLock { } } - fn spin_write(&self) -> i32 { + fn spin_write(&self) -> u32 { // Stop spinning when it's unlocked or when there's waiting writers, to keep things somewhat fair. self.spin_until(|state| is_unlocked(state) || has_writers_waiting(state)) } - fn spin_read(&self) -> i32 { + fn spin_read(&self) -> u32 { // Stop spinning when it's unlocked or read locked, or when there's waiting threads. self.spin_until(|state| { !is_write_locked(state) || has_readers_waiting(state) || has_writers_waiting(state) diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index 3ad03a88681..aedeb02e656 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -3,7 +3,6 @@ use crate::io::ErrorKind; pub use self::rand::hashmap_random_keys; -pub use libc::strlen; #[cfg(not(target_os = "espidf"))] #[macro_use] diff --git a/library/std/src/sys/unsupported/common.rs b/library/std/src/sys/unsupported/common.rs index 5274f53a7db..4c9ade4a8c7 100644 --- a/library/std/src/sys/unsupported/common.rs +++ b/library/std/src/sys/unsupported/common.rs @@ -4,10 +4,6 @@ pub mod memchr { pub use core::slice::memchr::{memchr, memrchr}; } -// This is not necessarily correct. May want to consider making it part of the -// spec definition? -use crate::os::raw::c_char; - // SAFETY: must be called only once during runtime initialization. // NOTE: this is not guaranteed to run, for example when Rust code is called externally. pub unsafe fn init(_argc: isize, _argv: *const *const u8) {} @@ -38,15 +34,3 @@ pub fn abort_internal() -> ! { pub fn hashmap_random_keys() -> (u64, u64) { (1, 2) } - -pub unsafe fn strlen(mut s: *const c_char) -> usize { - // SAFETY: The caller must guarantee `s` points to a valid 0-terminated string. - unsafe { - let mut n = 0; - while *s != 0 { - n += 1; - s = s.offset(1); - } - n - } -} diff --git a/library/std/src/sys/wasm/atomics/futex.rs b/library/std/src/sys/wasm/atomics/futex.rs index 3d8bf42f725..bbe9bd6951a 100644 --- a/library/std/src/sys/wasm/atomics/futex.rs +++ b/library/std/src/sys/wasm/atomics/futex.rs @@ -1,17 +1,21 @@ use crate::arch::wasm32; use crate::convert::TryInto; -use crate::sync::atomic::AtomicI32; +use crate::sync::atomic::AtomicU32; use crate::time::Duration; -pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) { +pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) { let timeout = timeout.and_then(|t| t.as_nanos().try_into().ok()).unwrap_or(-1); unsafe { - wasm32::memory_atomic_wait32(futex as *const AtomicI32 as *mut i32, expected, timeout); + wasm32::memory_atomic_wait32( + futex as *const AtomicU32 as *mut i32, + expected as i32, + timeout, + ); } } -pub fn futex_wake(futex: &AtomicI32) { +pub fn futex_wake(futex: &AtomicU32) { unsafe { - wasm32::memory_atomic_notify(futex as *const AtomicI32 as *mut i32, 1); + wasm32::memory_atomic_notify(futex as *const AtomicU32 as *mut i32, 1); } } diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs index 47917e57b19..31c7208bbf1 100644 --- a/library/std/src/sys/windows/mod.rs +++ b/library/std/src/sys/windows/mod.rs @@ -7,7 +7,6 @@ use crate::path::PathBuf; use crate::time::Duration; pub use self::rand::hashmap_random_keys; -pub use libc::strlen; #[macro_use] pub mod compat; diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs index 09d1dd55989..013c776c476 100644 --- a/library/std/src/sys/windows/pipe.rs +++ b/library/std/src/sys/windows/pipe.rs @@ -165,6 +165,46 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res } } +/// Takes an asynchronous source pipe and returns a synchronous pipe suitable +/// for sending to a child process. +/// +/// This is achieved by creating a new set of pipes and spawning a thread that +/// relays messages between the source and the synchronous pipe. +pub fn spawn_pipe_relay( + source: &AnonPipe, + ours_readable: bool, + their_handle_inheritable: bool, +) -> io::Result<AnonPipe> { + // We need this handle to live for the lifetime of the thread spawned below. + let source = source.duplicate()?; + + // create a new pair of anon pipes. + let Pipes { theirs, ours } = anon_pipe(ours_readable, their_handle_inheritable)?; + + // Spawn a thread that passes messages from one pipe to the other. + // Any errors will simply cause the thread to exit. + let (reader, writer) = if ours_readable { (ours, source) } else { (source, ours) }; + crate::thread::spawn(move || { + let mut buf = [0_u8; 4096]; + 'reader: while let Ok(len) = reader.read(&mut buf) { + if len == 0 { + break; + } + let mut start = 0; + while let Ok(written) = writer.write(&buf[start..len]) { + start += written; + if start == len { + continue 'reader; + } + } + break; + } + }); + + // Return the pipe that should be sent to the child process. + Ok(theirs) +} + fn random_number() -> usize { static N: AtomicUsize = AtomicUsize::new(0); loop { @@ -192,6 +232,9 @@ impl AnonPipe { pub fn into_handle(self) -> Handle { self.inner } + fn duplicate(&self) -> io::Result<Self> { + self.inner.duplicate(0, false, c::DUPLICATE_SAME_ACCESS).map(|inner| AnonPipe { inner }) + } pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { let result = unsafe { diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index a13585a0222..a0c0f5dc3ec 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -172,6 +172,7 @@ pub enum Stdio { Inherit, Null, MakePipe, + Pipe(AnonPipe), Handle(Handle), } @@ -528,6 +529,11 @@ impl Stdio { Ok(pipes.theirs.into_handle()) } + Stdio::Pipe(ref source) => { + let ours_readable = stdio_id != c::STD_INPUT_HANDLE; + pipe::spawn_pipe_relay(source, ours_readable, true).map(AnonPipe::into_handle) + } + Stdio::Handle(ref handle) => handle.duplicate(0, true, c::DUPLICATE_SAME_ACCESS), // Open up a reference to NUL with appropriate read/write @@ -552,7 +558,7 @@ impl Stdio { impl From<AnonPipe> for Stdio { fn from(pipe: AnonPipe) -> Stdio { - Stdio::Handle(pipe.into_handle()) + Stdio::Pipe(pipe) } } diff --git a/library/std/src/sys_common/thread_parker/futex.rs b/library/std/src/sys_common/thread_parker/futex.rs index 0132743b244..fbf6231ff4a 100644 --- a/library/std/src/sys_common/thread_parker/futex.rs +++ b/library/std/src/sys_common/thread_parker/futex.rs @@ -1,14 +1,14 @@ -use crate::sync::atomic::AtomicI32; +use crate::sync::atomic::AtomicU32; use crate::sync::atomic::Ordering::{Acquire, Release}; use crate::sys::futex::{futex_wait, futex_wake}; use crate::time::Duration; -const PARKED: i32 = -1; -const EMPTY: i32 = 0; -const NOTIFIED: i32 = 1; +const PARKED: u32 = u32::MAX; +const EMPTY: u32 = 0; +const NOTIFIED: u32 = 1; pub struct Parker { - state: AtomicI32, + state: AtomicU32, } // Notes about memory ordering: @@ -34,7 +34,7 @@ pub struct Parker { impl Parker { #[inline] pub const fn new() -> Self { - Parker { state: AtomicI32::new(EMPTY) } + Parker { state: AtomicU32::new(EMPTY) } } // Assumes this is only called by the thread that owns the Parker, diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 077a86af50b..a2802f76008 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -441,7 +441,6 @@ impl Step for Std { t!(fs::create_dir_all(&out)); let compiler = builder.compiler(stage, builder.config.build); - builder.ensure(compile::Std { compiler, target }); let out_dir = builder.stage_out(compiler, Mode::Std).join(target.triple).join("doc"); t!(fs::copy(builder.src.join("src/doc/rust.css"), out.join("rust.css"))); @@ -548,7 +547,6 @@ impl Step for Rustc { fn run(self, builder: &Builder<'_>) { let stage = self.stage; let target = self.target; - builder.info(&format!("Documenting stage{} compiler ({})", stage, target)); let paths = builder .paths @@ -563,9 +561,12 @@ impl Step for Rustc { let out = builder.compiler_doc_out(target); t!(fs::create_dir_all(&out)); - // Build rustc. + // Build the standard library, so that proc-macros can use it. + // (Normally, only the metadata would be necessary, but proc-macros are special since they run at compile-time.) let compiler = builder.compiler(stage, builder.config.build); - builder.ensure(compile::Rustc { compiler, target }); + builder.ensure(compile::Std { compiler, target: builder.config.build }); + + builder.info(&format!("Documenting stage{} compiler ({})", stage, target)); // This uses a shared directory so that librustdoc documentation gets // correctly built and merged with the rustc documentation. This is @@ -642,7 +643,6 @@ macro_rules! tool_doc { ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?] $(,)?) => { #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct $tool { - stage: u32, target: TargetSelection, } @@ -657,7 +657,7 @@ macro_rules! tool_doc { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure($tool { stage: run.builder.top_stage, target: run.target }); + run.builder.ensure($tool { target: run.target }); } /// Generates compiler documentation. @@ -667,8 +667,21 @@ macro_rules! tool_doc { /// we do not merge it with the other documentation from std, test and /// proc_macros. This is largely just a wrapper around `cargo doc`. fn run(self, builder: &Builder<'_>) { - let stage = self.stage; + let stage = builder.top_stage; let target = self.target; + + // This is the intended out directory for compiler documentation. + let out = builder.compiler_doc_out(target); + t!(fs::create_dir_all(&out)); + + // Build rustc docs so that we generate relative links. + builder.ensure(Rustc { stage, target }); + // Rustdoc needs the rustc sysroot available to build. + // FIXME: is there a way to only ensure `check::Rustc` here? Last time I tried it failed + // with strange errors, but only on a full bors test ... + let compiler = builder.compiler(stage, builder.config.build); + builder.ensure(compile::Rustc { compiler, target }); + builder.info( &format!( "Documenting stage{} {} ({})", @@ -678,15 +691,6 @@ macro_rules! tool_doc { ), ); - // This is the intended out directory for compiler documentation. - let out = builder.compiler_doc_out(target); - t!(fs::create_dir_all(&out)); - - let compiler = builder.compiler(stage, builder.config.build); - - // Build rustc docs so that we generate relative links. - builder.ensure(Rustc { stage, target }); - // Symlink compiler docs to the output directory of rustdoc documentation. let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target.triple).join("doc"); t!(fs::create_dir_all(&out_dir)); diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 5622422d50f..173ee170c9f 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -99,7 +99,7 @@ x--expand-yaml-anchors--remove: run: git config --global core.autocrlf false - name: checkout the source code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 2 @@ -703,7 +703,7 @@ jobs: if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust' steps: - name: checkout the source code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 2 diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 2cf26603273..952d8ef48fe 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -15,12 +15,15 @@ - [Platform Support](platform-support.md) - [Template for target-specific documentation](platform-support/TEMPLATE.md) - [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md) + - [aarch64-unknown-none-hermitkernel](platform-support/aarch64-unknown-none-hermitkernel.md) - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) - [\*-kmc-solid_\*](platform-support/kmc-solid.md) + - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md) + - [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md) - [*-unknown-openbsd](platform-support/openbsd.md) - - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md) - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md) + - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md) - [Target Tier Policy](target-tier-policy.md) - [Targets](targets/index.md) - [Built-in Targets](targets/built-in.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index b3c4a52c414..12ac575210a 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -248,9 +248,9 @@ target | std | host | notes `i686-uwp-windows-gnu` | ? | | `i686-uwp-windows-msvc` | ? | | `i686-wrs-vxworks` | ? | | -`m68k-unknown-linux-gnu` | ? | | Motorola 680x0 Linux +[`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux `mips-unknown-linux-uclibc` | ✓ | | MIPS Linux with uClibc -`mips64-openwrt-linux-musl` | ? | | MIPS64 for OpenWrt Linux MUSL +[`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? | | MIPS64 for OpenWrt Linux MUSL `mipsel-sony-psp` | * | | MIPS (LE) Sony PlayStation Portable (PSP) `mipsel-unknown-linux-uclibc` | ✓ | | MIPS (LE) Linux with uClibc `mipsel-unknown-none` | * | | Bare MIPS (LE) softfloat diff --git a/src/doc/rustc/src/tests/index.md b/src/doc/rustc/src/tests/index.md index 0e0eb85db74..32baed9c944 100644 --- a/src/doc/rustc/src/tests/index.md +++ b/src/doc/rustc/src/tests/index.md @@ -15,7 +15,8 @@ fn it_works() { ``` Tests "pass" if they return without an error. They "fail" if they [panic], or -return a [`Result`] with an error. +return a type such as [`Result`] that implements the [`Termination`] trait +with a non-zero value. By passing the [`--test` option] to `rustc`, the compiler will build the crate in a special mode to construct an executable that will run the tests in the @@ -304,6 +305,7 @@ Experimental support for using custom test harnesses is available on the [`libtest`]: ../../test/index.html [`main` function]: ../../reference/crates-and-source-files.html#main-functions [`Result`]: ../../std/result/index.html +[`Termination`]: ../../std/process/trait.Termination.html [`test` cfg option]: ../../reference/conditional-compilation.html#test [attribute-ignore]: ../../reference/attributes/testing.html#the-ignore-attribute [attribute-should_panic]: ../../reference/attributes/testing.html#the-should_panic-attribute diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index 731e18b1eec..06c63ec97d7 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -119,11 +119,14 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { fn visit_mod(&mut self, m: &'tcx Mod<'tcx>, span: Span, id: HirId) { // To make the difference between "mod foo {}" and "mod foo;". In case we "import" another // file, we want to link to it. Otherwise no need to create a link. - if !span.overlaps(m.inner) { + if !span.overlaps(m.spans.inner_span) { // Now that we confirmed it's a file import, we want to get the span for the module // name only and not all the "mod foo;". if let Some(Node::Item(item)) = self.tcx.hir().find(id) { - self.matches.insert(item.ident.span, LinkFromSrc::Local(clean::Span::new(m.inner))); + self.matches.insert( + item.ident.span, + LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)), + ); } } intravisit::walk_mod(self, m, id); diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs index 00e10c6d5a7..a620ffa9878 100644 --- a/src/librustdoc/passes/html_tags.rs +++ b/src/librustdoc/passes/html_tags.rs @@ -215,7 +215,7 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> { // We don't try to detect stuff `<like, this>` because that's not valid HTML, // and we don't try to detect stuff `<like this>` because that's not valid Rust. if let Some(Some(generics_start)) = (is_open_tag - && dox[..range.end].ends_with(">")) + && dox[..range.end].ends_with('>')) .then(|| extract_path_backwards(&dox, range.start)) { let generics_sp = match super::source_span_for_markdown_range( diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index e793ee75fd2..75276d18fe5 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -154,7 +154,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { m: &'tcx hir::Mod<'tcx>, name: Symbol, ) -> Module<'tcx> { - let mut om = Module::new(name, id, m.inner); + let mut om = Module::new(name, id, m.spans.inner_span); let def_id = self.cx.tcx.hir().local_def_id(id).to_def_id(); // Keep track of if there were any private modules in the path. let orig_inside_public_path = self.inside_public_path; diff --git a/src/test/assembly/asm/global_asm.rs b/src/test/assembly/asm/global_asm.rs index 0358bc6d27c..b76ce7ac387 100644 --- a/src/test/assembly/asm/global_asm.rs +++ b/src/test/assembly/asm/global_asm.rs @@ -1,15 +1,26 @@ // only-x86_64 +// only-linux // assembly-output: emit-asm // compile-flags: -C llvm-args=--x86-asm-syntax=intel -#![feature(asm_const)] +#![feature(asm_const, asm_sym)] #![crate_type = "rlib"] use std::arch::global_asm; +#[no_mangle] +fn my_func() {} + +#[no_mangle] +static MY_STATIC: i32 = 0; + // CHECK: mov eax, eax global_asm!("mov eax, eax"); // CHECK: mov ebx, 5 global_asm!("mov ebx, {}", const 5); // CHECK: mov ecx, 5 global_asm!("movl ${}, %ecx", const 5, options(att_syntax)); +// CHECK: call my_func +global_asm!("call {}", sym my_func); +// CHECK: lea rax, [rip + MY_STATIC] +global_asm!("lea rax, [rip + {}]", sym MY_STATIC); diff --git a/src/test/codegen/simd_arith_offset.rs b/src/test/codegen/simd_arith_offset.rs new file mode 100644 index 00000000000..a858270d4e7 --- /dev/null +++ b/src/test/codegen/simd_arith_offset.rs @@ -0,0 +1,26 @@ +// compile-flags: -C no-prepopulate-passes +// only-64bit (because the LLVM type of i64 for usize shows up) +// + +#![crate_type = "lib"] +#![feature(repr_simd, platform_intrinsics)] + +extern "platform-intrinsic" { + pub(crate) fn simd_arith_offset<T, U>(ptrs: T, offsets: U) -> T; +} + +/// A vector of *const T. +#[derive(Debug, Copy, Clone)] +#[repr(simd)] +pub struct SimdConstPtr<T, const LANES: usize>([*const T; LANES]); + +#[derive(Debug, Copy, Clone)] +#[repr(simd)] +pub struct Simd<T, const LANES: usize>([T; LANES]); + +// CHECK-LABEL: smoke +#[no_mangle] +pub fn smoke(ptrs: SimdConstPtr<u8, 8>, offsets: Simd<usize, 8>) -> SimdConstPtr<u8, 8> { + // CHECK: getelementptr i8, <8 x i8*> %_3, <8 x i64> %_4 + unsafe { simd_arith_offset(ptrs, offsets) } +} diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile b/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile index d8ceace7fff..4cda243ffb5 100644 --- a/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile +++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile @@ -2,10 +2,25 @@ include ../tools.mk # ignore-stage1 +# This test both exists as a check that -Zcodegen-backend is capable of loading external codegen +# backends and that this external codegen backend is only included in the dep info if +# -Zbinary-dep-depinfo is used. + all: /bin/echo || exit 0 # This test requires /bin/echo to exist $(RUSTC) the_backend.rs --crate-name the_backend --crate-type dylib \ -o $(TMPDIR)/the_backend.dylib + + $(RUSTC) some_crate.rs --crate-name some_crate --crate-type lib -o $(TMPDIR)/some_crate \ + -Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options \ + --emit link,dep-info + grep -x "This has been \"compiled\" successfully." $(TMPDIR)/libsome_crate.rlib + # don't declare a dependency on the codegen backend if -Zbinary-dep-depinfo isn't used. + grep -v "the_backend.dylib" $(TMPDIR)/some_crate.d + $(RUSTC) some_crate.rs --crate-name some_crate --crate-type lib -o $(TMPDIR)/some_crate \ - -Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options - grep -x "This has been \"compiled\" successfully." $(TMPDIR)/some_crate + -Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options \ + --emit link,dep-info -Zbinary-dep-depinfo + grep -x "This has been \"compiled\" successfully." $(TMPDIR)/libsome_crate.rlib + # but declare a dependency on the codegen backend if -Zbinary-dep-depinfo it used. + grep "the_backend.dylib" $(TMPDIR)/some_crate.d diff --git a/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.rs b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.rs new file mode 100644 index 00000000000..c71e5bee12e --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.rs @@ -0,0 +1,6 @@ +// Regression test for issue #95879. + +use unresolved_crate::module::Name; //~ ERROR failed to resolve + +/// [Name] +pub struct S; diff --git a/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr new file mode 100644 index 00000000000..b60ab6050d7 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr @@ -0,0 +1,11 @@ +error[E0433]: failed to resolve: maybe a missing crate `unresolved_crate`? + --> $DIR/unresolved-import-recovery.rs:3:5 + | +LL | use unresolved_crate::module::Name; + | ^^^^^^^^^^^^^^^^ maybe a missing crate `unresolved_crate`? + +error: Compilation failed, aborting rustdoc + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/arg-count-mismatch.rs b/src/test/ui/arg-count-mismatch.rs deleted file mode 100644 index 18926f5daf7..00000000000 --- a/src/test/ui/arg-count-mismatch.rs +++ /dev/null @@ -1,5 +0,0 @@ -// error-pattern: arguments were supplied - -fn f(x: isize) { } - -fn main() { let i: (); i = f(); } diff --git a/src/test/ui/arg-count-mismatch.stderr b/src/test/ui/arg-count-mismatch.stderr deleted file mode 100644 index d0577e4864a..00000000000 --- a/src/test/ui/arg-count-mismatch.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0061]: this function takes 1 argument but 0 arguments were supplied - --> $DIR/arg-count-mismatch.rs:5:28 - | -LL | fn main() { let i: (); i = f(); } - | ^-- supplied 0 arguments - | | - | expected 1 argument - | -note: function defined here - --> $DIR/arg-count-mismatch.rs:3:4 - | -LL | fn f(x: isize) { } - | ^ -------- - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/arg-type-mismatch.rs b/src/test/ui/arg-type-mismatch.rs deleted file mode 100644 index 04ce2888785..00000000000 --- a/src/test/ui/arg-type-mismatch.rs +++ /dev/null @@ -1,5 +0,0 @@ -// error-pattern: mismatched types - -fn f(x: isize) { } - -fn main() { let i: (); i = f(()); } diff --git a/src/test/ui/arg-type-mismatch.stderr b/src/test/ui/arg-type-mismatch.stderr deleted file mode 100644 index 05b21efeece..00000000000 --- a/src/test/ui/arg-type-mismatch.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/arg-type-mismatch.rs:5:30 - | -LL | fn main() { let i: (); i = f(()); } - | ^^ expected `isize`, found `()` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/argument-suggestions/basic.rs b/src/test/ui/argument-suggestions/basic.rs new file mode 100644 index 00000000000..765b2d5d68e --- /dev/null +++ b/src/test/ui/argument-suggestions/basic.rs @@ -0,0 +1,25 @@ +// Some basic "obvious" cases for the heuristic error messages added for #65853 +// One for each of the detected cases + +enum E { X, Y } +enum F { X2, Y2 } +struct G {} +struct H {} +struct X {} +struct Y {} +struct Z {} + + +fn invalid(_i: u32) {} +fn extra() {} +fn missing(_i: u32) {} +fn swapped(_i: u32, _s: &str) {} +fn permuted(_x: X, _y: Y, _z: Z) {} + +fn main() { + invalid(1.0); //~ ERROR mismatched types + extra(""); //~ ERROR this function takes + missing(); //~ ERROR this function takes + swapped("", 1); //~ ERROR arguments to this function are incorrect + permuted(Y {}, Z {}, X {}); //~ ERROR arguments to this function are incorrect +} diff --git a/src/test/ui/argument-suggestions/basic.stderr b/src/test/ui/argument-suggestions/basic.stderr new file mode 100644 index 00000000000..78f82b07619 --- /dev/null +++ b/src/test/ui/argument-suggestions/basic.stderr @@ -0,0 +1,87 @@ +error[E0308]: mismatched types + --> $DIR/basic.rs:20:13 + | +LL | invalid(1.0); + | ------- ^^^ expected `u32`, found floating-point number + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/basic.rs:13:4 + | +LL | fn invalid(_i: u32) {} + | ^^^^^^^ ------- + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/basic.rs:21:5 + | +LL | extra(""); + | ^^^^^ -- argument unexpected + | +note: function defined here + --> $DIR/basic.rs:14:4 + | +LL | fn extra() {} + | ^^^^^ +help: remove the extra argument + | +LL | extra(); + | ~~~~~~~ + +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/basic.rs:22:5 + | +LL | missing(); + | ^^^^^^^-- an argument of type `u32` is missing + | +note: function defined here + --> $DIR/basic.rs:15:4 + | +LL | fn missing(_i: u32) {} + | ^^^^^^^ ------- +help: provide the argument + | +LL | missing({u32}); + | ~~~~~~~~~~~~~~ + +error[E0308]: arguments to this function are incorrect + --> $DIR/basic.rs:23:5 + | +LL | swapped("", 1); + | ^^^^^^^ -- - expected `&str`,found `{integer}` + | | + | expected `u32`,found `&'static str` + | +note: function defined here + --> $DIR/basic.rs:16:4 + | +LL | fn swapped(_i: u32, _s: &str) {} + | ^^^^^^^ ------- -------- +help: swap these arguments + | +LL | swapped(1, ""); + | ~~~~~~~~~~~~~~ + +error[E0308]: arguments to this function are incorrect + --> $DIR/basic.rs:24:5 + | +LL | permuted(Y {}, Z {}, X {}); + | ^^^^^^^^ ---- ---- ---- expected `Z`,found `X` + | | | + | | expected `Y`,found `Z` + | expected `X`,found `Y` + | +note: function defined here + --> $DIR/basic.rs:17:4 + | +LL | fn permuted(_x: X, _y: Y, _z: Z) {} + | ^^^^^^^^ ----- ----- ----- +help: reorder these arguments + | +LL | permuted(X {}, Y {}, Z {}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0061, E0308. +For more information about an error, try `rustc --explain E0061`. diff --git a/src/test/ui/argument-suggestions/complex.rs b/src/test/ui/argument-suggestions/complex.rs new file mode 100644 index 00000000000..384cdca7e4f --- /dev/null +++ b/src/test/ui/argument-suggestions/complex.rs @@ -0,0 +1,16 @@ +// A complex case with mixed suggestions from #65853 + +enum E { X, Y } +enum F { X2, Y2 } +struct G {} +struct H {} +struct X {} +struct Y {} +struct Z {} + +fn complex(_i: u32, _s: &str, _e: E, _f: F, _g: G, _x: X, _y: Y, _z: Z ) {} + +fn main() { + complex(1.0, H {}, &"", G{}, F::X2, Z {}, X {}, Y {}); + //~^ ERROR arguments to this function are incorrect +} diff --git a/src/test/ui/argument-suggestions/complex.stderr b/src/test/ui/argument-suggestions/complex.stderr new file mode 100644 index 00000000000..c628f7dff34 --- /dev/null +++ b/src/test/ui/argument-suggestions/complex.stderr @@ -0,0 +1,19 @@ +error[E0308]: arguments to this function are incorrect + --> $DIR/complex.rs:14:3 + | +LL | complex(1.0, H {}, &"", G{}, F::X2, Z {}, X {}, Y {}); + | ^^^^^^^ --- expected `u32`, found floating-point number + | +note: function defined here + --> $DIR/complex.rs:11:4 + | +LL | fn complex(_i: u32, _s: &str, _e: E, _f: F, _g: G, _x: X, _y: Y, _z: Z ) {} + | ^^^^^^^ ------- -------- ----- ----- ----- ----- ----- ------ +help: did you mean + | +LL | complex({u32}, &"", {E}, F::X2, G{}, X {}, Y {}, Z {}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/argument-suggestions/extra_arguments.rs b/src/test/ui/argument-suggestions/extra_arguments.rs new file mode 100644 index 00000000000..3706ac4e8e1 --- /dev/null +++ b/src/test/ui/argument-suggestions/extra_arguments.rs @@ -0,0 +1,35 @@ +fn empty() {} +fn one_arg(_a: i32) {} +fn two_arg_same(_a: i32, _b: i32) {} +fn two_arg_diff(_a: i32, _b: &str) {} + +fn main() { + empty(""); //~ ERROR this function takes + + one_arg(1, 1); //~ ERROR this function takes + one_arg(1, ""); //~ ERROR this function takes + one_arg(1, "", 1.0); //~ ERROR this function takes + + two_arg_same(1, 1, 1); //~ ERROR this function takes + two_arg_same(1, 1, 1.0); //~ ERROR this function takes + + two_arg_diff(1, 1, ""); //~ ERROR this function takes + two_arg_diff(1, "", ""); //~ ERROR this function takes + two_arg_diff(1, 1, "", ""); //~ ERROR this function takes + two_arg_diff(1, "", 1, ""); //~ ERROR this function takes + + // Check with weird spacing and newlines + two_arg_same(1, 1, ""); //~ ERROR this function takes + two_arg_diff(1, 1, ""); //~ ERROR this function takes + two_arg_same( //~ ERROR this function takes + 1, + 1, + "" + ); + + two_arg_diff( //~ ERROR this function takes + 1, + 1, + "" + ); +} diff --git a/src/test/ui/argument-suggestions/extra_arguments.stderr b/src/test/ui/argument-suggestions/extra_arguments.stderr new file mode 100644 index 00000000000..9b63f9bcbfa --- /dev/null +++ b/src/test/ui/argument-suggestions/extra_arguments.stderr @@ -0,0 +1,239 @@ +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/extra_arguments.rs:7:3 + | +LL | empty(""); + | ^^^^^ -- argument unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:1:4 + | +LL | fn empty() {} + | ^^^^^ +help: remove the extra argument + | +LL | empty(); + | ~~~~~~~ + +error[E0061]: this function takes 1 argument but 2 arguments were supplied + --> $DIR/extra_arguments.rs:9:3 + | +LL | one_arg(1, 1); + | ^^^^^^^ - argument unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:2:4 + | +LL | fn one_arg(_a: i32) {} + | ^^^^^^^ ------- +help: remove the extra argument + | +LL | one_arg(1); + | ~~~~~~~~~~ + +error[E0061]: this function takes 1 argument but 2 arguments were supplied + --> $DIR/extra_arguments.rs:10:3 + | +LL | one_arg(1, ""); + | ^^^^^^^ -- argument unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:2:4 + | +LL | fn one_arg(_a: i32) {} + | ^^^^^^^ ------- +help: remove the extra argument + | +LL | one_arg(1); + | ~~~~~~~~~~ + +error[E0061]: this function takes 1 argument but 3 arguments were supplied + --> $DIR/extra_arguments.rs:11:3 + | +LL | one_arg(1, "", 1.0); + | ^^^^^^^ -- --- argument unexpected + | | + | argument unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:2:4 + | +LL | fn one_arg(_a: i32) {} + | ^^^^^^^ ------- +help: remove the extra arguments + | +LL | one_arg(1); + | ~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/extra_arguments.rs:13:3 + | +LL | two_arg_same(1, 1, 1); + | ^^^^^^^^^^^^ - argument unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:3:4 + | +LL | fn two_arg_same(_a: i32, _b: i32) {} + | ^^^^^^^^^^^^ ------- ------- +help: remove the extra argument + | +LL | two_arg_same(1, 1); + | ~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/extra_arguments.rs:14:3 + | +LL | two_arg_same(1, 1, 1.0); + | ^^^^^^^^^^^^ --- argument unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:3:4 + | +LL | fn two_arg_same(_a: i32, _b: i32) {} + | ^^^^^^^^^^^^ ------- ------- +help: remove the extra argument + | +LL | two_arg_same(1, 1); + | ~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/extra_arguments.rs:16:3 + | +LL | two_arg_diff(1, 1, ""); + | ^^^^^^^^^^^^ - argument of type `&str` unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:4:4 + | +LL | fn two_arg_diff(_a: i32, _b: &str) {} + | ^^^^^^^^^^^^ ------- -------- +help: remove the extra argument + | +LL | two_arg_diff(1, ""); + | ~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/extra_arguments.rs:17:3 + | +LL | two_arg_diff(1, "", ""); + | ^^^^^^^^^^^^ -- argument unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:4:4 + | +LL | fn two_arg_diff(_a: i32, _b: &str) {} + | ^^^^^^^^^^^^ ------- -------- +help: remove the extra argument + | +LL | two_arg_diff(1, ""); + | ~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 4 arguments were supplied + --> $DIR/extra_arguments.rs:18:3 + | +LL | two_arg_diff(1, 1, "", ""); + | ^^^^^^^^^^^^ - -- argument unexpected + | | + | argument of type `&str` unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:4:4 + | +LL | fn two_arg_diff(_a: i32, _b: &str) {} + | ^^^^^^^^^^^^ ------- -------- +help: remove the extra arguments + | +LL | two_arg_diff(1, ""); + | ~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 4 arguments were supplied + --> $DIR/extra_arguments.rs:19:3 + | +LL | two_arg_diff(1, "", 1, ""); + | ^^^^^^^^^^^^ - -- argument unexpected + | | + | argument unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:4:4 + | +LL | fn two_arg_diff(_a: i32, _b: &str) {} + | ^^^^^^^^^^^^ ------- -------- +help: remove the extra arguments + | +LL | two_arg_diff(1, ""); + | ~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/extra_arguments.rs:22:3 + | +LL | two_arg_same(1, 1, ""); + | ^^^^^^^^^^^^ -- argument unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:3:4 + | +LL | fn two_arg_same(_a: i32, _b: i32) {} + | ^^^^^^^^^^^^ ------- ------- +help: remove the extra argument + | +LL | two_arg_same(1, 1); + | ~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/extra_arguments.rs:23:3 + | +LL | two_arg_diff(1, 1, ""); + | ^^^^^^^^^^^^ - argument of type `&str` unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:4:4 + | +LL | fn two_arg_diff(_a: i32, _b: &str) {} + | ^^^^^^^^^^^^ ------- -------- +help: remove the extra argument + | +LL | two_arg_diff(1, ""); + | ~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/extra_arguments.rs:24:3 + | +LL | two_arg_same( + | ^^^^^^^^^^^^ +... +LL | "" + | -- argument unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:3:4 + | +LL | fn two_arg_same(_a: i32, _b: i32) {} + | ^^^^^^^^^^^^ ------- ------- +help: remove the extra argument + | +LL | two_arg_same(1, 1); + | ~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/extra_arguments.rs:30:3 + | +LL | two_arg_diff( + | ^^^^^^^^^^^^ +LL | 1, +LL | 1, + | - argument of type `&str` unexpected + | +note: function defined here + --> $DIR/extra_arguments.rs:4:4 + | +LL | fn two_arg_diff(_a: i32, _b: &str) {} + | ^^^^^^^^^^^^ ------- -------- +help: remove the extra argument + | +LL | two_arg_diff(1, ""); + | ~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 14 previous errors + +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/argument-suggestions/invalid_arguments.rs b/src/test/ui/argument-suggestions/invalid_arguments.rs new file mode 100644 index 00000000000..53fbdd4b5da --- /dev/null +++ b/src/test/ui/argument-suggestions/invalid_arguments.rs @@ -0,0 +1,43 @@ +// More nuanced test cases for invalid arguments #65853 + +struct X {} + +fn one_arg(_a: i32) {} +fn two_arg_same(_a: i32, _b: i32) {} +fn two_arg_diff(_a: i32, _b: f32) {} +fn three_arg_diff(_a: i32, _b: f32, _c: &str) {} +fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {} + +fn main() { + // Providing an incorrect argument for a single parameter function + one_arg(1.0); //~ ERROR mismatched types + + // Providing one or two invalid arguments to a two parameter function + two_arg_same(1, ""); //~ ERROR mismatched types + two_arg_same("", 1); //~ ERROR mismatched types + two_arg_same("", ""); //~ ERROR arguments to this function are incorrect + two_arg_diff(1, ""); //~ ERROR mismatched types + two_arg_diff("", 1.0); //~ ERROR mismatched types + two_arg_diff("", ""); //~ ERROR arguments to this function are incorrect + + // Providing invalid arguments to a three parameter function + three_arg_diff(X{}, 1.0, ""); //~ ERROR mismatched types + three_arg_diff(1, X {}, ""); //~ ERROR mismatched types + three_arg_diff(1, 1.0, X {}); //~ ERROR mismatched types + + three_arg_diff(X {}, X {}, ""); //~ ERROR arguments to this function are incorrect + three_arg_diff(X {}, 1.0, X {}); //~ ERROR arguments to this function are incorrect + three_arg_diff(1, X {}, X {}); //~ ERROR arguments to this function are incorrect + + three_arg_diff(X {}, X {}, X {}); //~ ERROR arguments to this function are incorrect + + three_arg_repeat(X {}, 1, ""); //~ ERROR mismatched types + three_arg_repeat(1, X {}, ""); //~ ERROR mismatched types + three_arg_repeat(1, 1, X {}); //~ ERROR mismatched types + + three_arg_repeat(X {}, X {}, ""); //~ ERROR arguments to this function are incorrect + three_arg_repeat(X {}, 1, X {}); //~ ERROR arguments to this function are incorrect + three_arg_repeat(1, X {}, X{}); //~ ERROR arguments to this function are incorrect + + three_arg_repeat(X {}, X {}, X {}); //~ ERROR arguments to this function are incorrect +} diff --git a/src/test/ui/argument-suggestions/invalid_arguments.stderr b/src/test/ui/argument-suggestions/invalid_arguments.stderr new file mode 100644 index 00000000000..33f27d48fec --- /dev/null +++ b/src/test/ui/argument-suggestions/invalid_arguments.stderr @@ -0,0 +1,299 @@ +error[E0308]: mismatched types + --> $DIR/invalid_arguments.rs:13:11 + | +LL | one_arg(1.0); + | ------- ^^^ expected `i32`, found floating-point number + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/invalid_arguments.rs:5:4 + | +LL | fn one_arg(_a: i32) {} + | ^^^^^^^ ------- + +error[E0308]: mismatched types + --> $DIR/invalid_arguments.rs:16:19 + | +LL | two_arg_same(1, ""); + | ------------ ^^ expected `i32`, found `&str` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/invalid_arguments.rs:6:4 + | +LL | fn two_arg_same(_a: i32, _b: i32) {} + | ^^^^^^^^^^^^ ------- ------- + +error[E0308]: mismatched types + --> $DIR/invalid_arguments.rs:17:16 + | +LL | two_arg_same("", 1); + | ------------ ^^ expected `i32`, found `&str` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/invalid_arguments.rs:6:4 + | +LL | fn two_arg_same(_a: i32, _b: i32) {} + | ^^^^^^^^^^^^ ------- ------- + +error[E0308]: arguments to this function are incorrect + --> $DIR/invalid_arguments.rs:18:3 + | +LL | two_arg_same("", ""); + | ^^^^^^^^^^^^ -- -- expected `i32`, found `&str` + | | + | expected `i32`, found `&str` + | +note: function defined here + --> $DIR/invalid_arguments.rs:6:4 + | +LL | fn two_arg_same(_a: i32, _b: i32) {} + | ^^^^^^^^^^^^ ------- ------- + +error[E0308]: mismatched types + --> $DIR/invalid_arguments.rs:19:19 + | +LL | two_arg_diff(1, ""); + | ------------ ^^ expected `f32`, found `&str` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/invalid_arguments.rs:7:4 + | +LL | fn two_arg_diff(_a: i32, _b: f32) {} + | ^^^^^^^^^^^^ ------- ------- + +error[E0308]: mismatched types + --> $DIR/invalid_arguments.rs:20:16 + | +LL | two_arg_diff("", 1.0); + | ------------ ^^ expected `i32`, found `&str` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/invalid_arguments.rs:7:4 + | +LL | fn two_arg_diff(_a: i32, _b: f32) {} + | ^^^^^^^^^^^^ ------- ------- + +error[E0308]: arguments to this function are incorrect + --> $DIR/invalid_arguments.rs:21:3 + | +LL | two_arg_diff("", ""); + | ^^^^^^^^^^^^ -- -- expected `f32`, found `&str` + | | + | expected `i32`, found `&str` + | +note: function defined here + --> $DIR/invalid_arguments.rs:7:4 + | +LL | fn two_arg_diff(_a: i32, _b: f32) {} + | ^^^^^^^^^^^^ ------- ------- + +error[E0308]: mismatched types + --> $DIR/invalid_arguments.rs:24:18 + | +LL | three_arg_diff(X{}, 1.0, ""); + | -------------- ^^^ expected `i32`, found struct `X` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/invalid_arguments.rs:8:4 + | +LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^^^^^ ------- ------- -------- + +error[E0308]: mismatched types + --> $DIR/invalid_arguments.rs:25:21 + | +LL | three_arg_diff(1, X {}, ""); + | -------------- ^^^^ expected `f32`, found struct `X` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/invalid_arguments.rs:8:4 + | +LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^^^^^ ------- ------- -------- + +error[E0308]: mismatched types + --> $DIR/invalid_arguments.rs:26:26 + | +LL | three_arg_diff(1, 1.0, X {}); + | -------------- ^^^^ expected `&str`, found struct `X` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/invalid_arguments.rs:8:4 + | +LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^^^^^ ------- ------- -------- + +error[E0308]: arguments to this function are incorrect + --> $DIR/invalid_arguments.rs:28:3 + | +LL | three_arg_diff(X {}, X {}, ""); + | ^^^^^^^^^^^^^^ ---- ---- expected `f32`, found struct `X` + | | + | expected `i32`, found struct `X` + | +note: function defined here + --> $DIR/invalid_arguments.rs:8:4 + | +LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^^^^^ ------- ------- -------- + +error[E0308]: arguments to this function are incorrect + --> $DIR/invalid_arguments.rs:29:3 + | +LL | three_arg_diff(X {}, 1.0, X {}); + | ^^^^^^^^^^^^^^ ---- ---- expected `&str`, found struct `X` + | | + | expected `i32`, found struct `X` + | +note: function defined here + --> $DIR/invalid_arguments.rs:8:4 + | +LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^^^^^ ------- ------- -------- + +error[E0308]: arguments to this function are incorrect + --> $DIR/invalid_arguments.rs:30:3 + | +LL | three_arg_diff(1, X {}, X {}); + | ^^^^^^^^^^^^^^ ---- ---- expected `&str`, found struct `X` + | | + | expected `f32`, found struct `X` + | +note: function defined here + --> $DIR/invalid_arguments.rs:8:4 + | +LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^^^^^ ------- ------- -------- + +error[E0308]: arguments to this function are incorrect + --> $DIR/invalid_arguments.rs:32:3 + | +LL | three_arg_diff(X {}, X {}, X {}); + | ^^^^^^^^^^^^^^ ---- ---- ---- expected `&str`, found struct `X` + | | | + | | expected `f32`, found struct `X` + | expected `i32`, found struct `X` + | +note: function defined here + --> $DIR/invalid_arguments.rs:8:4 + | +LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^^^^^ ------- ------- -------- + +error[E0308]: mismatched types + --> $DIR/invalid_arguments.rs:34:20 + | +LL | three_arg_repeat(X {}, 1, ""); + | ---------------- ^^^^ expected `i32`, found struct `X` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/invalid_arguments.rs:9:4 + | +LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {} + | ^^^^^^^^^^^^^^^^ ------- ------- -------- + +error[E0308]: mismatched types + --> $DIR/invalid_arguments.rs:35:23 + | +LL | three_arg_repeat(1, X {}, ""); + | ---------------- ^^^^ expected `i32`, found struct `X` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/invalid_arguments.rs:9:4 + | +LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {} + | ^^^^^^^^^^^^^^^^ ------- ------- -------- + +error[E0308]: mismatched types + --> $DIR/invalid_arguments.rs:36:26 + | +LL | three_arg_repeat(1, 1, X {}); + | ---------------- ^^^^ expected `&str`, found struct `X` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/invalid_arguments.rs:9:4 + | +LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {} + | ^^^^^^^^^^^^^^^^ ------- ------- -------- + +error[E0308]: arguments to this function are incorrect + --> $DIR/invalid_arguments.rs:38:3 + | +LL | three_arg_repeat(X {}, X {}, ""); + | ^^^^^^^^^^^^^^^^ ---- ---- expected `i32`, found struct `X` + | | + | expected `i32`, found struct `X` + | +note: function defined here + --> $DIR/invalid_arguments.rs:9:4 + | +LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {} + | ^^^^^^^^^^^^^^^^ ------- ------- -------- + +error[E0308]: arguments to this function are incorrect + --> $DIR/invalid_arguments.rs:39:3 + | +LL | three_arg_repeat(X {}, 1, X {}); + | ^^^^^^^^^^^^^^^^ ---- ---- expected `&str`, found struct `X` + | | + | expected `i32`, found struct `X` + | +note: function defined here + --> $DIR/invalid_arguments.rs:9:4 + | +LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {} + | ^^^^^^^^^^^^^^^^ ------- ------- -------- + +error[E0308]: arguments to this function are incorrect + --> $DIR/invalid_arguments.rs:40:3 + | +LL | three_arg_repeat(1, X {}, X{}); + | ^^^^^^^^^^^^^^^^ ---- --- expected `&str`, found struct `X` + | | + | expected `i32`, found struct `X` + | +note: function defined here + --> $DIR/invalid_arguments.rs:9:4 + | +LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {} + | ^^^^^^^^^^^^^^^^ ------- ------- -------- + +error[E0308]: arguments to this function are incorrect + --> $DIR/invalid_arguments.rs:42:3 + | +LL | three_arg_repeat(X {}, X {}, X {}); + | ^^^^^^^^^^^^^^^^ ---- ---- ---- expected `&str`, found struct `X` + | | | + | | expected `i32`, found struct `X` + | expected `i32`, found struct `X` + | +note: function defined here + --> $DIR/invalid_arguments.rs:9:4 + | +LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {} + | ^^^^^^^^^^^^^^^^ ------- ------- -------- + +error: aborting due to 21 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/argument-suggestions/missing_arguments.rs b/src/test/ui/argument-suggestions/missing_arguments.rs new file mode 100644 index 00000000000..ae0dabf27b1 --- /dev/null +++ b/src/test/ui/argument-suggestions/missing_arguments.rs @@ -0,0 +1,40 @@ +fn one_arg(_a: i32) {} +fn two_same(_a: i32, _b: i32) {} +fn two_diff(_a: i32, _b: f32) {} +fn three_same(_a: i32, _b: i32, _c: i32) {} +fn three_diff(_a: i32, _b: f32, _c: &str) {} +fn four_repeated(_a: i32, _b: f32, _c: f32, _d: &str) {} +fn complex(_a: i32, _b: f32, _c: i32, _d: f32, _e: &str) {} + +fn main() { + one_arg(); //~ ERROR this function takes + // The headers here show the types expected, + // with formatting to emphasize which arguments are missing + /* i32 f32 */ + two_same( ); //~ ERROR this function takes + two_same( 1 ); //~ ERROR this function takes + two_diff( ); //~ ERROR this function takes + two_diff( 1 ); //~ ERROR this function takes + two_diff( 1.0 ); //~ ERROR this function takes + + /* i32 i32 i32 */ + three_same( ); //~ ERROR this function takes + three_same( 1 ); //~ ERROR this function takes + three_same( 1, 1 ); //~ ERROR this function takes + + /* i32 f32 &str */ + three_diff( 1.0, "" ); //~ ERROR this function takes + three_diff( 1, "" ); //~ ERROR this function takes + three_diff( 1, 1.0 ); //~ ERROR this function takes + three_diff( "" ); //~ ERROR this function takes + three_diff( 1.0 ); //~ ERROR this function takes + three_diff( 1 ); //~ ERROR this function takes + + /* i32 f32 f32 &str */ + four_repeated( ); //~ ERROR this function takes + four_repeated( 1, "" ); //~ ERROR this function takes + + /* i32 f32 i32 f32 &str */ + complex( ); //~ ERROR this function takes + complex( 1, "" ); //~ ERROR this function takes +} diff --git a/src/test/ui/argument-suggestions/missing_arguments.stderr b/src/test/ui/argument-suggestions/missing_arguments.stderr new file mode 100644 index 00000000000..b4dadb1b9da --- /dev/null +++ b/src/test/ui/argument-suggestions/missing_arguments.stderr @@ -0,0 +1,310 @@ +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/missing_arguments.rs:10:3 + | +LL | one_arg(); + | ^^^^^^^-- an argument of type `i32` is missing + | +note: function defined here + --> $DIR/missing_arguments.rs:1:4 + | +LL | fn one_arg(_a: i32) {} + | ^^^^^^^ ------- +help: provide the argument + | +LL | one_arg({i32}); + | ~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 0 arguments were supplied + --> $DIR/missing_arguments.rs:14:3 + | +LL | two_same( ); + | ^^^^^^^^----------------- two arguments of type `i32` and `i32` are missing + | +note: function defined here + --> $DIR/missing_arguments.rs:2:4 + | +LL | fn two_same(_a: i32, _b: i32) {} + | ^^^^^^^^ ------- ------- +help: provide the arguments + | +LL | two_same({i32}, {i32}); + | ~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 1 argument was supplied + --> $DIR/missing_arguments.rs:15:3 + | +LL | two_same( 1 ); + | ^^^^^^^^----------------- an argument of type `i32` is missing + | +note: function defined here + --> $DIR/missing_arguments.rs:2:4 + | +LL | fn two_same(_a: i32, _b: i32) {} + | ^^^^^^^^ ------- ------- +help: provide the argument + | +LL | two_same(1, {i32}); + | ~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 0 arguments were supplied + --> $DIR/missing_arguments.rs:16:3 + | +LL | two_diff( ); + | ^^^^^^^^----------------- two arguments of type `i32` and `f32` are missing + | +note: function defined here + --> $DIR/missing_arguments.rs:3:4 + | +LL | fn two_diff(_a: i32, _b: f32) {} + | ^^^^^^^^ ------- ------- +help: provide the arguments + | +LL | two_diff({i32}, {f32}); + | ~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 1 argument was supplied + --> $DIR/missing_arguments.rs:17:3 + | +LL | two_diff( 1 ); + | ^^^^^^^^----------------- an argument of type `f32` is missing + | +note: function defined here + --> $DIR/missing_arguments.rs:3:4 + | +LL | fn two_diff(_a: i32, _b: f32) {} + | ^^^^^^^^ ------- ------- +help: provide the argument + | +LL | two_diff(1, {f32}); + | ~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 2 arguments but 1 argument was supplied + --> $DIR/missing_arguments.rs:18:3 + | +LL | two_diff( 1.0 ); + | ^^^^^^^^ --- an argument of type `i32` is missing + | +note: function defined here + --> $DIR/missing_arguments.rs:3:4 + | +LL | fn two_diff(_a: i32, _b: f32) {} + | ^^^^^^^^ ------- ------- +help: provide the argument + | +LL | two_diff({i32}, 1.0); + | ~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 3 arguments but 0 arguments were supplied + --> $DIR/missing_arguments.rs:21:3 + | +LL | three_same( ); + | ^^^^^^^^^^------------------------- three arguments of type `i32`, `i32`, and `i32` are missing + | +note: function defined here + --> $DIR/missing_arguments.rs:4:4 + | +LL | fn three_same(_a: i32, _b: i32, _c: i32) {} + | ^^^^^^^^^^ ------- ------- ------- +help: provide the arguments + | +LL | three_same({i32}, {i32}, {i32}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 3 arguments but 1 argument was supplied + --> $DIR/missing_arguments.rs:22:3 + | +LL | three_same( 1 ); + | ^^^^^^^^^^------------------------- two arguments of type `i32` and `i32` are missing + | +note: function defined here + --> $DIR/missing_arguments.rs:4:4 + | +LL | fn three_same(_a: i32, _b: i32, _c: i32) {} + | ^^^^^^^^^^ ------- ------- ------- +help: provide the arguments + | +LL | three_same(1, {i32}, {i32}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 3 arguments but 2 arguments were supplied + --> $DIR/missing_arguments.rs:23:3 + | +LL | three_same( 1, 1 ); + | ^^^^^^^^^^------------------------- an argument of type `i32` is missing + | +note: function defined here + --> $DIR/missing_arguments.rs:4:4 + | +LL | fn three_same(_a: i32, _b: i32, _c: i32) {} + | ^^^^^^^^^^ ------- ------- ------- +help: provide the argument + | +LL | three_same(1, 1, {i32}); + | ~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 3 arguments but 2 arguments were supplied + --> $DIR/missing_arguments.rs:26:3 + | +LL | three_diff( 1.0, "" ); + | ^^^^^^^^^^ --- an argument of type `i32` is missing + | +note: function defined here + --> $DIR/missing_arguments.rs:5:4 + | +LL | fn three_diff(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: provide the argument + | +LL | three_diff({i32}, 1.0, ""); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 3 arguments but 2 arguments were supplied + --> $DIR/missing_arguments.rs:27:3 + | +LL | three_diff( 1, "" ); + | ^^^^^^^^^^ -- an argument of type `f32` is missing + | +note: function defined here + --> $DIR/missing_arguments.rs:5:4 + | +LL | fn three_diff(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: provide the argument + | +LL | three_diff(1, {f32}, ""); + | ~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 3 arguments but 2 arguments were supplied + --> $DIR/missing_arguments.rs:28:3 + | +LL | three_diff( 1, 1.0 ); + | ^^^^^^^^^^------------------------- an argument of type `&str` is missing + | +note: function defined here + --> $DIR/missing_arguments.rs:5:4 + | +LL | fn three_diff(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: provide the argument + | +LL | three_diff(1, 1.0, {&str}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 3 arguments but 1 argument was supplied + --> $DIR/missing_arguments.rs:29:3 + | +LL | three_diff( "" ); + | ^^^^^^^^^^------------------------- two arguments of type `i32` and `f32` are missing + | +note: function defined here + --> $DIR/missing_arguments.rs:5:4 + | +LL | fn three_diff(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: provide the arguments + | +LL | three_diff({i32}, {f32}, ""); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 3 arguments but 1 argument was supplied + --> $DIR/missing_arguments.rs:30:3 + | +LL | three_diff( 1.0 ); + | ^^^^^^^^^^------------------------- + | | | + | | an argument of type `i32` is missing + | an argument of type `&str` is missing + | +note: function defined here + --> $DIR/missing_arguments.rs:5:4 + | +LL | fn three_diff(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: provide the arguments + | +LL | three_diff({i32}, 1.0, {&str}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 3 arguments but 1 argument was supplied + --> $DIR/missing_arguments.rs:31:3 + | +LL | three_diff( 1 ); + | ^^^^^^^^^^------------------------- two arguments of type `f32` and `&str` are missing + | +note: function defined here + --> $DIR/missing_arguments.rs:5:4 + | +LL | fn three_diff(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: provide the arguments + | +LL | three_diff(1, {f32}, {&str}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 4 arguments but 0 arguments were supplied + --> $DIR/missing_arguments.rs:34:3 + | +LL | four_repeated( ); + | ^^^^^^^^^^^^^--------------------------------- multiple arguments are missing + | +note: function defined here + --> $DIR/missing_arguments.rs:6:4 + | +LL | fn four_repeated(_a: i32, _b: f32, _c: f32, _d: &str) {} + | ^^^^^^^^^^^^^ ------- ------- ------- -------- +help: provide the arguments + | +LL | four_repeated({i32}, {f32}, {f32}, {&str}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 4 arguments but 2 arguments were supplied + --> $DIR/missing_arguments.rs:35:3 + | +LL | four_repeated( 1, "" ); + | ^^^^^^^^^^^^^--------------------------------- two arguments of type `f32` and `f32` are missing + | +note: function defined here + --> $DIR/missing_arguments.rs:6:4 + | +LL | fn four_repeated(_a: i32, _b: f32, _c: f32, _d: &str) {} + | ^^^^^^^^^^^^^ ------- ------- ------- -------- +help: provide the arguments + | +LL | four_repeated(1, {f32}, {f32}, ""); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 5 arguments but 0 arguments were supplied + --> $DIR/missing_arguments.rs:38:3 + | +LL | complex( ); + | ^^^^^^^--------------------------------- multiple arguments are missing + | +note: function defined here + --> $DIR/missing_arguments.rs:7:4 + | +LL | fn complex(_a: i32, _b: f32, _c: i32, _d: f32, _e: &str) {} + | ^^^^^^^ ------- ------- ------- ------- -------- +help: provide the arguments + | +LL | complex({i32}, {f32}, {i32}, {f32}, {&str}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 5 arguments but 2 arguments were supplied + --> $DIR/missing_arguments.rs:39:3 + | +LL | complex( 1, "" ); + | ^^^^^^^--------------------------------- three arguments of type `f32`, `i32`, and `i32` are missing + | +note: function defined here + --> $DIR/missing_arguments.rs:7:4 + | +LL | fn complex(_a: i32, _b: f32, _c: i32, _d: f32, _e: &str) {} + | ^^^^^^^ ------- ------- ------- ------- -------- +help: provide the arguments + | +LL | complex(1, {f32}, {i32}, {f32}, ""); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 19 previous errors + +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/argument-suggestions/mixed_cases.rs b/src/test/ui/argument-suggestions/mixed_cases.rs new file mode 100644 index 00000000000..73678482b30 --- /dev/null +++ b/src/test/ui/argument-suggestions/mixed_cases.rs @@ -0,0 +1,24 @@ +// Cases where multiple argument suggestions are mixed + +struct X {} + +fn two_args(_a: i32, _b: f32) {} +fn three_args(_a: i32, _b: f32, _c: &str) {} + +fn main() { + // Extra + Invalid + two_args(1, "", X {}); //~ ERROR this function takes + three_args(1, "", X {}, ""); //~ ERROR this function takes + + // Missing and Invalid + three_args(1, X {}); //~ ERROR this function takes + + // Missing and Extra + three_args(1, "", X {}); //~ ERROR arguments to this function are incorrect + + // Swapped and Invalid + three_args("", X {}, 1); //~ ERROR arguments to this function are incorrect + + // Swapped and missing + three_args("", 1); //~ ERROR this function takes +} diff --git a/src/test/ui/argument-suggestions/mixed_cases.stderr b/src/test/ui/argument-suggestions/mixed_cases.stderr new file mode 100644 index 00000000000..61da02f5837 --- /dev/null +++ b/src/test/ui/argument-suggestions/mixed_cases.stderr @@ -0,0 +1,117 @@ +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/mixed_cases.rs:10:3 + | +LL | two_args(1, "", X {}); + | ^^^^^^^^ -- ---- argument unexpected + | | + | expected `f32`, found `&str` + | +note: function defined here + --> $DIR/mixed_cases.rs:5:4 + | +LL | fn two_args(_a: i32, _b: f32) {} + | ^^^^^^^^ ------- ------- +help: remove the extra argument + | +LL | two_args(1, {f32}); + | ~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 3 arguments but 4 arguments were supplied + --> $DIR/mixed_cases.rs:11:3 + | +LL | three_args(1, "", X {}, ""); + | ^^^^^^^^^^ -- ---- -- argument unexpected + | | | + | | argument of type `&str` unexpected + | an argument of type `f32` is missing + | +note: function defined here + --> $DIR/mixed_cases.rs:6:4 + | +LL | fn three_args(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: did you mean + | +LL | three_args(1, {f32}, ""); + | ~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 3 arguments but 2 arguments were supplied + --> $DIR/mixed_cases.rs:14:3 + | +LL | three_args(1, X {}); + | ^^^^^^^^^^--------- + | | | + | | expected `f32`, found struct `X` + | an argument of type `&str` is missing + | +note: function defined here + --> $DIR/mixed_cases.rs:6:4 + | +LL | fn three_args(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: provide the argument + | +LL | three_args(1, {f32}, {&str}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0308]: arguments to this function are incorrect + --> $DIR/mixed_cases.rs:17:3 + | +LL | three_args(1, "", X {}); + | ^^^^^^^^^^ -- ---- argument of type `&str` unexpected + | | + | an argument of type `f32` is missing + | +note: function defined here + --> $DIR/mixed_cases.rs:6:4 + | +LL | fn three_args(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: did you mean + | +LL | three_args(1, {f32}, ""); + | ~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0308]: arguments to this function are incorrect + --> $DIR/mixed_cases.rs:20:3 + | +LL | three_args("", X {}, 1); + | ^^^^^^^^^^ -- ---- - expected `&str`,found `{integer}` + | | | + | | expected `f32`, found struct `X` + | expected `i32`,found `&'static str` + | +note: function defined here + --> $DIR/mixed_cases.rs:6:4 + | +LL | fn three_args(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: swap these arguments + | +LL | three_args(1, {f32}, ""); + | ~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0061]: this function takes 3 arguments but 2 arguments were supplied + --> $DIR/mixed_cases.rs:23:3 + | +LL | three_args("", 1); + | ^^^^^^^^^^ -- - + | | | + | | an argument of type `f32` is missing + | | expected `&str`,found `{integer}` + | expected `i32`,found `&'static str` + | +note: function defined here + --> $DIR/mixed_cases.rs:6:4 + | +LL | fn three_args(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: did you mean + | +LL | three_args(1, {f32}, ""); + | ~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0061, E0308. +For more information about an error, try `rustc --explain E0061`. diff --git a/src/test/ui/argument-suggestions/permuted_arguments.rs b/src/test/ui/argument-suggestions/permuted_arguments.rs new file mode 100644 index 00000000000..f512fde651c --- /dev/null +++ b/src/test/ui/argument-suggestions/permuted_arguments.rs @@ -0,0 +1,13 @@ +// More complicated permutations +struct X {} +struct Y {} + +fn three_args(_a: i32, _b: f32, _c: &str) {} +fn many_args(_a: i32, _b: f32, _c: &str, _d: X, _e: Y) {} + +fn main() { + // b, c, a + three_args(1.0, "", 1); //~ ERROR arguments to this function are incorrect + // d, e, b, a, c + many_args(X {}, Y {}, 1, 1.0, ""); //~ ERROR arguments to this function are incorrect +} diff --git a/src/test/ui/argument-suggestions/permuted_arguments.stderr b/src/test/ui/argument-suggestions/permuted_arguments.stderr new file mode 100644 index 00000000000..52890f4e6a5 --- /dev/null +++ b/src/test/ui/argument-suggestions/permuted_arguments.stderr @@ -0,0 +1,43 @@ +error[E0308]: arguments to this function are incorrect + --> $DIR/permuted_arguments.rs:10:3 + | +LL | three_args(1.0, "", 1); + | ^^^^^^^^^^ --- -- - expected `&str`,found `{integer}` + | | | + | | expected `f32`,found `&'static str` + | expected `i32`,found `{float}` + | +note: function defined here + --> $DIR/permuted_arguments.rs:5:4 + | +LL | fn three_args(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: reorder these arguments + | +LL | three_args(1, 1.0, ""); + | ~~~~~~~~~~~~~~~~~~~~~~ + +error[E0308]: arguments to this function are incorrect + --> $DIR/permuted_arguments.rs:12:3 + | +LL | many_args(X {}, Y {}, 1, 1.0, ""); + | ^^^^^^^^^ ---- ---- - --- -- expected `Y`,found `&'static str` + | | | | | + | | | | expected `X`,found `{float}` + | | | expected `&str`,found `{integer}` + | | expected `f32`,found `Y` + | expected `i32`,found `X` + | +note: function defined here + --> $DIR/permuted_arguments.rs:6:4 + | +LL | fn many_args(_a: i32, _b: f32, _c: &str, _d: X, _e: Y) {} + | ^^^^^^^^^ ------- ------- -------- ----- ----- +help: reorder these arguments + | +LL | many_args(1, 1.0, "", X {}, Y {}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/argument-suggestions/swapped_arguments.rs b/src/test/ui/argument-suggestions/swapped_arguments.rs new file mode 100644 index 00000000000..a21de610c6a --- /dev/null +++ b/src/test/ui/argument-suggestions/swapped_arguments.rs @@ -0,0 +1,14 @@ +struct X {} + +fn two_args(_a: i32, _b: f32) {} +fn three_args(_a: i32, _b: f32, _c: &str) {} +fn four_args(_a: i32, _b: f32, _c: &str, _d: X) {} + +fn main() { + two_args(1.0, 1); //~ ERROR arguments to this function are incorrect + three_args(1.0, 1, ""); //~ ERROR arguments to this function are incorrect + three_args( 1, "", 1.0); //~ ERROR arguments to this function are incorrect + three_args( "", 1.0, 1); //~ ERROR arguments to this function are incorrect + + four_args(1.0, 1, X {}, ""); //~ ERROR arguments to this function are incorrect +} diff --git a/src/test/ui/argument-suggestions/swapped_arguments.stderr b/src/test/ui/argument-suggestions/swapped_arguments.stderr new file mode 100644 index 00000000000..672f0d5bb56 --- /dev/null +++ b/src/test/ui/argument-suggestions/swapped_arguments.stderr @@ -0,0 +1,95 @@ +error[E0308]: arguments to this function are incorrect + --> $DIR/swapped_arguments.rs:8:3 + | +LL | two_args(1.0, 1); + | ^^^^^^^^ --- - expected `f32`,found `{integer}` + | | + | expected `i32`,found `{float}` + | +note: function defined here + --> $DIR/swapped_arguments.rs:3:4 + | +LL | fn two_args(_a: i32, _b: f32) {} + | ^^^^^^^^ ------- ------- +help: swap these arguments + | +LL | two_args(1, 1.0); + | ~~~~~~~~~~~~~~~~ + +error[E0308]: arguments to this function are incorrect + --> $DIR/swapped_arguments.rs:9:3 + | +LL | three_args(1.0, 1, ""); + | ^^^^^^^^^^ --- - expected `f32`,found `{integer}` + | | + | expected `i32`,found `{float}` + | +note: function defined here + --> $DIR/swapped_arguments.rs:4:4 + | +LL | fn three_args(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: swap these arguments + | +LL | three_args(1, 1.0, ""); + | ~~~~~~~~~~~~~~~~~~~~~~ + +error[E0308]: arguments to this function are incorrect + --> $DIR/swapped_arguments.rs:10:3 + | +LL | three_args( 1, "", 1.0); + | ^^^^^^^^^^ -- --- expected `&str`,found `{float}` + | | + | expected `f32`,found `&'static str` + | +note: function defined here + --> $DIR/swapped_arguments.rs:4:4 + | +LL | fn three_args(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: swap these arguments + | +LL | three_args(1, 1.0, ""); + | ~~~~~~~~~~~~~~~~~~~~~~ + +error[E0308]: arguments to this function are incorrect + --> $DIR/swapped_arguments.rs:11:3 + | +LL | three_args( "", 1.0, 1); + | ^^^^^^^^^^ -- - expected `&str`,found `{integer}` + | | + | expected `i32`,found `&'static str` + | +note: function defined here + --> $DIR/swapped_arguments.rs:4:4 + | +LL | fn three_args(_a: i32, _b: f32, _c: &str) {} + | ^^^^^^^^^^ ------- ------- -------- +help: swap these arguments + | +LL | three_args(1, 1.0, ""); + | ~~~~~~~~~~~~~~~~~~~~~~ + +error[E0308]: arguments to this function are incorrect + --> $DIR/swapped_arguments.rs:13:3 + | +LL | four_args(1.0, 1, X {}, ""); + | ^^^^^^^^^ --- - ---- -- expected `X`,found `&'static str` + | | | | + | | | expected `&str`,found `X` + | | expected `f32`,found `{integer}` + | expected `i32`,found `{float}` + | +note: function defined here + --> $DIR/swapped_arguments.rs:5:4 + | +LL | fn four_args(_a: i32, _b: f32, _c: &str, _d: X) {} + | ^^^^^^^^^ ------- ------- -------- ----- +help: did you mean + | +LL | four_args(1, 1.0, "", X {}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/asm/aarch64/parse-error.rs b/src/test/ui/asm/aarch64/parse-error.rs index 59d6b28d0fd..cbc93cd3f75 100644 --- a/src/test/ui/asm/aarch64/parse-error.rs +++ b/src/test/ui/asm/aarch64/parse-error.rs @@ -29,7 +29,7 @@ fn main() { asm!("{}", in(reg) foo => bar); //~^ ERROR expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>` asm!("{}", sym foo + bar); - //~^ ERROR argument to `sym` must be a path expression + //~^ ERROR expected a path for argument to `sym` asm!("", options(foo)); //~^ ERROR expected one of asm!("", options(nomem foo)); diff --git a/src/test/ui/asm/aarch64/parse-error.stderr b/src/test/ui/asm/aarch64/parse-error.stderr index 3f705ba5b64..f2013046cda 100644 --- a/src/test/ui/asm/aarch64/parse-error.stderr +++ b/src/test/ui/asm/aarch64/parse-error.stderr @@ -58,7 +58,7 @@ error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>` LL | asm!("{}", in(reg) foo => bar); | ^^ expected one of 7 possible tokens -error: argument to `sym` must be a path expression +error: expected a path for argument to `sym` --> $DIR/parse-error.rs:31:24 | LL | asm!("{}", sym foo + bar); @@ -350,17 +350,17 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); | = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` -error: expected one of `clobber_abi`, `const`, or `options`, found `""` +error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `""` --> $DIR/parse-error.rs:126:28 | LL | global_asm!("", options(), ""); - | ^^ expected one of `clobber_abi`, `const`, or `options` + | ^^ expected one of `clobber_abi`, `const`, `options`, or `sym` -error: expected one of `clobber_abi`, `const`, or `options`, found `"{}"` +error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `"{}"` --> $DIR/parse-error.rs:128:30 | LL | global_asm!("{}", const FOO, "{}", const FOO); - | ^^^^ expected one of `clobber_abi`, `const`, or `options` + | ^^^^ expected one of `clobber_abi`, `const`, `options`, or `sym` error: asm template must be a string literal --> $DIR/parse-error.rs:130:13 diff --git a/src/test/ui/asm/aarch64/type-check-2.rs b/src/test/ui/asm/aarch64/type-check-2.rs index 1b91f5d0678..9e53a2e0c52 100644 --- a/src/test/ui/asm/aarch64/type-check-2.rs +++ b/src/test/ui/asm/aarch64/type-check-2.rs @@ -2,7 +2,7 @@ #![feature(repr_simd, never_type, asm_sym)] -use std::arch::asm; +use std::arch::{asm, global_asm}; #[repr(simd)] #[derive(Clone, Copy)] @@ -39,9 +39,7 @@ fn main() { asm!("{}", sym S); asm!("{}", sym main); asm!("{}", sym C); - //~^ ERROR asm `sym` operand must point to a fn or static - asm!("{}", sym x); - //~^ ERROR asm `sym` operand must point to a fn or static + //~^ ERROR invalid `sym` operand // Register operands must be Copy @@ -84,3 +82,12 @@ fn main() { asm!("{}", in(reg) u); } } + +// Sym operands must point to a function or static + +const C: i32 = 0; +static S: i32 = 0; +global_asm!("{}", sym S); +global_asm!("{}", sym main); +global_asm!("{}", sym C); +//~^ ERROR invalid `sym` operand diff --git a/src/test/ui/asm/aarch64/type-check-2.stderr b/src/test/ui/asm/aarch64/type-check-2.stderr index beb301c7c74..6047bed6e78 100644 --- a/src/test/ui/asm/aarch64/type-check-2.stderr +++ b/src/test/ui/asm/aarch64/type-check-2.stderr @@ -1,13 +1,13 @@ error: arguments for inline assembly must be copyable - --> $DIR/type-check-2.rs:48:31 + --> $DIR/type-check-2.rs:46:31 | LL | asm!("{:v}", in(vreg) SimdNonCopy(0.0, 0.0, 0.0, 0.0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `SimdNonCopy` does not implement the Copy trait -error: cannot use value of type `[closure@$DIR/type-check-2.rs:60:28: 60:38]` for inline assembly - --> $DIR/type-check-2.rs:60:28 +error: cannot use value of type `[closure@$DIR/type-check-2.rs:58:28: 58:38]` for inline assembly + --> $DIR/type-check-2.rs:58:28 | LL | asm!("{}", in(reg) |x: i32| x); | ^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | asm!("{}", in(reg) |x: i32| x); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `Vec<i32>` for inline assembly - --> $DIR/type-check-2.rs:62:28 + --> $DIR/type-check-2.rs:60:28 | LL | asm!("{}", in(reg) vec![0]); | ^^^^^^^ @@ -24,7 +24,7 @@ LL | asm!("{}", in(reg) vec![0]); = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot use value of type `(i32, i32, i32)` for inline assembly - --> $DIR/type-check-2.rs:64:28 + --> $DIR/type-check-2.rs:62:28 | LL | asm!("{}", in(reg) (1, 2, 3)); | ^^^^^^^^^ @@ -32,7 +32,7 @@ LL | asm!("{}", in(reg) (1, 2, 3)); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `[i32; 3]` for inline assembly - --> $DIR/type-check-2.rs:66:28 + --> $DIR/type-check-2.rs:64:28 | LL | asm!("{}", in(reg) [1, 2, 3]); | ^^^^^^^^^ @@ -40,7 +40,7 @@ LL | asm!("{}", in(reg) [1, 2, 3]); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `fn() {main}` for inline assembly - --> $DIR/type-check-2.rs:74:31 + --> $DIR/type-check-2.rs:72:31 | LL | asm!("{}", inout(reg) f); | ^ @@ -48,24 +48,28 @@ LL | asm!("{}", inout(reg) f); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `&mut i32` for inline assembly - --> $DIR/type-check-2.rs:77:31 + --> $DIR/type-check-2.rs:75:31 | LL | asm!("{}", inout(reg) r); | ^ | = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly -error: asm `sym` operand must point to a fn or static - --> $DIR/type-check-2.rs:41:24 +error: invalid `sym` operand + --> $DIR/type-check-2.rs:41:20 | LL | asm!("{}", sym C); - | ^ + | ^^^^^ is an `i32` + | + = help: `sym` operands must refer to either a function or a static -error: asm `sym` operand must point to a fn or static - --> $DIR/type-check-2.rs:43:24 +error: invalid `sym` operand + --> $DIR/type-check-2.rs:92:19 + | +LL | global_asm!("{}", sym C); + | ^^^^^ is an `i32` | -LL | asm!("{}", sym x); - | ^ + = help: `sym` operands must refer to either a function or a static error[E0381]: use of possibly-uninitialized variable: `x` --> $DIR/type-check-2.rs:19:28 diff --git a/src/test/ui/asm/type-check-1.rs b/src/test/ui/asm/type-check-1.rs index 695fd27efd4..9f0121e11b4 100644 --- a/src/test/ui/asm/type-check-1.rs +++ b/src/test/ui/asm/type-check-1.rs @@ -3,7 +3,7 @@ // ignore-spirv // ignore-wasm32 -#![feature(asm_const)] +#![feature(asm_const, asm_sym)] use std::arch::{asm, global_asm}; @@ -44,6 +44,8 @@ fn main() { asm!("{}", const const_bar(0)); asm!("{}", const const_bar(x)); //~^ ERROR attempt to use a non-constant value in a constant + asm!("{}", sym x); + //~^ ERROR invalid `sym` operand // Const operands must be integers and must be constants. @@ -59,6 +61,11 @@ fn main() { } } +unsafe fn generic<T>() { + asm!("{}", sym generic::<T>); + //~^ generic parameters may not be used in const operations +} + // Const operands must be integers and must be constants. global_asm!("{}", const 0); diff --git a/src/test/ui/asm/type-check-1.stderr b/src/test/ui/asm/type-check-1.stderr index d774c78ca9a..7dba69fb745 100644 --- a/src/test/ui/asm/type-check-1.stderr +++ b/src/test/ui/asm/type-check-1.stderr @@ -25,14 +25,31 @@ LL | let x = 0; LL | asm!("{}", const const_bar(x)); | ^ non-constant value +error: invalid `sym` operand + --> $DIR/type-check-1.rs:47:24 + | +LL | asm!("{}", sym x); + | ^ is a local variable + | + = help: `sym` operands must refer to either a function or a static + +error: generic parameters may not be used in const operations + --> $DIR/type-check-1.rs:65:30 + | +LL | asm!("{}", sym generic::<T>); + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + error[E0308]: mismatched types - --> $DIR/type-check-1.rs:53:26 + --> $DIR/type-check-1.rs:55:26 | LL | asm!("{}", const 0f32); | ^^^^ expected integer, found `f32` error[E0308]: mismatched types - --> $DIR/type-check-1.rs:55:26 + --> $DIR/type-check-1.rs:57:26 | LL | asm!("{}", const 0 as *mut u8); | ^^^^^^^^^^^^ expected integer, found *-ptr @@ -41,7 +58,7 @@ LL | asm!("{}", const 0 as *mut u8); found raw pointer `*mut u8` error[E0308]: mismatched types - --> $DIR/type-check-1.rs:57:26 + --> $DIR/type-check-1.rs:59:26 | LL | asm!("{}", const &0); | ^^ expected integer, found `&{integer}` @@ -92,13 +109,13 @@ LL | asm!("{}", inout(reg) v[..]); = note: all inline asm arguments must have a statically known size error[E0308]: mismatched types - --> $DIR/type-check-1.rs:67:25 + --> $DIR/type-check-1.rs:74:25 | LL | global_asm!("{}", const 0f32); | ^^^^ expected integer, found `f32` error[E0308]: mismatched types - --> $DIR/type-check-1.rs:69:25 + --> $DIR/type-check-1.rs:76:25 | LL | global_asm!("{}", const 0 as *mut u8); | ^^^^^^^^^^^^ expected integer, found *-ptr @@ -106,7 +123,7 @@ LL | global_asm!("{}", const 0 as *mut u8); = note: expected type `{integer}` found raw pointer `*mut u8` -error: aborting due to 13 previous errors +error: aborting due to 15 previous errors Some errors have detailed explanations: E0277, E0308, E0435. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/asm/x86_64/parse-error.rs b/src/test/ui/asm/x86_64/parse-error.rs index f0629f9f51c..9aeb6b2853f 100644 --- a/src/test/ui/asm/x86_64/parse-error.rs +++ b/src/test/ui/asm/x86_64/parse-error.rs @@ -29,7 +29,7 @@ fn main() { asm!("{}", in(reg) foo => bar); //~^ ERROR expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>` asm!("{}", sym foo + bar); - //~^ ERROR argument to `sym` must be a path expression + //~^ ERROR expected a path for argument to `sym` asm!("", options(foo)); //~^ ERROR expected one of asm!("", options(nomem foo)); diff --git a/src/test/ui/asm/x86_64/parse-error.stderr b/src/test/ui/asm/x86_64/parse-error.stderr index 194cd66a66e..1fd317a96a8 100644 --- a/src/test/ui/asm/x86_64/parse-error.stderr +++ b/src/test/ui/asm/x86_64/parse-error.stderr @@ -58,7 +58,7 @@ error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>` LL | asm!("{}", in(reg) foo => bar); | ^^ expected one of 7 possible tokens -error: argument to `sym` must be a path expression +error: expected a path for argument to `sym` --> $DIR/parse-error.rs:31:24 | LL | asm!("{}", sym foo + bar); @@ -362,17 +362,17 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); | = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` -error: expected one of `clobber_abi`, `const`, or `options`, found `""` +error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `""` --> $DIR/parse-error.rs:130:28 | LL | global_asm!("", options(), ""); - | ^^ expected one of `clobber_abi`, `const`, or `options` + | ^^ expected one of `clobber_abi`, `const`, `options`, or `sym` -error: expected one of `clobber_abi`, `const`, or `options`, found `"{}"` +error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `"{}"` --> $DIR/parse-error.rs:132:30 | LL | global_asm!("{}", const FOO, "{}", const FOO); - | ^^^^ expected one of `clobber_abi`, `const`, or `options` + | ^^^^ expected one of `clobber_abi`, `const`, `options`, or `sym` error: asm template must be a string literal --> $DIR/parse-error.rs:134:13 diff --git a/src/test/ui/asm/x86_64/type-check-2.rs b/src/test/ui/asm/x86_64/type-check-2.rs index f95aebb78b5..eb87ea91085 100644 --- a/src/test/ui/asm/x86_64/type-check-2.rs +++ b/src/test/ui/asm/x86_64/type-check-2.rs @@ -2,7 +2,7 @@ #![feature(repr_simd, never_type, asm_sym)] -use std::arch::asm; +use std::arch::{asm, global_asm}; #[repr(simd)] struct SimdNonCopy(f32, f32, f32, f32); @@ -35,9 +35,7 @@ fn main() { asm!("{}", sym S); asm!("{}", sym main); asm!("{}", sym C); - //~^ ERROR asm `sym` operand must point to a fn or static - asm!("{}", sym x); - //~^ ERROR asm `sym` operand must point to a fn or static + //~^ ERROR invalid `sym` operand // Register operands must be Copy @@ -80,3 +78,12 @@ fn main() { asm!("{}", in(reg) u); } } + +// Sym operands must point to a function or static + +const C: i32 = 0; +static S: i32 = 0; +global_asm!("{}", sym S); +global_asm!("{}", sym main); +global_asm!("{}", sym C); +//~^ ERROR invalid `sym` operand diff --git a/src/test/ui/asm/x86_64/type-check-2.stderr b/src/test/ui/asm/x86_64/type-check-2.stderr index cec750fdf9a..cb3960acdf9 100644 --- a/src/test/ui/asm/x86_64/type-check-2.stderr +++ b/src/test/ui/asm/x86_64/type-check-2.stderr @@ -1,13 +1,13 @@ error: arguments for inline assembly must be copyable - --> $DIR/type-check-2.rs:44:32 + --> $DIR/type-check-2.rs:42:32 | LL | asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `SimdNonCopy` does not implement the Copy trait -error: cannot use value of type `[closure@$DIR/type-check-2.rs:56:28: 56:38]` for inline assembly - --> $DIR/type-check-2.rs:56:28 +error: cannot use value of type `[closure@$DIR/type-check-2.rs:54:28: 54:38]` for inline assembly + --> $DIR/type-check-2.rs:54:28 | LL | asm!("{}", in(reg) |x: i32| x); | ^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | asm!("{}", in(reg) |x: i32| x); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `Vec<i32>` for inline assembly - --> $DIR/type-check-2.rs:58:28 + --> $DIR/type-check-2.rs:56:28 | LL | asm!("{}", in(reg) vec![0]); | ^^^^^^^ @@ -24,7 +24,7 @@ LL | asm!("{}", in(reg) vec![0]); = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot use value of type `(i32, i32, i32)` for inline assembly - --> $DIR/type-check-2.rs:60:28 + --> $DIR/type-check-2.rs:58:28 | LL | asm!("{}", in(reg) (1, 2, 3)); | ^^^^^^^^^ @@ -32,7 +32,7 @@ LL | asm!("{}", in(reg) (1, 2, 3)); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `[i32; 3]` for inline assembly - --> $DIR/type-check-2.rs:62:28 + --> $DIR/type-check-2.rs:60:28 | LL | asm!("{}", in(reg) [1, 2, 3]); | ^^^^^^^^^ @@ -40,7 +40,7 @@ LL | asm!("{}", in(reg) [1, 2, 3]); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `fn() {main}` for inline assembly - --> $DIR/type-check-2.rs:70:31 + --> $DIR/type-check-2.rs:68:31 | LL | asm!("{}", inout(reg) f); | ^ @@ -48,24 +48,28 @@ LL | asm!("{}", inout(reg) f); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `&mut i32` for inline assembly - --> $DIR/type-check-2.rs:73:31 + --> $DIR/type-check-2.rs:71:31 | LL | asm!("{}", inout(reg) r); | ^ | = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly -error: asm `sym` operand must point to a fn or static - --> $DIR/type-check-2.rs:37:24 +error: invalid `sym` operand + --> $DIR/type-check-2.rs:37:20 | LL | asm!("{}", sym C); - | ^ + | ^^^^^ is an `i32` + | + = help: `sym` operands must refer to either a function or a static -error: asm `sym` operand must point to a fn or static - --> $DIR/type-check-2.rs:39:24 +error: invalid `sym` operand + --> $DIR/type-check-2.rs:88:19 + | +LL | global_asm!("{}", sym C); + | ^^^^^ is an `i32` | -LL | asm!("{}", sym x); - | ^ + = help: `sym` operands must refer to either a function or a static error[E0381]: use of possibly-uninitialized variable: `x` --> $DIR/type-check-2.rs:15:28 diff --git a/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr b/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr index 07f207627f4..b904ad102e9 100644 --- a/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr +++ b/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr @@ -2,25 +2,57 @@ error[E0308]: mismatched types --> $DIR/associated-type-projection-from-supertrait.rs:27:23 | LL | fn b() { dent(ModelT, Blue); } - | ^^^^ expected struct `Black`, found struct `Blue` + | ---- ^^^^ expected struct `Black`, found struct `Blue` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/associated-type-projection-from-supertrait.rs:25:4 + | +LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) } + | ^^^^ ---- --------------- error[E0308]: mismatched types --> $DIR/associated-type-projection-from-supertrait.rs:28:23 | LL | fn c() { dent(ModelU, Black); } - | ^^^^^ expected struct `Blue`, found struct `Black` + | ---- ^^^^^ expected struct `Blue`, found struct `Black` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/associated-type-projection-from-supertrait.rs:25:4 + | +LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) } + | ^^^^ ---- --------------- error[E0308]: mismatched types --> $DIR/associated-type-projection-from-supertrait.rs:32:28 | LL | fn f() { ModelT.chip_paint(Blue); } - | ^^^^ expected struct `Black`, found struct `Blue` + | ---------- ^^^^ expected struct `Black`, found struct `Blue` + | | + | arguments to this function are incorrect + | +note: associated function defined here + --> $DIR/associated-type-projection-from-supertrait.rs:12:8 + | +LL | fn chip_paint(&self, c: Self::Color) { } + | ^^^^^^^^^^ ----- -------------- error[E0308]: mismatched types --> $DIR/associated-type-projection-from-supertrait.rs:33:28 | LL | fn g() { ModelU.chip_paint(Black); } - | ^^^^^ expected struct `Blue`, found struct `Black` + | ---------- ^^^^^ expected struct `Blue`, found struct `Black` + | | + | arguments to this function are incorrect + | +note: associated function defined here + --> $DIR/associated-type-projection-from-supertrait.rs:12:8 + | +LL | fn chip_paint(&self, c: Self::Color) { } + | ^^^^^^^^^^ ----- -------------- error: aborting due to 4 previous errors diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr index 2d8d513409d..1d0b84d31d4 100644 --- a/src/test/ui/associated-types/associated-types-path-2.stderr +++ b/src/test/ui/associated-types/associated-types-path-2.stderr @@ -2,8 +2,15 @@ error[E0308]: mismatched types --> $DIR/associated-types-path-2.rs:19:14 | LL | f1(2i32, 4i32); - | ^^^^ expected `u32`, found `i32` + | -- ^^^^ expected `u32`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/associated-types-path-2.rs:13:8 | +LL | pub fn f1<T: Foo>(a: T, x: T::A) {} + | ^^ ---- ------- help: change the type of the numeric literal from `i32` to `u32` | LL | f1(2i32, 4u32); diff --git a/src/test/ui/async-await/dont-suggest-missing-await.stderr b/src/test/ui/async-await/dont-suggest-missing-await.stderr index 289a567209c..627bf05bba2 100644 --- a/src/test/ui/async-await/dont-suggest-missing-await.stderr +++ b/src/test/ui/async-await/dont-suggest-missing-await.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/dont-suggest-missing-await.rs:14:18 | LL | take_u32(x) - | ^ expected `u32`, found opaque type + | -------- ^ expected `u32`, found opaque type + | | + | arguments to this function are incorrect | note: while checking the return type of the `async fn` --> $DIR/dont-suggest-missing-await.rs:7:24 @@ -11,6 +13,11 @@ LL | async fn make_u32() -> u32 { | ^^^ checked the `Output` of this `async fn`, found opaque type = note: expected type `u32` found opaque type `impl Future<Output = u32>` +note: function defined here + --> $DIR/dont-suggest-missing-await.rs:5:4 + | +LL | fn take_u32(x: u32) {} + | ^^^^^^^^ ------ help: consider `await`ing on the `Future` | LL | take_u32(x.await) diff --git a/src/test/ui/async-await/generator-desc.stderr b/src/test/ui/async-await/generator-desc.stderr index 3ebc4392f2c..b205fd61915 100644 --- a/src/test/ui/async-await/generator-desc.stderr +++ b/src/test/ui/async-await/generator-desc.stderr @@ -2,52 +2,67 @@ error[E0308]: mismatched types --> $DIR/generator-desc.rs:10:25 | LL | fun(async {}, async {}); - | -- ^^ expected `async` block, found a different `async` block - | | + | -- ^^ + | | | + | | expected `async` block, found a different `async` block + | | arguments to this function are incorrect | the expected `async` block | = note: expected `async` block `[static generator@$DIR/generator-desc.rs:10:15: 10:17]` found `async` block `[static generator@$DIR/generator-desc.rs:10:25: 10:27]` +note: function defined here + --> $SRC_DIR/core/src/future/mod.rs:LL:COL + | +LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return> + | ^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/generator-desc.rs:12:16 | LL | fun(one(), two()); - | ^^^^^ expected opaque type, found a different opaque type - | -note: while checking the return type of the `async fn` - --> $DIR/generator-desc.rs:5:16 + | --- ^^^^^ expected opaque type, found a different opaque type + | | + | arguments to this function are incorrect | -LL | async fn one() {} - | ^ checked the `Output` of this `async fn`, expected opaque type note: while checking the return type of the `async fn` --> $DIR/generator-desc.rs:6:16 | LL | async fn two() {} | ^ checked the `Output` of this `async fn`, found opaque type - = note: expected opaque type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:5:16>) - found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:6:16>) + = note: expected type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:5:16>) + found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:6:16>) = help: consider `await`ing on both `Future`s = note: distinct uses of `impl Trait` result in different opaque types +note: function defined here + --> $DIR/generator-desc.rs:8:4 + | +LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {} + | ^^^ ----- ----- error[E0308]: mismatched types --> $DIR/generator-desc.rs:14:26 | LL | fun((async || {})(), (async || {})()); - | -- ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body - | | - | the expected `async` closure body + | --- ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body + | | + | arguments to this function are incorrect | ::: $SRC_DIR/core/src/future/mod.rs:LL:COL | LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return> - | ------------------------------- - | | - | the expected opaque type - | the found opaque type + | ------------------------------- the found opaque type + | + = note: expected type `impl Future<Output = ()>` (`async` closure body) + found opaque type `impl Future<Output = ()>` (`async` closure body) +note: function defined here + --> $DIR/generator-desc.rs:8:4 + | +LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {} + | ^^^ ----- ----- +help: consider `await`ing on the `Future` | - = note: expected opaque type `impl Future<Output = ()>` (`async` closure body) - found opaque type `impl Future<Output = ()>` (`async` closure body) +LL | fun((async || {})(), (async || {})().await); + | ++++++ error: aborting due to 3 previous errors diff --git a/src/test/ui/async-await/suggest-missing-await-closure.stderr b/src/test/ui/async-await/suggest-missing-await-closure.stderr index d951c8ed094..a5958baffba 100644 --- a/src/test/ui/async-await/suggest-missing-await-closure.stderr +++ b/src/test/ui/async-await/suggest-missing-await-closure.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await-closure.rs:16:18 | LL | take_u32(x) - | ^ expected `u32`, found opaque type + | -------- ^ expected `u32`, found opaque type + | | + | arguments to this function are incorrect | note: while checking the return type of the `async fn` --> $DIR/suggest-missing-await-closure.rs:8:24 @@ -11,6 +13,11 @@ LL | async fn make_u32() -> u32 { | ^^^ checked the `Output` of this `async fn`, found opaque type = note: expected type `u32` found opaque type `impl Future<Output = u32>` +note: function defined here + --> $DIR/suggest-missing-await-closure.rs:6:4 + | +LL | fn take_u32(_x: u32) {} + | ^^^^^^^^ ------- help: consider `await`ing on the `Future` | LL | take_u32(x.await) diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index 76073c4c879..ba9ed5cb65f 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:12:14 | LL | take_u32(x) - | ^ expected `u32`, found opaque type + | -------- ^ expected `u32`, found opaque type + | | + | arguments to this function are incorrect | note: while checking the return type of the `async fn` --> $DIR/suggest-missing-await.rs:5:24 @@ -11,6 +13,11 @@ LL | async fn make_u32() -> u32 { | ^^^ checked the `Output` of this `async fn`, found opaque type = note: expected type `u32` found opaque type `impl Future<Output = u32>` +note: function defined here + --> $DIR/suggest-missing-await.rs:3:4 + | +LL | fn take_u32(_x: u32) {} + | ^^^^^^^^ ------- help: consider `await`ing on the `Future` | LL | take_u32(x.await) diff --git a/src/test/ui/binding/issue-53114-safety-checks.rs b/src/test/ui/binding/issue-53114-safety-checks.rs index ca4f0efd239..5042ad024af 100644 --- a/src/test/ui/binding/issue-53114-safety-checks.rs +++ b/src/test/ui/binding/issue-53114-safety-checks.rs @@ -20,13 +20,13 @@ fn let_wild_gets_unsafe_field() { let u1 = U { a: I(0) }; let u2 = U { a: I(1) }; let p = P { a: &2, b: &3 }; - let _ = &p.b; //~ WARN reference to packed field + let _ = &p.b; //~ ERROR reference to packed field //~^ WARN will become a hard error let _ = u1.a; // #53114: should eventually signal error as well let _ = &u2.a; //~ ERROR [E0133] // variation on above with `_` in substructure - let (_,) = (&p.b,); //~ WARN reference to packed field + let (_,) = (&p.b,); //~ ERROR reference to packed field //~^ WARN will become a hard error let (_,) = (u1.a,); //~ ERROR [E0133] let (_,) = (&u2.a,); //~ ERROR [E0133] @@ -36,13 +36,13 @@ fn match_unsafe_field_to_wild() { let u1 = U { a: I(0) }; let u2 = U { a: I(1) }; let p = P { a: &2, b: &3 }; - match &p.b { _ => { } } //~ WARN reference to packed field + match &p.b { _ => { } } //~ ERROR reference to packed field //~^ WARN will become a hard error match u1.a { _ => { } } //~ ERROR [E0133] match &u2.a { _ => { } } //~ ERROR [E0133] // variation on above with `_` in substructure - match (&p.b,) { (_,) => { } } //~ WARN reference to packed field + match (&p.b,) { (_,) => { } } //~ ERROR reference to packed field //~^ WARN will become a hard error match (u1.a,) { (_,) => { } } //~ ERROR [E0133] match (&u2.a,) { (_,) => { } } //~ ERROR [E0133] diff --git a/src/test/ui/binding/issue-53114-safety-checks.stderr b/src/test/ui/binding/issue-53114-safety-checks.stderr index 84cdb1453f8..f3840273cfa 100644 --- a/src/test/ui/binding/issue-53114-safety-checks.stderr +++ b/src/test/ui/binding/issue-53114-safety-checks.stderr @@ -1,16 +1,16 @@ -warning: reference to packed field is unaligned +error: reference to packed field is unaligned --> $DIR/issue-53114-safety-checks.rs:23:13 | LL | let _ = &p.b; | ^^^^ | - = note: `#[warn(unaligned_references)]` on by default + = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -warning: reference to packed field is unaligned +error: reference to packed field is unaligned --> $DIR/issue-53114-safety-checks.rs:29:17 | LL | let (_,) = (&p.b,); @@ -21,7 +21,7 @@ LL | let (_,) = (&p.b,); = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -warning: reference to packed field is unaligned +error: reference to packed field is unaligned --> $DIR/issue-53114-safety-checks.rs:39:11 | LL | match &p.b { _ => { } } @@ -32,7 +32,7 @@ LL | match &p.b { _ => { } } = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) -warning: reference to packed field is unaligned +error: reference to packed field is unaligned --> $DIR/issue-53114-safety-checks.rs:45:12 | LL | match (&p.b,) { (_,) => { } } @@ -99,6 +99,58 @@ LL | match (&u2.a,) { (_,) => { } } | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error: aborting due to 7 previous errors; 4 warnings emitted +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0133`. +Future incompatibility report: Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:23:13 + | +LL | let _ = &p.b; + | ^^^^ + | + = note: `#[deny(unaligned_references)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:29:17 + | +LL | let (_,) = (&p.b,); + | ^^^^ + | + = note: `#[deny(unaligned_references)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:39:11 + | +LL | match &p.b { _ => { } } + | ^^^^ + | + = note: `#[deny(unaligned_references)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:45:12 + | +LL | match (&p.b,) { (_,) => { } } + | ^^^^ + | + = note: `#[deny(unaligned_references)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + diff --git a/src/test/ui/c-variadic/variadic-ffi-1.stderr b/src/test/ui/c-variadic/variadic-ffi-1.stderr index 5b4e656d9dc..9acf1e93b07 100644 --- a/src/test/ui/c-variadic/variadic-ffi-1.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-1.stderr @@ -8,29 +8,33 @@ error[E0060]: this function takes at least 2 arguments but 0 arguments were supp --> $DIR/variadic-ffi-1.rs:20:9 | LL | foo(); - | ^^^-- supplied 0 arguments - | | - | expected at least 2 arguments + | ^^^-- two arguments of type `isize` and `u8` are missing | note: function defined here --> $DIR/variadic-ffi-1.rs:13:8 | LL | fn foo(f: isize, x: u8, ...); | ^^^ +help: provide the arguments + | +LL | foo({isize}, {u8}); + | ~~~~~~~~~~~~~~~~~~ error[E0060]: this function takes at least 2 arguments but 1 argument was supplied --> $DIR/variadic-ffi-1.rs:21:9 | LL | foo(1); - | ^^^ - supplied 1 argument - | | - | expected at least 2 arguments + | ^^^--- an argument of type `u8` is missing | note: function defined here --> $DIR/variadic-ffi-1.rs:13:8 | LL | fn foo(f: isize, x: u8, ...); | ^^^ +help: provide the argument + | +LL | foo(1, {u8}); + | ~~~~~~~~~~~~ error[E0308]: mismatched types --> $DIR/variadic-ffi-1.rs:23:56 diff --git a/src/test/ui/cast/cast-int-to-char.stderr b/src/test/ui/cast/cast-int-to-char.stderr index 55b9462db8d..ef606b6ae5f 100644 --- a/src/test/ui/cast/cast-int-to-char.stderr +++ b/src/test/ui/cast/cast-int-to-char.stderr @@ -2,8 +2,15 @@ error[E0308]: mismatched types --> $DIR/cast-int-to-char.rs:4:16 | LL | foo::<u32>('0'); - | ^^^ expected `u32`, found `char` + | ---------- ^^^ expected `u32`, found `char` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/cast-int-to-char.rs:1:4 + | +LL | fn foo<T>(_t: T) {} + | ^^^ ----- help: you can cast a `char` to a `u32`, since a `char` always occupies 4 bytes | LL | foo::<u32>('0' as u32); @@ -13,8 +20,15 @@ error[E0308]: mismatched types --> $DIR/cast-int-to-char.rs:5:16 | LL | foo::<i32>('0'); - | ^^^ expected `i32`, found `char` + | ---------- ^^^ expected `i32`, found `char` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/cast-int-to-char.rs:1:4 | +LL | fn foo<T>(_t: T) {} + | ^^^ ----- help: you can cast a `char` to an `i32`, since a `char` always occupies 4 bytes | LL | foo::<i32>('0' as i32); @@ -24,8 +38,15 @@ error[E0308]: mismatched types --> $DIR/cast-int-to-char.rs:6:16 | LL | foo::<u64>('0'); - | ^^^ expected `u64`, found `char` + | ---------- ^^^ expected `u64`, found `char` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/cast-int-to-char.rs:1:4 | +LL | fn foo<T>(_t: T) {} + | ^^^ ----- help: you can cast a `char` to a `u64`, since a `char` always occupies 4 bytes | LL | foo::<u64>('0' as u64); @@ -35,8 +56,15 @@ error[E0308]: mismatched types --> $DIR/cast-int-to-char.rs:7:16 | LL | foo::<i64>('0'); - | ^^^ expected `i64`, found `char` + | ---------- ^^^ expected `i64`, found `char` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/cast-int-to-char.rs:1:4 + | +LL | fn foo<T>(_t: T) {} + | ^^^ ----- help: you can cast a `char` to an `i64`, since a `char` always occupies 4 bytes | LL | foo::<i64>('0' as i64); @@ -46,7 +74,15 @@ error[E0308]: mismatched types --> $DIR/cast-int-to-char.rs:8:17 | LL | foo::<char>(0u32); - | ^^^^ expected `char`, found `u32` + | ----------- ^^^^ expected `char`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/cast-int-to-char.rs:1:4 + | +LL | fn foo<T>(_t: T) {} + | ^^^ ----- error: aborting due to 5 previous errors diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs index 4799f488d7d..1488f329648 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs @@ -1,7 +1,5 @@ // edition:2021 -// check-pass - // Given how the closure desugaring is implemented (at least at the time of writing this test), // we don't need to truncate the captured path to a reference into a packed-struct if the field // being referenced will be moved into the closure, since it's safe to move out a field from a @@ -11,9 +9,8 @@ // inlined we will truncate the capture to access just the struct regardless of if the field // might get moved into the closure. // -// It is possible for someone to try writing the code that relies on the desugaring to access a ref -// into a packed-struct without explicity using unsafe. Here we test that the compiler warns the -// user that such an access is still unsafe. +// It is possible for someone to try writing the code that relies on the desugaring to create a ref +// into a packed-struct. Here we test that the compiler still detects that case. fn test_missing_unsafe_warning_on_repr_packed() { #[repr(packed)] struct Foo { x: String } @@ -22,7 +19,7 @@ fn test_missing_unsafe_warning_on_repr_packed() { let c = || { println!("{}", foo.x); - //~^ WARNING: reference to packed field is unaligned + //~^ ERROR: reference to packed field is unaligned //~| WARNING: this was previously accepted by the compiler but is being phased out let _z = foo.x; }; diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr index fc0179d2cb4..8629837ba8d 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr @@ -1,15 +1,29 @@ -warning: reference to packed field is unaligned - --> $DIR/repr_packed.rs:24:24 +error: reference to packed field is unaligned + --> $DIR/repr_packed.rs:21:24 | LL | println!("{}", foo.x); | ^^^^^ | - = note: `#[warn(unaligned_references)]` on by default + = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) - = note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) -warning: 1 warning emitted +error: aborting due to previous error + +Future incompatibility report: Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/repr_packed.rs:21:24 + | +LL | println!("{}", foo.x); + | ^^^^^ + | + = note: `#[deny(unaligned_references)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/closures/closure-reform-bad.stderr b/src/test/ui/closures/closure-reform-bad.stderr index 37813879ce7..534828ab348 100644 --- a/src/test/ui/closures/closure-reform-bad.stderr +++ b/src/test/ui/closures/closure-reform-bad.stderr @@ -4,7 +4,9 @@ error[E0308]: mismatched types LL | let f = |s: &str| println!("{}{}", s, string); | ------------------------------------- the found closure LL | call_bare(f) - | ^ expected fn pointer, found closure + | --------- ^ expected fn pointer, found closure + | | + | arguments to this function are incorrect | = note: expected fn pointer `for<'r> fn(&'r str)` found closure `[closure@$DIR/closure-reform-bad.rs:10:13: 10:50]` @@ -13,6 +15,11 @@ note: closures can only be coerced to `fn` types if they do not capture any vari | LL | let f = |s: &str| println!("{}{}", s, string); | ^^^^^^ `string` captured here +note: function defined here + --> $DIR/closure-reform-bad.rs:4:4 + | +LL | fn call_bare(f: fn(&str)) { + | ^^^^^^^^^ ----------- error: aborting due to previous error diff --git a/src/test/ui/closures/issue-84128.stderr b/src/test/ui/closures/issue-84128.stderr index 70d9273ddf7..09c44d261af 100644 --- a/src/test/ui/closures/issue-84128.stderr +++ b/src/test/ui/closures/issue-84128.stderr @@ -2,13 +2,20 @@ error[E0308]: mismatched types --> $DIR/issue-84128.rs:13:13 | LL | Foo(()) - | ^^ expected integer, found `()` + | --- ^^ expected integer, found `()` + | | + | arguments to this struct are incorrect | note: return type inferred to be `{integer}` here --> $DIR/issue-84128.rs:10:20 | LL | return Foo(0); | ^^^^^^ +note: tuple struct defined here + --> $DIR/issue-84128.rs:5:8 + | +LL | struct Foo<T>(T); + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/closures/issue-87461.stderr b/src/test/ui/closures/issue-87461.stderr index a3cff2c1212..b35fa2b8c9a 100644 --- a/src/test/ui/closures/issue-87461.stderr +++ b/src/test/ui/closures/issue-87461.stderr @@ -2,19 +2,25 @@ error[E0308]: mismatched types --> $DIR/issue-87461.rs:10:8 | LL | Ok(()) - | ^^ expected `u16`, found `()` + | -- ^^ expected `u16`, found `()` + | | + | arguments to this enum variant are incorrect error[E0308]: mismatched types --> $DIR/issue-87461.rs:17:8 | LL | Ok(()) - | ^^ expected `u16`, found `()` + | -- ^^ expected `u16`, found `()` + | | + | arguments to this enum variant are incorrect error[E0308]: mismatched types --> $DIR/issue-87461.rs:26:12 | LL | Ok(()) - | ^^ expected `u16`, found `()` + | -- ^^ expected `u16`, found `()` + | | + | arguments to this enum variant are incorrect error: aborting due to 3 previous errors diff --git a/src/test/ui/coercion/coerce-mut.stderr b/src/test/ui/coercion/coerce-mut.stderr index 2601ca5e91e..11a4f310154 100644 --- a/src/test/ui/coercion/coerce-mut.stderr +++ b/src/test/ui/coercion/coerce-mut.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/coerce-mut.rs:5:7 | LL | f(&x); - | ^^ types differ in mutability + | - ^^ types differ in mutability + | | + | arguments to this function are incorrect | = note: expected mutable reference `&mut i32` found reference `&{integer}` +note: function defined here + --> $DIR/coerce-mut.rs:1:4 + | +LL | fn f(x: &mut i32) {} + | ^ ----------- error: aborting due to previous error diff --git a/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr b/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr index 59b0ec496f1..4f266b166d6 100644 --- a/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr +++ b/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/coerce-reborrow-multi-arg-fail.rs:4:18 | LL | test(&mut 7, &7); - | ^^ types differ in mutability + | ---- ^^ types differ in mutability + | | + | arguments to this function are incorrect | - = note: expected mutable reference `&mut {integer}` - found reference `&{integer}` + = note: expected type `&mut {integer}` + found reference `&{integer}` +note: function defined here + --> $DIR/coerce-reborrow-multi-arg-fail.rs:1:4 + | +LL | fn test<T>(_a: T, _b: T) {} + | ^^^^ ----- ----- error: aborting due to previous error diff --git a/src/test/ui/coercion/coerce-to-bang.stderr b/src/test/ui/coercion/coerce-to-bang.stderr index 390aa7c692d..add8f14cfa5 100644 --- a/src/test/ui/coercion/coerce-to-bang.stderr +++ b/src/test/ui/coercion/coerce-to-bang.stderr @@ -2,46 +2,81 @@ error[E0308]: mismatched types --> $DIR/coerce-to-bang.rs:6:17 | LL | foo(return, 22, 44); - | ^^ expected `!`, found integer + | --- ^^ expected `!`, found integer + | | + | arguments to this function are incorrect | = note: expected type `!` found type `{integer}` +note: function defined here + --> $DIR/coerce-to-bang.rs:3:4 + | +LL | fn foo(x: usize, y: !, z: usize) { } + | ^^^ -------- ---- -------- error[E0308]: mismatched types --> $DIR/coerce-to-bang.rs:18:13 | LL | foo(22, 44, return); - | ^^ expected `!`, found integer + | --- ^^ expected `!`, found integer + | | + | arguments to this function are incorrect | = note: expected type `!` found type `{integer}` +note: function defined here + --> $DIR/coerce-to-bang.rs:3:4 + | +LL | fn foo(x: usize, y: !, z: usize) { } + | ^^^ -------- ---- -------- error[E0308]: mismatched types --> $DIR/coerce-to-bang.rs:26:12 | LL | foo(a, b, c); // ... and hence a reference to `a` is expected to diverge. - | ^ expected `!`, found integer + | --- ^ expected `!`, found integer + | | + | arguments to this function are incorrect | = note: expected type `!` found type `{integer}` +note: function defined here + --> $DIR/coerce-to-bang.rs:3:4 + | +LL | fn foo(x: usize, y: !, z: usize) { } + | ^^^ -------- ---- -------- error[E0308]: mismatched types --> $DIR/coerce-to-bang.rs:36:12 | LL | foo(a, b, c); - | ^ expected `!`, found integer + | --- ^ expected `!`, found integer + | | + | arguments to this function are incorrect | = note: expected type `!` found type `{integer}` +note: function defined here + --> $DIR/coerce-to-bang.rs:3:4 + | +LL | fn foo(x: usize, y: !, z: usize) { } + | ^^^ -------- ---- -------- error[E0308]: mismatched types --> $DIR/coerce-to-bang.rs:45:12 | LL | foo(a, b, c); - | ^ expected `!`, found integer + | --- ^ expected `!`, found integer + | | + | arguments to this function are incorrect | = note: expected type `!` found type `{integer}` +note: function defined here + --> $DIR/coerce-to-bang.rs:3:4 + | +LL | fn foo(x: usize, y: !, z: usize) { } + | ^^^ -------- ---- -------- error[E0308]: mismatched types --> $DIR/coerce-to-bang.rs:50:21 diff --git a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr new file mode 100644 index 00000000000..e9854f0b9b5 --- /dev/null +++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr @@ -0,0 +1,29 @@ +error[E0308]: arguments to this function are incorrect + --> $DIR/const-argument-cross-crate-mismatch.rs:7:41 + | +LL | let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8])); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^----------^ + | | + | expected `[u8; 3]`, found `[u8; 2]` + | +help: provide an argument of the correct type + | +LL | let _ = const_generic_lib::function(({[u8; 3]})); + | ^^^^^^^^^^^ + +error[E0308]: arguments to this function are incorrect + --> $DIR/const-argument-cross-crate-mismatch.rs:9:39 + | +LL | let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^ + | | + | expected `[u8; 2]`, found `[u8; 3]` + | +help: provide an argument of the correct type + | +LL | let _: const_generic_lib::Alias = ({[u8; 2]}); + | ^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr index aefd514f7a6..42f469d9817 100644 --- a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr +++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr @@ -2,13 +2,17 @@ error[E0308]: mismatched types --> $DIR/const-argument-cross-crate-mismatch.rs:6:67 | LL | let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8])); - | ^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements + | ------------------------- ^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements + | | + | arguments to this struct are incorrect error[E0308]: mismatched types --> $DIR/const-argument-cross-crate-mismatch.rs:8:65 | LL | let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]); - | ^^^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements + | ------------------------- ^^^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements + | | + | arguments to this struct are incorrect error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr index 5d45e302888..9bea4105d58 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr @@ -1,19 +1,26 @@ +error: constant expression depends on a generic parameter + --> $DIR/issue-62504.rs:18:25 + | +LL | ArrayHolder([0; Self::SIZE]) + | ^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + error[E0308]: mismatched types --> $DIR/issue-62504.rs:18:21 | LL | ArrayHolder([0; Self::SIZE]) - | ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE` + | ----------- ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE` + | | + | arguments to this struct are incorrect | = note: expected array `[u32; X]` found array `[u32; _]` - -error: constant expression depends on a generic parameter - --> $DIR/issue-62504.rs:18:25 +note: tuple struct defined here + --> $DIR/issue-62504.rs:14:8 | -LL | ArrayHolder([0; Self::SIZE]) - | ^^^^^^^^^^ - | - = note: this may fail depending on what value the parameter takes +LL | struct ArrayHolder<const X: usize>([u32; X]); + | ^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/derives/deriving-with-repr-packed.stderr b/src/test/ui/derives/deriving-with-repr-packed.stderr index 667f82ee0cf..1002b359f60 100644 --- a/src/test/ui/derives/deriving-with-repr-packed.stderr +++ b/src/test/ui/derives/deriving-with-repr-packed.stderr @@ -45,3 +45,67 @@ LL | #[derive(PartialEq)] error: aborting due to 4 previous errors +Future incompatibility report: Future breakage diagnostic: +error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133) + --> $DIR/deriving-with-repr-packed.rs:8:16 + | +LL | #[derive(Copy, Clone, PartialEq, Eq)] + | ^^^^^ + | +note: the lint level is defined here + --> $DIR/deriving-with-repr-packed.rs:1:9 + | +LL | #![deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) + +Future breakage diagnostic: +error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133) + --> $DIR/deriving-with-repr-packed.rs:8:23 + | +LL | #[derive(Copy, Clone, PartialEq, Eq)] + | ^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/deriving-with-repr-packed.rs:1:9 + | +LL | #![deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +Future breakage diagnostic: +error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133) + --> $DIR/deriving-with-repr-packed.rs:16:10 + | +LL | #[derive(PartialEq, Eq)] + | ^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/deriving-with-repr-packed.rs:1:9 + | +LL | #![deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +Future breakage diagnostic: +error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133) + --> $DIR/deriving-with-repr-packed.rs:25:10 + | +LL | #[derive(PartialEq)] + | ^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/deriving-with-repr-packed.rs:1:9 + | +LL | #![deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + diff --git a/src/test/ui/deriving/deriving-default-enum.rs b/src/test/ui/deriving/deriving-default-enum.rs index 931ff1a5847..d1a81c72c2f 100644 --- a/src/test/ui/deriving/deriving-default-enum.rs +++ b/src/test/ui/deriving/deriving-default-enum.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(derive_default_enum)] - // nb: does not impl Default #[derive(Debug, PartialEq)] struct NotDefault; diff --git a/src/test/ui/deriving/deriving-with-helper.rs b/src/test/ui/deriving/deriving-with-helper.rs index d8f0b27a2e5..1c30b0b6fba 100644 --- a/src/test/ui/deriving/deriving-with-helper.rs +++ b/src/test/ui/deriving/deriving-with-helper.rs @@ -5,7 +5,6 @@ #![feature(lang_items)] #![feature(no_core)] #![feature(rustc_attrs)] -#![feature(derive_default_enum)] #![no_core] diff --git a/src/test/ui/did_you_mean/issue-42764.stderr b/src/test/ui/did_you_mean/issue-42764.stderr index dbe46704b93..95b572133c5 100644 --- a/src/test/ui/did_you_mean/issue-42764.stderr +++ b/src/test/ui/did_you_mean/issue-42764.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/issue-42764.rs:11:43 | LL | this_function_expects_a_double_option(n); - | ^ expected enum `DoubleOption`, found `usize` + | ------------------------------------- ^ expected enum `DoubleOption`, found `usize` + | | + | arguments to this function are incorrect | = note: expected enum `DoubleOption<_>` found type `usize` +note: function defined here + --> $DIR/issue-42764.rs:7:4 + | +LL | fn this_function_expects_a_double_option<T>(d: DoubleOption<T>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------ help: try wrapping the expression in a variant of `DoubleOption` | LL | this_function_expects_a_double_option(DoubleOption::FirstSome(n)); diff --git a/src/test/ui/disambiguate-identical-names.stderr b/src/test/ui/disambiguate-identical-names.stderr index 0c6bd9379f7..42925cfed55 100644 --- a/src/test/ui/disambiguate-identical-names.stderr +++ b/src/test/ui/disambiguate-identical-names.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/disambiguate-identical-names.rs:13:10 | LL | test(&v); - | ^^ expected struct `std::vec::Vec`, found struct `HashMap` + | ---- ^^ expected struct `std::vec::Vec`, found struct `HashMap` + | | + | arguments to this function are incorrect | = note: expected reference `&std::vec::Vec<std::vec::Vec<u32>>` found reference `&HashMap<u8, u8>` +note: function defined here + --> $DIR/disambiguate-identical-names.rs:6:4 + | +LL | fn test(_v: &Vec<Vec<u32>>) { + | ^^^^ ------------------ error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0057.stderr b/src/test/ui/error-codes/E0057.stderr index 31579e28289..a151b20f865 100644 --- a/src/test/ui/error-codes/E0057.stderr +++ b/src/test/ui/error-codes/E0057.stderr @@ -2,17 +2,23 @@ error[E0057]: this function takes 1 argument but 0 arguments were supplied --> $DIR/E0057.rs:3:13 | LL | let a = f(); - | ^-- supplied 0 arguments - | | - | expected 1 argument + | ^-- an argument is missing + | +help: provide the argument + | +LL | let a = f({_}); + | ~~~~~~ error[E0057]: this function takes 1 argument but 2 arguments were supplied --> $DIR/E0057.rs:5:13 | LL | let c = f(2, 3); - | ^ - - supplied 2 arguments - | | - | expected 1 argument + | ^ - argument unexpected + | +help: remove the extra argument + | +LL | let c = f(2); + | ~~~~ error: aborting due to 2 previous errors diff --git a/src/test/ui/error-codes/E0060.rs b/src/test/ui/error-codes/E0060.rs index 941eb2a210b..7050a1dff6c 100644 --- a/src/test/ui/error-codes/E0060.rs +++ b/src/test/ui/error-codes/E0060.rs @@ -5,5 +5,4 @@ extern "C" { fn main() { unsafe { printf(); } //~^ ERROR E0060 - //~| expected at least 1 argument } diff --git a/src/test/ui/error-codes/E0060.stderr b/src/test/ui/error-codes/E0060.stderr index c80014d1476..9dd649239e2 100644 --- a/src/test/ui/error-codes/E0060.stderr +++ b/src/test/ui/error-codes/E0060.stderr @@ -2,15 +2,17 @@ error[E0060]: this function takes at least 1 argument but 0 arguments were suppl --> $DIR/E0060.rs:6:14 | LL | unsafe { printf(); } - | ^^^^^^-- supplied 0 arguments - | | - | expected at least 1 argument + | ^^^^^^-- an argument of type `*const u8` is missing | note: function defined here --> $DIR/E0060.rs:2:8 | LL | fn printf(_: *const u8, ...) -> u32; | ^^^^^^ +help: provide the argument + | +LL | unsafe { printf({*const u8}); } + | ~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0061.rs b/src/test/ui/error-codes/E0061.rs index c7b5fe4310e..b6fae6c63d7 100644 --- a/src/test/ui/error-codes/E0061.rs +++ b/src/test/ui/error-codes/E0061.rs @@ -5,9 +5,7 @@ fn f2(a: u16) {} fn main() { f(0); //~^ ERROR E0061 - //~| expected 2 arguments f2(); //~^ ERROR E0061 - //~| expected 1 argument } diff --git a/src/test/ui/error-codes/E0061.stderr b/src/test/ui/error-codes/E0061.stderr index 98488a2d298..f92c548f2de 100644 --- a/src/test/ui/error-codes/E0061.stderr +++ b/src/test/ui/error-codes/E0061.stderr @@ -2,29 +2,33 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/E0061.rs:6:5 | LL | f(0); - | ^ - supplied 1 argument - | | - | expected 2 arguments + | ^--- an argument of type `&str` is missing | note: function defined here --> $DIR/E0061.rs:1:4 | LL | fn f(a: u16, b: &str) {} | ^ ------ ------- +help: provide the argument + | +LL | f(0, {&str}); + | ~~~~~~~~~~~~ error[E0061]: this function takes 1 argument but 0 arguments were supplied - --> $DIR/E0061.rs:10:5 + --> $DIR/E0061.rs:9:5 | LL | f2(); - | ^^-- supplied 0 arguments - | | - | expected 1 argument + | ^^-- an argument of type `u16` is missing | note: function defined here --> $DIR/E0061.rs:3:4 | LL | fn f2(a: u16) {} | ^^ ------ +help: provide the argument + | +LL | f2({u16}); + | ~~~~~~~~~ error: aborting due to 2 previous errors diff --git a/src/test/ui/estr-subtyping.rs b/src/test/ui/estr-subtyping.rs new file mode 100644 index 00000000000..9c5825fff85 --- /dev/null +++ b/src/test/ui/estr-subtyping.rs @@ -0,0 +1,15 @@ +fn wants_uniq(x: String) { } +fn wants_slice(x: &str) { } + +fn has_uniq(x: String) { + wants_uniq(x); + wants_slice(&*x); +} + +fn has_slice(x: &str) { + wants_uniq(x); //~ ERROR mismatched types + wants_slice(x); +} + +fn main() { +} diff --git a/src/test/ui/estr-subtyping.stderr b/src/test/ui/estr-subtyping.stderr new file mode 100644 index 00000000000..adebb7d1e63 --- /dev/null +++ b/src/test/ui/estr-subtyping.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/estr-subtyping.rs:10:15 + | +LL | wants_uniq(x); + | ---------- ^- help: try using a conversion method: `.to_string()` + | | | + | | expected struct `String`, found `&str` + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/estr-subtyping.rs:1:4 + | +LL | fn wants_uniq(x: String) { } + | ^^^^^^^^^^ --------- + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs b/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs deleted file mode 100644 index 05a5d4e1422..00000000000 --- a/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs +++ /dev/null @@ -1,7 +0,0 @@ -#[derive(Default)] //~ ERROR deriving `Default` on enums is experimental -enum Foo { - #[default] - Alpha, -} - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr b/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr deleted file mode 100644 index 58dd4d508a7..00000000000 --- a/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0658]: deriving `Default` on enums is experimental - --> $DIR/feature-gate-derive_default_enum.rs:1:10 - | -LL | #[derive(Default)] - | ^^^^^^^ - | - = note: see issue #86985 <https://github.com/rust-lang/rust/issues/86985> for more information - = help: add `#![feature(derive_default_enum)]` to the crate attributes to enable - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/fmt/ifmt-bad-arg.stderr b/src/test/ui/fmt/ifmt-bad-arg.stderr index 3f1f1006713..c25da900951 100644 --- a/src/test/ui/fmt/ifmt-bad-arg.stderr +++ b/src/test/ui/fmt/ifmt-bad-arg.stderr @@ -296,20 +296,36 @@ error[E0308]: mismatched types --> $DIR/ifmt-bad-arg.rs:78:32 | LL | println!("{} {:.*} {}", 1, 3.2, 4); - | ^^^ expected `usize`, found floating-point number + | ---------------------------^^^---- + | | | + | | expected `usize`, found floating-point number + | arguments to this function are incorrect | = note: expected reference `&usize` found reference `&{float}` +note: associated function defined here + --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL + | +LL | pub fn from_usize(x: &usize) -> ArgumentV1<'_> { + | ^^^^^^^^^^ = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/ifmt-bad-arg.rs:81:35 | LL | println!("{} {:07$.*} {}", 1, 3.2, 4); - | ^^^ expected `usize`, found floating-point number + | ------------------------------^^^---- + | | | + | | expected `usize`, found floating-point number + | arguments to this function are incorrect | = note: expected reference `&usize` found reference `&{float}` +note: associated function defined here + --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL + | +LL | pub fn from_usize(x: &usize) -> ArgumentV1<'_> { + | ^^^^^^^^^^ = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 36 previous errors diff --git a/src/test/ui/fn/fn-item-type.rs b/src/test/ui/fn/fn-item-type.rs index 415e87b42fa..16a0c10ea3a 100644 --- a/src/test/ui/fn/fn-item-type.rs +++ b/src/test/ui/fn/fn-item-type.rs @@ -12,7 +12,7 @@ impl<T> Foo for T { /* `foo` is still default here */ } fn main() { eq(foo::<u8>, bar::<u8>); //~^ ERROR mismatched types - //~| expected fn item `fn(_) -> _ {foo::<u8>}` + //~| expected type `fn(_) -> _ {foo::<u8>}` //~| found fn item `fn(_) -> _ {bar::<u8>}` //~| expected fn item, found a different fn item //~| different `fn` items always have unique types, even if their signatures are the same @@ -28,7 +28,7 @@ fn main() { eq(bar::<String>, bar::<Vec<u8>>); //~^ ERROR mismatched types - //~| expected fn item `fn(_) -> _ {bar::<String>}` + //~| expected type `fn(_) -> _ {bar::<String>}` //~| found fn item `fn(_) -> _ {bar::<Vec<u8>>}` //~| expected struct `String`, found struct `Vec` //~| different `fn` items always have unique types, even if their signatures are the same @@ -45,7 +45,7 @@ fn main() { eq(foo::<u8>, bar::<u8> as fn(isize) -> isize); //~^ ERROR mismatched types - //~| expected fn item `fn(_) -> _ {foo::<u8>}` + //~| expected type `fn(_) -> _ {foo::<u8>}` //~| found fn pointer `fn(_) -> _` //~| expected fn item, found fn pointer //~| change the expected type to be function pointer diff --git a/src/test/ui/fn/fn-item-type.stderr b/src/test/ui/fn/fn-item-type.stderr index 4bd51a668a6..1fb120eb7a7 100644 --- a/src/test/ui/fn/fn-item-type.stderr +++ b/src/test/ui/fn/fn-item-type.stderr @@ -2,60 +2,95 @@ error[E0308]: mismatched types --> $DIR/fn-item-type.rs:13:19 | LL | eq(foo::<u8>, bar::<u8>); - | ^^^^^^^^^ expected fn item, found a different fn item + | -- ^^^^^^^^^ expected fn item, found a different fn item + | | + | arguments to this function are incorrect | - = note: expected fn item `fn(_) -> _ {foo::<u8>}` - found fn item `fn(_) -> _ {bar::<u8>}` + = note: expected type `fn(_) -> _ {foo::<u8>}` + found fn item `fn(_) -> _ {bar::<u8>}` = note: different `fn` items always have unique types, even if their signatures are the same = help: change the expected type to be function pointer `fn(isize) -> isize` = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `foo::<u8> as fn(isize) -> isize` +note: function defined here + --> $DIR/fn-item-type.rs:7:4 + | +LL | fn eq<T>(x: T, y: T) { } + | ^^ ---- ---- error[E0308]: mismatched types --> $DIR/fn-item-type.rs:22:19 | LL | eq(foo::<u8>, foo::<i8>); - | ^^^^^^^^^ expected `u8`, found `i8` + | -- ^^^^^^^^^ expected `u8`, found `i8` + | | + | arguments to this function are incorrect | - = note: expected fn item `fn(_) -> _ {foo::<u8>}` - found fn item `fn(_) -> _ {foo::<i8>}` + = note: expected type `fn(_) -> _ {foo::<u8>}` + found fn item `fn(_) -> _ {foo::<i8>}` = note: different `fn` items always have unique types, even if their signatures are the same = help: change the expected type to be function pointer `fn(isize) -> isize` = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `foo::<u8> as fn(isize) -> isize` +note: function defined here + --> $DIR/fn-item-type.rs:7:4 + | +LL | fn eq<T>(x: T, y: T) { } + | ^^ ---- ---- error[E0308]: mismatched types --> $DIR/fn-item-type.rs:29:23 | LL | eq(bar::<String>, bar::<Vec<u8>>); - | ^^^^^^^^^^^^^^ expected struct `String`, found struct `Vec` + | -- ^^^^^^^^^^^^^^ expected struct `String`, found struct `Vec` + | | + | arguments to this function are incorrect | - = note: expected fn item `fn(_) -> _ {bar::<String>}` - found fn item `fn(_) -> _ {bar::<Vec<u8>>}` + = note: expected type `fn(_) -> _ {bar::<String>}` + found fn item `fn(_) -> _ {bar::<Vec<u8>>}` = note: different `fn` items always have unique types, even if their signatures are the same = help: change the expected type to be function pointer `fn(isize) -> isize` = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `bar::<String> as fn(isize) -> isize` +note: function defined here + --> $DIR/fn-item-type.rs:7:4 + | +LL | fn eq<T>(x: T, y: T) { } + | ^^ ---- ---- error[E0308]: mismatched types --> $DIR/fn-item-type.rs:39:26 | LL | eq(<u8 as Foo>::foo, <u16 as Foo>::foo); - | ^^^^^^^^^^^^^^^^^ expected `u8`, found `u16` + | -- ^^^^^^^^^^^^^^^^^ expected `u8`, found `u16` + | | + | arguments to this function are incorrect | - = note: expected fn item `fn() {<u8 as Foo>::foo}` - found fn item `fn() {<u16 as Foo>::foo}` + = note: expected type `fn() {<u8 as Foo>::foo}` + found fn item `fn() {<u16 as Foo>::foo}` = note: different `fn` items always have unique types, even if their signatures are the same = help: change the expected type to be function pointer `fn()` = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `<u8 as Foo>::foo as fn()` +note: function defined here + --> $DIR/fn-item-type.rs:7:4 + | +LL | fn eq<T>(x: T, y: T) { } + | ^^ ---- ---- error[E0308]: mismatched types --> $DIR/fn-item-type.rs:46:19 | LL | eq(foo::<u8>, bar::<u8> as fn(isize) -> isize); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found fn pointer + | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found fn pointer + | | + | arguments to this function are incorrect | - = note: expected fn item `fn(_) -> _ {foo::<u8>}` + = note: expected type `fn(_) -> _ {foo::<u8>}` found fn pointer `fn(_) -> _` = help: change the expected type to be function pointer `fn(isize) -> isize` = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `foo::<u8> as fn(isize) -> isize` +note: function defined here + --> $DIR/fn-item-type.rs:7:4 + | +LL | fn eq<T>(x: T, y: T) { } + | ^^ ---- ---- error: aborting due to 5 previous errors diff --git a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs index 26deb598762..e48ab4aa96f 100644 --- a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs +++ b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs @@ -8,15 +8,7 @@ where //~^ ERROR cannot find type `T` in this scope //~| NOTE not found in this scope { - // The part where it claims that there is no method named `len` is a bug. Feel free to fix it. - // This test is intended to ensure that a different bug, where it claimed - // that `v` was a function, does not regress. fn method(v: Vec<u8>) { v.len(); } - //~^ ERROR type annotations needed - //~| NOTE cannot infer type - //~| NOTE type must be known at this point - //~| ERROR no method named `len` - //~| NOTE private field, not a method } fn main() {} diff --git a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr index 958ce3c25d0..26bdf460f5e 100644 --- a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr +++ b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr @@ -12,21 +12,6 @@ error[E0412]: cannot find type `T` in this scope LL | T: Copy, | ^ not found in this scope -error[E0282]: type annotations needed - --> $DIR/fn-help-with-err-generic-is-not-function.rs:14:31 - | -LL | fn method(v: Vec<u8>) { v.len(); } - | ^^^ cannot infer type - | - = note: type must be known at this point - -error[E0599]: no method named `len` found for struct `Vec<u8>` in the current scope - --> $DIR/fn-help-with-err-generic-is-not-function.rs:14:31 - | -LL | fn method(v: Vec<u8>) { v.len(); } - | ^^^ private field, not a method - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0282, E0412, E0599. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/generic-associated-types/issue-68648-2.stderr b/src/test/ui/generic-associated-types/issue-68648-2.stderr index 7a7d5a6c231..06c1efcd80b 100644 --- a/src/test/ui/generic-associated-types/issue-68648-2.stderr +++ b/src/test/ui/generic-associated-types/issue-68648-2.stderr @@ -4,10 +4,17 @@ error[E0308]: mismatched types LL | fn bug<'a, T: Fun<F<'a> = T>>(t: T) -> T::F<'a> { | - this type parameter LL | T::identity(()) - | ^^ expected type parameter `T`, found `()` + | ----------- ^^ expected type parameter `T`, found `()` + | | + | arguments to this function are incorrect | = note: expected type parameter `T` found unit type `()` +note: associated function defined here + --> $DIR/issue-68648-2.rs:6:8 + | +LL | fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t } + | ^^^^^^^^ -------------- error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/missing-bounds.stderr b/src/test/ui/generic-associated-types/missing-bounds.stderr index c9603b8d1ea..240be93cf96 100644 --- a/src/test/ui/generic-associated-types/missing-bounds.stderr +++ b/src/test/ui/generic-associated-types/missing-bounds.stderr @@ -17,10 +17,17 @@ LL | impl<B> Add for A<B> where B: Add { | - this type parameter ... LL | A(self.0 + rhs.0) - | ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type + | - ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type + | | + | arguments to this struct are incorrect | = note: expected type parameter `B` found associated type `<B as Add>::Output` +note: tuple struct defined here + --> $DIR/missing-bounds.rs:5:8 + | +LL | struct A<B>(B); + | ^ help: consider further restricting this bound | LL | impl<B> Add for A<B> where B: Add + Add<Output = B> { @@ -33,10 +40,17 @@ LL | impl<B: Add> Add for C<B> { | - this type parameter ... LL | Self(self.0 + rhs.0) - | ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type + | ---- ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type + | | + | arguments to this function are incorrect | = note: expected type parameter `B` found associated type `<B as Add>::Output` +note: tuple struct defined here + --> $DIR/missing-bounds.rs:15:8 + | +LL | struct C<B>(B); + | ^ help: consider further restricting this bound | LL | impl<B: Add + Add<Output = B>> Add for C<B> { @@ -62,10 +76,17 @@ LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B { | - this type parameter ... LL | Self(self.0 + rhs.0) - | ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type + | ---- ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type + | | + | arguments to this function are incorrect | = note: expected type parameter `B` found associated type `<B as Add>::Output` +note: tuple struct defined here + --> $DIR/missing-bounds.rs:35:8 + | +LL | struct E<B>(B); + | ^ help: consider further restricting type parameter `B` | LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B, B: Add<Output = B> { diff --git a/src/test/ui/hello.rs b/src/test/ui/hello.rs index c207c25545e..c66b7c60fb4 100644 --- a/src/test/ui/hello.rs +++ b/src/test/ui/hello.rs @@ -1,5 +1,12 @@ // run-pass +// revisions: e2015 e2018 e2021 e2024 -pub fn main() { - println!("hello, world"); +//[e2018] edition:2018 +//[e2021] edition:2021 +//[e2024] edition:2024 + +//[e2024] compile-flags: -Zunstable-options + +fn main() { + println!("hello"); } diff --git a/src/test/ui/hello2021.rs b/src/test/ui/hello2021.rs deleted file mode 100644 index 134d8af5bfb..00000000000 --- a/src/test/ui/hello2021.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// edition:2021 - -fn main() { - println!("hello, 2021"); -} diff --git a/src/test/ui/hrtb/issue-58451.stderr b/src/test/ui/hrtb/issue-58451.stderr index 2cc1c7a2e72..d2b3b1c2aa0 100644 --- a/src/test/ui/hrtb/issue-58451.stderr +++ b/src/test/ui/hrtb/issue-58451.stderr @@ -2,15 +2,17 @@ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/issue-58451.rs:12:9 | LL | f(&[f()]); - | ^-- supplied 0 arguments - | | - | expected 1 argument + | ^-- an argument is missing | note: function defined here --> $DIR/issue-58451.rs:5:4 | LL | fn f<I>(i: I) | ^ ---- +help: provide the argument + | +LL | f(&[f({_})]); + | ~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/issues/issue-74282.stderr b/src/test/ui/impl-trait/issues/issue-74282.stderr index 6e02a6b2b87..0f855ef5792 100644 --- a/src/test/ui/impl-trait/issues/issue-74282.stderr +++ b/src/test/ui/impl-trait/issues/issue-74282.stderr @@ -5,7 +5,9 @@ LL | type Closure = impl Fn() -> u64; | ---------------- the expected opaque type ... LL | Anonymous(|| { - | _______________^ + | _____---------_^ + | | | + | | arguments to this struct are incorrect LL | | 3 LL | | }) | |_____^ expected closure, found a different closure @@ -14,6 +16,11 @@ LL | | }) found closure `[closure@$DIR/issue-74282.rs:8:15: 10:6]` = note: no two closures, even if identical, have the same type = help: consider boxing your closure and/or using it as a trait object +note: tuple struct defined here + --> $DIR/issue-74282.rs:4:8 + | +LL | struct Anonymous(Closure); + | ^^^^^^^^^ error[E0308]: mismatched types --> $DIR/issue-74282.rs:8:5 diff --git a/src/test/ui/imports/overlapping_pub_trait.rs b/src/test/ui/imports/overlapping_pub_trait.rs index f5f5d4ed380..69aba3ae9b4 100644 --- a/src/test/ui/imports/overlapping_pub_trait.rs +++ b/src/test/ui/imports/overlapping_pub_trait.rs @@ -4,10 +4,10 @@ * This crate declares two public paths, `m::Tr` and `prelude::_`. Make sure we prefer the former. */ extern crate overlapping_pub_trait_source; +//~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it: +//~| SUGGESTION overlapping_pub_trait_source::m::Tr fn main() { - //~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it: - //~| SUGGESTION overlapping_pub_trait_source::m::Tr use overlapping_pub_trait_source::S; S.method(); //~^ ERROR no method named `method` found for struct `S` in the current scope [E0599] diff --git a/src/test/ui/imports/unnamed_pub_trait.rs b/src/test/ui/imports/unnamed_pub_trait.rs index b06b1e1d07d..c38fb17b976 100644 --- a/src/test/ui/imports/unnamed_pub_trait.rs +++ b/src/test/ui/imports/unnamed_pub_trait.rs @@ -5,10 +5,10 @@ * importing it by name, and instead we suggest importing it by glob. */ extern crate unnamed_pub_trait_source; +//~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it: +//~| SUGGESTION unnamed_pub_trait_source::prelude::*; // trait Tr fn main() { - //~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it: - //~| SUGGESTION unnamed_pub_trait_source::prelude::*; // trait Tr use unnamed_pub_trait_source::S; S.method(); //~^ ERROR no method named `method` found for struct `S` in the current scope [E0599] diff --git a/src/test/ui/indexing-requires-a-uint.stderr b/src/test/ui/indexing-requires-a-uint.stderr index dae11a702fb..a9adff4fade 100644 --- a/src/test/ui/indexing-requires-a-uint.stderr +++ b/src/test/ui/indexing-requires-a-uint.stderr @@ -12,12 +12,15 @@ error[E0308]: mismatched types --> $DIR/indexing-requires-a-uint.rs:12:18 | LL | bar::<isize>(i); // i should not be re-coerced back to an isize - | ^ expected `isize`, found `usize` + | ------------ ^ expected `isize`, found `usize` + | | + | arguments to this function are incorrect | -help: you can convert a `usize` to an `isize` and panic if the converted value doesn't fit +note: function defined here + --> $DIR/indexing-requires-a-uint.rs:5:8 | -LL | bar::<isize>(i.try_into().unwrap()); // i should not be re-coerced back to an isize - | ++++++++++++++++++++ +LL | fn bar<T>(_: T) {} + | ^^^ ---- error: aborting due to 2 previous errors diff --git a/src/test/ui/inference/deref-suggestion.stderr b/src/test/ui/inference/deref-suggestion.stderr index 28c9afaa52c..8ba9dacb4b2 100644 --- a/src/test/ui/inference/deref-suggestion.stderr +++ b/src/test/ui/inference/deref-suggestion.stderr @@ -2,16 +2,30 @@ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:8:9 | LL | foo(s); - | ^- help: try using a conversion method: `.to_string()` - | | - | expected struct `String`, found `&String` + | --- ^- help: try using a conversion method: `.to_string()` + | | | + | | expected struct `String`, found `&String` + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/deref-suggestion.rs:5:4 + | +LL | fn foo(_: String) {} + | ^^^ --------- error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:14:10 | LL | foo3(u); - | ^ expected `u32`, found `&u32` + | ---- ^ expected `u32`, found `&u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/deref-suggestion.rs:12:4 | +LL | fn foo3(_: u32) {} + | ^^^^ ------ help: consider dereferencing the borrow | LL | foo3(*u); @@ -21,8 +35,15 @@ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:30:9 | LL | foo(&"aaa".to_owned()); - | ^^^^^^^^^^^^^^^^^ expected struct `String`, found `&String` + | --- ^^^^^^^^^^^^^^^^^ expected struct `String`, found `&String` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/deref-suggestion.rs:5:4 + | +LL | fn foo(_: String) {} + | ^^^ --------- help: consider removing the borrow | LL - foo(&"aaa".to_owned()); @@ -33,8 +54,15 @@ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:32:9 | LL | foo(&mut "aaa".to_owned()); - | ^^^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String` + | --- ^^^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/deref-suggestion.rs:5:4 | +LL | fn foo(_: String) {} + | ^^^ --------- help: consider removing the borrow | LL - foo(&mut "aaa".to_owned()); @@ -48,8 +76,15 @@ LL | ($x:expr) => { &$x } | ^^^ expected `u32`, found `&{integer}` ... LL | foo3(borrow!(0)); - | ---------- in this macro invocation + | ---- ---------- in this macro invocation + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/deref-suggestion.rs:12:4 | +LL | fn foo3(_: u32) {} + | ^^^^ ------ = note: this error originates in the macro `borrow` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types diff --git a/src/test/ui/inference/tutorial-suffix-inference-test.stderr b/src/test/ui/inference/tutorial-suffix-inference-test.stderr index fbfbffbd24e..d83a1367dbf 100644 --- a/src/test/ui/inference/tutorial-suffix-inference-test.stderr +++ b/src/test/ui/inference/tutorial-suffix-inference-test.stderr @@ -2,8 +2,15 @@ error[E0308]: mismatched types --> $DIR/tutorial-suffix-inference-test.rs:9:18 | LL | identity_u16(x); - | ^ expected `u16`, found `u8` + | ------------ ^ expected `u16`, found `u8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/tutorial-suffix-inference-test.rs:6:8 + | +LL | fn identity_u16(n: u16) -> u16 { n } + | ^^^^^^^^^^^^ ------ help: you can convert a `u8` to a `u16` | LL | identity_u16(x.into()); @@ -13,8 +20,15 @@ error[E0308]: mismatched types --> $DIR/tutorial-suffix-inference-test.rs:12:18 | LL | identity_u16(y); - | ^ expected `u16`, found `i32` + | ------------ ^ expected `u16`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/tutorial-suffix-inference-test.rs:6:8 | +LL | fn identity_u16(n: u16) -> u16 { n } + | ^^^^^^^^^^^^ ------ help: you can convert an `i32` to a `u16` and panic if the converted value doesn't fit | LL | identity_u16(y.try_into().unwrap()); @@ -24,8 +38,15 @@ error[E0308]: mismatched types --> $DIR/tutorial-suffix-inference-test.rs:21:18 | LL | identity_u16(a); - | ^ expected `u16`, found `isize` + | ------------ ^ expected `u16`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/tutorial-suffix-inference-test.rs:6:8 | +LL | fn identity_u16(n: u16) -> u16 { n } + | ^^^^^^^^^^^^ ------ help: you can convert an `isize` to a `u16` and panic if the converted value doesn't fit | LL | identity_u16(a.try_into().unwrap()); diff --git a/src/test/ui/issues/issue-10764.stderr b/src/test/ui/issues/issue-10764.stderr index b0bafc9942e..4d8a85a1397 100644 --- a/src/test/ui/issues/issue-10764.stderr +++ b/src/test/ui/issues/issue-10764.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/issue-10764.rs:4:15 | LL | fn main() { f(bar) } - | ^^^ expected "Rust" fn, found "C" fn + | - ^^^ expected "Rust" fn, found "C" fn + | | + | arguments to this function are incorrect | = note: expected fn pointer `fn()` found fn item `extern "C" fn() {bar}` +note: function defined here + --> $DIR/issue-10764.rs:1:4 + | +LL | fn f(_: extern "Rust" fn()) {} + | ^ --------------------- error: aborting due to previous error diff --git a/src/test/ui/issues/issue-11374.stderr b/src/test/ui/issues/issue-11374.stderr index d6a3e758de8..3a1d43310e2 100644 --- a/src/test/ui/issues/issue-11374.stderr +++ b/src/test/ui/issues/issue-11374.stderr @@ -2,13 +2,19 @@ error[E0308]: mismatched types --> $DIR/issue-11374.rs:26:15 | LL | c.read_to(v); - | ^ - | | - | expected `&mut [u8]`, found struct `Vec` - | help: consider mutably borrowing here: `&mut v` + | ------- ^ + | | | + | | expected `&mut [u8]`, found struct `Vec` + | | help: consider mutably borrowing here: `&mut v` + | arguments to this function are incorrect | = note: expected mutable reference `&mut [u8]` found struct `Vec<_>` +note: associated function defined here + --> $DIR/issue-11374.rs:13:12 + | +LL | pub fn read_to(&mut self, vec: &mut [u8]) { + | ^^^^^^^ --------- -------------- error: aborting due to previous error diff --git a/src/test/ui/issues/issue-12997-2.stderr b/src/test/ui/issues/issue-12997-2.stderr index 3b89e8bc451..2a3d0e3457b 100644 --- a/src/test/ui/issues/issue-12997-2.stderr +++ b/src/test/ui/issues/issue-12997-2.stderr @@ -4,8 +4,16 @@ error[E0308]: mismatched types LL | #[bench] | -------- in this procedural macro expansion LL | fn bar(x: isize) { } - | ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `&mut Bencher` + | ^^^^^^^^^^^^^^^^^^^^ + | | + | expected `isize`, found `&mut Bencher` + | arguments to this function are incorrect | +note: function defined here + --> $DIR/issue-12997-2.rs:8:4 + | +LL | fn bar(x: isize) { } + | ^^^ -------- = note: this error originates in the attribute macro `bench` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-13359.stderr b/src/test/ui/issues/issue-13359.stderr index 075c92e65de..db6283ea11f 100644 --- a/src/test/ui/issues/issue-13359.stderr +++ b/src/test/ui/issues/issue-13359.stderr @@ -2,23 +2,29 @@ error[E0308]: mismatched types --> $DIR/issue-13359.rs:6:9 | LL | foo(1*(1 as isize)); - | ^^^^^^^^^^^^^^ expected `i16`, found `isize` + | --- ^^^^^^^^^^^^^^ expected `i16`, found `isize` + | | + | arguments to this function are incorrect | -help: you can convert an `isize` to an `i16` and panic if the converted value doesn't fit +note: function defined here + --> $DIR/issue-13359.rs:1:4 | -LL | foo((1*(1 as isize)).try_into().unwrap()); - | + +++++++++++++++++++++ +LL | fn foo(_s: i16) { } + | ^^^ ------- error[E0308]: mismatched types --> $DIR/issue-13359.rs:10:9 | LL | bar(1*(1 as usize)); - | ^^^^^^^^^^^^^^ expected `u32`, found `usize` + | --- ^^^^^^^^^^^^^^ expected `u32`, found `usize` + | | + | arguments to this function are incorrect | -help: you can convert a `usize` to a `u32` and panic if the converted value doesn't fit +note: function defined here + --> $DIR/issue-13359.rs:3:4 | -LL | bar((1*(1 as usize)).try_into().unwrap()); - | + +++++++++++++++++++++ +LL | fn bar(_s: u32) { } + | ^^^ ------- error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-13853.stderr b/src/test/ui/issues/issue-13853.stderr index 527e0225eb9..657bda5f62b 100644 --- a/src/test/ui/issues/issue-13853.stderr +++ b/src/test/ui/issues/issue-13853.stderr @@ -20,13 +20,19 @@ error[E0308]: mismatched types --> $DIR/issue-13853.rs:37:13 | LL | iterate(graph); - | ^^^^^ - | | - | expected reference, found struct `Vec` - | help: consider borrowing here: `&graph` + | ------- ^^^^^ + | | | + | | expected reference, found struct `Vec` + | | help: consider borrowing here: `&graph` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `Vec<Stuff>` +note: function defined here + --> $DIR/issue-13853.rs:26:4 + | +LL | fn iterate<N: Node, G: Graph<N>>(graph: &G) { + | ^^^^^^^ --------- error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-1448-2.stderr b/src/test/ui/issues/issue-1448-2.stderr index da44566d075..203dd92c9fb 100644 --- a/src/test/ui/issues/issue-1448-2.stderr +++ b/src/test/ui/issues/issue-1448-2.stderr @@ -2,8 +2,15 @@ error[E0308]: mismatched types --> $DIR/issue-1448-2.rs:6:24 | LL | println!("{}", foo(10i32)); - | ^^^^^ expected `u32`, found `i32` + | --- ^^^^^ expected `u32`, found `i32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/issue-1448-2.rs:3:4 + | +LL | fn foo(a: u32) -> u32 { a } + | ^^^ ------ help: change the type of the numeric literal from `i32` to `u32` | LL | println!("{}", foo(10u32)); diff --git a/src/test/ui/issues/issue-15783.stderr b/src/test/ui/issues/issue-15783.stderr index 0b09751676e..660dfe9ed3d 100644 --- a/src/test/ui/issues/issue-15783.stderr +++ b/src/test/ui/issues/issue-15783.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/issue-15783.rs:8:19 | LL | let msg = foo(x); - | ^ expected slice `[&str]`, found array `[&str; 1]` + | --- ^ expected slice `[&str]`, found array `[&str; 1]` + | | + | arguments to this function are incorrect | = note: expected enum `Option<&[&str]>` found enum `Option<&[&str; 1]>` +note: function defined here + --> $DIR/issue-15783.rs:1:8 + | +LL | pub fn foo(params: Option<&[&str]>) -> usize { + | ^^^ ----------------------- error: aborting due to previous error diff --git a/src/test/ui/issues/issue-16939.stderr b/src/test/ui/issues/issue-16939.stderr index 8e4237039fa..294524f0b61 100644 --- a/src/test/ui/issues/issue-16939.stderr +++ b/src/test/ui/issues/issue-16939.stderr @@ -2,15 +2,17 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/issue-16939.rs:5:9 | LL | |t| f(t); - | ^ - supplied 1 argument - | | - | expected 0 arguments + | ^ - argument unexpected | note: associated function defined here --> $SRC_DIR/core/src/ops/function.rs:LL:COL | LL | extern "rust-call" fn call(&self, args: Args) -> Self::Output; | ^^^^ +help: remove the extra argument + | +LL | |t| f(); + | ~~~ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17033.stderr b/src/test/ui/issues/issue-17033.stderr index 518fc30142c..f26bee5ff45 100644 --- a/src/test/ui/issues/issue-17033.stderr +++ b/src/test/ui/issues/issue-17033.stderr @@ -2,10 +2,11 @@ error[E0308]: mismatched types --> $DIR/issue-17033.rs:2:10 | LL | (*p)(()) - | ^^ - | | - | expected `&mut ()`, found `()` - | help: consider mutably borrowing here: `&mut ()` + | ---- ^^ + | | | + | | expected `&mut ()`, found `()` + | | help: consider mutably borrowing here: `&mut ()` + | arguments to this function are incorrect error: aborting due to previous error diff --git a/src/test/ui/issues/issue-18819.stderr b/src/test/ui/issues/issue-18819.stderr index b10d26abe34..db228fded6e 100644 --- a/src/test/ui/issues/issue-18819.stderr +++ b/src/test/ui/issues/issue-18819.stderr @@ -2,15 +2,26 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/issue-18819.rs:16:5 | LL | print_x(X); - | ^^^^^^^ - supplied 1 argument - | | - | expected 2 arguments + | ^^^^^^^--- + | || + | |expected reference, found struct `X` + | an argument of type `&str` is missing | + = note: expected reference `&dyn Foo<Item = bool>` + found struct `X` note: function defined here --> $DIR/issue-18819.rs:11:4 | LL | fn print_x(_: &dyn Foo<Item=bool>, extra: &str) { | ^^^^^^^ ---------------------- ----------- +help: consider borrowing here + | +LL | print_x(&X); + | ~~ +help: provide the argument + | +LL | print_x({&dyn Foo<Item = bool>}, {&str}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-24819.stderr b/src/test/ui/issues/issue-24819.stderr index 2f931e59d59..982a11fef80 100644 --- a/src/test/ui/issues/issue-24819.stderr +++ b/src/test/ui/issues/issue-24819.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/issue-24819.rs:5:9 | LL | foo(&mut v); - | ^^^^^^ expected struct `HashSet`, found struct `Vec` + | --- ^^^^^^ expected struct `HashSet`, found struct `Vec` + | | + | arguments to this function are incorrect | = note: expected mutable reference `&mut HashSet<u32>` found mutable reference `&mut Vec<_>` +note: function defined here + --> $DIR/issue-24819.rs:10:4 + | +LL | fn foo(h: &mut HashSet<u32>) { + | ^^^ -------------------- error: aborting due to previous error diff --git a/src/test/ui/issues/issue-26094.rs b/src/test/ui/issues/issue-26094.rs index 78fb0491d82..981c3abb4ba 100644 --- a/src/test/ui/issues/issue-26094.rs +++ b/src/test/ui/issues/issue-26094.rs @@ -1,6 +1,6 @@ macro_rules! some_macro { ($other: expr) => ({ - $other(None) //~ NOTE supplied 1 argument + $other(None) //~ NOTE argument unexpected }) } @@ -9,5 +9,5 @@ fn some_function() {} //~ NOTE defined here fn main() { some_macro!(some_function); //~^ ERROR this function takes 0 arguments but 1 argument was supplied - //~| NOTE expected 0 arguments + //~| NOTE in this expansion of some_macro! } diff --git a/src/test/ui/issues/issue-26094.stderr b/src/test/ui/issues/issue-26094.stderr index a6f1ac9286c..1013518e1da 100644 --- a/src/test/ui/issues/issue-26094.stderr +++ b/src/test/ui/issues/issue-26094.stderr @@ -2,16 +2,20 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/issue-26094.rs:10:17 | LL | $other(None) - | ---- supplied 1 argument + | ---- argument unexpected ... LL | some_macro!(some_function); - | ^^^^^^^^^^^^^ expected 0 arguments + | ^^^^^^^^^^^^^ | note: function defined here --> $DIR/issue-26094.rs:7:4 | LL | fn some_function() {} | ^^^^^^^^^^^^^ +help: remove the extra argument + | +LL | some_function() + | ~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3044.rs b/src/test/ui/issues/issue-3044.rs index 81d76a90eb0..7363cae8370 100644 --- a/src/test/ui/issues/issue-3044.rs +++ b/src/test/ui/issues/issue-3044.rs @@ -2,5 +2,6 @@ fn main() { let needlesArr: Vec<char> = vec!['a', 'f']; needlesArr.iter().fold(|x, y| { }); - //~^^ ERROR this function takes 2 arguments but 1 argument was supplied + //~^^ ERROR mismatched types + //~| ERROR this function takes 2 arguments but 1 argument was supplied } diff --git a/src/test/ui/issues/issue-3044.stderr b/src/test/ui/issues/issue-3044.stderr index b93aeade95e..5bb07cfda21 100644 --- a/src/test/ui/issues/issue-3044.stderr +++ b/src/test/ui/issues/issue-3044.stderr @@ -1,19 +1,34 @@ +error[E0308]: mismatched types + --> $DIR/issue-3044.rs:3:35 + | +LL | needlesArr.iter().fold(|x, y| { + | ___________________________________^ +LL | | }); + | |_____^ expected closure, found `()` + | + = note: expected closure `[closure@$DIR/issue-3044.rs:3:28: 4:6]` + found unit type `()` + error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/issue-3044.rs:3:23 | LL | needlesArr.iter().fold(|x, y| { - | _______________________^^^^_- - | | | - | | expected 2 arguments + | _______________________^^^^- LL | | }); - | |_____- supplied 1 argument + | |______- an argument is missing | note: associated function defined here --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL | LL | fn fold<B, F>(mut self, init: B, mut f: F) -> B | ^^^^ +help: provide the argument + | +LL ~ needlesArr.iter().fold(|x, y| { +LL ~ }, {_}); + | -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0061`. +Some errors have detailed explanations: E0061, E0308. +For more information about an error, try `rustc --explain E0061`. diff --git a/src/test/ui/issues/issue-43420-no-over-suggest.stderr b/src/test/ui/issues/issue-43420-no-over-suggest.stderr index 77d52f6ecab..58fd1121a6b 100644 --- a/src/test/ui/issues/issue-43420-no-over-suggest.stderr +++ b/src/test/ui/issues/issue-43420-no-over-suggest.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/issue-43420-no-over-suggest.rs:8:9 | LL | foo(&a); - | ^^ expected slice `[u16]`, found struct `Vec` + | --- ^^ expected slice `[u16]`, found struct `Vec` + | | + | arguments to this function are incorrect | = note: expected reference `&[u16]` found reference `&Vec<u8>` +note: function defined here + --> $DIR/issue-43420-no-over-suggest.rs:4:4 + | +LL | fn foo(b: &[u16]) {} + | ^^^ --------- error: aborting due to previous error diff --git a/src/test/ui/issues/issue-4517.stderr b/src/test/ui/issues/issue-4517.stderr index 1ae97b69c6c..70b4ca5ec49 100644 --- a/src/test/ui/issues/issue-4517.stderr +++ b/src/test/ui/issues/issue-4517.stderr @@ -2,7 +2,15 @@ error[E0308]: mismatched types --> $DIR/issue-4517.rs:5:9 | LL | bar(foo); - | ^^^ expected `usize`, found array `[u8; 4]` + | --- ^^^ expected `usize`, found array `[u8; 4]` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/issue-4517.rs:1:4 + | +LL | fn bar(int_param: usize) {} + | ^^^ ---------------- error: aborting due to previous error diff --git a/src/test/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr b/src/test/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr index 2d666e2b66c..e874ded8ec5 100644 --- a/src/test/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr +++ b/src/test/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr @@ -2,19 +2,33 @@ error[E0308]: mismatched types --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:12:42 | LL | light_flows_our_war_of_mocking_words(behold as usize); - | ^^^^^^^^^^^^^^^ - | | - | expected `&usize`, found `usize` - | help: consider borrowing here: `&(behold as usize)` + | ------------------------------------ ^^^^^^^^^^^^^^^ + | | | + | | expected `&usize`, found `usize` + | | help: consider borrowing here: `&(behold as usize)` + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:5:4 + | +LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- error[E0308]: mismatched types --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:14:42 | LL | light_flows_our_war_of_mocking_words(with_tears + 4); - | ^^^^^^^^^^^^^^ - | | - | expected `&usize`, found `usize` - | help: consider borrowing here: `&(with_tears + 4)` + | ------------------------------------ ^^^^^^^^^^^^^^ + | | | + | | expected `&usize`, found `usize` + | | help: consider borrowing here: `&(with_tears + 4)` + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:5:4 + | +LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-48364.stderr b/src/test/ui/issues/issue-48364.stderr index 37a42d2382d..7fd36676df8 100644 --- a/src/test/ui/issues/issue-48364.stderr +++ b/src/test/ui/issues/issue-48364.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/issue-48364.rs:2:21 | LL | b"".starts_with(stringify!(foo)) - | ^^^^^^^^^^^^^^^ expected slice `[u8]`, found `str` + | ----------- ^^^^^^^^^^^^^^^ expected slice `[u8]`, found `str` + | | + | arguments to this function are incorrect | = note: expected reference `&[u8]` found reference `&'static str` +note: associated function defined here + --> $SRC_DIR/core/src/slice/mod.rs:LL:COL + | +LL | pub fn starts_with(&self, needle: &[T]) -> bool + | ^^^^^^^^^^^ = note: this error originates in the macro `stringify` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/issues/issue-4935.stderr b/src/test/ui/issues/issue-4935.stderr index 03b9b91edef..b4cebe2a68b 100644 --- a/src/test/ui/issues/issue-4935.stderr +++ b/src/test/ui/issues/issue-4935.stderr @@ -2,15 +2,17 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/issue-4935.rs:5:13 | LL | fn main() { foo(5, 6) } - | ^^^ - - supplied 2 arguments - | | - | expected 1 argument + | ^^^ - argument unexpected | note: function defined here --> $DIR/issue-4935.rs:3:4 | LL | fn foo(a: usize) {} | ^^^ -------- +help: remove the extra argument + | +LL | fn main() { foo(5) } + | ~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-51154.stderr b/src/test/ui/issues/issue-51154.stderr index 3c3428f3096..f2cbc3e6feb 100644 --- a/src/test/ui/issues/issue-51154.stderr +++ b/src/test/ui/issues/issue-51154.stderr @@ -4,11 +4,18 @@ error[E0308]: mismatched types LL | fn foo<F: FnMut()>() { | - this type parameter LL | let _: Box<F> = Box::new(|| ()); - | ^^^^^ expected type parameter `F`, found closure + | -------- ^^^^^ expected type parameter `F`, found closure + | | + | arguments to this function are incorrect | = note: expected type parameter `F` found closure `[closure@$DIR/issue-51154.rs:2:30: 2:35]` = help: every closure has a distinct type and so could not always match the caller-chosen type of parameter `F` +note: associated function defined here + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + | +LL | pub fn new(x: T) -> Self { + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-5216.stderr b/src/test/ui/issues/issue-5216.stderr index 29c95e4fb62..1afff28f0b4 100644 --- a/src/test/ui/issues/issue-5216.stderr +++ b/src/test/ui/issues/issue-5216.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/issue-5216.rs:3:21 | LL | pub static C: S = S(f); - | ^ expected struct `Box`, found fn item + | - ^ expected struct `Box`, found fn item + | | + | arguments to this struct are incorrect | = note: expected struct `Box<(dyn FnMut() + Sync + 'static)>` found fn item `fn() {f}` +note: tuple struct defined here + --> $DIR/issue-5216.rs:2:8 + | +LL | struct S(Box<dyn FnMut() + Sync>); + | ^ error[E0308]: mismatched types --> $DIR/issue-5216.rs:8:19 diff --git a/src/test/ui/issues/issue-61106.stderr b/src/test/ui/issues/issue-61106.stderr index 2d841d28ee2..2bc09234116 100644 --- a/src/test/ui/issues/issue-61106.stderr +++ b/src/test/ui/issues/issue-61106.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/issue-61106.rs:3:9 | LL | foo(x.clone()); - | ^^^^^^^^^ - | | - | expected `&str`, found struct `String` - | help: consider borrowing here: `&x` + | --- ^^^^^^^^^ + | | | + | | expected `&str`, found struct `String` + | | help: consider borrowing here: `&x` + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/issue-61106.rs:6:4 + | +LL | fn foo(_: &str) {} + | ^^^ ------- error: aborting due to previous error diff --git a/src/test/ui/issues/issue-69306.stderr b/src/test/ui/issues/issue-69306.stderr index 58e85ec700d..61ec5d3180c 100644 --- a/src/test/ui/issues/issue-69306.stderr +++ b/src/test/ui/issues/issue-69306.stderr @@ -4,10 +4,17 @@ error[E0308]: mismatched types LL | impl<T> S0<T> { | - this type parameter LL | const C: S0<u8> = Self(0); - | ^ expected type parameter `T`, found integer + | ---- ^ expected type parameter `T`, found integer + | | + | arguments to this function are incorrect | = note: expected type parameter `T` found type `{integer}` +note: tuple struct defined here + --> $DIR/issue-69306.rs:3:8 + | +LL | struct S0<T>(T); + | ^^ error[E0308]: mismatched types --> $DIR/issue-69306.rs:5:23 @@ -27,10 +34,17 @@ LL | impl<T> S0<T> { | - this type parameter ... LL | Self(0); - | ^ expected type parameter `T`, found integer + | ---- ^ expected type parameter `T`, found integer + | | + | arguments to this function are incorrect | = note: expected type parameter `T` found type `{integer}` +note: tuple struct defined here + --> $DIR/issue-69306.rs:3:8 + | +LL | struct S0<T>(T); + | ^^ error[E0308]: mismatched types --> $DIR/issue-69306.rs:27:14 @@ -39,10 +53,17 @@ LL | impl<T> Foo<T> for <S0<T> as Fun>::Out { | - this type parameter LL | fn foo() { LL | Self(0); - | ^ expected type parameter `T`, found integer + | ---- ^ expected type parameter `T`, found integer + | | + | arguments to this function are incorrect | = note: expected type parameter `T` found type `{integer}` +note: tuple struct defined here + --> $DIR/issue-69306.rs:3:8 + | +LL | struct S0<T>(T); + | ^^ error[E0308]: mismatched types --> $DIR/issue-69306.rs:33:32 @@ -50,10 +71,17 @@ error[E0308]: mismatched types LL | impl<T> S1<T, u8> { | - this type parameter LL | const C: S1<u8, u8> = Self(0, 1); - | ^ expected type parameter `T`, found integer + | ---- ^ expected type parameter `T`, found integer + | | + | arguments to this function are incorrect | = note: expected type parameter `T` found type `{integer}` +note: tuple struct defined here + --> $DIR/issue-69306.rs:31:8 + | +LL | struct S1<T, U>(T, U); + | ^^ error[E0308]: mismatched types --> $DIR/issue-69306.rs:33:27 @@ -74,12 +102,19 @@ LL | impl<T> S2<T> { LL | fn map<U>(x: U) -> S2<U> { | - found type parameter LL | Self(x) - | ^ expected type parameter `T`, found type parameter `U` + | ---- ^ expected type parameter `T`, found type parameter `U` + | | + | arguments to this function are incorrect | = note: expected type parameter `T` found type parameter `U` = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters +note: tuple struct defined here + --> $DIR/issue-69306.rs:38:8 + | +LL | struct S2<T>(T); + | ^^ error[E0308]: mismatched types --> $DIR/issue-69306.rs:41:9 diff --git a/src/test/ui/lint/unaligned_references.stderr b/src/test/ui/lint/unaligned_references.stderr index 53c9380fb7e..ed5dd2ec011 100644 --- a/src/test/ui/lint/unaligned_references.stderr +++ b/src/test/ui/lint/unaligned_references.stderr @@ -82,3 +82,122 @@ LL | let _ = &packed2.x; error: aborting due to 7 previous errors +Future incompatibility report: Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:22:17 + | +LL | let _ = &good.ptr; + | ^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unaligned_references.rs:1:9 + | +LL | #![deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:24:17 + | +LL | let _ = &good.data; + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unaligned_references.rs:1:9 + | +LL | #![deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:27:17 + | +LL | let _ = &good.data as *const _; + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unaligned_references.rs:1:9 + | +LL | #![deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:29:27 + | +LL | let _: *const _ = &good.data; + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unaligned_references.rs:1:9 + | +LL | #![deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:32:17 + | +LL | let _ = good.data.clone(); + | ^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unaligned_references.rs:1:9 + | +LL | #![deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:35:17 + | +LL | let _ = &good.data2[0]; + | ^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unaligned_references.rs:1:9 + | +LL | #![deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:45:17 + | +LL | let _ = &packed2.x; + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unaligned_references.rs:1:9 + | +LL | #![deny(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + diff --git a/src/test/ui/lint/unaligned_references_external_macro.stderr b/src/test/ui/lint/unaligned_references_external_macro.stderr index 01e2395049d..1262c21ee78 100644 --- a/src/test/ui/lint/unaligned_references_external_macro.stderr +++ b/src/test/ui/lint/unaligned_references_external_macro.stderr @@ -29,3 +29,33 @@ LL | | } error: aborting due to previous error +Future incompatibility report: Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/unaligned_references_external_macro.rs:5:1 + | +LL | / unaligned_references_external_crate::mac! { +LL | | +LL | | #[repr(packed)] +LL | | pub struct X { +LL | | pub field: u16 +LL | | } +LL | | } + | |_^ + | +note: the lint level is defined here + --> $DIR/unaligned_references_external_macro.rs:5:1 + | +LL | / unaligned_references_external_crate::mac! { +LL | | +LL | | #[repr(packed)] +LL | | pub struct X { +LL | | pub field: u16 +LL | | } +LL | | } + | |_^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: this error originates in the macro `unaligned_references_external_crate::mac` (in Nightly builds, run with -Z macro-backtrace for more info) + diff --git a/src/test/ui/macros/issue-29084.stderr b/src/test/ui/macros/issue-29084.stderr index a973e23e29e..f83e192130b 100644 --- a/src/test/ui/macros/issue-29084.stderr +++ b/src/test/ui/macros/issue-29084.stderr @@ -2,11 +2,21 @@ error[E0308]: mismatched types --> $DIR/issue-29084.rs:4:13 | LL | bar(&mut $d); - | ^^^^^^^ expected `u8`, found `&mut u8` + | --- ^^^^^^^ expected `u8`, found `&mut u8` + | | + | arguments to this function are incorrect ... LL | foo!(0u8); | --------- in this macro invocation | +note: function defined here + --> $DIR/issue-29084.rs:3:12 + | +LL | fn bar(d: u8) { } + | ^^^ ----- +... +LL | foo!(0u8); + | --------- in this macro invocation = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/macros/macros-nonfatal-errors.rs b/src/test/ui/macros/macros-nonfatal-errors.rs index 98f64aa6f80..e7a01f105de 100644 --- a/src/test/ui/macros/macros-nonfatal-errors.rs +++ b/src/test/ui/macros/macros-nonfatal-errors.rs @@ -5,7 +5,6 @@ #![feature(trace_macros, concat_idents)] #![feature(stmt_expr_attributes, arbitrary_enum_discriminant)] -#![feature(derive_default_enum)] use std::arch::asm; diff --git a/src/test/ui/macros/macros-nonfatal-errors.stderr b/src/test/ui/macros/macros-nonfatal-errors.stderr index 79e8db9c1d4..b3c6d07f967 100644 --- a/src/test/ui/macros/macros-nonfatal-errors.stderr +++ b/src/test/ui/macros/macros-nonfatal-errors.stderr @@ -1,41 +1,41 @@ error: the `#[default]` attribute may only be used on unit enum variants - --> $DIR/macros-nonfatal-errors.rs:14:5 + --> $DIR/macros-nonfatal-errors.rs:13:5 | LL | #[default] | ^^^^^^^^^^ error: the `#[default]` attribute may only be used on unit enum variants - --> $DIR/macros-nonfatal-errors.rs:19:36 + --> $DIR/macros-nonfatal-errors.rs:18:36 | LL | struct DefaultInnerAttrTupleStruct(#[default] ()); | ^^^^^^^^^^ error: the `#[default]` attribute may only be used on unit enum variants - --> $DIR/macros-nonfatal-errors.rs:23:1 + --> $DIR/macros-nonfatal-errors.rs:22:1 | LL | #[default] | ^^^^^^^^^^ error: the `#[default]` attribute may only be used on unit enum variants - --> $DIR/macros-nonfatal-errors.rs:27:1 + --> $DIR/macros-nonfatal-errors.rs:26:1 | LL | #[default] | ^^^^^^^^^^ error: the `#[default]` attribute may only be used on unit enum variants - --> $DIR/macros-nonfatal-errors.rs:37:11 + --> $DIR/macros-nonfatal-errors.rs:36:11 | LL | Foo = #[default] 0, | ^^^^^^^^^^ error: the `#[default]` attribute may only be used on unit enum variants - --> $DIR/macros-nonfatal-errors.rs:38:14 + --> $DIR/macros-nonfatal-errors.rs:37:14 | LL | Bar([u8; #[default] 1]), | ^^^^^^^^^^ error: no default declared - --> $DIR/macros-nonfatal-errors.rs:43:10 + --> $DIR/macros-nonfatal-errors.rs:42:10 | LL | #[derive(Default)] | ^^^^^^^ @@ -44,7 +44,7 @@ LL | #[derive(Default)] = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) error: multiple declared defaults - --> $DIR/macros-nonfatal-errors.rs:49:10 + --> $DIR/macros-nonfatal-errors.rs:48:10 | LL | #[derive(Default)] | ^^^^^^^ @@ -62,7 +62,7 @@ LL | Baz, = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) error: `#[default]` attribute does not accept a value - --> $DIR/macros-nonfatal-errors.rs:61:5 + --> $DIR/macros-nonfatal-errors.rs:60:5 | LL | #[default = 1] | ^^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL | #[default = 1] = help: try using `#[default]` error: multiple `#[default]` attributes - --> $DIR/macros-nonfatal-errors.rs:69:5 + --> $DIR/macros-nonfatal-errors.rs:68:5 | LL | #[default] | ---------- `#[default]` used here @@ -81,13 +81,13 @@ LL | Foo, | = note: only one `#[default]` attribute is needed help: try removing this - --> $DIR/macros-nonfatal-errors.rs:68:5 + --> $DIR/macros-nonfatal-errors.rs:67:5 | LL | #[default] | ^^^^^^^^^^ error: multiple `#[default]` attributes - --> $DIR/macros-nonfatal-errors.rs:79:5 + --> $DIR/macros-nonfatal-errors.rs:78:5 | LL | #[default] | ---------- `#[default]` used here @@ -99,7 +99,7 @@ LL | Foo, | = note: only one `#[default]` attribute is needed help: try removing these - --> $DIR/macros-nonfatal-errors.rs:76:5 + --> $DIR/macros-nonfatal-errors.rs:75:5 | LL | #[default] | ^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | #[default] | ^^^^^^^^^^ error: the `#[default]` attribute may only be used on unit enum variants - --> $DIR/macros-nonfatal-errors.rs:86:5 + --> $DIR/macros-nonfatal-errors.rs:85:5 | LL | Foo {}, | ^^^ @@ -117,7 +117,7 @@ LL | Foo {}, = help: consider a manual implementation of `Default` error: default variant must be exhaustive - --> $DIR/macros-nonfatal-errors.rs:94:5 + --> $DIR/macros-nonfatal-errors.rs:93:5 | LL | #[non_exhaustive] | ----------------- declared `#[non_exhaustive]` here @@ -127,37 +127,37 @@ LL | Foo, = help: consider a manual implementation of `Default` error: asm template must be a string literal - --> $DIR/macros-nonfatal-errors.rs:99:10 + --> $DIR/macros-nonfatal-errors.rs:98:10 | LL | asm!(invalid); | ^^^^^^^ error: concat_idents! requires ident args - --> $DIR/macros-nonfatal-errors.rs:102:5 + --> $DIR/macros-nonfatal-errors.rs:101:5 | LL | concat_idents!("not", "idents"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: argument must be a string literal - --> $DIR/macros-nonfatal-errors.rs:104:17 + --> $DIR/macros-nonfatal-errors.rs:103:17 | LL | option_env!(invalid); | ^^^^^^^ error: expected string literal - --> $DIR/macros-nonfatal-errors.rs:105:10 + --> $DIR/macros-nonfatal-errors.rs:104:10 | LL | env!(invalid); | ^^^^^^^ error: expected string literal - --> $DIR/macros-nonfatal-errors.rs:106:10 + --> $DIR/macros-nonfatal-errors.rs:105:10 | LL | env!(foo, abr, baz); | ^^^ error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined - --> $DIR/macros-nonfatal-errors.rs:107:5 + --> $DIR/macros-nonfatal-errors.rs:106:5 | LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -165,7 +165,7 @@ LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST"); = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) error: format argument must be a string literal - --> $DIR/macros-nonfatal-errors.rs:109:13 + --> $DIR/macros-nonfatal-errors.rs:108:13 | LL | format!(invalid); | ^^^^^^^ @@ -176,19 +176,19 @@ LL | format!("{}", invalid); | +++++ error: argument must be a string literal - --> $DIR/macros-nonfatal-errors.rs:111:14 + --> $DIR/macros-nonfatal-errors.rs:110:14 | LL | include!(invalid); | ^^^^^^^ error: argument must be a string literal - --> $DIR/macros-nonfatal-errors.rs:113:18 + --> $DIR/macros-nonfatal-errors.rs:112:18 | LL | include_str!(invalid); | ^^^^^^^ error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2) - --> $DIR/macros-nonfatal-errors.rs:114:5 + --> $DIR/macros-nonfatal-errors.rs:113:5 | LL | include_str!("i'd be quite surprised if a file with this name existed"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -196,13 +196,13 @@ LL | include_str!("i'd be quite surprised if a file with this name existed") = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info) error: argument must be a string literal - --> $DIR/macros-nonfatal-errors.rs:115:20 + --> $DIR/macros-nonfatal-errors.rs:114:20 | LL | include_bytes!(invalid); | ^^^^^^^ error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2) - --> $DIR/macros-nonfatal-errors.rs:116:5 + --> $DIR/macros-nonfatal-errors.rs:115:5 | LL | include_bytes!("i'd be quite surprised if a file with this name existed"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -210,13 +210,13 @@ LL | include_bytes!("i'd be quite surprised if a file with this name existed = note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info) error: trace_macros! accepts only `true` or `false` - --> $DIR/macros-nonfatal-errors.rs:118:5 + --> $DIR/macros-nonfatal-errors.rs:117:5 | LL | trace_macros!(invalid); | ^^^^^^^^^^^^^^^^^^^^^^ error: cannot find macro `llvm_asm` in this scope - --> $DIR/macros-nonfatal-errors.rs:100:5 + --> $DIR/macros-nonfatal-errors.rs:99:5 | LL | llvm_asm!(invalid); | ^^^^^^^^ diff --git a/src/test/ui/methods/method-call-err-msg.stderr b/src/test/ui/methods/method-call-err-msg.stderr index c410e076dde..53e582f7f13 100644 --- a/src/test/ui/methods/method-call-err-msg.stderr +++ b/src/test/ui/methods/method-call-err-msg.stderr @@ -2,43 +2,49 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/method-call-err-msg.rs:13:7 | LL | x.zero(0) - | ^^^^ - supplied 1 argument - | | - | expected 0 arguments + | ^^^^ - argument unexpected | note: associated function defined here --> $DIR/method-call-err-msg.rs:5:8 | LL | fn zero(self) -> Foo { self } | ^^^^ ---- +help: remove the extra argument + | +LL | x.zero() + | ~~~~~~ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/method-call-err-msg.rs:14:7 | LL | .one() - | ^^^- supplied 0 arguments - | | - | expected 1 argument + | ^^^-- an argument of type `isize` is missing | note: associated function defined here --> $DIR/method-call-err-msg.rs:6:8 | LL | fn one(self, _: isize) -> Foo { self } | ^^^ ---- -------- +help: provide the argument + | +LL | .one({isize}) + | ~~~~~~~~~~~~ error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/method-call-err-msg.rs:15:7 | LL | .two(0); - | ^^^ - supplied 1 argument - | | - | expected 2 arguments + | ^^^--- an argument of type `isize` is missing | note: associated function defined here --> $DIR/method-call-err-msg.rs:7:8 | LL | fn two(self, _: isize, _: isize) -> Foo { self } | ^^^ ---- -------- -------- +help: provide the argument + | +LL | .two(0, {isize}); + | ~~~~~~~~~~~~~~~ error[E0599]: `Foo` is not an iterator --> $DIR/method-call-err-msg.rs:19:7 @@ -74,15 +80,17 @@ error[E0061]: this function takes 3 arguments but 0 arguments were supplied --> $DIR/method-call-err-msg.rs:21:7 | LL | y.three::<usize>(); - | ^^^^^--------- supplied 0 arguments - | | - | expected 3 arguments + | ^^^^^^^^^^^^^^-- three arguments of type `usize`, `usize`, and `usize` are missing | note: associated function defined here --> $DIR/method-call-err-msg.rs:8:8 | LL | fn three<T>(self, _: T, _: T, _: T) -> Foo { self } | ^^^^^ ---- ---- ---- ---- +help: provide the arguments + | +LL | y.three::<usize>({usize}, {usize}, {usize}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 5 previous errors diff --git a/src/test/ui/methods/method-self-arg-1.stderr b/src/test/ui/methods/method-self-arg-1.stderr index 17ea61fc4bd..01fec6fcaae 100644 --- a/src/test/ui/methods/method-self-arg-1.stderr +++ b/src/test/ui/methods/method-self-arg-1.stderr @@ -2,19 +2,33 @@ error[E0308]: mismatched types --> $DIR/method-self-arg-1.rs:11:14 | LL | Foo::bar(x); - | ^ - | | - | expected `&Foo`, found struct `Foo` - | help: consider borrowing here: `&x` + | -------- ^ + | | | + | | expected `&Foo`, found struct `Foo` + | | help: consider borrowing here: `&x` + | arguments to this function are incorrect + | +note: associated function defined here + --> $DIR/method-self-arg-1.rs:6:8 + | +LL | fn bar(&self) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/method-self-arg-1.rs:13:14 | LL | Foo::bar(&42); - | ^^^ expected struct `Foo`, found integer + | -------- ^^^ expected struct `Foo`, found integer + | | + | arguments to this function are incorrect | = note: expected reference `&Foo` found reference `&{integer}` +note: associated function defined here + --> $DIR/method-self-arg-1.rs:6:8 + | +LL | fn bar(&self) {} + | ^^^ ----- error: aborting due to 2 previous errors diff --git a/src/test/ui/mir/issue-92893.rs b/src/test/ui/mir/issue-92893.rs new file mode 100644 index 00000000000..d2bbb4f1101 --- /dev/null +++ b/src/test/ui/mir/issue-92893.rs @@ -0,0 +1,7 @@ +struct Bug<A = [(); (let a = (), 1).1]> { + //~^ `let` expressions are not supported here + //~^^ `let` expressions in this position are unstable [E0658] + a: A +} + +fn main() {} diff --git a/src/test/ui/mir/issue-92893.stderr b/src/test/ui/mir/issue-92893.stderr new file mode 100644 index 00000000000..063b5d66feb --- /dev/null +++ b/src/test/ui/mir/issue-92893.stderr @@ -0,0 +1,20 @@ +error: `let` expressions are not supported here + --> $DIR/issue-92893.rs:1:22 + | +LL | struct Bug<A = [(); (let a = (), 1).1]> { + | ^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error[E0658]: `let` expressions in this position are unstable + --> $DIR/issue-92893.rs:1:22 + | +LL | struct Bug<A = [(); (let a = (), 1).1]> { + | ^^^^^^^^^^ + | + = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information + = help: add `#![feature(let_chains)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs b/src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs new file mode 100644 index 00000000000..cd6c5bf2719 --- /dev/null +++ b/src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs @@ -0,0 +1,10 @@ +// check-pass +// compile-flags: -Zvalidate-mir + +fn foo(_a: &str) {} + +fn main() { + let x = foo as fn(&'static str); + + let _ = x == foo; +} diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index da8a976daaf..579a5b7ecb9 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -1,17 +1,20 @@ error[E0308]: mismatched types --> $DIR/issue-26480.rs:16:19 | +LL | write(stdout, $arr.as_ptr() as *const i8, + | ----- arguments to this function are incorrect LL | $arr.len() * size_of($arr[0])); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found `usize` ... LL | write!(hello); | ------------- in this macro invocation | - = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) -help: you can convert a `usize` to a `u64` and panic if the converted value doesn't fit +note: function defined here + --> $DIR/issue-26480.rs:2:8 | -LL | ($arr.len() * size_of($arr[0])).try_into().unwrap()); - | + +++++++++++++++++++++ +LL | fn write(fildes: i32, buf: *const i8, nbyte: u64) -> i64; + | ^^^^^ + = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0605]: non-primitive cast: `{integer}` as `()` --> $DIR/issue-26480.rs:22:19 diff --git a/src/test/ui/mismatched_types/issue-35030.stderr b/src/test/ui/mismatched_types/issue-35030.stderr index 9f4e4398984..f0dea75001c 100644 --- a/src/test/ui/mismatched_types/issue-35030.stderr +++ b/src/test/ui/mismatched_types/issue-35030.stderr @@ -5,7 +5,9 @@ LL | impl<bool> Parser<bool> for bool { | ---- this type parameter LL | fn parse(text: &str) -> Option<bool> { LL | Some(true) - | ^^^^ expected type parameter `bool`, found `bool` + | ---- ^^^^ expected type parameter `bool`, found `bool` + | | + | arguments to this enum variant are incorrect | = note: expected type parameter `bool` (type parameter `bool`) found type `bool` (`bool`) diff --git a/src/test/ui/mismatched_types/numeric-literal-cast.stderr b/src/test/ui/mismatched_types/numeric-literal-cast.stderr index 55e45a8f162..fcf3eccbcba 100644 --- a/src/test/ui/mismatched_types/numeric-literal-cast.stderr +++ b/src/test/ui/mismatched_types/numeric-literal-cast.stderr @@ -2,8 +2,15 @@ error[E0308]: mismatched types --> $DIR/numeric-literal-cast.rs:6:9 | LL | foo(1u8); - | ^^^ expected `u16`, found `u8` + | --- ^^^ expected `u16`, found `u8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-literal-cast.rs:1:4 + | +LL | fn foo(_: u16) {} + | ^^^ ------ help: change the type of the numeric literal from `u8` to `u16` | LL | foo(1u16); @@ -13,8 +20,15 @@ error[E0308]: mismatched types --> $DIR/numeric-literal-cast.rs:8:10 | LL | foo1(2f32); - | ^^^^ expected `f64`, found `f32` + | ---- ^^^^ expected `f64`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-literal-cast.rs:2:4 | +LL | fn foo1(_: f64) {} + | ^^^^ ------ help: change the type of the numeric literal from `f32` to `f64` | LL | foo1(2f64); @@ -24,8 +38,15 @@ error[E0308]: mismatched types --> $DIR/numeric-literal-cast.rs:10:10 | LL | foo2(3i16); - | ^^^^ expected `i32`, found `i16` + | ---- ^^^^ expected `i32`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-literal-cast.rs:3:4 | +LL | fn foo2(_: i32) {} + | ^^^^ ------ help: change the type of the numeric literal from `i16` to `i32` | LL | foo2(3i32); diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.rs b/src/test/ui/mismatched_types/overloaded-calls-bad.rs index d62625faaaa..902a6ec81d6 100644 --- a/src/test/ui/mismatched_types/overloaded-calls-bad.rs +++ b/src/test/ui/mismatched_types/overloaded-calls-bad.rs @@ -30,5 +30,4 @@ fn main() { //~^ ERROR this function takes 1 argument but 0 arguments were supplied let ans = s("burma", "shave"); //~^ ERROR this function takes 1 argument but 2 arguments were supplied - //~| ERROR mismatched types } diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr index 9ae9c474162..a5742d6fe8c 100644 --- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr +++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr @@ -2,43 +2,51 @@ error[E0308]: mismatched types --> $DIR/overloaded-calls-bad.rs:28:17 | LL | let ans = s("what"); - | ^^^^^^ expected `isize`, found `&str` + | - ^^^^^^ expected `isize`, found `&str` + | | + | arguments to this function are incorrect + | +note: associated function defined here + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; + | ^^^^^^^^ error[E0057]: this function takes 1 argument but 0 arguments were supplied --> $DIR/overloaded-calls-bad.rs:29:15 | LL | let ans = s(); - | ^-- supplied 0 arguments - | | - | expected 1 argument + | ^-- an argument of type `isize` is missing | note: associated function defined here --> $SRC_DIR/core/src/ops/function.rs:LL:COL | LL | extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; | ^^^^^^^^ - -error[E0308]: mismatched types - --> $DIR/overloaded-calls-bad.rs:31:17 +help: provide the argument | -LL | let ans = s("burma", "shave"); - | ^^^^^^^ expected `isize`, found `&str` +LL | let ans = s({isize}); + | ~~~~~~~~~~ error[E0057]: this function takes 1 argument but 2 arguments were supplied --> $DIR/overloaded-calls-bad.rs:31:15 | LL | let ans = s("burma", "shave"); - | ^ ------- ------- supplied 2 arguments - | | - | expected 1 argument + | ^ ------- ------- argument unexpected + | | + | expected `isize`, found `&str` | note: associated function defined here --> $SRC_DIR/core/src/ops/function.rs:LL:COL | LL | extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; | ^^^^^^^^ +help: remove the extra argument + | +LL | let ans = s({isize}); + | ~~~~~~~~~~ -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0057, E0308. For more information about an error, try `rustc --explain E0057`. diff --git a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr index 485fae6d4d9..80aef7fcbe8 100644 --- a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr +++ b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/trait-bounds-cant-coerce.rs:13:7 | LL | a(x); - | ^ expected trait `Foo + Send`, found trait `Foo` + | - ^ expected trait `Foo + Send`, found trait `Foo` + | | + | arguments to this function are incorrect | = note: expected struct `Box<(dyn Foo + Send + 'static)>` found struct `Box<(dyn Foo + 'static)>` +note: function defined here + --> $DIR/trait-bounds-cant-coerce.rs:5:4 + | +LL | fn a(_x: Box<dyn Foo + Send>) { + | ^ ----------------------- error: aborting due to previous error diff --git a/src/test/ui/mut/mut-cross-borrowing.stderr b/src/test/ui/mut/mut-cross-borrowing.stderr index b77813f8af0..ee739d6286a 100644 --- a/src/test/ui/mut/mut-cross-borrowing.stderr +++ b/src/test/ui/mut/mut-cross-borrowing.stderr @@ -2,13 +2,19 @@ error[E0308]: mismatched types --> $DIR/mut-cross-borrowing.rs:7:7 | LL | f(x) - | ^ - | | - | expected `&mut isize`, found struct `Box` - | help: consider mutably borrowing here: `&mut x` + | - ^ + | | | + | | expected `&mut isize`, found struct `Box` + | | help: consider mutably borrowing here: `&mut x` + | arguments to this function are incorrect | = note: expected mutable reference `&mut isize` found struct `Box<{integer}>` +note: function defined here + --> $DIR/mut-cross-borrowing.rs:1:4 + | +LL | fn f(_: &mut isize) {} + | ^ ------------- error: aborting due to previous error diff --git a/src/test/ui/never_type/call-fn-never-arg-wrong-type.stderr b/src/test/ui/never_type/call-fn-never-arg-wrong-type.stderr index eacef1dc330..fa3db33c960 100644 --- a/src/test/ui/never_type/call-fn-never-arg-wrong-type.stderr +++ b/src/test/ui/never_type/call-fn-never-arg-wrong-type.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/call-fn-never-arg-wrong-type.rs:10:9 | LL | foo("wow"); - | ^^^^^ expected `!`, found `&str` + | --- ^^^^^ expected `!`, found `&str` + | | + | arguments to this function are incorrect | = note: expected type `!` found reference `&'static str` +note: function defined here + --> $DIR/call-fn-never-arg-wrong-type.rs:5:4 + | +LL | fn foo(x: !) -> ! { + | ^^^ ---- error: aborting due to previous error diff --git a/src/test/ui/not-enough-arguments.stderr b/src/test/ui/not-enough-arguments.stderr index df957837241..4f502acc95c 100644 --- a/src/test/ui/not-enough-arguments.stderr +++ b/src/test/ui/not-enough-arguments.stderr @@ -2,23 +2,23 @@ error[E0061]: this function takes 4 arguments but 3 arguments were supplied --> $DIR/not-enough-arguments.rs:27:3 | LL | foo(1, 2, 3); - | ^^^ - - - supplied 3 arguments - | | - | expected 4 arguments + | ^^^--------- an argument of type `isize` is missing | note: function defined here --> $DIR/not-enough-arguments.rs:5:4 | LL | fn foo(a: isize, b: isize, c: isize, d:isize) { | ^^^ -------- -------- -------- ------- +help: provide the argument + | +LL | foo(1, 2, 3, {isize}); + | ~~~~~~~~~~~~~~~~~~~~~ error[E0061]: this function takes 6 arguments but 3 arguments were supplied --> $DIR/not-enough-arguments.rs:29:3 | LL | bar(1, 2, 3); - | ^^^ - - - supplied 3 arguments - | | - | expected 6 arguments + | ^^^--------- three arguments of type `i32`, `i32`, and `i32` are missing | note: function defined here --> $DIR/not-enough-arguments.rs:10:4 @@ -37,6 +37,10 @@ LL | e: i32, | ------ LL | f: i32, | ------ +help: provide the arguments + | +LL | bar(1, 2, 3, {i32}, {i32}, {i32}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 2 previous errors diff --git a/src/test/ui/numeric/integer-literal-suffix-inference.stderr b/src/test/ui/numeric/integer-literal-suffix-inference.stderr index 4c29c4a1cb0..5045f584c89 100644 --- a/src/test/ui/numeric/integer-literal-suffix-inference.stderr +++ b/src/test/ui/numeric/integer-literal-suffix-inference.stderr @@ -2,8 +2,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:38:11 | LL | id_i8(a16); - | ^^^ expected `i8`, found `i16` + | ----- ^^^ expected `i8`, found `i16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:15:8 + | +LL | fn id_i8(n: i8) -> i8 { n } + | ^^^^^ ----- help: you can convert an `i16` to an `i8` and panic if the converted value doesn't fit | LL | id_i8(a16.try_into().unwrap()); @@ -13,8 +20,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:41:11 | LL | id_i8(a32); - | ^^^ expected `i8`, found `i32` + | ----- ^^^ expected `i8`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:15:8 | +LL | fn id_i8(n: i8) -> i8 { n } + | ^^^^^ ----- help: you can convert an `i32` to an `i8` and panic if the converted value doesn't fit | LL | id_i8(a32.try_into().unwrap()); @@ -24,8 +38,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:44:11 | LL | id_i8(a64); - | ^^^ expected `i8`, found `i64` + | ----- ^^^ expected `i8`, found `i64` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:15:8 + | +LL | fn id_i8(n: i8) -> i8 { n } + | ^^^^^ ----- help: you can convert an `i64` to an `i8` and panic if the converted value doesn't fit | LL | id_i8(a64.try_into().unwrap()); @@ -35,8 +56,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:47:11 | LL | id_i8(asize); - | ^^^^^ expected `i8`, found `isize` + | ----- ^^^^^ expected `i8`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:15:8 | +LL | fn id_i8(n: i8) -> i8 { n } + | ^^^^^ ----- help: you can convert an `isize` to an `i8` and panic if the converted value doesn't fit | LL | id_i8(asize.try_into().unwrap()); @@ -46,8 +74,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:51:12 | LL | id_i16(a8); - | ^^ expected `i16`, found `i8` + | ------ ^^ expected `i16`, found `i8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:16:8 + | +LL | fn id_i16(n: i16) -> i16 { n } + | ^^^^^^ ------ help: you can convert an `i8` to an `i16` | LL | id_i16(a8.into()); @@ -57,8 +92,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:55:12 | LL | id_i16(a32); - | ^^^ expected `i16`, found `i32` + | ------ ^^^ expected `i16`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:16:8 | +LL | fn id_i16(n: i16) -> i16 { n } + | ^^^^^^ ------ help: you can convert an `i32` to an `i16` and panic if the converted value doesn't fit | LL | id_i16(a32.try_into().unwrap()); @@ -68,8 +110,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:58:12 | LL | id_i16(a64); - | ^^^ expected `i16`, found `i64` + | ------ ^^^ expected `i16`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:16:8 | +LL | fn id_i16(n: i16) -> i16 { n } + | ^^^^^^ ------ help: you can convert an `i64` to an `i16` and panic if the converted value doesn't fit | LL | id_i16(a64.try_into().unwrap()); @@ -79,8 +128,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:61:12 | LL | id_i16(asize); - | ^^^^^ expected `i16`, found `isize` + | ------ ^^^^^ expected `i16`, found `isize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:16:8 + | +LL | fn id_i16(n: i16) -> i16 { n } + | ^^^^^^ ------ help: you can convert an `isize` to an `i16` and panic if the converted value doesn't fit | LL | id_i16(asize.try_into().unwrap()); @@ -90,8 +146,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:65:12 | LL | id_i32(a8); - | ^^ expected `i32`, found `i8` + | ------ ^^ expected `i32`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:17:8 | +LL | fn id_i32(n: i32) -> i32 { n } + | ^^^^^^ ------ help: you can convert an `i8` to an `i32` | LL | id_i32(a8.into()); @@ -101,8 +164,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:68:12 | LL | id_i32(a16); - | ^^^ expected `i32`, found `i16` + | ------ ^^^ expected `i32`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:17:8 | +LL | fn id_i32(n: i32) -> i32 { n } + | ^^^^^^ ------ help: you can convert an `i16` to an `i32` | LL | id_i32(a16.into()); @@ -112,8 +182,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:72:12 | LL | id_i32(a64); - | ^^^ expected `i32`, found `i64` + | ------ ^^^ expected `i32`, found `i64` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:17:8 + | +LL | fn id_i32(n: i32) -> i32 { n } + | ^^^^^^ ------ help: you can convert an `i64` to an `i32` and panic if the converted value doesn't fit | LL | id_i32(a64.try_into().unwrap()); @@ -123,8 +200,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:75:12 | LL | id_i32(asize); - | ^^^^^ expected `i32`, found `isize` + | ------ ^^^^^ expected `i32`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:17:8 | +LL | fn id_i32(n: i32) -> i32 { n } + | ^^^^^^ ------ help: you can convert an `isize` to an `i32` and panic if the converted value doesn't fit | LL | id_i32(asize.try_into().unwrap()); @@ -134,8 +218,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:79:12 | LL | id_i64(a8); - | ^^ expected `i64`, found `i8` + | ------ ^^ expected `i64`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:18:8 | +LL | fn id_i64(n: i64) -> i64 { n } + | ^^^^^^ ------ help: you can convert an `i8` to an `i64` | LL | id_i64(a8.into()); @@ -145,8 +236,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:82:12 | LL | id_i64(a16); - | ^^^ expected `i64`, found `i16` + | ------ ^^^ expected `i64`, found `i16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:18:8 + | +LL | fn id_i64(n: i64) -> i64 { n } + | ^^^^^^ ------ help: you can convert an `i16` to an `i64` | LL | id_i64(a16.into()); @@ -156,8 +254,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:85:12 | LL | id_i64(a32); - | ^^^ expected `i64`, found `i32` + | ------ ^^^ expected `i64`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:18:8 | +LL | fn id_i64(n: i64) -> i64 { n } + | ^^^^^^ ------ help: you can convert an `i32` to an `i64` | LL | id_i64(a32.into()); @@ -167,8 +272,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:89:12 | LL | id_i64(asize); - | ^^^^^ expected `i64`, found `isize` + | ------ ^^^^^ expected `i64`, found `isize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:18:8 + | +LL | fn id_i64(n: i64) -> i64 { n } + | ^^^^^^ ------ help: you can convert an `isize` to an `i64` and panic if the converted value doesn't fit | LL | id_i64(asize.try_into().unwrap()); @@ -178,8 +290,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:93:14 | LL | id_isize(a8); - | ^^ expected `isize`, found `i8` + | -------- ^^ expected `isize`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:19:8 | +LL | fn id_isize(n: isize) -> isize { n } + | ^^^^^^^^ -------- help: you can convert an `i8` to an `isize` | LL | id_isize(a8.into()); @@ -189,8 +308,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:96:14 | LL | id_isize(a16); - | ^^^ expected `isize`, found `i16` + | -------- ^^^ expected `isize`, found `i16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:19:8 + | +LL | fn id_isize(n: isize) -> isize { n } + | ^^^^^^^^ -------- help: you can convert an `i16` to an `isize` | LL | id_isize(a16.into()); @@ -200,8 +326,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:99:14 | LL | id_isize(a32); - | ^^^ expected `isize`, found `i32` + | -------- ^^^ expected `isize`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:19:8 | +LL | fn id_isize(n: isize) -> isize { n } + | ^^^^^^^^ -------- help: you can convert an `i32` to an `isize` and panic if the converted value doesn't fit | LL | id_isize(a32.try_into().unwrap()); @@ -211,8 +344,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:102:14 | LL | id_isize(a64); - | ^^^ expected `isize`, found `i64` + | -------- ^^^ expected `isize`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:19:8 | +LL | fn id_isize(n: isize) -> isize { n } + | ^^^^^^^^ -------- help: you can convert an `i64` to an `isize` and panic if the converted value doesn't fit | LL | id_isize(a64.try_into().unwrap()); @@ -222,8 +362,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:108:11 | LL | id_i8(c16); - | ^^^ expected `i8`, found `i16` + | ----- ^^^ expected `i8`, found `i16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:15:8 + | +LL | fn id_i8(n: i8) -> i8 { n } + | ^^^^^ ----- help: you can convert an `i16` to an `i8` and panic if the converted value doesn't fit | LL | id_i8(c16.try_into().unwrap()); @@ -233,8 +380,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:111:11 | LL | id_i8(c32); - | ^^^ expected `i8`, found `i32` + | ----- ^^^ expected `i8`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:15:8 | +LL | fn id_i8(n: i8) -> i8 { n } + | ^^^^^ ----- help: you can convert an `i32` to an `i8` and panic if the converted value doesn't fit | LL | id_i8(c32.try_into().unwrap()); @@ -244,8 +398,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:114:11 | LL | id_i8(c64); - | ^^^ expected `i8`, found `i64` + | ----- ^^^ expected `i8`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:15:8 | +LL | fn id_i8(n: i8) -> i8 { n } + | ^^^^^ ----- help: you can convert an `i64` to an `i8` and panic if the converted value doesn't fit | LL | id_i8(c64.try_into().unwrap()); @@ -255,8 +416,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:118:12 | LL | id_i16(c8); - | ^^ expected `i16`, found `i8` + | ------ ^^ expected `i16`, found `i8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:16:8 + | +LL | fn id_i16(n: i16) -> i16 { n } + | ^^^^^^ ------ help: you can convert an `i8` to an `i16` | LL | id_i16(c8.into()); @@ -266,8 +434,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:122:12 | LL | id_i16(c32); - | ^^^ expected `i16`, found `i32` + | ------ ^^^ expected `i16`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:16:8 | +LL | fn id_i16(n: i16) -> i16 { n } + | ^^^^^^ ------ help: you can convert an `i32` to an `i16` and panic if the converted value doesn't fit | LL | id_i16(c32.try_into().unwrap()); @@ -277,8 +452,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:125:12 | LL | id_i16(c64); - | ^^^ expected `i16`, found `i64` + | ------ ^^^ expected `i16`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:16:8 | +LL | fn id_i16(n: i16) -> i16 { n } + | ^^^^^^ ------ help: you can convert an `i64` to an `i16` and panic if the converted value doesn't fit | LL | id_i16(c64.try_into().unwrap()); @@ -288,8 +470,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:129:12 | LL | id_i32(c8); - | ^^ expected `i32`, found `i8` + | ------ ^^ expected `i32`, found `i8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:17:8 + | +LL | fn id_i32(n: i32) -> i32 { n } + | ^^^^^^ ------ help: you can convert an `i8` to an `i32` | LL | id_i32(c8.into()); @@ -299,8 +488,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:132:12 | LL | id_i32(c16); - | ^^^ expected `i32`, found `i16` + | ------ ^^^ expected `i32`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:17:8 | +LL | fn id_i32(n: i32) -> i32 { n } + | ^^^^^^ ------ help: you can convert an `i16` to an `i32` | LL | id_i32(c16.into()); @@ -310,8 +506,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:136:12 | LL | id_i32(c64); - | ^^^ expected `i32`, found `i64` + | ------ ^^^ expected `i32`, found `i64` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:17:8 + | +LL | fn id_i32(n: i32) -> i32 { n } + | ^^^^^^ ------ help: you can convert an `i64` to an `i32` and panic if the converted value doesn't fit | LL | id_i32(c64.try_into().unwrap()); @@ -321,8 +524,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:140:12 | LL | id_i64(a8); - | ^^ expected `i64`, found `i8` + | ------ ^^ expected `i64`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:18:8 | +LL | fn id_i64(n: i64) -> i64 { n } + | ^^^^^^ ------ help: you can convert an `i8` to an `i64` | LL | id_i64(a8.into()); @@ -332,8 +542,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:143:12 | LL | id_i64(a16); - | ^^^ expected `i64`, found `i16` + | ------ ^^^ expected `i64`, found `i16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:18:8 + | +LL | fn id_i64(n: i64) -> i64 { n } + | ^^^^^^ ------ help: you can convert an `i16` to an `i64` | LL | id_i64(a16.into()); @@ -343,8 +560,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:146:12 | LL | id_i64(a32); - | ^^^ expected `i64`, found `i32` + | ------ ^^^ expected `i64`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:18:8 | +LL | fn id_i64(n: i64) -> i64 { n } + | ^^^^^^ ------ help: you can convert an `i32` to an `i64` | LL | id_i64(a32.into()); @@ -354,8 +578,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:152:11 | LL | id_u8(b16); - | ^^^ expected `u8`, found `u16` + | ----- ^^^ expected `u8`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:27:8 | +LL | fn id_u8(n: u8) -> u8 { n } + | ^^^^^ ----- help: you can convert a `u16` to a `u8` and panic if the converted value doesn't fit | LL | id_u8(b16.try_into().unwrap()); @@ -365,8 +596,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:155:11 | LL | id_u8(b32); - | ^^^ expected `u8`, found `u32` + | ----- ^^^ expected `u8`, found `u32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:27:8 + | +LL | fn id_u8(n: u8) -> u8 { n } + | ^^^^^ ----- help: you can convert a `u32` to a `u8` and panic if the converted value doesn't fit | LL | id_u8(b32.try_into().unwrap()); @@ -376,8 +614,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:158:11 | LL | id_u8(b64); - | ^^^ expected `u8`, found `u64` + | ----- ^^^ expected `u8`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:27:8 | +LL | fn id_u8(n: u8) -> u8 { n } + | ^^^^^ ----- help: you can convert a `u64` to a `u8` and panic if the converted value doesn't fit | LL | id_u8(b64.try_into().unwrap()); @@ -387,8 +632,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:161:11 | LL | id_u8(bsize); - | ^^^^^ expected `u8`, found `usize` + | ----- ^^^^^ expected `u8`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:27:8 | +LL | fn id_u8(n: u8) -> u8 { n } + | ^^^^^ ----- help: you can convert a `usize` to a `u8` and panic if the converted value doesn't fit | LL | id_u8(bsize.try_into().unwrap()); @@ -398,8 +650,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:165:12 | LL | id_u16(b8); - | ^^ expected `u16`, found `u8` + | ------ ^^ expected `u16`, found `u8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:28:8 + | +LL | fn id_u16(n: u16) -> u16 { n } + | ^^^^^^ ------ help: you can convert a `u8` to a `u16` | LL | id_u16(b8.into()); @@ -409,8 +668,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:169:12 | LL | id_u16(b32); - | ^^^ expected `u16`, found `u32` + | ------ ^^^ expected `u16`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:28:8 | +LL | fn id_u16(n: u16) -> u16 { n } + | ^^^^^^ ------ help: you can convert a `u32` to a `u16` and panic if the converted value doesn't fit | LL | id_u16(b32.try_into().unwrap()); @@ -420,8 +686,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:172:12 | LL | id_u16(b64); - | ^^^ expected `u16`, found `u64` + | ------ ^^^ expected `u16`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:28:8 | +LL | fn id_u16(n: u16) -> u16 { n } + | ^^^^^^ ------ help: you can convert a `u64` to a `u16` and panic if the converted value doesn't fit | LL | id_u16(b64.try_into().unwrap()); @@ -431,8 +704,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:175:12 | LL | id_u16(bsize); - | ^^^^^ expected `u16`, found `usize` + | ------ ^^^^^ expected `u16`, found `usize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:28:8 + | +LL | fn id_u16(n: u16) -> u16 { n } + | ^^^^^^ ------ help: you can convert a `usize` to a `u16` and panic if the converted value doesn't fit | LL | id_u16(bsize.try_into().unwrap()); @@ -442,8 +722,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:179:12 | LL | id_u32(b8); - | ^^ expected `u32`, found `u8` + | ------ ^^ expected `u32`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:29:8 | +LL | fn id_u32(n: u32) -> u32 { n } + | ^^^^^^ ------ help: you can convert a `u8` to a `u32` | LL | id_u32(b8.into()); @@ -453,8 +740,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:182:12 | LL | id_u32(b16); - | ^^^ expected `u32`, found `u16` + | ------ ^^^ expected `u32`, found `u16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:29:8 + | +LL | fn id_u32(n: u32) -> u32 { n } + | ^^^^^^ ------ help: you can convert a `u16` to a `u32` | LL | id_u32(b16.into()); @@ -464,8 +758,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:186:12 | LL | id_u32(b64); - | ^^^ expected `u32`, found `u64` + | ------ ^^^ expected `u32`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:29:8 | +LL | fn id_u32(n: u32) -> u32 { n } + | ^^^^^^ ------ help: you can convert a `u64` to a `u32` and panic if the converted value doesn't fit | LL | id_u32(b64.try_into().unwrap()); @@ -475,8 +776,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:189:12 | LL | id_u32(bsize); - | ^^^^^ expected `u32`, found `usize` + | ------ ^^^^^ expected `u32`, found `usize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:29:8 + | +LL | fn id_u32(n: u32) -> u32 { n } + | ^^^^^^ ------ help: you can convert a `usize` to a `u32` and panic if the converted value doesn't fit | LL | id_u32(bsize.try_into().unwrap()); @@ -486,8 +794,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:193:12 | LL | id_u64(b8); - | ^^ expected `u64`, found `u8` + | ------ ^^ expected `u64`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:30:8 | +LL | fn id_u64(n: u64) -> u64 { n } + | ^^^^^^ ------ help: you can convert a `u8` to a `u64` | LL | id_u64(b8.into()); @@ -497,8 +812,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:196:12 | LL | id_u64(b16); - | ^^^ expected `u64`, found `u16` + | ------ ^^^ expected `u64`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:30:8 | +LL | fn id_u64(n: u64) -> u64 { n } + | ^^^^^^ ------ help: you can convert a `u16` to a `u64` | LL | id_u64(b16.into()); @@ -508,8 +830,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:199:12 | LL | id_u64(b32); - | ^^^ expected `u64`, found `u32` + | ------ ^^^ expected `u64`, found `u32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:30:8 + | +LL | fn id_u64(n: u64) -> u64 { n } + | ^^^^^^ ------ help: you can convert a `u32` to a `u64` | LL | id_u64(b32.into()); @@ -519,8 +848,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:203:12 | LL | id_u64(bsize); - | ^^^^^ expected `u64`, found `usize` + | ------ ^^^^^ expected `u64`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:30:8 | +LL | fn id_u64(n: u64) -> u64 { n } + | ^^^^^^ ------ help: you can convert a `usize` to a `u64` and panic if the converted value doesn't fit | LL | id_u64(bsize.try_into().unwrap()); @@ -530,8 +866,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:207:14 | LL | id_usize(b8); - | ^^ expected `usize`, found `u8` + | -------- ^^ expected `usize`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:31:8 | +LL | fn id_usize(n: usize) -> usize { n } + | ^^^^^^^^ -------- help: you can convert a `u8` to a `usize` | LL | id_usize(b8.into()); @@ -541,8 +884,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:210:14 | LL | id_usize(b16); - | ^^^ expected `usize`, found `u16` + | -------- ^^^ expected `usize`, found `u16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:31:8 + | +LL | fn id_usize(n: usize) -> usize { n } + | ^^^^^^^^ -------- help: you can convert a `u16` to a `usize` | LL | id_usize(b16.into()); @@ -552,8 +902,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:213:14 | LL | id_usize(b32); - | ^^^ expected `usize`, found `u32` + | -------- ^^^ expected `usize`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:31:8 | +LL | fn id_usize(n: usize) -> usize { n } + | ^^^^^^^^ -------- help: you can convert a `u32` to a `usize` and panic if the converted value doesn't fit | LL | id_usize(b32.try_into().unwrap()); @@ -563,8 +920,15 @@ error[E0308]: mismatched types --> $DIR/integer-literal-suffix-inference.rs:216:14 | LL | id_usize(b64); - | ^^^ expected `usize`, found `u64` + | -------- ^^^ expected `usize`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/integer-literal-suffix-inference.rs:31:8 | +LL | fn id_usize(n: usize) -> usize { n } + | ^^^^^^^^ -------- help: you can convert a `u64` to a `usize` and panic if the converted value doesn't fit | LL | id_usize(b64.try_into().unwrap()); diff --git a/src/test/ui/numeric/len.stderr b/src/test/ui/numeric/len.stderr index 6319c1ead24..55a61b5e443 100644 --- a/src/test/ui/numeric/len.stderr +++ b/src/test/ui/numeric/len.stderr @@ -2,8 +2,15 @@ error[E0308]: mismatched types --> $DIR/len.rs:3:10 | LL | test(array.len()); - | ^^^^^^^^^^^ expected `u32`, found `usize` + | ---- ^^^^^^^^^^^ expected `u32`, found `usize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/len.rs:6:4 + | +LL | fn test(length: u32) { + | ^^^^ ----------- help: you can convert a `usize` to a `u32` and panic if the converted value doesn't fit | LL | test(array.len().try_into().unwrap()); diff --git a/src/test/ui/numeric/numeric-cast-without-suggestion.stderr b/src/test/ui/numeric/numeric-cast-without-suggestion.stderr index a96518a3434..581b548abca 100644 --- a/src/test/ui/numeric/numeric-cast-without-suggestion.stderr +++ b/src/test/ui/numeric/numeric-cast-without-suggestion.stderr @@ -2,127 +2,295 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:17:18 | LL | foo::<usize>(x_f64); - | ^^^^^ expected `usize`, found `f64` + | ------------ ^^^^^ expected `usize`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:18:18 | LL | foo::<usize>(x_f32); - | ^^^^^ expected `usize`, found `f32` + | ------------ ^^^^^ expected `usize`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:19:18 | LL | foo::<isize>(x_f64); - | ^^^^^ expected `isize`, found `f64` + | ------------ ^^^^^ expected `isize`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:20:18 | LL | foo::<isize>(x_f32); - | ^^^^^ expected `isize`, found `f32` + | ------------ ^^^^^ expected `isize`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:21:16 | LL | foo::<u64>(x_f64); - | ^^^^^ expected `u64`, found `f64` + | ---------- ^^^^^ expected `u64`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:22:16 | LL | foo::<u64>(x_f32); - | ^^^^^ expected `u64`, found `f32` + | ---------- ^^^^^ expected `u64`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:23:16 | LL | foo::<i64>(x_f64); - | ^^^^^ expected `i64`, found `f64` + | ---------- ^^^^^ expected `i64`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:24:16 | LL | foo::<i64>(x_f32); - | ^^^^^ expected `i64`, found `f32` + | ---------- ^^^^^ expected `i64`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:25:16 | LL | foo::<u32>(x_f64); - | ^^^^^ expected `u32`, found `f64` + | ---------- ^^^^^ expected `u32`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:26:16 | LL | foo::<u32>(x_f32); - | ^^^^^ expected `u32`, found `f32` + | ---------- ^^^^^ expected `u32`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:27:16 | LL | foo::<i32>(x_f64); - | ^^^^^ expected `i32`, found `f64` + | ---------- ^^^^^ expected `i32`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:28:16 | LL | foo::<i32>(x_f32); - | ^^^^^ expected `i32`, found `f32` + | ---------- ^^^^^ expected `i32`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:29:16 | LL | foo::<u16>(x_f64); - | ^^^^^ expected `u16`, found `f64` + | ---------- ^^^^^ expected `u16`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:30:16 | LL | foo::<u16>(x_f32); - | ^^^^^ expected `u16`, found `f32` + | ---------- ^^^^^ expected `u16`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:31:16 | LL | foo::<i16>(x_f64); - | ^^^^^ expected `i16`, found `f64` + | ---------- ^^^^^ expected `i16`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:32:16 | LL | foo::<i16>(x_f32); - | ^^^^^ expected `i16`, found `f32` + | ---------- ^^^^^ expected `i16`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:33:15 | LL | foo::<u8>(x_f64); - | ^^^^^ expected `u8`, found `f64` + | --------- ^^^^^ expected `u8`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:34:15 | LL | foo::<u8>(x_f32); - | ^^^^^ expected `u8`, found `f32` + | --------- ^^^^^ expected `u8`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:35:15 | LL | foo::<i8>(x_f64); - | ^^^^^ expected `i8`, found `f64` + | --------- ^^^^^ expected `i8`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:36:15 | LL | foo::<i8>(x_f32); - | ^^^^^ expected `i8`, found `f32` + | --------- ^^^^^ expected `i8`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error[E0308]: mismatched types --> $DIR/numeric-cast-without-suggestion.rs:37:16 | LL | foo::<f32>(x_f64); - | ^^^^^ expected `f32`, found `f64` + | ---------- ^^^^^ expected `f32`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast-without-suggestion.rs:1:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- error: aborting due to 21 previous errors diff --git a/src/test/ui/numeric/numeric-cast.stderr b/src/test/ui/numeric/numeric-cast.stderr index b8f2d88ab49..d347875d5a9 100644 --- a/src/test/ui/numeric/numeric-cast.stderr +++ b/src/test/ui/numeric/numeric-cast.stderr @@ -2,8 +2,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:23:18 | LL | foo::<usize>(x_u64); - | ^^^^^ expected `usize`, found `u64` + | ------------ ^^^^^ expected `usize`, found `u64` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u64` to a `usize` and panic if the converted value doesn't fit | LL | foo::<usize>(x_u64.try_into().unwrap()); @@ -13,8 +20,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:25:18 | LL | foo::<usize>(x_u32); - | ^^^^^ expected `usize`, found `u32` + | ------------ ^^^^^ expected `usize`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u32` to a `usize` and panic if the converted value doesn't fit | LL | foo::<usize>(x_u32.try_into().unwrap()); @@ -24,8 +38,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:27:18 | LL | foo::<usize>(x_u16); - | ^^^^^ expected `usize`, found `u16` + | ------------ ^^^^^ expected `usize`, found `u16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u16` to a `usize` | LL | foo::<usize>(x_u16.into()); @@ -35,8 +56,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:29:18 | LL | foo::<usize>(x_u8); - | ^^^^ expected `usize`, found `u8` + | ------------ ^^^^ expected `usize`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u8` to a `usize` | LL | foo::<usize>(x_u8.into()); @@ -46,8 +74,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:31:18 | LL | foo::<usize>(x_isize); - | ^^^^^^^ expected `usize`, found `isize` + | ------------ ^^^^^^^ expected `usize`, found `isize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `isize` to a `usize` and panic if the converted value doesn't fit | LL | foo::<usize>(x_isize.try_into().unwrap()); @@ -57,8 +92,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:33:18 | LL | foo::<usize>(x_i64); - | ^^^^^ expected `usize`, found `i64` + | ------------ ^^^^^ expected `usize`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i64` to a `usize` and panic if the converted value doesn't fit | LL | foo::<usize>(x_i64.try_into().unwrap()); @@ -68,8 +110,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:35:18 | LL | foo::<usize>(x_i32); - | ^^^^^ expected `usize`, found `i32` + | ------------ ^^^^^ expected `usize`, found `i32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i32` to a `usize` and panic if the converted value doesn't fit | LL | foo::<usize>(x_i32.try_into().unwrap()); @@ -79,8 +128,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:37:18 | LL | foo::<usize>(x_i16); - | ^^^^^ expected `usize`, found `i16` + | ------------ ^^^^^ expected `usize`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i16` to a `usize` and panic if the converted value doesn't fit | LL | foo::<usize>(x_i16.try_into().unwrap()); @@ -90,8 +146,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:39:18 | LL | foo::<usize>(x_i8); - | ^^^^ expected `usize`, found `i8` + | ------------ ^^^^ expected `usize`, found `i8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i8` to a `usize` and panic if the converted value doesn't fit | LL | foo::<usize>(x_i8.try_into().unwrap()); @@ -101,8 +164,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:44:18 | LL | foo::<isize>(x_usize); - | ^^^^^^^ expected `isize`, found `usize` + | ------------ ^^^^^^^ expected `isize`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `usize` to an `isize` and panic if the converted value doesn't fit | LL | foo::<isize>(x_usize.try_into().unwrap()); @@ -112,8 +182,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:46:18 | LL | foo::<isize>(x_u64); - | ^^^^^ expected `isize`, found `u64` + | ------------ ^^^^^ expected `isize`, found `u64` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u64` to an `isize` and panic if the converted value doesn't fit | LL | foo::<isize>(x_u64.try_into().unwrap()); @@ -123,8 +200,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:48:18 | LL | foo::<isize>(x_u32); - | ^^^^^ expected `isize`, found `u32` + | ------------ ^^^^^ expected `isize`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u32` to an `isize` and panic if the converted value doesn't fit | LL | foo::<isize>(x_u32.try_into().unwrap()); @@ -134,8 +218,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:50:18 | LL | foo::<isize>(x_u16); - | ^^^^^ expected `isize`, found `u16` + | ------------ ^^^^^ expected `isize`, found `u16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u16` to an `isize` and panic if the converted value doesn't fit | LL | foo::<isize>(x_u16.try_into().unwrap()); @@ -145,8 +236,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:52:18 | LL | foo::<isize>(x_u8); - | ^^^^ expected `isize`, found `u8` + | ------------ ^^^^ expected `isize`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u8` to an `isize` | LL | foo::<isize>(x_u8.into()); @@ -156,8 +254,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:55:18 | LL | foo::<isize>(x_i64); - | ^^^^^ expected `isize`, found `i64` + | ------------ ^^^^^ expected `isize`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i64` to an `isize` and panic if the converted value doesn't fit | LL | foo::<isize>(x_i64.try_into().unwrap()); @@ -167,8 +272,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:57:18 | LL | foo::<isize>(x_i32); - | ^^^^^ expected `isize`, found `i32` + | ------------ ^^^^^ expected `isize`, found `i32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i32` to an `isize` and panic if the converted value doesn't fit | LL | foo::<isize>(x_i32.try_into().unwrap()); @@ -178,8 +290,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:59:18 | LL | foo::<isize>(x_i16); - | ^^^^^ expected `isize`, found `i16` + | ------------ ^^^^^ expected `isize`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i16` to an `isize` | LL | foo::<isize>(x_i16.into()); @@ -189,8 +308,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:61:18 | LL | foo::<isize>(x_i8); - | ^^^^ expected `isize`, found `i8` + | ------------ ^^^^ expected `isize`, found `i8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i8` to an `isize` | LL | foo::<isize>(x_i8.into()); @@ -200,8 +326,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:66:16 | LL | foo::<u64>(x_usize); - | ^^^^^^^ expected `u64`, found `usize` + | ---------- ^^^^^^^ expected `u64`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `usize` to a `u64` and panic if the converted value doesn't fit | LL | foo::<u64>(x_usize.try_into().unwrap()); @@ -211,8 +344,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:69:16 | LL | foo::<u64>(x_u32); - | ^^^^^ expected `u64`, found `u32` + | ---------- ^^^^^ expected `u64`, found `u32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u32` to a `u64` | LL | foo::<u64>(x_u32.into()); @@ -222,8 +362,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:71:16 | LL | foo::<u64>(x_u16); - | ^^^^^ expected `u64`, found `u16` + | ---------- ^^^^^ expected `u64`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u16` to a `u64` | LL | foo::<u64>(x_u16.into()); @@ -233,8 +380,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:73:16 | LL | foo::<u64>(x_u8); - | ^^^^ expected `u64`, found `u8` + | ---------- ^^^^ expected `u64`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u8` to a `u64` | LL | foo::<u64>(x_u8.into()); @@ -244,8 +398,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:75:16 | LL | foo::<u64>(x_isize); - | ^^^^^^^ expected `u64`, found `isize` + | ---------- ^^^^^^^ expected `u64`, found `isize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `isize` to a `u64` and panic if the converted value doesn't fit | LL | foo::<u64>(x_isize.try_into().unwrap()); @@ -255,8 +416,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:77:16 | LL | foo::<u64>(x_i64); - | ^^^^^ expected `u64`, found `i64` + | ---------- ^^^^^ expected `u64`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i64` to a `u64` and panic if the converted value doesn't fit | LL | foo::<u64>(x_i64.try_into().unwrap()); @@ -266,8 +434,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:79:16 | LL | foo::<u64>(x_i32); - | ^^^^^ expected `u64`, found `i32` + | ---------- ^^^^^ expected `u64`, found `i32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i32` to a `u64` and panic if the converted value doesn't fit | LL | foo::<u64>(x_i32.try_into().unwrap()); @@ -277,8 +452,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:81:16 | LL | foo::<u64>(x_i16); - | ^^^^^ expected `u64`, found `i16` + | ---------- ^^^^^ expected `u64`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i16` to a `u64` and panic if the converted value doesn't fit | LL | foo::<u64>(x_i16.try_into().unwrap()); @@ -288,8 +470,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:83:16 | LL | foo::<u64>(x_i8); - | ^^^^ expected `u64`, found `i8` + | ---------- ^^^^ expected `u64`, found `i8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i8` to a `u64` and panic if the converted value doesn't fit | LL | foo::<u64>(x_i8.try_into().unwrap()); @@ -299,8 +488,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:88:16 | LL | foo::<i64>(x_usize); - | ^^^^^^^ expected `i64`, found `usize` + | ---------- ^^^^^^^ expected `i64`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `usize` to an `i64` and panic if the converted value doesn't fit | LL | foo::<i64>(x_usize.try_into().unwrap()); @@ -310,8 +506,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:90:16 | LL | foo::<i64>(x_u64); - | ^^^^^ expected `i64`, found `u64` + | ---------- ^^^^^ expected `i64`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u64` to an `i64` and panic if the converted value doesn't fit | LL | foo::<i64>(x_u64.try_into().unwrap()); @@ -321,8 +524,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:92:16 | LL | foo::<i64>(x_u32); - | ^^^^^ expected `i64`, found `u32` + | ---------- ^^^^^ expected `i64`, found `u32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u32` to an `i64` | LL | foo::<i64>(x_u32.into()); @@ -332,8 +542,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:94:16 | LL | foo::<i64>(x_u16); - | ^^^^^ expected `i64`, found `u16` + | ---------- ^^^^^ expected `i64`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u16` to an `i64` | LL | foo::<i64>(x_u16.into()); @@ -343,8 +560,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:96:16 | LL | foo::<i64>(x_u8); - | ^^^^ expected `i64`, found `u8` + | ---------- ^^^^ expected `i64`, found `u8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u8` to an `i64` | LL | foo::<i64>(x_u8.into()); @@ -354,8 +578,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:98:16 | LL | foo::<i64>(x_isize); - | ^^^^^^^ expected `i64`, found `isize` + | ---------- ^^^^^^^ expected `i64`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `isize` to an `i64` and panic if the converted value doesn't fit | LL | foo::<i64>(x_isize.try_into().unwrap()); @@ -365,8 +596,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:101:16 | LL | foo::<i64>(x_i32); - | ^^^^^ expected `i64`, found `i32` + | ---------- ^^^^^ expected `i64`, found `i32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i32` to an `i64` | LL | foo::<i64>(x_i32.into()); @@ -376,8 +614,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:103:16 | LL | foo::<i64>(x_i16); - | ^^^^^ expected `i64`, found `i16` + | ---------- ^^^^^ expected `i64`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i16` to an `i64` | LL | foo::<i64>(x_i16.into()); @@ -387,8 +632,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:105:16 | LL | foo::<i64>(x_i8); - | ^^^^ expected `i64`, found `i8` + | ---------- ^^^^ expected `i64`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i8` to an `i64` | LL | foo::<i64>(x_i8.into()); @@ -398,8 +650,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:110:16 | LL | foo::<u32>(x_usize); - | ^^^^^^^ expected `u32`, found `usize` + | ---------- ^^^^^^^ expected `u32`, found `usize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `usize` to a `u32` and panic if the converted value doesn't fit | LL | foo::<u32>(x_usize.try_into().unwrap()); @@ -409,8 +668,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:112:16 | LL | foo::<u32>(x_u64); - | ^^^^^ expected `u32`, found `u64` + | ---------- ^^^^^ expected `u32`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u64` to a `u32` and panic if the converted value doesn't fit | LL | foo::<u32>(x_u64.try_into().unwrap()); @@ -420,8 +686,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:115:16 | LL | foo::<u32>(x_u16); - | ^^^^^ expected `u32`, found `u16` + | ---------- ^^^^^ expected `u32`, found `u16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u16` to a `u32` | LL | foo::<u32>(x_u16.into()); @@ -431,8 +704,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:117:16 | LL | foo::<u32>(x_u8); - | ^^^^ expected `u32`, found `u8` + | ---------- ^^^^ expected `u32`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u8` to a `u32` | LL | foo::<u32>(x_u8.into()); @@ -442,8 +722,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:119:16 | LL | foo::<u32>(x_isize); - | ^^^^^^^ expected `u32`, found `isize` + | ---------- ^^^^^^^ expected `u32`, found `isize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `isize` to a `u32` and panic if the converted value doesn't fit | LL | foo::<u32>(x_isize.try_into().unwrap()); @@ -453,8 +740,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:121:16 | LL | foo::<u32>(x_i64); - | ^^^^^ expected `u32`, found `i64` + | ---------- ^^^^^ expected `u32`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i64` to a `u32` and panic if the converted value doesn't fit | LL | foo::<u32>(x_i64.try_into().unwrap()); @@ -464,8 +758,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:123:16 | LL | foo::<u32>(x_i32); - | ^^^^^ expected `u32`, found `i32` + | ---------- ^^^^^ expected `u32`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit | LL | foo::<u32>(x_i32.try_into().unwrap()); @@ -475,8 +776,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:125:16 | LL | foo::<u32>(x_i16); - | ^^^^^ expected `u32`, found `i16` + | ---------- ^^^^^ expected `u32`, found `i16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i16` to a `u32` and panic if the converted value doesn't fit | LL | foo::<u32>(x_i16.try_into().unwrap()); @@ -486,8 +794,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:127:16 | LL | foo::<u32>(x_i8); - | ^^^^ expected `u32`, found `i8` + | ---------- ^^^^ expected `u32`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i8` to a `u32` and panic if the converted value doesn't fit | LL | foo::<u32>(x_i8.try_into().unwrap()); @@ -497,8 +812,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:132:16 | LL | foo::<i32>(x_usize); - | ^^^^^^^ expected `i32`, found `usize` + | ---------- ^^^^^^^ expected `i32`, found `usize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `usize` to an `i32` and panic if the converted value doesn't fit | LL | foo::<i32>(x_usize.try_into().unwrap()); @@ -508,8 +830,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:134:16 | LL | foo::<i32>(x_u64); - | ^^^^^ expected `i32`, found `u64` + | ---------- ^^^^^ expected `i32`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u64` to an `i32` and panic if the converted value doesn't fit | LL | foo::<i32>(x_u64.try_into().unwrap()); @@ -519,8 +848,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:136:16 | LL | foo::<i32>(x_u32); - | ^^^^^ expected `i32`, found `u32` + | ---------- ^^^^^ expected `i32`, found `u32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit | LL | foo::<i32>(x_u32.try_into().unwrap()); @@ -530,8 +866,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:138:16 | LL | foo::<i32>(x_u16); - | ^^^^^ expected `i32`, found `u16` + | ---------- ^^^^^ expected `i32`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u16` to an `i32` | LL | foo::<i32>(x_u16.into()); @@ -541,8 +884,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:140:16 | LL | foo::<i32>(x_u8); - | ^^^^ expected `i32`, found `u8` + | ---------- ^^^^ expected `i32`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u8` to an `i32` | LL | foo::<i32>(x_u8.into()); @@ -552,8 +902,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:142:16 | LL | foo::<i32>(x_isize); - | ^^^^^^^ expected `i32`, found `isize` + | ---------- ^^^^^^^ expected `i32`, found `isize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `isize` to an `i32` and panic if the converted value doesn't fit | LL | foo::<i32>(x_isize.try_into().unwrap()); @@ -563,8 +920,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:144:16 | LL | foo::<i32>(x_i64); - | ^^^^^ expected `i32`, found `i64` + | ---------- ^^^^^ expected `i32`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i64` to an `i32` and panic if the converted value doesn't fit | LL | foo::<i32>(x_i64.try_into().unwrap()); @@ -574,8 +938,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:147:16 | LL | foo::<i32>(x_i16); - | ^^^^^ expected `i32`, found `i16` + | ---------- ^^^^^ expected `i32`, found `i16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i16` to an `i32` | LL | foo::<i32>(x_i16.into()); @@ -585,8 +956,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:149:16 | LL | foo::<i32>(x_i8); - | ^^^^ expected `i32`, found `i8` + | ---------- ^^^^ expected `i32`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i8` to an `i32` | LL | foo::<i32>(x_i8.into()); @@ -596,8 +974,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:154:16 | LL | foo::<u16>(x_usize); - | ^^^^^^^ expected `u16`, found `usize` + | ---------- ^^^^^^^ expected `u16`, found `usize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `usize` to a `u16` and panic if the converted value doesn't fit | LL | foo::<u16>(x_usize.try_into().unwrap()); @@ -607,8 +992,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:156:16 | LL | foo::<u16>(x_u64); - | ^^^^^ expected `u16`, found `u64` + | ---------- ^^^^^ expected `u16`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u64` to a `u16` and panic if the converted value doesn't fit | LL | foo::<u16>(x_u64.try_into().unwrap()); @@ -618,8 +1010,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:158:16 | LL | foo::<u16>(x_u32); - | ^^^^^ expected `u16`, found `u32` + | ---------- ^^^^^ expected `u16`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u32` to a `u16` and panic if the converted value doesn't fit | LL | foo::<u16>(x_u32.try_into().unwrap()); @@ -629,8 +1028,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:161:16 | LL | foo::<u16>(x_u8); - | ^^^^ expected `u16`, found `u8` + | ---------- ^^^^ expected `u16`, found `u8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u8` to a `u16` | LL | foo::<u16>(x_u8.into()); @@ -640,8 +1046,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:163:16 | LL | foo::<u16>(x_isize); - | ^^^^^^^ expected `u16`, found `isize` + | ---------- ^^^^^^^ expected `u16`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `isize` to a `u16` and panic if the converted value doesn't fit | LL | foo::<u16>(x_isize.try_into().unwrap()); @@ -651,8 +1064,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:165:16 | LL | foo::<u16>(x_i64); - | ^^^^^ expected `u16`, found `i64` + | ---------- ^^^^^ expected `u16`, found `i64` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i64` to a `u16` and panic if the converted value doesn't fit | LL | foo::<u16>(x_i64.try_into().unwrap()); @@ -662,8 +1082,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:167:16 | LL | foo::<u16>(x_i32); - | ^^^^^ expected `u16`, found `i32` + | ---------- ^^^^^ expected `u16`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i32` to a `u16` and panic if the converted value doesn't fit | LL | foo::<u16>(x_i32.try_into().unwrap()); @@ -673,8 +1100,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:169:16 | LL | foo::<u16>(x_i16); - | ^^^^^ expected `u16`, found `i16` + | ---------- ^^^^^ expected `u16`, found `i16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i16` to a `u16` and panic if the converted value doesn't fit | LL | foo::<u16>(x_i16.try_into().unwrap()); @@ -684,8 +1118,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:171:16 | LL | foo::<u16>(x_i8); - | ^^^^ expected `u16`, found `i8` + | ---------- ^^^^ expected `u16`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i8` to a `u16` and panic if the converted value doesn't fit | LL | foo::<u16>(x_i8.try_into().unwrap()); @@ -695,8 +1136,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:176:16 | LL | foo::<i16>(x_usize); - | ^^^^^^^ expected `i16`, found `usize` + | ---------- ^^^^^^^ expected `i16`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `usize` to an `i16` and panic if the converted value doesn't fit | LL | foo::<i16>(x_usize.try_into().unwrap()); @@ -706,8 +1154,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:178:16 | LL | foo::<i16>(x_u64); - | ^^^^^ expected `i16`, found `u64` + | ---------- ^^^^^ expected `i16`, found `u64` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u64` to an `i16` and panic if the converted value doesn't fit | LL | foo::<i16>(x_u64.try_into().unwrap()); @@ -717,8 +1172,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:180:16 | LL | foo::<i16>(x_u32); - | ^^^^^ expected `i16`, found `u32` + | ---------- ^^^^^ expected `i16`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u32` to an `i16` and panic if the converted value doesn't fit | LL | foo::<i16>(x_u32.try_into().unwrap()); @@ -728,8 +1190,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:182:16 | LL | foo::<i16>(x_u16); - | ^^^^^ expected `i16`, found `u16` + | ---------- ^^^^^ expected `i16`, found `u16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u16` to an `i16` and panic if the converted value doesn't fit | LL | foo::<i16>(x_u16.try_into().unwrap()); @@ -739,8 +1208,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:184:16 | LL | foo::<i16>(x_u8); - | ^^^^ expected `i16`, found `u8` + | ---------- ^^^^ expected `i16`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u8` to an `i16` | LL | foo::<i16>(x_u8.into()); @@ -750,8 +1226,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:186:16 | LL | foo::<i16>(x_isize); - | ^^^^^^^ expected `i16`, found `isize` + | ---------- ^^^^^^^ expected `i16`, found `isize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `isize` to an `i16` and panic if the converted value doesn't fit | LL | foo::<i16>(x_isize.try_into().unwrap()); @@ -761,8 +1244,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:188:16 | LL | foo::<i16>(x_i64); - | ^^^^^ expected `i16`, found `i64` + | ---------- ^^^^^ expected `i16`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i64` to an `i16` and panic if the converted value doesn't fit | LL | foo::<i16>(x_i64.try_into().unwrap()); @@ -772,8 +1262,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:190:16 | LL | foo::<i16>(x_i32); - | ^^^^^ expected `i16`, found `i32` + | ---------- ^^^^^ expected `i16`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i32` to an `i16` and panic if the converted value doesn't fit | LL | foo::<i16>(x_i32.try_into().unwrap()); @@ -783,8 +1280,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:193:16 | LL | foo::<i16>(x_i8); - | ^^^^ expected `i16`, found `i8` + | ---------- ^^^^ expected `i16`, found `i8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i8` to an `i16` | LL | foo::<i16>(x_i8.into()); @@ -794,8 +1298,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:198:15 | LL | foo::<u8>(x_usize); - | ^^^^^^^ expected `u8`, found `usize` + | --------- ^^^^^^^ expected `u8`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `usize` to a `u8` and panic if the converted value doesn't fit | LL | foo::<u8>(x_usize.try_into().unwrap()); @@ -805,8 +1316,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:200:15 | LL | foo::<u8>(x_u64); - | ^^^^^ expected `u8`, found `u64` + | --------- ^^^^^ expected `u8`, found `u64` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u64` to a `u8` and panic if the converted value doesn't fit | LL | foo::<u8>(x_u64.try_into().unwrap()); @@ -816,8 +1334,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:202:15 | LL | foo::<u8>(x_u32); - | ^^^^^ expected `u8`, found `u32` + | --------- ^^^^^ expected `u8`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u32` to a `u8` and panic if the converted value doesn't fit | LL | foo::<u8>(x_u32.try_into().unwrap()); @@ -827,8 +1352,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:204:15 | LL | foo::<u8>(x_u16); - | ^^^^^ expected `u8`, found `u16` + | --------- ^^^^^ expected `u8`, found `u16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u16` to a `u8` and panic if the converted value doesn't fit | LL | foo::<u8>(x_u16.try_into().unwrap()); @@ -838,8 +1370,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:207:15 | LL | foo::<u8>(x_isize); - | ^^^^^^^ expected `u8`, found `isize` + | --------- ^^^^^^^ expected `u8`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `isize` to a `u8` and panic if the converted value doesn't fit | LL | foo::<u8>(x_isize.try_into().unwrap()); @@ -849,8 +1388,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:209:15 | LL | foo::<u8>(x_i64); - | ^^^^^ expected `u8`, found `i64` + | --------- ^^^^^ expected `u8`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i64` to a `u8` and panic if the converted value doesn't fit | LL | foo::<u8>(x_i64.try_into().unwrap()); @@ -860,8 +1406,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:211:15 | LL | foo::<u8>(x_i32); - | ^^^^^ expected `u8`, found `i32` + | --------- ^^^^^ expected `u8`, found `i32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i32` to a `u8` and panic if the converted value doesn't fit | LL | foo::<u8>(x_i32.try_into().unwrap()); @@ -871,8 +1424,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:213:15 | LL | foo::<u8>(x_i16); - | ^^^^^ expected `u8`, found `i16` + | --------- ^^^^^ expected `u8`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i16` to a `u8` and panic if the converted value doesn't fit | LL | foo::<u8>(x_i16.try_into().unwrap()); @@ -882,8 +1442,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:215:15 | LL | foo::<u8>(x_i8); - | ^^^^ expected `u8`, found `i8` + | --------- ^^^^ expected `u8`, found `i8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i8` to a `u8` and panic if the converted value doesn't fit | LL | foo::<u8>(x_i8.try_into().unwrap()); @@ -893,8 +1460,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:220:15 | LL | foo::<i8>(x_usize); - | ^^^^^^^ expected `i8`, found `usize` + | --------- ^^^^^^^ expected `i8`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `usize` to an `i8` and panic if the converted value doesn't fit | LL | foo::<i8>(x_usize.try_into().unwrap()); @@ -904,8 +1478,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:222:15 | LL | foo::<i8>(x_u64); - | ^^^^^ expected `i8`, found `u64` + | --------- ^^^^^ expected `i8`, found `u64` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u64` to an `i8` and panic if the converted value doesn't fit | LL | foo::<i8>(x_u64.try_into().unwrap()); @@ -915,8 +1496,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:224:15 | LL | foo::<i8>(x_u32); - | ^^^^^ expected `i8`, found `u32` + | --------- ^^^^^ expected `i8`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u32` to an `i8` and panic if the converted value doesn't fit | LL | foo::<i8>(x_u32.try_into().unwrap()); @@ -926,8 +1514,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:226:15 | LL | foo::<i8>(x_u16); - | ^^^^^ expected `i8`, found `u16` + | --------- ^^^^^ expected `i8`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u16` to an `i8` and panic if the converted value doesn't fit | LL | foo::<i8>(x_u16.try_into().unwrap()); @@ -937,8 +1532,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:228:15 | LL | foo::<i8>(x_u8); - | ^^^^ expected `i8`, found `u8` + | --------- ^^^^ expected `i8`, found `u8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u8` to an `i8` and panic if the converted value doesn't fit | LL | foo::<i8>(x_u8.try_into().unwrap()); @@ -948,8 +1550,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:230:15 | LL | foo::<i8>(x_isize); - | ^^^^^^^ expected `i8`, found `isize` + | --------- ^^^^^^^ expected `i8`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `isize` to an `i8` and panic if the converted value doesn't fit | LL | foo::<i8>(x_isize.try_into().unwrap()); @@ -959,8 +1568,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:232:15 | LL | foo::<i8>(x_i64); - | ^^^^^ expected `i8`, found `i64` + | --------- ^^^^^ expected `i8`, found `i64` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i64` to an `i8` and panic if the converted value doesn't fit | LL | foo::<i8>(x_i64.try_into().unwrap()); @@ -970,8 +1586,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:234:15 | LL | foo::<i8>(x_i32); - | ^^^^^ expected `i8`, found `i32` + | --------- ^^^^^ expected `i8`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i32` to an `i8` and panic if the converted value doesn't fit | LL | foo::<i8>(x_i32.try_into().unwrap()); @@ -981,8 +1604,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:236:15 | LL | foo::<i8>(x_i16); - | ^^^^^ expected `i8`, found `i16` + | --------- ^^^^^ expected `i8`, found `i16` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i16` to an `i8` and panic if the converted value doesn't fit | LL | foo::<i8>(x_i16.try_into().unwrap()); @@ -992,8 +1622,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:242:16 | LL | foo::<f64>(x_usize); - | ^^^^^^^ expected `f64`, found `usize` + | ---------- ^^^^^^^ expected `f64`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can cast a `usize` to an `f64`, producing the floating point representation of the integer, rounded if necessary | LL | foo::<f64>(x_usize as f64); @@ -1003,8 +1640,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:244:16 | LL | foo::<f64>(x_u64); - | ^^^^^ expected `f64`, found `u64` + | ---------- ^^^^^ expected `f64`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can cast a `u64` to an `f64`, producing the floating point representation of the integer, rounded if necessary | LL | foo::<f64>(x_u64 as f64); @@ -1014,8 +1658,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:246:16 | LL | foo::<f64>(x_u32); - | ^^^^^ expected `f64`, found `u32` + | ---------- ^^^^^ expected `f64`, found `u32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u32` to an `f64`, producing the floating point representation of the integer | LL | foo::<f64>(x_u32.into()); @@ -1025,8 +1676,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:248:16 | LL | foo::<f64>(x_u16); - | ^^^^^ expected `f64`, found `u16` + | ---------- ^^^^^ expected `f64`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u16` to an `f64`, producing the floating point representation of the integer | LL | foo::<f64>(x_u16.into()); @@ -1036,8 +1694,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:250:16 | LL | foo::<f64>(x_u8); - | ^^^^ expected `f64`, found `u8` + | ---------- ^^^^ expected `f64`, found `u8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u8` to an `f64`, producing the floating point representation of the integer | LL | foo::<f64>(x_u8.into()); @@ -1047,8 +1712,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:252:16 | LL | foo::<f64>(x_isize); - | ^^^^^^^ expected `f64`, found `isize` + | ---------- ^^^^^^^ expected `f64`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `isize` to an `f64`, producing the floating point representation of the integer, rounded if necessary | LL | foo::<f64>(x_isize as f64); @@ -1058,8 +1730,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:254:16 | LL | foo::<f64>(x_i64); - | ^^^^^ expected `f64`, found `i64` + | ---------- ^^^^^ expected `f64`, found `i64` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i64` to an `f64`, producing the floating point representation of the integer, rounded if necessary | LL | foo::<f64>(x_i64 as f64); @@ -1069,8 +1748,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:256:16 | LL | foo::<f64>(x_i32); - | ^^^^^ expected `f64`, found `i32` + | ---------- ^^^^^ expected `f64`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i32` to an `f64`, producing the floating point representation of the integer | LL | foo::<f64>(x_i32.into()); @@ -1080,8 +1766,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:258:16 | LL | foo::<f64>(x_i16); - | ^^^^^ expected `f64`, found `i16` + | ---------- ^^^^^ expected `f64`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i16` to an `f64`, producing the floating point representation of the integer | LL | foo::<f64>(x_i16.into()); @@ -1091,8 +1784,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:260:16 | LL | foo::<f64>(x_i8); - | ^^^^ expected `f64`, found `i8` + | ---------- ^^^^ expected `f64`, found `i8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i8` to an `f64`, producing the floating point representation of the integer | LL | foo::<f64>(x_i8.into()); @@ -1102,8 +1802,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:263:16 | LL | foo::<f64>(x_f32); - | ^^^^^ expected `f64`, found `f32` + | ---------- ^^^^^ expected `f64`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `f32` to an `f64` | LL | foo::<f64>(x_f32.into()); @@ -1113,8 +1820,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:266:16 | LL | foo::<f32>(x_usize); - | ^^^^^^^ expected `f32`, found `usize` + | ---------- ^^^^^^^ expected `f32`, found `usize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can cast a `usize` to an `f32`, producing the floating point representation of the integer, rounded if necessary | LL | foo::<f32>(x_usize as f32); @@ -1124,8 +1838,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:268:16 | LL | foo::<f32>(x_u64); - | ^^^^^ expected `f32`, found `u64` + | ---------- ^^^^^ expected `f32`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can cast a `u64` to an `f32`, producing the floating point representation of the integer, rounded if necessary | LL | foo::<f32>(x_u64 as f32); @@ -1135,8 +1856,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:270:16 | LL | foo::<f32>(x_u32); - | ^^^^^ expected `f32`, found `u32` + | ---------- ^^^^^ expected `f32`, found `u32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can cast a `u32` to an `f32`, producing the floating point representation of the integer, rounded if necessary | LL | foo::<f32>(x_u32 as f32); @@ -1146,8 +1874,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:272:16 | LL | foo::<f32>(x_u16); - | ^^^^^ expected `f32`, found `u16` + | ---------- ^^^^^ expected `f32`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u16` to an `f32`, producing the floating point representation of the integer | LL | foo::<f32>(x_u16.into()); @@ -1157,8 +1892,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:274:16 | LL | foo::<f32>(x_u8); - | ^^^^ expected `f32`, found `u8` + | ---------- ^^^^ expected `f32`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u8` to an `f32`, producing the floating point representation of the integer | LL | foo::<f32>(x_u8.into()); @@ -1168,8 +1910,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:276:16 | LL | foo::<f32>(x_isize); - | ^^^^^^^ expected `f32`, found `isize` + | ---------- ^^^^^^^ expected `f32`, found `isize` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `isize` to an `f32`, producing the floating point representation of the integer, rounded if necessary | LL | foo::<f32>(x_isize as f32); @@ -1179,8 +1928,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:278:16 | LL | foo::<f32>(x_i64); - | ^^^^^ expected `f32`, found `i64` + | ---------- ^^^^^ expected `f32`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i64` to an `f32`, producing the floating point representation of the integer, rounded if necessary | LL | foo::<f32>(x_i64 as f32); @@ -1190,8 +1946,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:280:16 | LL | foo::<f32>(x_i32); - | ^^^^^ expected `f32`, found `i32` + | ---------- ^^^^^ expected `f32`, found `i32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i32` to an `f32`, producing the floating point representation of the integer, rounded if necessary | LL | foo::<f32>(x_i32 as f32); @@ -1201,8 +1964,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:282:16 | LL | foo::<f32>(x_i16); - | ^^^^^ expected `f32`, found `i16` + | ---------- ^^^^^ expected `f32`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i16` to an `f32`, producing the floating point representation of the integer | LL | foo::<f32>(x_i16.into()); @@ -1212,8 +1982,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:284:16 | LL | foo::<f32>(x_i8); - | ^^^^ expected `f32`, found `i8` + | ---------- ^^^^ expected `f32`, found `i8` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i8` to an `f32`, producing the floating point representation of the integer | LL | foo::<f32>(x_i8.into()); @@ -1223,8 +2000,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:289:16 | LL | foo::<u32>(x_u8 as u16); - | ^^^^^^^^^^^ expected `u32`, found `u16` + | ---------- ^^^^^^^^^^^ expected `u32`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert a `u16` to a `u32` | LL | foo::<u32>((x_u8 as u16).into()); @@ -1234,8 +2018,15 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:291:16 | LL | foo::<i32>(-x_i8); - | ^^^^^ expected `i32`, found `i8` + | ---------- ^^^^^ expected `i32`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-cast.rs:6:4 | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- help: you can convert an `i8` to an `i32` | LL | foo::<i32>((-x_i8).into()); diff --git a/src/test/ui/numeric/numeric-suffix.fixed b/src/test/ui/numeric/numeric-suffix.fixed deleted file mode 100644 index 53c5fe0f435..00000000000 --- a/src/test/ui/numeric/numeric-suffix.fixed +++ /dev/null @@ -1,298 +0,0 @@ -// run-rustfix - -fn foo<N>(_x: N) {} - -fn main() { - foo::<usize>(42_usize); - foo::<usize>(42_usize); - //~^ ERROR mismatched types - foo::<usize>(42_usize); - //~^ ERROR mismatched types - foo::<usize>(42_usize); - //~^ ERROR mismatched types - foo::<usize>(42_usize); - //~^ ERROR mismatched types - foo::<usize>(42_usize); - //~^ ERROR mismatched types - foo::<usize>(42_usize); - //~^ ERROR mismatched types - foo::<usize>(42_usize); - //~^ ERROR mismatched types - foo::<usize>(42_usize); - //~^ ERROR mismatched types - foo::<usize>(42_usize); - //~^ ERROR mismatched types - foo::<usize>(42usize); - //~^ ERROR mismatched types - foo::<usize>(42usize); - //~^ ERROR mismatched types - - foo::<isize>(42_isize); - //~^ ERROR mismatched types - foo::<isize>(42_isize); - //~^ ERROR mismatched types - foo::<isize>(42_isize); - //~^ ERROR mismatched types - foo::<isize>(42_isize); - //~^ ERROR mismatched types - foo::<isize>(42_isize); - //~^ ERROR mismatched types - foo::<isize>(42_isize); - foo::<isize>(42_isize); - //~^ ERROR mismatched types - foo::<isize>(42_isize); - //~^ ERROR mismatched types - foo::<isize>(42_isize); - //~^ ERROR mismatched types - foo::<isize>(42_isize); - //~^ ERROR mismatched types - foo::<isize>(42isize); - //~^ ERROR mismatched types - foo::<isize>(42isize); - //~^ ERROR mismatched types - - foo::<u64>(42_u64); - //~^ ERROR mismatched types - foo::<u64>(42_u64); - foo::<u64>(42_u64); - //~^ ERROR mismatched types - foo::<u64>(42_u64); - //~^ ERROR mismatched types - foo::<u64>(42_u64); - //~^ ERROR mismatched types - foo::<u64>(42_u64); - //~^ ERROR mismatched types - foo::<u64>(42_u64); - //~^ ERROR mismatched types - foo::<u64>(42_u64); - //~^ ERROR mismatched types - foo::<u64>(42_u64); - //~^ ERROR mismatched types - foo::<u64>(42_u64); - //~^ ERROR mismatched types - foo::<u64>(42u64); - //~^ ERROR mismatched types - foo::<u64>(42u64); - //~^ ERROR mismatched types - - foo::<i64>(42_i64); - //~^ ERROR mismatched types - foo::<i64>(42_i64); - //~^ ERROR mismatched types - foo::<i64>(42_i64); - //~^ ERROR mismatched types - foo::<i64>(42_i64); - //~^ ERROR mismatched types - foo::<i64>(42_i64); - //~^ ERROR mismatched types - foo::<i64>(42_i64); - //~^ ERROR mismatched types - foo::<i64>(42_i64); - foo::<i64>(42_i64); - //~^ ERROR mismatched types - foo::<i64>(42_i64); - //~^ ERROR mismatched types - foo::<i64>(42_i64); - //~^ ERROR mismatched types - foo::<i64>(42i64); - //~^ ERROR mismatched types - foo::<i64>(42i64); - //~^ ERROR mismatched types - - foo::<u32>(42_u32); - //~^ ERROR mismatched types - foo::<u32>(42_u32); - //~^ ERROR mismatched types - foo::<u32>(42_u32); - foo::<u32>(42_u32); - //~^ ERROR mismatched types - foo::<u32>(42_u32); - //~^ ERROR mismatched types - foo::<u32>(42_u32); - //~^ ERROR mismatched types - foo::<u32>(42_u32); - //~^ ERROR mismatched types - foo::<u32>(42_u32); - //~^ ERROR mismatched types - foo::<u32>(42_u32); - //~^ ERROR mismatched types - foo::<u32>(42_u32); - //~^ ERROR mismatched types - foo::<u32>(42u32); - //~^ ERROR mismatched types - foo::<u32>(42u32); - //~^ ERROR mismatched types - - foo::<i32>(42_i32); - //~^ ERROR mismatched types - foo::<i32>(42_i32); - //~^ ERROR mismatched types - foo::<i32>(42_i32); - //~^ ERROR mismatched types - foo::<i32>(42_i32); - //~^ ERROR mismatched types - foo::<i32>(42_i32); - //~^ ERROR mismatched types - foo::<i32>(42_i32); - //~^ ERROR mismatched types - foo::<i32>(42_i32); - //~^ ERROR mismatched types - foo::<i32>(42_i32); - foo::<i32>(42_i32); - //~^ ERROR mismatched types - foo::<i32>(42_i32); - //~^ ERROR mismatched types - foo::<i32>(42i32); - //~^ ERROR mismatched types - foo::<i32>(42i32); - //~^ ERROR mismatched types - - foo::<u16>(42_u16); - //~^ ERROR mismatched types - foo::<u16>(42_u16); - //~^ ERROR mismatched types - foo::<u16>(42_u16); - //~^ ERROR mismatched types - foo::<u16>(42_u16); - foo::<u16>(42_u16); - //~^ ERROR mismatched types - foo::<u16>(42_u16); - //~^ ERROR mismatched types - foo::<u16>(42_u16); - //~^ ERROR mismatched types - foo::<u16>(42_u16); - //~^ ERROR mismatched types - foo::<u16>(42_u16); - //~^ ERROR mismatched types - foo::<u16>(42_u16); - //~^ ERROR mismatched types - foo::<u16>(42u16); - //~^ ERROR mismatched types - foo::<u16>(42u16); - //~^ ERROR mismatched types - - foo::<i16>(42_i16); - //~^ ERROR mismatched types - foo::<i16>(42_i16); - //~^ ERROR mismatched types - foo::<i16>(42_i16); - //~^ ERROR mismatched types - foo::<i16>(42_i16); - //~^ ERROR mismatched types - foo::<i16>(42_i16); - //~^ ERROR mismatched types - foo::<i16>(42_i16); - //~^ ERROR mismatched types - foo::<i16>(42_i16); - //~^ ERROR mismatched types - foo::<i16>(42_i16); - //~^ ERROR mismatched types - foo::<i16>(42_i16); - foo::<i16>(42_i16); - //~^ ERROR mismatched types - foo::<i16>(42i16); - //~^ ERROR mismatched types - foo::<i16>(42i16); - //~^ ERROR mismatched types - - foo::<u8>(42_u8); - //~^ ERROR mismatched types - foo::<u8>(42_u8); - //~^ ERROR mismatched types - foo::<u8>(42_u8); - //~^ ERROR mismatched types - foo::<u8>(42_u8); - //~^ ERROR mismatched types - foo::<u8>(42_u8); - foo::<u8>(42_u8); - //~^ ERROR mismatched types - foo::<u8>(42_u8); - //~^ ERROR mismatched types - foo::<u8>(42_u8); - //~^ ERROR mismatched types - foo::<u8>(42_u8); - //~^ ERROR mismatched types - foo::<u8>(42_u8); - //~^ ERROR mismatched types - foo::<u8>(42u8); - //~^ ERROR mismatched types - foo::<u8>(42u8); - //~^ ERROR mismatched types - - foo::<i8>(42_i8); - //~^ ERROR mismatched types - foo::<i8>(42_i8); - //~^ ERROR mismatched types - foo::<i8>(42_i8); - //~^ ERROR mismatched types - foo::<i8>(42_i8); - //~^ ERROR mismatched types - foo::<i8>(42_i8); - //~^ ERROR mismatched types - foo::<i8>(42_i8); - //~^ ERROR mismatched types - foo::<i8>(42_i8); - //~^ ERROR mismatched types - foo::<i8>(42_i8); - //~^ ERROR mismatched types - foo::<i8>(42_i8); - //~^ ERROR mismatched types - foo::<i8>(42_i8); - foo::<i8>(42i8); - //~^ ERROR mismatched types - foo::<i8>(42i8); - //~^ ERROR mismatched types - - foo::<f64>(42_f64); - //~^ ERROR mismatched types - foo::<f64>(42_f64); - //~^ ERROR mismatched types - foo::<f64>(42_u32.into()); - //~^ ERROR mismatched types - foo::<f64>(42_u16.into()); - //~^ ERROR mismatched types - foo::<f64>(42_u8.into()); - //~^ ERROR mismatched types - foo::<f64>(42_f64); - //~^ ERROR mismatched types - foo::<f64>(42_f64); - //~^ ERROR mismatched types - foo::<f64>(42_i32.into()); - //~^ ERROR mismatched types - foo::<f64>(42_i16.into()); - //~^ ERROR mismatched types - foo::<f64>(42_i8.into()); - //~^ ERROR mismatched types - foo::<f64>(42.0_f64); - foo::<f64>(42.0_f64); - //~^ ERROR mismatched types - - foo::<f32>(42_f32); - //~^ ERROR mismatched types - foo::<f32>(42_f32); - //~^ ERROR mismatched types - foo::<f32>(42_f32); - //~^ ERROR mismatched types - foo::<f32>(42_u16.into()); - //~^ ERROR mismatched types - foo::<f32>(42_u8.into()); - //~^ ERROR mismatched types - foo::<f32>(42_f32); - //~^ ERROR mismatched types - foo::<f32>(42_f32); - //~^ ERROR mismatched types - foo::<f32>(42_f32); - //~^ ERROR mismatched types - foo::<f32>(42_i16.into()); - //~^ ERROR mismatched types - foo::<f32>(42_i8.into()); - //~^ ERROR mismatched types - foo::<f32>(42.0_f32); - //~^ ERROR mismatched types - foo::<f32>(42.0_f32); - - foo::<u32>((42_u8 as u16).into()); - //~^ ERROR mismatched types - foo::<i32>((-42_i8).into()); - //~^ ERROR mismatched types -} diff --git a/src/test/ui/numeric/numeric-suffix.rs b/src/test/ui/numeric/numeric-suffix.rs deleted file mode 100644 index ca38ed82220..00000000000 --- a/src/test/ui/numeric/numeric-suffix.rs +++ /dev/null @@ -1,298 +0,0 @@ -// run-rustfix - -fn foo<N>(_x: N) {} - -fn main() { - foo::<usize>(42_usize); - foo::<usize>(42_u64); - //~^ ERROR mismatched types - foo::<usize>(42_u32); - //~^ ERROR mismatched types - foo::<usize>(42_u16); - //~^ ERROR mismatched types - foo::<usize>(42_u8); - //~^ ERROR mismatched types - foo::<usize>(42_isize); - //~^ ERROR mismatched types - foo::<usize>(42_i64); - //~^ ERROR mismatched types - foo::<usize>(42_i32); - //~^ ERROR mismatched types - foo::<usize>(42_i16); - //~^ ERROR mismatched types - foo::<usize>(42_i8); - //~^ ERROR mismatched types - foo::<usize>(42.0_f64); - //~^ ERROR mismatched types - foo::<usize>(42.0_f32); - //~^ ERROR mismatched types - - foo::<isize>(42_usize); - //~^ ERROR mismatched types - foo::<isize>(42_u64); - //~^ ERROR mismatched types - foo::<isize>(42_u32); - //~^ ERROR mismatched types - foo::<isize>(42_u16); - //~^ ERROR mismatched types - foo::<isize>(42_u8); - //~^ ERROR mismatched types - foo::<isize>(42_isize); - foo::<isize>(42_i64); - //~^ ERROR mismatched types - foo::<isize>(42_i32); - //~^ ERROR mismatched types - foo::<isize>(42_i16); - //~^ ERROR mismatched types - foo::<isize>(42_i8); - //~^ ERROR mismatched types - foo::<isize>(42.0_f64); - //~^ ERROR mismatched types - foo::<isize>(42.0_f32); - //~^ ERROR mismatched types - - foo::<u64>(42_usize); - //~^ ERROR mismatched types - foo::<u64>(42_u64); - foo::<u64>(42_u32); - //~^ ERROR mismatched types - foo::<u64>(42_u16); - //~^ ERROR mismatched types - foo::<u64>(42_u8); - //~^ ERROR mismatched types - foo::<u64>(42_isize); - //~^ ERROR mismatched types - foo::<u64>(42_i64); - //~^ ERROR mismatched types - foo::<u64>(42_i32); - //~^ ERROR mismatched types - foo::<u64>(42_i16); - //~^ ERROR mismatched types - foo::<u64>(42_i8); - //~^ ERROR mismatched types - foo::<u64>(42.0_f64); - //~^ ERROR mismatched types - foo::<u64>(42.0_f32); - //~^ ERROR mismatched types - - foo::<i64>(42_usize); - //~^ ERROR mismatched types - foo::<i64>(42_u64); - //~^ ERROR mismatched types - foo::<i64>(42_u32); - //~^ ERROR mismatched types - foo::<i64>(42_u16); - //~^ ERROR mismatched types - foo::<i64>(42_u8); - //~^ ERROR mismatched types - foo::<i64>(42_isize); - //~^ ERROR mismatched types - foo::<i64>(42_i64); - foo::<i64>(42_i32); - //~^ ERROR mismatched types - foo::<i64>(42_i16); - //~^ ERROR mismatched types - foo::<i64>(42_i8); - //~^ ERROR mismatched types - foo::<i64>(42.0_f64); - //~^ ERROR mismatched types - foo::<i64>(42.0_f32); - //~^ ERROR mismatched types - - foo::<u32>(42_usize); - //~^ ERROR mismatched types - foo::<u32>(42_u64); - //~^ ERROR mismatched types - foo::<u32>(42_u32); - foo::<u32>(42_u16); - //~^ ERROR mismatched types - foo::<u32>(42_u8); - //~^ ERROR mismatched types - foo::<u32>(42_isize); - //~^ ERROR mismatched types - foo::<u32>(42_i64); - //~^ ERROR mismatched types - foo::<u32>(42_i32); - //~^ ERROR mismatched types - foo::<u32>(42_i16); - //~^ ERROR mismatched types - foo::<u32>(42_i8); - //~^ ERROR mismatched types - foo::<u32>(42.0_f64); - //~^ ERROR mismatched types - foo::<u32>(42.0_f32); - //~^ ERROR mismatched types - - foo::<i32>(42_usize); - //~^ ERROR mismatched types - foo::<i32>(42_u64); - //~^ ERROR mismatched types - foo::<i32>(42_u32); - //~^ ERROR mismatched types - foo::<i32>(42_u16); - //~^ ERROR mismatched types - foo::<i32>(42_u8); - //~^ ERROR mismatched types - foo::<i32>(42_isize); - //~^ ERROR mismatched types - foo::<i32>(42_i64); - //~^ ERROR mismatched types - foo::<i32>(42_i32); - foo::<i32>(42_i16); - //~^ ERROR mismatched types - foo::<i32>(42_i8); - //~^ ERROR mismatched types - foo::<i32>(42.0_f64); - //~^ ERROR mismatched types - foo::<i32>(42.0_f32); - //~^ ERROR mismatched types - - foo::<u16>(42_usize); - //~^ ERROR mismatched types - foo::<u16>(42_u64); - //~^ ERROR mismatched types - foo::<u16>(42_u32); - //~^ ERROR mismatched types - foo::<u16>(42_u16); - foo::<u16>(42_u8); - //~^ ERROR mismatched types - foo::<u16>(42_isize); - //~^ ERROR mismatched types - foo::<u16>(42_i64); - //~^ ERROR mismatched types - foo::<u16>(42_i32); - //~^ ERROR mismatched types - foo::<u16>(42_i16); - //~^ ERROR mismatched types - foo::<u16>(42_i8); - //~^ ERROR mismatched types - foo::<u16>(42.0_f64); - //~^ ERROR mismatched types - foo::<u16>(42.0_f32); - //~^ ERROR mismatched types - - foo::<i16>(42_usize); - //~^ ERROR mismatched types - foo::<i16>(42_u64); - //~^ ERROR mismatched types - foo::<i16>(42_u32); - //~^ ERROR mismatched types - foo::<i16>(42_u16); - //~^ ERROR mismatched types - foo::<i16>(42_u8); - //~^ ERROR mismatched types - foo::<i16>(42_isize); - //~^ ERROR mismatched types - foo::<i16>(42_i64); - //~^ ERROR mismatched types - foo::<i16>(42_i32); - //~^ ERROR mismatched types - foo::<i16>(42_i16); - foo::<i16>(42_i8); - //~^ ERROR mismatched types - foo::<i16>(42.0_f64); - //~^ ERROR mismatched types - foo::<i16>(42.0_f32); - //~^ ERROR mismatched types - - foo::<u8>(42_usize); - //~^ ERROR mismatched types - foo::<u8>(42_u64); - //~^ ERROR mismatched types - foo::<u8>(42_u32); - //~^ ERROR mismatched types - foo::<u8>(42_u16); - //~^ ERROR mismatched types - foo::<u8>(42_u8); - foo::<u8>(42_isize); - //~^ ERROR mismatched types - foo::<u8>(42_i64); - //~^ ERROR mismatched types - foo::<u8>(42_i32); - //~^ ERROR mismatched types - foo::<u8>(42_i16); - //~^ ERROR mismatched types - foo::<u8>(42_i8); - //~^ ERROR mismatched types - foo::<u8>(42.0_f64); - //~^ ERROR mismatched types - foo::<u8>(42.0_f32); - //~^ ERROR mismatched types - - foo::<i8>(42_usize); - //~^ ERROR mismatched types - foo::<i8>(42_u64); - //~^ ERROR mismatched types - foo::<i8>(42_u32); - //~^ ERROR mismatched types - foo::<i8>(42_u16); - //~^ ERROR mismatched types - foo::<i8>(42_u8); - //~^ ERROR mismatched types - foo::<i8>(42_isize); - //~^ ERROR mismatched types - foo::<i8>(42_i64); - //~^ ERROR mismatched types - foo::<i8>(42_i32); - //~^ ERROR mismatched types - foo::<i8>(42_i16); - //~^ ERROR mismatched types - foo::<i8>(42_i8); - foo::<i8>(42.0_f64); - //~^ ERROR mismatched types - foo::<i8>(42.0_f32); - //~^ ERROR mismatched types - - foo::<f64>(42_usize); - //~^ ERROR mismatched types - foo::<f64>(42_u64); - //~^ ERROR mismatched types - foo::<f64>(42_u32); - //~^ ERROR mismatched types - foo::<f64>(42_u16); - //~^ ERROR mismatched types - foo::<f64>(42_u8); - //~^ ERROR mismatched types - foo::<f64>(42_isize); - //~^ ERROR mismatched types - foo::<f64>(42_i64); - //~^ ERROR mismatched types - foo::<f64>(42_i32); - //~^ ERROR mismatched types - foo::<f64>(42_i16); - //~^ ERROR mismatched types - foo::<f64>(42_i8); - //~^ ERROR mismatched types - foo::<f64>(42.0_f64); - foo::<f64>(42.0_f32); - //~^ ERROR mismatched types - - foo::<f32>(42_usize); - //~^ ERROR mismatched types - foo::<f32>(42_u64); - //~^ ERROR mismatched types - foo::<f32>(42_u32); - //~^ ERROR mismatched types - foo::<f32>(42_u16); - //~^ ERROR mismatched types - foo::<f32>(42_u8); - //~^ ERROR mismatched types - foo::<f32>(42_isize); - //~^ ERROR mismatched types - foo::<f32>(42_i64); - //~^ ERROR mismatched types - foo::<f32>(42_i32); - //~^ ERROR mismatched types - foo::<f32>(42_i16); - //~^ ERROR mismatched types - foo::<f32>(42_i8); - //~^ ERROR mismatched types - foo::<f32>(42.0_f64); - //~^ ERROR mismatched types - foo::<f32>(42.0_f32); - - foo::<u32>(42_u8 as u16); - //~^ ERROR mismatched types - foo::<i32>(-42_i8); - //~^ ERROR mismatched types -} diff --git a/src/test/ui/numeric/numeric-suffix.stderr b/src/test/ui/numeric/numeric-suffix.stderr deleted file mode 100644 index b829946e522..00000000000 --- a/src/test/ui/numeric/numeric-suffix.stderr +++ /dev/null @@ -1,1477 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:7:18 - | -LL | foo::<usize>(42_u64); - | ^^^^^^ expected `usize`, found `u64` - | -help: change the type of the numeric literal from `u64` to `usize` - | -LL | foo::<usize>(42_usize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:9:18 - | -LL | foo::<usize>(42_u32); - | ^^^^^^ expected `usize`, found `u32` - | -help: change the type of the numeric literal from `u32` to `usize` - | -LL | foo::<usize>(42_usize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:11:18 - | -LL | foo::<usize>(42_u16); - | ^^^^^^ expected `usize`, found `u16` - | -help: change the type of the numeric literal from `u16` to `usize` - | -LL | foo::<usize>(42_usize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:13:18 - | -LL | foo::<usize>(42_u8); - | ^^^^^ expected `usize`, found `u8` - | -help: change the type of the numeric literal from `u8` to `usize` - | -LL | foo::<usize>(42_usize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:15:18 - | -LL | foo::<usize>(42_isize); - | ^^^^^^^^ expected `usize`, found `isize` - | -help: change the type of the numeric literal from `isize` to `usize` - | -LL | foo::<usize>(42_usize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:17:18 - | -LL | foo::<usize>(42_i64); - | ^^^^^^ expected `usize`, found `i64` - | -help: change the type of the numeric literal from `i64` to `usize` - | -LL | foo::<usize>(42_usize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:19:18 - | -LL | foo::<usize>(42_i32); - | ^^^^^^ expected `usize`, found `i32` - | -help: change the type of the numeric literal from `i32` to `usize` - | -LL | foo::<usize>(42_usize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:21:18 - | -LL | foo::<usize>(42_i16); - | ^^^^^^ expected `usize`, found `i16` - | -help: change the type of the numeric literal from `i16` to `usize` - | -LL | foo::<usize>(42_usize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:23:18 - | -LL | foo::<usize>(42_i8); - | ^^^^^ expected `usize`, found `i8` - | -help: change the type of the numeric literal from `i8` to `usize` - | -LL | foo::<usize>(42_usize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:25:18 - | -LL | foo::<usize>(42.0_f64); - | ^^^^^^^^ expected `usize`, found `f64` - | -help: change the type of the numeric literal from `f64` to `usize` - | -LL | foo::<usize>(42usize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:27:18 - | -LL | foo::<usize>(42.0_f32); - | ^^^^^^^^ expected `usize`, found `f32` - | -help: change the type of the numeric literal from `f32` to `usize` - | -LL | foo::<usize>(42usize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:30:18 - | -LL | foo::<isize>(42_usize); - | ^^^^^^^^ expected `isize`, found `usize` - | -help: change the type of the numeric literal from `usize` to `isize` - | -LL | foo::<isize>(42_isize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:32:18 - | -LL | foo::<isize>(42_u64); - | ^^^^^^ expected `isize`, found `u64` - | -help: change the type of the numeric literal from `u64` to `isize` - | -LL | foo::<isize>(42_isize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:34:18 - | -LL | foo::<isize>(42_u32); - | ^^^^^^ expected `isize`, found `u32` - | -help: change the type of the numeric literal from `u32` to `isize` - | -LL | foo::<isize>(42_isize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:36:18 - | -LL | foo::<isize>(42_u16); - | ^^^^^^ expected `isize`, found `u16` - | -help: change the type of the numeric literal from `u16` to `isize` - | -LL | foo::<isize>(42_isize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:38:18 - | -LL | foo::<isize>(42_u8); - | ^^^^^ expected `isize`, found `u8` - | -help: change the type of the numeric literal from `u8` to `isize` - | -LL | foo::<isize>(42_isize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:41:18 - | -LL | foo::<isize>(42_i64); - | ^^^^^^ expected `isize`, found `i64` - | -help: change the type of the numeric literal from `i64` to `isize` - | -LL | foo::<isize>(42_isize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:43:18 - | -LL | foo::<isize>(42_i32); - | ^^^^^^ expected `isize`, found `i32` - | -help: change the type of the numeric literal from `i32` to `isize` - | -LL | foo::<isize>(42_isize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:45:18 - | -LL | foo::<isize>(42_i16); - | ^^^^^^ expected `isize`, found `i16` - | -help: change the type of the numeric literal from `i16` to `isize` - | -LL | foo::<isize>(42_isize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:47:18 - | -LL | foo::<isize>(42_i8); - | ^^^^^ expected `isize`, found `i8` - | -help: change the type of the numeric literal from `i8` to `isize` - | -LL | foo::<isize>(42_isize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:49:18 - | -LL | foo::<isize>(42.0_f64); - | ^^^^^^^^ expected `isize`, found `f64` - | -help: change the type of the numeric literal from `f64` to `isize` - | -LL | foo::<isize>(42isize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:51:18 - | -LL | foo::<isize>(42.0_f32); - | ^^^^^^^^ expected `isize`, found `f32` - | -help: change the type of the numeric literal from `f32` to `isize` - | -LL | foo::<isize>(42isize); - | ~~~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:54:16 - | -LL | foo::<u64>(42_usize); - | ^^^^^^^^ expected `u64`, found `usize` - | -help: change the type of the numeric literal from `usize` to `u64` - | -LL | foo::<u64>(42_u64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:57:16 - | -LL | foo::<u64>(42_u32); - | ^^^^^^ expected `u64`, found `u32` - | -help: change the type of the numeric literal from `u32` to `u64` - | -LL | foo::<u64>(42_u64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:59:16 - | -LL | foo::<u64>(42_u16); - | ^^^^^^ expected `u64`, found `u16` - | -help: change the type of the numeric literal from `u16` to `u64` - | -LL | foo::<u64>(42_u64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:61:16 - | -LL | foo::<u64>(42_u8); - | ^^^^^ expected `u64`, found `u8` - | -help: change the type of the numeric literal from `u8` to `u64` - | -LL | foo::<u64>(42_u64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:63:16 - | -LL | foo::<u64>(42_isize); - | ^^^^^^^^ expected `u64`, found `isize` - | -help: change the type of the numeric literal from `isize` to `u64` - | -LL | foo::<u64>(42_u64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:65:16 - | -LL | foo::<u64>(42_i64); - | ^^^^^^ expected `u64`, found `i64` - | -help: change the type of the numeric literal from `i64` to `u64` - | -LL | foo::<u64>(42_u64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:67:16 - | -LL | foo::<u64>(42_i32); - | ^^^^^^ expected `u64`, found `i32` - | -help: change the type of the numeric literal from `i32` to `u64` - | -LL | foo::<u64>(42_u64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:69:16 - | -LL | foo::<u64>(42_i16); - | ^^^^^^ expected `u64`, found `i16` - | -help: change the type of the numeric literal from `i16` to `u64` - | -LL | foo::<u64>(42_u64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:71:16 - | -LL | foo::<u64>(42_i8); - | ^^^^^ expected `u64`, found `i8` - | -help: change the type of the numeric literal from `i8` to `u64` - | -LL | foo::<u64>(42_u64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:73:16 - | -LL | foo::<u64>(42.0_f64); - | ^^^^^^^^ expected `u64`, found `f64` - | -help: change the type of the numeric literal from `f64` to `u64` - | -LL | foo::<u64>(42u64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:75:16 - | -LL | foo::<u64>(42.0_f32); - | ^^^^^^^^ expected `u64`, found `f32` - | -help: change the type of the numeric literal from `f32` to `u64` - | -LL | foo::<u64>(42u64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:78:16 - | -LL | foo::<i64>(42_usize); - | ^^^^^^^^ expected `i64`, found `usize` - | -help: change the type of the numeric literal from `usize` to `i64` - | -LL | foo::<i64>(42_i64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:80:16 - | -LL | foo::<i64>(42_u64); - | ^^^^^^ expected `i64`, found `u64` - | -help: change the type of the numeric literal from `u64` to `i64` - | -LL | foo::<i64>(42_i64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:82:16 - | -LL | foo::<i64>(42_u32); - | ^^^^^^ expected `i64`, found `u32` - | -help: change the type of the numeric literal from `u32` to `i64` - | -LL | foo::<i64>(42_i64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:84:16 - | -LL | foo::<i64>(42_u16); - | ^^^^^^ expected `i64`, found `u16` - | -help: change the type of the numeric literal from `u16` to `i64` - | -LL | foo::<i64>(42_i64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:86:16 - | -LL | foo::<i64>(42_u8); - | ^^^^^ expected `i64`, found `u8` - | -help: change the type of the numeric literal from `u8` to `i64` - | -LL | foo::<i64>(42_i64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:88:16 - | -LL | foo::<i64>(42_isize); - | ^^^^^^^^ expected `i64`, found `isize` - | -help: change the type of the numeric literal from `isize` to `i64` - | -LL | foo::<i64>(42_i64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:91:16 - | -LL | foo::<i64>(42_i32); - | ^^^^^^ expected `i64`, found `i32` - | -help: change the type of the numeric literal from `i32` to `i64` - | -LL | foo::<i64>(42_i64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:93:16 - | -LL | foo::<i64>(42_i16); - | ^^^^^^ expected `i64`, found `i16` - | -help: change the type of the numeric literal from `i16` to `i64` - | -LL | foo::<i64>(42_i64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:95:16 - | -LL | foo::<i64>(42_i8); - | ^^^^^ expected `i64`, found `i8` - | -help: change the type of the numeric literal from `i8` to `i64` - | -LL | foo::<i64>(42_i64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:97:16 - | -LL | foo::<i64>(42.0_f64); - | ^^^^^^^^ expected `i64`, found `f64` - | -help: change the type of the numeric literal from `f64` to `i64` - | -LL | foo::<i64>(42i64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:99:16 - | -LL | foo::<i64>(42.0_f32); - | ^^^^^^^^ expected `i64`, found `f32` - | -help: change the type of the numeric literal from `f32` to `i64` - | -LL | foo::<i64>(42i64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:102:16 - | -LL | foo::<u32>(42_usize); - | ^^^^^^^^ expected `u32`, found `usize` - | -help: change the type of the numeric literal from `usize` to `u32` - | -LL | foo::<u32>(42_u32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:104:16 - | -LL | foo::<u32>(42_u64); - | ^^^^^^ expected `u32`, found `u64` - | -help: change the type of the numeric literal from `u64` to `u32` - | -LL | foo::<u32>(42_u32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:107:16 - | -LL | foo::<u32>(42_u16); - | ^^^^^^ expected `u32`, found `u16` - | -help: change the type of the numeric literal from `u16` to `u32` - | -LL | foo::<u32>(42_u32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:109:16 - | -LL | foo::<u32>(42_u8); - | ^^^^^ expected `u32`, found `u8` - | -help: change the type of the numeric literal from `u8` to `u32` - | -LL | foo::<u32>(42_u32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:111:16 - | -LL | foo::<u32>(42_isize); - | ^^^^^^^^ expected `u32`, found `isize` - | -help: change the type of the numeric literal from `isize` to `u32` - | -LL | foo::<u32>(42_u32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:113:16 - | -LL | foo::<u32>(42_i64); - | ^^^^^^ expected `u32`, found `i64` - | -help: change the type of the numeric literal from `i64` to `u32` - | -LL | foo::<u32>(42_u32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:115:16 - | -LL | foo::<u32>(42_i32); - | ^^^^^^ expected `u32`, found `i32` - | -help: change the type of the numeric literal from `i32` to `u32` - | -LL | foo::<u32>(42_u32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:117:16 - | -LL | foo::<u32>(42_i16); - | ^^^^^^ expected `u32`, found `i16` - | -help: change the type of the numeric literal from `i16` to `u32` - | -LL | foo::<u32>(42_u32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:119:16 - | -LL | foo::<u32>(42_i8); - | ^^^^^ expected `u32`, found `i8` - | -help: change the type of the numeric literal from `i8` to `u32` - | -LL | foo::<u32>(42_u32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:121:16 - | -LL | foo::<u32>(42.0_f64); - | ^^^^^^^^ expected `u32`, found `f64` - | -help: change the type of the numeric literal from `f64` to `u32` - | -LL | foo::<u32>(42u32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:123:16 - | -LL | foo::<u32>(42.0_f32); - | ^^^^^^^^ expected `u32`, found `f32` - | -help: change the type of the numeric literal from `f32` to `u32` - | -LL | foo::<u32>(42u32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:126:16 - | -LL | foo::<i32>(42_usize); - | ^^^^^^^^ expected `i32`, found `usize` - | -help: change the type of the numeric literal from `usize` to `i32` - | -LL | foo::<i32>(42_i32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:128:16 - | -LL | foo::<i32>(42_u64); - | ^^^^^^ expected `i32`, found `u64` - | -help: change the type of the numeric literal from `u64` to `i32` - | -LL | foo::<i32>(42_i32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:130:16 - | -LL | foo::<i32>(42_u32); - | ^^^^^^ expected `i32`, found `u32` - | -help: change the type of the numeric literal from `u32` to `i32` - | -LL | foo::<i32>(42_i32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:132:16 - | -LL | foo::<i32>(42_u16); - | ^^^^^^ expected `i32`, found `u16` - | -help: change the type of the numeric literal from `u16` to `i32` - | -LL | foo::<i32>(42_i32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:134:16 - | -LL | foo::<i32>(42_u8); - | ^^^^^ expected `i32`, found `u8` - | -help: change the type of the numeric literal from `u8` to `i32` - | -LL | foo::<i32>(42_i32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:136:16 - | -LL | foo::<i32>(42_isize); - | ^^^^^^^^ expected `i32`, found `isize` - | -help: change the type of the numeric literal from `isize` to `i32` - | -LL | foo::<i32>(42_i32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:138:16 - | -LL | foo::<i32>(42_i64); - | ^^^^^^ expected `i32`, found `i64` - | -help: change the type of the numeric literal from `i64` to `i32` - | -LL | foo::<i32>(42_i32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:141:16 - | -LL | foo::<i32>(42_i16); - | ^^^^^^ expected `i32`, found `i16` - | -help: change the type of the numeric literal from `i16` to `i32` - | -LL | foo::<i32>(42_i32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:143:16 - | -LL | foo::<i32>(42_i8); - | ^^^^^ expected `i32`, found `i8` - | -help: change the type of the numeric literal from `i8` to `i32` - | -LL | foo::<i32>(42_i32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:145:16 - | -LL | foo::<i32>(42.0_f64); - | ^^^^^^^^ expected `i32`, found `f64` - | -help: change the type of the numeric literal from `f64` to `i32` - | -LL | foo::<i32>(42i32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:147:16 - | -LL | foo::<i32>(42.0_f32); - | ^^^^^^^^ expected `i32`, found `f32` - | -help: change the type of the numeric literal from `f32` to `i32` - | -LL | foo::<i32>(42i32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:150:16 - | -LL | foo::<u16>(42_usize); - | ^^^^^^^^ expected `u16`, found `usize` - | -help: change the type of the numeric literal from `usize` to `u16` - | -LL | foo::<u16>(42_u16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:152:16 - | -LL | foo::<u16>(42_u64); - | ^^^^^^ expected `u16`, found `u64` - | -help: change the type of the numeric literal from `u64` to `u16` - | -LL | foo::<u16>(42_u16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:154:16 - | -LL | foo::<u16>(42_u32); - | ^^^^^^ expected `u16`, found `u32` - | -help: change the type of the numeric literal from `u32` to `u16` - | -LL | foo::<u16>(42_u16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:157:16 - | -LL | foo::<u16>(42_u8); - | ^^^^^ expected `u16`, found `u8` - | -help: change the type of the numeric literal from `u8` to `u16` - | -LL | foo::<u16>(42_u16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:159:16 - | -LL | foo::<u16>(42_isize); - | ^^^^^^^^ expected `u16`, found `isize` - | -help: change the type of the numeric literal from `isize` to `u16` - | -LL | foo::<u16>(42_u16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:161:16 - | -LL | foo::<u16>(42_i64); - | ^^^^^^ expected `u16`, found `i64` - | -help: change the type of the numeric literal from `i64` to `u16` - | -LL | foo::<u16>(42_u16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:163:16 - | -LL | foo::<u16>(42_i32); - | ^^^^^^ expected `u16`, found `i32` - | -help: change the type of the numeric literal from `i32` to `u16` - | -LL | foo::<u16>(42_u16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:165:16 - | -LL | foo::<u16>(42_i16); - | ^^^^^^ expected `u16`, found `i16` - | -help: change the type of the numeric literal from `i16` to `u16` - | -LL | foo::<u16>(42_u16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:167:16 - | -LL | foo::<u16>(42_i8); - | ^^^^^ expected `u16`, found `i8` - | -help: change the type of the numeric literal from `i8` to `u16` - | -LL | foo::<u16>(42_u16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:169:16 - | -LL | foo::<u16>(42.0_f64); - | ^^^^^^^^ expected `u16`, found `f64` - | -help: change the type of the numeric literal from `f64` to `u16` - | -LL | foo::<u16>(42u16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:171:16 - | -LL | foo::<u16>(42.0_f32); - | ^^^^^^^^ expected `u16`, found `f32` - | -help: change the type of the numeric literal from `f32` to `u16` - | -LL | foo::<u16>(42u16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:174:16 - | -LL | foo::<i16>(42_usize); - | ^^^^^^^^ expected `i16`, found `usize` - | -help: change the type of the numeric literal from `usize` to `i16` - | -LL | foo::<i16>(42_i16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:176:16 - | -LL | foo::<i16>(42_u64); - | ^^^^^^ expected `i16`, found `u64` - | -help: change the type of the numeric literal from `u64` to `i16` - | -LL | foo::<i16>(42_i16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:178:16 - | -LL | foo::<i16>(42_u32); - | ^^^^^^ expected `i16`, found `u32` - | -help: change the type of the numeric literal from `u32` to `i16` - | -LL | foo::<i16>(42_i16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:180:16 - | -LL | foo::<i16>(42_u16); - | ^^^^^^ expected `i16`, found `u16` - | -help: change the type of the numeric literal from `u16` to `i16` - | -LL | foo::<i16>(42_i16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:182:16 - | -LL | foo::<i16>(42_u8); - | ^^^^^ expected `i16`, found `u8` - | -help: change the type of the numeric literal from `u8` to `i16` - | -LL | foo::<i16>(42_i16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:184:16 - | -LL | foo::<i16>(42_isize); - | ^^^^^^^^ expected `i16`, found `isize` - | -help: change the type of the numeric literal from `isize` to `i16` - | -LL | foo::<i16>(42_i16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:186:16 - | -LL | foo::<i16>(42_i64); - | ^^^^^^ expected `i16`, found `i64` - | -help: change the type of the numeric literal from `i64` to `i16` - | -LL | foo::<i16>(42_i16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:188:16 - | -LL | foo::<i16>(42_i32); - | ^^^^^^ expected `i16`, found `i32` - | -help: change the type of the numeric literal from `i32` to `i16` - | -LL | foo::<i16>(42_i16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:191:16 - | -LL | foo::<i16>(42_i8); - | ^^^^^ expected `i16`, found `i8` - | -help: change the type of the numeric literal from `i8` to `i16` - | -LL | foo::<i16>(42_i16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:193:16 - | -LL | foo::<i16>(42.0_f64); - | ^^^^^^^^ expected `i16`, found `f64` - | -help: change the type of the numeric literal from `f64` to `i16` - | -LL | foo::<i16>(42i16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:195:16 - | -LL | foo::<i16>(42.0_f32); - | ^^^^^^^^ expected `i16`, found `f32` - | -help: change the type of the numeric literal from `f32` to `i16` - | -LL | foo::<i16>(42i16); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:198:15 - | -LL | foo::<u8>(42_usize); - | ^^^^^^^^ expected `u8`, found `usize` - | -help: change the type of the numeric literal from `usize` to `u8` - | -LL | foo::<u8>(42_u8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:200:15 - | -LL | foo::<u8>(42_u64); - | ^^^^^^ expected `u8`, found `u64` - | -help: change the type of the numeric literal from `u64` to `u8` - | -LL | foo::<u8>(42_u8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:202:15 - | -LL | foo::<u8>(42_u32); - | ^^^^^^ expected `u8`, found `u32` - | -help: change the type of the numeric literal from `u32` to `u8` - | -LL | foo::<u8>(42_u8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:204:15 - | -LL | foo::<u8>(42_u16); - | ^^^^^^ expected `u8`, found `u16` - | -help: change the type of the numeric literal from `u16` to `u8` - | -LL | foo::<u8>(42_u8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:207:15 - | -LL | foo::<u8>(42_isize); - | ^^^^^^^^ expected `u8`, found `isize` - | -help: change the type of the numeric literal from `isize` to `u8` - | -LL | foo::<u8>(42_u8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:209:15 - | -LL | foo::<u8>(42_i64); - | ^^^^^^ expected `u8`, found `i64` - | -help: change the type of the numeric literal from `i64` to `u8` - | -LL | foo::<u8>(42_u8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:211:15 - | -LL | foo::<u8>(42_i32); - | ^^^^^^ expected `u8`, found `i32` - | -help: change the type of the numeric literal from `i32` to `u8` - | -LL | foo::<u8>(42_u8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:213:15 - | -LL | foo::<u8>(42_i16); - | ^^^^^^ expected `u8`, found `i16` - | -help: change the type of the numeric literal from `i16` to `u8` - | -LL | foo::<u8>(42_u8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:215:15 - | -LL | foo::<u8>(42_i8); - | ^^^^^ expected `u8`, found `i8` - | -help: change the type of the numeric literal from `i8` to `u8` - | -LL | foo::<u8>(42_u8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:217:15 - | -LL | foo::<u8>(42.0_f64); - | ^^^^^^^^ expected `u8`, found `f64` - | -help: change the type of the numeric literal from `f64` to `u8` - | -LL | foo::<u8>(42u8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:219:15 - | -LL | foo::<u8>(42.0_f32); - | ^^^^^^^^ expected `u8`, found `f32` - | -help: change the type of the numeric literal from `f32` to `u8` - | -LL | foo::<u8>(42u8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:222:15 - | -LL | foo::<i8>(42_usize); - | ^^^^^^^^ expected `i8`, found `usize` - | -help: change the type of the numeric literal from `usize` to `i8` - | -LL | foo::<i8>(42_i8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:224:15 - | -LL | foo::<i8>(42_u64); - | ^^^^^^ expected `i8`, found `u64` - | -help: change the type of the numeric literal from `u64` to `i8` - | -LL | foo::<i8>(42_i8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:226:15 - | -LL | foo::<i8>(42_u32); - | ^^^^^^ expected `i8`, found `u32` - | -help: change the type of the numeric literal from `u32` to `i8` - | -LL | foo::<i8>(42_i8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:228:15 - | -LL | foo::<i8>(42_u16); - | ^^^^^^ expected `i8`, found `u16` - | -help: change the type of the numeric literal from `u16` to `i8` - | -LL | foo::<i8>(42_i8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:230:15 - | -LL | foo::<i8>(42_u8); - | ^^^^^ expected `i8`, found `u8` - | -help: change the type of the numeric literal from `u8` to `i8` - | -LL | foo::<i8>(42_i8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:232:15 - | -LL | foo::<i8>(42_isize); - | ^^^^^^^^ expected `i8`, found `isize` - | -help: change the type of the numeric literal from `isize` to `i8` - | -LL | foo::<i8>(42_i8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:234:15 - | -LL | foo::<i8>(42_i64); - | ^^^^^^ expected `i8`, found `i64` - | -help: change the type of the numeric literal from `i64` to `i8` - | -LL | foo::<i8>(42_i8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:236:15 - | -LL | foo::<i8>(42_i32); - | ^^^^^^ expected `i8`, found `i32` - | -help: change the type of the numeric literal from `i32` to `i8` - | -LL | foo::<i8>(42_i8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:238:15 - | -LL | foo::<i8>(42_i16); - | ^^^^^^ expected `i8`, found `i16` - | -help: change the type of the numeric literal from `i16` to `i8` - | -LL | foo::<i8>(42_i8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:241:15 - | -LL | foo::<i8>(42.0_f64); - | ^^^^^^^^ expected `i8`, found `f64` - | -help: change the type of the numeric literal from `f64` to `i8` - | -LL | foo::<i8>(42i8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:243:15 - | -LL | foo::<i8>(42.0_f32); - | ^^^^^^^^ expected `i8`, found `f32` - | -help: change the type of the numeric literal from `f32` to `i8` - | -LL | foo::<i8>(42i8); - | ~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:246:16 - | -LL | foo::<f64>(42_usize); - | ^^^^^^^^ expected `f64`, found `usize` - | -help: change the type of the numeric literal from `usize` to `f64` - | -LL | foo::<f64>(42_f64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:248:16 - | -LL | foo::<f64>(42_u64); - | ^^^^^^ expected `f64`, found `u64` - | -help: change the type of the numeric literal from `u64` to `f64` - | -LL | foo::<f64>(42_f64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:250:16 - | -LL | foo::<f64>(42_u32); - | ^^^^^^ expected `f64`, found `u32` - | -help: you can convert a `u32` to an `f64`, producing the floating point representation of the integer - | -LL | foo::<f64>(42_u32.into()); - | +++++++ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:252:16 - | -LL | foo::<f64>(42_u16); - | ^^^^^^ expected `f64`, found `u16` - | -help: you can convert a `u16` to an `f64`, producing the floating point representation of the integer - | -LL | foo::<f64>(42_u16.into()); - | +++++++ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:254:16 - | -LL | foo::<f64>(42_u8); - | ^^^^^ expected `f64`, found `u8` - | -help: you can convert a `u8` to an `f64`, producing the floating point representation of the integer - | -LL | foo::<f64>(42_u8.into()); - | +++++++ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:256:16 - | -LL | foo::<f64>(42_isize); - | ^^^^^^^^ expected `f64`, found `isize` - | -help: change the type of the numeric literal from `isize` to `f64` - | -LL | foo::<f64>(42_f64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:258:16 - | -LL | foo::<f64>(42_i64); - | ^^^^^^ expected `f64`, found `i64` - | -help: change the type of the numeric literal from `i64` to `f64` - | -LL | foo::<f64>(42_f64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:260:16 - | -LL | foo::<f64>(42_i32); - | ^^^^^^ expected `f64`, found `i32` - | -help: you can convert an `i32` to an `f64`, producing the floating point representation of the integer - | -LL | foo::<f64>(42_i32.into()); - | +++++++ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:262:16 - | -LL | foo::<f64>(42_i16); - | ^^^^^^ expected `f64`, found `i16` - | -help: you can convert an `i16` to an `f64`, producing the floating point representation of the integer - | -LL | foo::<f64>(42_i16.into()); - | +++++++ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:264:16 - | -LL | foo::<f64>(42_i8); - | ^^^^^ expected `f64`, found `i8` - | -help: you can convert an `i8` to an `f64`, producing the floating point representation of the integer - | -LL | foo::<f64>(42_i8.into()); - | +++++++ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:267:16 - | -LL | foo::<f64>(42.0_f32); - | ^^^^^^^^ expected `f64`, found `f32` - | -help: change the type of the numeric literal from `f32` to `f64` - | -LL | foo::<f64>(42.0_f64); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:270:16 - | -LL | foo::<f32>(42_usize); - | ^^^^^^^^ expected `f32`, found `usize` - | -help: change the type of the numeric literal from `usize` to `f32` - | -LL | foo::<f32>(42_f32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:272:16 - | -LL | foo::<f32>(42_u64); - | ^^^^^^ expected `f32`, found `u64` - | -help: change the type of the numeric literal from `u64` to `f32` - | -LL | foo::<f32>(42_f32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:274:16 - | -LL | foo::<f32>(42_u32); - | ^^^^^^ expected `f32`, found `u32` - | -help: change the type of the numeric literal from `u32` to `f32` - | -LL | foo::<f32>(42_f32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:276:16 - | -LL | foo::<f32>(42_u16); - | ^^^^^^ expected `f32`, found `u16` - | -help: you can convert a `u16` to an `f32`, producing the floating point representation of the integer - | -LL | foo::<f32>(42_u16.into()); - | +++++++ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:278:16 - | -LL | foo::<f32>(42_u8); - | ^^^^^ expected `f32`, found `u8` - | -help: you can convert a `u8` to an `f32`, producing the floating point representation of the integer - | -LL | foo::<f32>(42_u8.into()); - | +++++++ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:280:16 - | -LL | foo::<f32>(42_isize); - | ^^^^^^^^ expected `f32`, found `isize` - | -help: change the type of the numeric literal from `isize` to `f32` - | -LL | foo::<f32>(42_f32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:282:16 - | -LL | foo::<f32>(42_i64); - | ^^^^^^ expected `f32`, found `i64` - | -help: change the type of the numeric literal from `i64` to `f32` - | -LL | foo::<f32>(42_f32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:284:16 - | -LL | foo::<f32>(42_i32); - | ^^^^^^ expected `f32`, found `i32` - | -help: change the type of the numeric literal from `i32` to `f32` - | -LL | foo::<f32>(42_f32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:286:16 - | -LL | foo::<f32>(42_i16); - | ^^^^^^ expected `f32`, found `i16` - | -help: you can convert an `i16` to an `f32`, producing the floating point representation of the integer - | -LL | foo::<f32>(42_i16.into()); - | +++++++ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:288:16 - | -LL | foo::<f32>(42_i8); - | ^^^^^ expected `f32`, found `i8` - | -help: you can convert an `i8` to an `f32`, producing the floating point representation of the integer - | -LL | foo::<f32>(42_i8.into()); - | +++++++ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:290:16 - | -LL | foo::<f32>(42.0_f64); - | ^^^^^^^^ expected `f32`, found `f64` - | -help: change the type of the numeric literal from `f64` to `f32` - | -LL | foo::<f32>(42.0_f32); - | ~~~ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:294:16 - | -LL | foo::<u32>(42_u8 as u16); - | ^^^^^^^^^^^^ expected `u32`, found `u16` - | -help: you can convert a `u16` to a `u32` - | -LL | foo::<u32>((42_u8 as u16).into()); - | + ++++++++ - -error[E0308]: mismatched types - --> $DIR/numeric-suffix.rs:296:16 - | -LL | foo::<i32>(-42_i8); - | ^^^^^^ expected `i32`, found `i8` - | -help: you can convert an `i8` to an `i32` - | -LL | foo::<i32>((-42_i8).into()); - | + ++++++++ - -error: aborting due to 134 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed new file mode 100644 index 00000000000..6e8c54df4b6 --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed @@ -0,0 +1,73 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + +fn main() { + foo::<i32>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_i32); + foo::<i32>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.rs new file mode 100644 index 00000000000..b47b0ed02e7 --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.rs @@ -0,0 +1,73 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + +fn main() { + foo::<i32>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_i32); + foo::<i32>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42.0_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(42.0_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr new file mode 100644 index 00000000000..f4fb14e7992 --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr @@ -0,0 +1,201 @@ +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i32.rs:28:16 + | +LL | foo::<i32>(42_usize); + | ---------- ^^^^^^^^ expected `i32`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `usize` to `i32` + | +LL | foo::<i32>(42_i32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i32.rs:32:16 + | +LL | foo::<i32>(42_u64); + | ---------- ^^^^^^ expected `i32`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u64` to `i32` + | +LL | foo::<i32>(42_i32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i32.rs:36:16 + | +LL | foo::<i32>(42_u32); + | ---------- ^^^^^^ expected `i32`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u32` to `i32` + | +LL | foo::<i32>(42_i32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i32.rs:40:16 + | +LL | foo::<i32>(42_u16); + | ---------- ^^^^^^ expected `i32`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u16` to `i32` + | +LL | foo::<i32>(42_i32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i32.rs:44:16 + | +LL | foo::<i32>(42_u8); + | ---------- ^^^^^ expected `i32`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u8` to `i32` + | +LL | foo::<i32>(42_i32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i32.rs:48:16 + | +LL | foo::<i32>(42_isize); + | ---------- ^^^^^^^^ expected `i32`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `isize` to `i32` + | +LL | foo::<i32>(42_i32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i32.rs:52:16 + | +LL | foo::<i32>(42_i64); + | ---------- ^^^^^^ expected `i32`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i64` to `i32` + | +LL | foo::<i32>(42_i32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i32.rs:57:16 + | +LL | foo::<i32>(42_i16); + | ---------- ^^^^^^ expected `i32`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i16` to `i32` + | +LL | foo::<i32>(42_i32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i32.rs:61:16 + | +LL | foo::<i32>(42_i8); + | ---------- ^^^^^ expected `i32`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i8` to `i32` + | +LL | foo::<i32>(42_i32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i32.rs:65:16 + | +LL | foo::<i32>(42.0_f64); + | ---------- ^^^^^^^^ expected `i32`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f64` to `i32` + | +LL | foo::<i32>(42i32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i32.rs:69:16 + | +LL | foo::<i32>(42.0_f32); + | ---------- ^^^^^^^^ expected `i32`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f32` to `i32` + | +LL | foo::<i32>(42i32); + | ~~~ + +error: aborting due to 11 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed new file mode 100644 index 00000000000..03821cd4470 --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed @@ -0,0 +1,73 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + +fn main() { + foo::<i64>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_i64); + foo::<i64>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.rs new file mode 100644 index 00000000000..629fe7e742c --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.rs @@ -0,0 +1,73 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + +fn main() { + foo::<i64>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_i64); + foo::<i64>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42.0_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i64>(42.0_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr new file mode 100644 index 00000000000..47efe9f08bb --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr @@ -0,0 +1,201 @@ +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i64.rs:28:16 + | +LL | foo::<i64>(42_usize); + | ---------- ^^^^^^^^ expected `i64`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `usize` to `i64` + | +LL | foo::<i64>(42_i64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i64.rs:32:16 + | +LL | foo::<i64>(42_u64); + | ---------- ^^^^^^ expected `i64`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u64` to `i64` + | +LL | foo::<i64>(42_i64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i64.rs:36:16 + | +LL | foo::<i64>(42_u32); + | ---------- ^^^^^^ expected `i64`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u32` to `i64` + | +LL | foo::<i64>(42_i64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i64.rs:40:16 + | +LL | foo::<i64>(42_u16); + | ---------- ^^^^^^ expected `i64`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u16` to `i64` + | +LL | foo::<i64>(42_i64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i64.rs:44:16 + | +LL | foo::<i64>(42_u8); + | ---------- ^^^^^ expected `i64`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u8` to `i64` + | +LL | foo::<i64>(42_i64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i64.rs:48:16 + | +LL | foo::<i64>(42_isize); + | ---------- ^^^^^^^^ expected `i64`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `isize` to `i64` + | +LL | foo::<i64>(42_i64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i64.rs:53:16 + | +LL | foo::<i64>(42_i32); + | ---------- ^^^^^^ expected `i64`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i32` to `i64` + | +LL | foo::<i64>(42_i64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i64.rs:57:16 + | +LL | foo::<i64>(42_i16); + | ---------- ^^^^^^ expected `i64`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i16` to `i64` + | +LL | foo::<i64>(42_i64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i64.rs:61:16 + | +LL | foo::<i64>(42_i8); + | ---------- ^^^^^ expected `i64`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i8` to `i64` + | +LL | foo::<i64>(42_i64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i64.rs:65:16 + | +LL | foo::<i64>(42.0_f64); + | ---------- ^^^^^^^^ expected `i64`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f64` to `i64` + | +LL | foo::<i64>(42i64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-i64.rs:69:16 + | +LL | foo::<i64>(42.0_f32); + | ---------- ^^^^^^^^ expected `i64`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-i64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f32` to `i64` + | +LL | foo::<i64>(42i64); + | ~~~ + +error: aborting due to 11 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed new file mode 100644 index 00000000000..faed65ca410 --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed @@ -0,0 +1,73 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + +fn main() { + foo::<isize>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_isize); + foo::<isize>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.rs new file mode 100644 index 00000000000..df0b4cb6204 --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.rs @@ -0,0 +1,73 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + +fn main() { + foo::<isize>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_isize); + foo::<isize>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42.0_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<isize>(42.0_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr new file mode 100644 index 00000000000..28b79413f68 --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr @@ -0,0 +1,201 @@ +error[E0308]: mismatched types + --> $DIR/numeric-suffix-isize.rs:28:18 + | +LL | foo::<isize>(42_usize); + | ------------ ^^^^^^^^ expected `isize`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-isize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `usize` to `isize` + | +LL | foo::<isize>(42_isize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-isize.rs:32:18 + | +LL | foo::<isize>(42_u64); + | ------------ ^^^^^^ expected `isize`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-isize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u64` to `isize` + | +LL | foo::<isize>(42_isize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-isize.rs:36:18 + | +LL | foo::<isize>(42_u32); + | ------------ ^^^^^^ expected `isize`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-isize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u32` to `isize` + | +LL | foo::<isize>(42_isize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-isize.rs:40:18 + | +LL | foo::<isize>(42_u16); + | ------------ ^^^^^^ expected `isize`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-isize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u16` to `isize` + | +LL | foo::<isize>(42_isize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-isize.rs:44:18 + | +LL | foo::<isize>(42_u8); + | ------------ ^^^^^ expected `isize`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-isize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u8` to `isize` + | +LL | foo::<isize>(42_isize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-isize.rs:49:18 + | +LL | foo::<isize>(42_i64); + | ------------ ^^^^^^ expected `isize`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-isize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i64` to `isize` + | +LL | foo::<isize>(42_isize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-isize.rs:53:18 + | +LL | foo::<isize>(42_i32); + | ------------ ^^^^^^ expected `isize`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-isize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i32` to `isize` + | +LL | foo::<isize>(42_isize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-isize.rs:57:18 + | +LL | foo::<isize>(42_i16); + | ------------ ^^^^^^ expected `isize`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-isize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i16` to `isize` + | +LL | foo::<isize>(42_isize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-isize.rs:61:18 + | +LL | foo::<isize>(42_i8); + | ------------ ^^^^^ expected `isize`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-isize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i8` to `isize` + | +LL | foo::<isize>(42_isize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-isize.rs:65:18 + | +LL | foo::<isize>(42.0_f64); + | ------------ ^^^^^^^^ expected `isize`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-isize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f64` to `isize` + | +LL | foo::<isize>(42isize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-isize.rs:69:18 + | +LL | foo::<isize>(42.0_f32); + | ------------ ^^^^^^^^ expected `isize`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-isize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f32` to `isize` + | +LL | foo::<isize>(42isize); + | ~~~~~ + +error: aborting due to 11 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed new file mode 100644 index 00000000000..5955829e72c --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed @@ -0,0 +1,73 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + +fn main() { + foo::<u32>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_u32); + foo::<u32>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.rs new file mode 100644 index 00000000000..5c303036a79 --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.rs @@ -0,0 +1,73 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + +fn main() { + foo::<u32>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_u32); + foo::<u32>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42.0_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u32>(42.0_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr new file mode 100644 index 00000000000..d966893a83b --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr @@ -0,0 +1,201 @@ +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u32.rs:28:16 + | +LL | foo::<u32>(42_usize); + | ---------- ^^^^^^^^ expected `u32`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `usize` to `u32` + | +LL | foo::<u32>(42_u32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u32.rs:32:16 + | +LL | foo::<u32>(42_u64); + | ---------- ^^^^^^ expected `u32`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u64` to `u32` + | +LL | foo::<u32>(42_u32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u32.rs:37:16 + | +LL | foo::<u32>(42_u16); + | ---------- ^^^^^^ expected `u32`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u16` to `u32` + | +LL | foo::<u32>(42_u32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u32.rs:41:16 + | +LL | foo::<u32>(42_u8); + | ---------- ^^^^^ expected `u32`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u8` to `u32` + | +LL | foo::<u32>(42_u32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u32.rs:45:16 + | +LL | foo::<u32>(42_isize); + | ---------- ^^^^^^^^ expected `u32`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `isize` to `u32` + | +LL | foo::<u32>(42_u32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u32.rs:49:16 + | +LL | foo::<u32>(42_i64); + | ---------- ^^^^^^ expected `u32`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i64` to `u32` + | +LL | foo::<u32>(42_u32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u32.rs:53:16 + | +LL | foo::<u32>(42_i32); + | ---------- ^^^^^^ expected `u32`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i32` to `u32` + | +LL | foo::<u32>(42_u32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u32.rs:57:16 + | +LL | foo::<u32>(42_i16); + | ---------- ^^^^^^ expected `u32`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i16` to `u32` + | +LL | foo::<u32>(42_u32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u32.rs:61:16 + | +LL | foo::<u32>(42_i8); + | ---------- ^^^^^ expected `u32`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i8` to `u32` + | +LL | foo::<u32>(42_u32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u32.rs:65:16 + | +LL | foo::<u32>(42.0_f64); + | ---------- ^^^^^^^^ expected `u32`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f64` to `u32` + | +LL | foo::<u32>(42u32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u32.rs:69:16 + | +LL | foo::<u32>(42.0_f32); + | ---------- ^^^^^^^^ expected `u32`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u32.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f32` to `u32` + | +LL | foo::<u32>(42u32); + | ~~~ + +error: aborting due to 11 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed new file mode 100644 index 00000000000..4623c211c1c --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed @@ -0,0 +1,73 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + +fn main() { + foo::<u64>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_u64); + foo::<u64>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.rs new file mode 100644 index 00000000000..3e9995c7496 --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.rs @@ -0,0 +1,73 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + +fn main() { + foo::<u64>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_u64); + foo::<u64>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42.0_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u64>(42.0_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr new file mode 100644 index 00000000000..ff332fa914d --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr @@ -0,0 +1,201 @@ +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u64.rs:28:16 + | +LL | foo::<u64>(42_usize); + | ---------- ^^^^^^^^ expected `u64`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `usize` to `u64` + | +LL | foo::<u64>(42_u64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u64.rs:33:16 + | +LL | foo::<u64>(42_u32); + | ---------- ^^^^^^ expected `u64`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u32` to `u64` + | +LL | foo::<u64>(42_u64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u64.rs:37:16 + | +LL | foo::<u64>(42_u16); + | ---------- ^^^^^^ expected `u64`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u16` to `u64` + | +LL | foo::<u64>(42_u64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u64.rs:41:16 + | +LL | foo::<u64>(42_u8); + | ---------- ^^^^^ expected `u64`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u8` to `u64` + | +LL | foo::<u64>(42_u64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u64.rs:45:16 + | +LL | foo::<u64>(42_isize); + | ---------- ^^^^^^^^ expected `u64`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `isize` to `u64` + | +LL | foo::<u64>(42_u64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u64.rs:49:16 + | +LL | foo::<u64>(42_i64); + | ---------- ^^^^^^ expected `u64`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i64` to `u64` + | +LL | foo::<u64>(42_u64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u64.rs:53:16 + | +LL | foo::<u64>(42_i32); + | ---------- ^^^^^^ expected `u64`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i32` to `u64` + | +LL | foo::<u64>(42_u64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u64.rs:57:16 + | +LL | foo::<u64>(42_i16); + | ---------- ^^^^^^ expected `u64`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i16` to `u64` + | +LL | foo::<u64>(42_u64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u64.rs:61:16 + | +LL | foo::<u64>(42_i8); + | ---------- ^^^^^ expected `u64`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i8` to `u64` + | +LL | foo::<u64>(42_u64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u64.rs:65:16 + | +LL | foo::<u64>(42.0_f64); + | ---------- ^^^^^^^^ expected `u64`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f64` to `u64` + | +LL | foo::<u64>(42u64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-u64.rs:69:16 + | +LL | foo::<u64>(42.0_f32); + | ---------- ^^^^^^^^ expected `u64`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-u64.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f32` to `u64` + | +LL | foo::<u64>(42u64); + | ~~~ + +error: aborting due to 11 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed new file mode 100644 index 00000000000..6cb5243ca84 --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed @@ -0,0 +1,73 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + +fn main() { + foo::<usize>(42_usize); + foo::<usize>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.rs new file mode 100644 index 00000000000..a2304ba26c6 --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.rs @@ -0,0 +1,73 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + +fn main() { + foo::<usize>(42_usize); + foo::<usize>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42.0_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<usize>(42.0_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr new file mode 100644 index 00000000000..4889abee69c --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr @@ -0,0 +1,201 @@ +error[E0308]: mismatched types + --> $DIR/numeric-suffix-usize.rs:29:18 + | +LL | foo::<usize>(42_u64); + | ------------ ^^^^^^ expected `usize`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-usize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u64` to `usize` + | +LL | foo::<usize>(42_usize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-usize.rs:33:18 + | +LL | foo::<usize>(42_u32); + | ------------ ^^^^^^ expected `usize`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-usize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u32` to `usize` + | +LL | foo::<usize>(42_usize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-usize.rs:37:18 + | +LL | foo::<usize>(42_u16); + | ------------ ^^^^^^ expected `usize`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-usize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u16` to `usize` + | +LL | foo::<usize>(42_usize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-usize.rs:41:18 + | +LL | foo::<usize>(42_u8); + | ------------ ^^^^^ expected `usize`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-usize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u8` to `usize` + | +LL | foo::<usize>(42_usize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-usize.rs:45:18 + | +LL | foo::<usize>(42_isize); + | ------------ ^^^^^^^^ expected `usize`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-usize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `isize` to `usize` + | +LL | foo::<usize>(42_usize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-usize.rs:49:18 + | +LL | foo::<usize>(42_i64); + | ------------ ^^^^^^ expected `usize`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-usize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i64` to `usize` + | +LL | foo::<usize>(42_usize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-usize.rs:53:18 + | +LL | foo::<usize>(42_i32); + | ------------ ^^^^^^ expected `usize`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-usize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i32` to `usize` + | +LL | foo::<usize>(42_usize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-usize.rs:57:18 + | +LL | foo::<usize>(42_i16); + | ------------ ^^^^^^ expected `usize`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-usize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i16` to `usize` + | +LL | foo::<usize>(42_usize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-usize.rs:61:18 + | +LL | foo::<usize>(42_i8); + | ------------ ^^^^^ expected `usize`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-usize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i8` to `usize` + | +LL | foo::<usize>(42_usize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-usize.rs:65:18 + | +LL | foo::<usize>(42.0_f64); + | ------------ ^^^^^^^^ expected `usize`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-usize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f64` to `usize` + | +LL | foo::<usize>(42usize); + | ~~~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix-usize.rs:69:18 + | +LL | foo::<usize>(42.0_f32); + | ------------ ^^^^^^^^ expected `usize`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix-usize.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f32` to `usize` + | +LL | foo::<usize>(42usize); + | ~~~~~ + +error: aborting due to 11 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix.fixed new file mode 100644 index 00000000000..69934db217b --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix.fixed @@ -0,0 +1,427 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + + +fn main() { + foo::<u16>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_u16); + foo::<u16>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + + foo::<i16>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_i16); + foo::<i16>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + + foo::<u8>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_u8); + foo::<u8>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + + foo::<i8>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_i8); + foo::<i8>(42i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + + foo::<f64>(42_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_u32.into()); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_u16.into()); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_u8.into()); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_i32.into()); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_i16.into()); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_i8.into()); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42.0_f64); + foo::<f64>(42.0_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + + foo::<f32>(42_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_u16.into()); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_u8.into()); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_i16.into()); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_i8.into()); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42.0_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42.0_f32); + + foo::<u32>((42_u8 as u16).into()); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>((-42_i8).into()); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix.rs new file mode 100644 index 00000000000..dabf43f8204 --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix.rs @@ -0,0 +1,427 @@ +// run-rustfix + +fn foo<N>(_x: N) {} +//~^ NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE function defined here +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE +//~| NOTE + + +fn main() { + foo::<u16>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_u16); + foo::<u16>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42.0_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u16>(42.0_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + + foo::<i16>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42_i16); + foo::<i16>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42.0_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i16>(42.0_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + + foo::<u8>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_u8); + foo::<u8>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42.0_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<u8>(42.0_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + + foo::<i8>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42_i8); + foo::<i8>(42.0_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i8>(42.0_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + + foo::<f64>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f64>(42.0_f64); + foo::<f64>(42.0_f32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + + foo::<f32>(42_usize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_u64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_u32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_u8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_isize); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_i64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_i32); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_i16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42.0_f64); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<f32>(42.0_f32); + + foo::<u32>(42_u8 as u16); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments + foo::<i32>(-42_i8); + //~^ ERROR mismatched types + //~| NOTE expected + //~| NOTE arguments +} diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix.stderr new file mode 100644 index 00000000000..e05913b9c62 --- /dev/null +++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix.stderr @@ -0,0 +1,1227 @@ +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:143:16 + | +LL | foo::<u16>(42_usize); + | ---------- ^^^^^^^^ expected `u16`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `usize` to `u16` + | +LL | foo::<u16>(42_u16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:147:16 + | +LL | foo::<u16>(42_u64); + | ---------- ^^^^^^ expected `u16`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u64` to `u16` + | +LL | foo::<u16>(42_u16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:151:16 + | +LL | foo::<u16>(42_u32); + | ---------- ^^^^^^ expected `u16`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u32` to `u16` + | +LL | foo::<u16>(42_u16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:156:16 + | +LL | foo::<u16>(42_u8); + | ---------- ^^^^^ expected `u16`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u8` to `u16` + | +LL | foo::<u16>(42_u16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:160:16 + | +LL | foo::<u16>(42_isize); + | ---------- ^^^^^^^^ expected `u16`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `isize` to `u16` + | +LL | foo::<u16>(42_u16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:164:16 + | +LL | foo::<u16>(42_i64); + | ---------- ^^^^^^ expected `u16`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i64` to `u16` + | +LL | foo::<u16>(42_u16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:168:16 + | +LL | foo::<u16>(42_i32); + | ---------- ^^^^^^ expected `u16`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i32` to `u16` + | +LL | foo::<u16>(42_u16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:172:16 + | +LL | foo::<u16>(42_i16); + | ---------- ^^^^^^ expected `u16`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i16` to `u16` + | +LL | foo::<u16>(42_u16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:176:16 + | +LL | foo::<u16>(42_i8); + | ---------- ^^^^^ expected `u16`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i8` to `u16` + | +LL | foo::<u16>(42_u16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:180:16 + | +LL | foo::<u16>(42.0_f64); + | ---------- ^^^^^^^^ expected `u16`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f64` to `u16` + | +LL | foo::<u16>(42u16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:184:16 + | +LL | foo::<u16>(42.0_f32); + | ---------- ^^^^^^^^ expected `u16`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f32` to `u16` + | +LL | foo::<u16>(42u16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:189:16 + | +LL | foo::<i16>(42_usize); + | ---------- ^^^^^^^^ expected `i16`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `usize` to `i16` + | +LL | foo::<i16>(42_i16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:193:16 + | +LL | foo::<i16>(42_u64); + | ---------- ^^^^^^ expected `i16`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u64` to `i16` + | +LL | foo::<i16>(42_i16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:197:16 + | +LL | foo::<i16>(42_u32); + | ---------- ^^^^^^ expected `i16`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u32` to `i16` + | +LL | foo::<i16>(42_i16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:201:16 + | +LL | foo::<i16>(42_u16); + | ---------- ^^^^^^ expected `i16`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u16` to `i16` + | +LL | foo::<i16>(42_i16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:205:16 + | +LL | foo::<i16>(42_u8); + | ---------- ^^^^^ expected `i16`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u8` to `i16` + | +LL | foo::<i16>(42_i16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:209:16 + | +LL | foo::<i16>(42_isize); + | ---------- ^^^^^^^^ expected `i16`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `isize` to `i16` + | +LL | foo::<i16>(42_i16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:213:16 + | +LL | foo::<i16>(42_i64); + | ---------- ^^^^^^ expected `i16`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i64` to `i16` + | +LL | foo::<i16>(42_i16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:217:16 + | +LL | foo::<i16>(42_i32); + | ---------- ^^^^^^ expected `i16`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i32` to `i16` + | +LL | foo::<i16>(42_i16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:222:16 + | +LL | foo::<i16>(42_i8); + | ---------- ^^^^^ expected `i16`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i8` to `i16` + | +LL | foo::<i16>(42_i16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:226:16 + | +LL | foo::<i16>(42.0_f64); + | ---------- ^^^^^^^^ expected `i16`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f64` to `i16` + | +LL | foo::<i16>(42i16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:230:16 + | +LL | foo::<i16>(42.0_f32); + | ---------- ^^^^^^^^ expected `i16`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f32` to `i16` + | +LL | foo::<i16>(42i16); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:235:15 + | +LL | foo::<u8>(42_usize); + | --------- ^^^^^^^^ expected `u8`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `usize` to `u8` + | +LL | foo::<u8>(42_u8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:239:15 + | +LL | foo::<u8>(42_u64); + | --------- ^^^^^^ expected `u8`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u64` to `u8` + | +LL | foo::<u8>(42_u8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:243:15 + | +LL | foo::<u8>(42_u32); + | --------- ^^^^^^ expected `u8`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u32` to `u8` + | +LL | foo::<u8>(42_u8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:247:15 + | +LL | foo::<u8>(42_u16); + | --------- ^^^^^^ expected `u8`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u16` to `u8` + | +LL | foo::<u8>(42_u8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:252:15 + | +LL | foo::<u8>(42_isize); + | --------- ^^^^^^^^ expected `u8`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `isize` to `u8` + | +LL | foo::<u8>(42_u8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:256:15 + | +LL | foo::<u8>(42_i64); + | --------- ^^^^^^ expected `u8`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i64` to `u8` + | +LL | foo::<u8>(42_u8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:260:15 + | +LL | foo::<u8>(42_i32); + | --------- ^^^^^^ expected `u8`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i32` to `u8` + | +LL | foo::<u8>(42_u8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:264:15 + | +LL | foo::<u8>(42_i16); + | --------- ^^^^^^ expected `u8`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i16` to `u8` + | +LL | foo::<u8>(42_u8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:268:15 + | +LL | foo::<u8>(42_i8); + | --------- ^^^^^ expected `u8`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i8` to `u8` + | +LL | foo::<u8>(42_u8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:272:15 + | +LL | foo::<u8>(42.0_f64); + | --------- ^^^^^^^^ expected `u8`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f64` to `u8` + | +LL | foo::<u8>(42u8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:276:15 + | +LL | foo::<u8>(42.0_f32); + | --------- ^^^^^^^^ expected `u8`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f32` to `u8` + | +LL | foo::<u8>(42u8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:281:15 + | +LL | foo::<i8>(42_usize); + | --------- ^^^^^^^^ expected `i8`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `usize` to `i8` + | +LL | foo::<i8>(42_i8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:285:15 + | +LL | foo::<i8>(42_u64); + | --------- ^^^^^^ expected `i8`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u64` to `i8` + | +LL | foo::<i8>(42_i8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:289:15 + | +LL | foo::<i8>(42_u32); + | --------- ^^^^^^ expected `i8`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u32` to `i8` + | +LL | foo::<i8>(42_i8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:293:15 + | +LL | foo::<i8>(42_u16); + | --------- ^^^^^^ expected `i8`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u16` to `i8` + | +LL | foo::<i8>(42_i8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:297:15 + | +LL | foo::<i8>(42_u8); + | --------- ^^^^^ expected `i8`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u8` to `i8` + | +LL | foo::<i8>(42_i8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:301:15 + | +LL | foo::<i8>(42_isize); + | --------- ^^^^^^^^ expected `i8`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `isize` to `i8` + | +LL | foo::<i8>(42_i8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:305:15 + | +LL | foo::<i8>(42_i64); + | --------- ^^^^^^ expected `i8`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i64` to `i8` + | +LL | foo::<i8>(42_i8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:309:15 + | +LL | foo::<i8>(42_i32); + | --------- ^^^^^^ expected `i8`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i32` to `i8` + | +LL | foo::<i8>(42_i8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:313:15 + | +LL | foo::<i8>(42_i16); + | --------- ^^^^^^ expected `i8`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i16` to `i8` + | +LL | foo::<i8>(42_i8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:318:15 + | +LL | foo::<i8>(42.0_f64); + | --------- ^^^^^^^^ expected `i8`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f64` to `i8` + | +LL | foo::<i8>(42i8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:322:15 + | +LL | foo::<i8>(42.0_f32); + | --------- ^^^^^^^^ expected `i8`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f32` to `i8` + | +LL | foo::<i8>(42i8); + | ~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:327:16 + | +LL | foo::<f64>(42_usize); + | ---------- ^^^^^^^^ expected `f64`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `usize` to `f64` + | +LL | foo::<f64>(42_f64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:331:16 + | +LL | foo::<f64>(42_u64); + | ---------- ^^^^^^ expected `f64`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u64` to `f64` + | +LL | foo::<f64>(42_f64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:335:16 + | +LL | foo::<f64>(42_u32); + | ---------- ^^^^^^ expected `f64`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: you can convert a `u32` to an `f64`, producing the floating point representation of the integer + | +LL | foo::<f64>(42_u32.into()); + | +++++++ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:339:16 + | +LL | foo::<f64>(42_u16); + | ---------- ^^^^^^ expected `f64`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: you can convert a `u16` to an `f64`, producing the floating point representation of the integer + | +LL | foo::<f64>(42_u16.into()); + | +++++++ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:343:16 + | +LL | foo::<f64>(42_u8); + | ---------- ^^^^^ expected `f64`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: you can convert a `u8` to an `f64`, producing the floating point representation of the integer + | +LL | foo::<f64>(42_u8.into()); + | +++++++ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:347:16 + | +LL | foo::<f64>(42_isize); + | ---------- ^^^^^^^^ expected `f64`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `isize` to `f64` + | +LL | foo::<f64>(42_f64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:351:16 + | +LL | foo::<f64>(42_i64); + | ---------- ^^^^^^ expected `f64`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i64` to `f64` + | +LL | foo::<f64>(42_f64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:355:16 + | +LL | foo::<f64>(42_i32); + | ---------- ^^^^^^ expected `f64`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: you can convert an `i32` to an `f64`, producing the floating point representation of the integer + | +LL | foo::<f64>(42_i32.into()); + | +++++++ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:359:16 + | +LL | foo::<f64>(42_i16); + | ---------- ^^^^^^ expected `f64`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: you can convert an `i16` to an `f64`, producing the floating point representation of the integer + | +LL | foo::<f64>(42_i16.into()); + | +++++++ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:363:16 + | +LL | foo::<f64>(42_i8); + | ---------- ^^^^^ expected `f64`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: you can convert an `i8` to an `f64`, producing the floating point representation of the integer + | +LL | foo::<f64>(42_i8.into()); + | +++++++ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:368:16 + | +LL | foo::<f64>(42.0_f32); + | ---------- ^^^^^^^^ expected `f64`, found `f32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f32` to `f64` + | +LL | foo::<f64>(42.0_f64); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:373:16 + | +LL | foo::<f32>(42_usize); + | ---------- ^^^^^^^^ expected `f32`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `usize` to `f32` + | +LL | foo::<f32>(42_f32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:377:16 + | +LL | foo::<f32>(42_u64); + | ---------- ^^^^^^ expected `f32`, found `u64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u64` to `f32` + | +LL | foo::<f32>(42_f32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:381:16 + | +LL | foo::<f32>(42_u32); + | ---------- ^^^^^^ expected `f32`, found `u32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `u32` to `f32` + | +LL | foo::<f32>(42_f32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:385:16 + | +LL | foo::<f32>(42_u16); + | ---------- ^^^^^^ expected `f32`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: you can convert a `u16` to an `f32`, producing the floating point representation of the integer + | +LL | foo::<f32>(42_u16.into()); + | +++++++ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:389:16 + | +LL | foo::<f32>(42_u8); + | ---------- ^^^^^ expected `f32`, found `u8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: you can convert a `u8` to an `f32`, producing the floating point representation of the integer + | +LL | foo::<f32>(42_u8.into()); + | +++++++ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:393:16 + | +LL | foo::<f32>(42_isize); + | ---------- ^^^^^^^^ expected `f32`, found `isize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `isize` to `f32` + | +LL | foo::<f32>(42_f32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:397:16 + | +LL | foo::<f32>(42_i64); + | ---------- ^^^^^^ expected `f32`, found `i64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i64` to `f32` + | +LL | foo::<f32>(42_f32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:401:16 + | +LL | foo::<f32>(42_i32); + | ---------- ^^^^^^ expected `f32`, found `i32` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `i32` to `f32` + | +LL | foo::<f32>(42_f32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:405:16 + | +LL | foo::<f32>(42_i16); + | ---------- ^^^^^^ expected `f32`, found `i16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: you can convert an `i16` to an `f32`, producing the floating point representation of the integer + | +LL | foo::<f32>(42_i16.into()); + | +++++++ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:409:16 + | +LL | foo::<f32>(42_i8); + | ---------- ^^^^^ expected `f32`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: you can convert an `i8` to an `f32`, producing the floating point representation of the integer + | +LL | foo::<f32>(42_i8.into()); + | +++++++ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:413:16 + | +LL | foo::<f32>(42.0_f64); + | ---------- ^^^^^^^^ expected `f32`, found `f64` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: change the type of the numeric literal from `f64` to `f32` + | +LL | foo::<f32>(42.0_f32); + | ~~~ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:419:16 + | +LL | foo::<u32>(42_u8 as u16); + | ---------- ^^^^^^^^^^^^ expected `u32`, found `u16` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: you can convert a `u16` to a `u32` + | +LL | foo::<u32>((42_u8 as u16).into()); + | + ++++++++ + +error[E0308]: mismatched types + --> $DIR/numeric-suffix.rs:423:16 + | +LL | foo::<i32>(-42_i8); + | ---------- ^^^^^^ expected `i32`, found `i8` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/numeric-suffix.rs:3:4 + | +LL | fn foo<N>(_x: N) {} + | ^^^ ----- +help: you can convert an `i8` to an `i32` + | +LL | foo::<i32>((-42_i8).into()); + | + ++++++++ + +error: aborting due to 68 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/packed/issue-27060-rpass.stderr b/src/test/ui/packed/issue-27060-rpass.stderr new file mode 100644 index 00000000000..667b70afb87 --- /dev/null +++ b/src/test/ui/packed/issue-27060-rpass.stderr @@ -0,0 +1,68 @@ +Future incompatibility report: Future breakage diagnostic: +warning: reference to packed field is unaligned + --> $DIR/issue-27060-rpass.rs:15:13 + | +LL | let _ = &good.data; // ok + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-27060-rpass.rs:11:9 + | +LL | #[allow(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +warning: reference to packed field is unaligned + --> $DIR/issue-27060-rpass.rs:16:13 + | +LL | let _ = &good.data2[0]; // ok + | ^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-27060-rpass.rs:11:9 + | +LL | #[allow(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +warning: reference to packed field is unaligned + --> $DIR/issue-27060-rpass.rs:18:13 + | +LL | let _ = &good.data; + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-27060-rpass.rs:11:9 + | +LL | #[allow(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +warning: reference to packed field is unaligned + --> $DIR/issue-27060-rpass.rs:19:13 + | +LL | let _ = &good.data2[0]; + | ^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-27060-rpass.rs:11:9 + | +LL | #[allow(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + diff --git a/src/test/ui/packed/issue-27060.rs b/src/test/ui/packed/issue-27060.rs index 5317a616719..886a00239f9 100644 --- a/src/test/ui/packed/issue-27060.rs +++ b/src/test/ui/packed/issue-27060.rs @@ -5,7 +5,6 @@ pub struct Good { aligned: [u8; 32], } -#[deny(unaligned_references)] fn main() { let good = Good { data: &0, diff --git a/src/test/ui/packed/issue-27060.stderr b/src/test/ui/packed/issue-27060.stderr index bba056d59f8..1bab16e6dda 100644 --- a/src/test/ui/packed/issue-27060.stderr +++ b/src/test/ui/packed/issue-27060.stderr @@ -1,21 +1,17 @@ error: reference to packed field is unaligned - --> $DIR/issue-27060.rs:16:13 + --> $DIR/issue-27060.rs:15:13 | LL | let _ = &good.data; | ^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/issue-27060.rs:8:8 - | -LL | #[deny(unaligned_references)] - | ^^^^^^^^^^^^^^^^^^^^ + = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error: reference to packed field is unaligned - --> $DIR/issue-27060.rs:18:13 + --> $DIR/issue-27060.rs:17:13 | LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ @@ -26,7 +22,7 @@ LL | let _ = &good.data2[0]; = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error: reference to packed field is unaligned - --> $DIR/issue-27060.rs:21:13 + --> $DIR/issue-27060.rs:20:13 | LL | let _ = &good.data; | ^^^^^^^^^^ @@ -37,7 +33,7 @@ LL | let _ = &good.data; = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error: reference to packed field is unaligned - --> $DIR/issue-27060.rs:23:13 + --> $DIR/issue-27060.rs:22:13 | LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ @@ -49,3 +45,55 @@ LL | let _ = &good.data2[0]; error: aborting due to 4 previous errors +Future incompatibility report: Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/issue-27060.rs:15:13 + | +LL | let _ = &good.data; + | ^^^^^^^^^^ + | + = note: `#[deny(unaligned_references)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/issue-27060.rs:17:13 + | +LL | let _ = &good.data2[0]; + | ^^^^^^^^^^^^^^ + | + = note: `#[deny(unaligned_references)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/issue-27060.rs:20:13 + | +LL | let _ = &good.data; + | ^^^^^^^^^^ + | + = note: `#[deny(unaligned_references)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +error: reference to packed field is unaligned + --> $DIR/issue-27060.rs:22:13 + | +LL | let _ = &good.data2[0]; + | ^^^^^^^^^^^^^^ + | + = note: `#[deny(unaligned_references)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + diff --git a/src/test/ui/packed/packed-struct-address-of-element.rs b/src/test/ui/packed/packed-struct-address-of-element.rs index fb3875e6804..d86698cbf38 100644 --- a/src/test/ui/packed/packed-struct-address-of-element.rs +++ b/src/test/ui/packed/packed-struct-address-of-element.rs @@ -1,6 +1,5 @@ // run-pass #![allow(dead_code)] -#![deny(unaligned_references)] #![feature(raw_ref_op)] // ignore-emscripten weird assertion? diff --git a/src/test/ui/packed/packed-struct-borrow-element-64bit.rs b/src/test/ui/packed/packed-struct-borrow-element-64bit.rs index ad932fdcd01..00bddfe40b2 100644 --- a/src/test/ui/packed/packed-struct-borrow-element-64bit.rs +++ b/src/test/ui/packed/packed-struct-borrow-element-64bit.rs @@ -9,6 +9,7 @@ struct Foo4C { baz: usize } +#[warn(unaligned_references)] pub fn main() { let foo = Foo4C { bar: 1, baz: 2 }; let brw = &foo.baz; //~WARN reference to packed field is unaligned diff --git a/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr b/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr index 04585b49986..dcd1c19fa16 100644 --- a/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr +++ b/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr @@ -1,10 +1,14 @@ warning: reference to packed field is unaligned - --> $DIR/packed-struct-borrow-element-64bit.rs:14:15 + --> $DIR/packed-struct-borrow-element-64bit.rs:15:15 | LL | let brw = &foo.baz; | ^^^^^^^^ | - = note: `#[warn(unaligned_references)]` on by default +note: the lint level is defined here + --> $DIR/packed-struct-borrow-element-64bit.rs:12:8 + | +LL | #[warn(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) @@ -12,3 +16,20 @@ LL | let brw = &foo.baz; warning: 1 warning emitted +Future incompatibility report: Future breakage diagnostic: +warning: reference to packed field is unaligned + --> $DIR/packed-struct-borrow-element-64bit.rs:15:15 + | +LL | let brw = &foo.baz; + | ^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/packed-struct-borrow-element-64bit.rs:12:8 + | +LL | #[warn(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + diff --git a/src/test/ui/packed/packed-struct-borrow-element.rs b/src/test/ui/packed/packed-struct-borrow-element.rs index fb6c9c11d56..a6ee90cef44 100644 --- a/src/test/ui/packed/packed-struct-borrow-element.rs +++ b/src/test/ui/packed/packed-struct-borrow-element.rs @@ -20,6 +20,7 @@ struct Foo4C { baz: usize } +#[warn(unaligned_references)] pub fn main() { let foo = Foo1 { bar: 1, baz: 2 }; let brw = &foo.baz; //~WARN reference to packed field is unaligned diff --git a/src/test/ui/packed/packed-struct-borrow-element.stderr b/src/test/ui/packed/packed-struct-borrow-element.stderr index a50b1302001..fb483227e20 100644 --- a/src/test/ui/packed/packed-struct-borrow-element.stderr +++ b/src/test/ui/packed/packed-struct-borrow-element.stderr @@ -1,17 +1,21 @@ warning: reference to packed field is unaligned - --> $DIR/packed-struct-borrow-element.rs:25:15 + --> $DIR/packed-struct-borrow-element.rs:26:15 | LL | let brw = &foo.baz; | ^^^^^^^^ | - = note: `#[warn(unaligned_references)]` on by default +note: the lint level is defined here + --> $DIR/packed-struct-borrow-element.rs:23:8 + | +LL | #[warn(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) warning: reference to packed field is unaligned - --> $DIR/packed-struct-borrow-element.rs:30:15 + --> $DIR/packed-struct-borrow-element.rs:31:15 | LL | let brw = &foo.baz; | ^^^^^^^^ @@ -23,3 +27,37 @@ LL | let brw = &foo.baz; warning: 2 warnings emitted +Future incompatibility report: Future breakage diagnostic: +warning: reference to packed field is unaligned + --> $DIR/packed-struct-borrow-element.rs:26:15 + | +LL | let brw = &foo.baz; + | ^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/packed-struct-borrow-element.rs:23:8 + | +LL | #[warn(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +Future breakage diagnostic: +warning: reference to packed field is unaligned + --> $DIR/packed-struct-borrow-element.rs:31:15 + | +LL | let brw = &foo.baz; + | ^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/packed-struct-borrow-element.rs:23:8 + | +LL | #[warn(unaligned_references)] + | ^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + diff --git a/src/test/ui/parser/fn-arg-doc-comment.rs b/src/test/ui/parser/fn-arg-doc-comment.rs index 2d1554183cc..21d753ad037 100644 --- a/src/test/ui/parser/fn-arg-doc-comment.rs +++ b/src/test/ui/parser/fn-arg-doc-comment.rs @@ -1,26 +1,30 @@ -pub fn f( +pub fn f( //~ NOTE function defined here /// Comment //~^ ERROR documentation comments cannot be applied to function parameters //~| NOTE doc comments are not allowed here + //~| NOTE id: u8, /// Other //~^ ERROR documentation comments cannot be applied to function parameters //~| NOTE doc comments are not allowed here + //~| NOTE a: u8, ) {} fn bar(id: #[allow(dead_code)] i32) {} //~^ ERROR attributes cannot be applied to a function parameter's type //~| NOTE attributes are not allowed here +//~| NOTE function defined here +//~| NOTE fn main() { // verify that the parser recovered and properly typechecked the args f("", ""); - //~^ ERROR mismatched types + //~^ ERROR arguments to this function are incorrect //~| NOTE expected `u8`, found `&str` - //~| ERROR mismatched types //~| NOTE expected `u8`, found `&str` bar(""); //~^ ERROR mismatched types + //~| NOTE arguments to this function are incorrect //~| NOTE expected `i32`, found `&str` } diff --git a/src/test/ui/parser/fn-arg-doc-comment.stderr b/src/test/ui/parser/fn-arg-doc-comment.stderr index 41f2c080b94..c8d7e2efe79 100644 --- a/src/test/ui/parser/fn-arg-doc-comment.stderr +++ b/src/test/ui/parser/fn-arg-doc-comment.stderr @@ -1,5 +1,5 @@ error: attributes cannot be applied to a function parameter's type - --> $DIR/fn-arg-doc-comment.rs:12:12 + --> $DIR/fn-arg-doc-comment.rs:14:12 | LL | fn bar(id: #[allow(dead_code)] i32) {} | ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here @@ -11,29 +11,51 @@ LL | /// Comment | ^^^^^^^^^^^ doc comments are not allowed here error: documentation comments cannot be applied to function parameters - --> $DIR/fn-arg-doc-comment.rs:6:5 + --> $DIR/fn-arg-doc-comment.rs:7:5 | LL | /// Other | ^^^^^^^^^ doc comments are not allowed here -error[E0308]: mismatched types - --> $DIR/fn-arg-doc-comment.rs:18:7 +error[E0308]: arguments to this function are incorrect + --> $DIR/fn-arg-doc-comment.rs:22:5 | LL | f("", ""); - | ^^ expected `u8`, found `&str` - -error[E0308]: mismatched types - --> $DIR/fn-arg-doc-comment.rs:18:11 + | ^ -- -- expected `u8`, found `&str` + | | + | expected `u8`, found `&str` | -LL | f("", ""); - | ^^ expected `u8`, found `&str` +note: function defined here + --> $DIR/fn-arg-doc-comment.rs:1:8 + | +LL | pub fn f( + | ^ +LL | / /// Comment +LL | | +LL | | +LL | | +LL | | id: u8, + | |__________- +LL | / /// Other +LL | | +LL | | +LL | | +LL | | a: u8, + | |_________- error[E0308]: mismatched types - --> $DIR/fn-arg-doc-comment.rs:23:9 + --> $DIR/fn-arg-doc-comment.rs:26:9 | LL | bar(""); - | ^^ expected `i32`, found `&str` + | --- ^^ expected `i32`, found `&str` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/fn-arg-doc-comment.rs:14:4 + | +LL | fn bar(id: #[allow(dead_code)] i32) {} + | ^^^ --------------------------- -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr index c800afdae2a..4c2eff63ab5 100644 --- a/src/test/ui/pattern/pattern-error-continue.stderr +++ b/src/test/ui/pattern/pattern-error-continue.stderr @@ -46,7 +46,15 @@ error[E0308]: mismatched types --> $DIR/pattern-error-continue.rs:28:7 | LL | f(true); - | ^^^^ expected `char`, found `bool` + | - ^^^^ expected `char`, found `bool` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/pattern-error-continue.rs:13:4 + | +LL | fn f(_c: char) {} + | ^ -------- error: aborting due to 5 previous errors diff --git a/src/test/ui/proc-macro/signature.stderr b/src/test/ui/proc-macro/signature.stderr index 80a459c4125..262a64acc54 100644 --- a/src/test/ui/proc-macro/signature.stderr +++ b/src/test/ui/proc-macro/signature.stderr @@ -9,6 +9,11 @@ LL | | } | = note: expected fn pointer `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` found fn item `unsafe extern "C" fn(i32, u32) -> u32 {foo}` +note: associated function defined here + --> $SRC_DIR/proc_macro/src/bridge/client.rs:LL:COL + | +LL | pub const fn custom_derive( + | ^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/range/issue-54505-no-literals.stderr b/src/test/ui/range/issue-54505-no-literals.stderr index 065e16a8227..4cbf8869d0c 100644 --- a/src/test/ui/range/issue-54505-no-literals.stderr +++ b/src/test/ui/range/issue-54505-no-literals.stderr @@ -2,145 +2,217 @@ error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:16:16 | LL | take_range(std::ops::Range { start: 0, end: 1 }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected reference, found struct `std::ops::Range` - | help: consider borrowing here: `&std::ops::Range { start: 0, end: 1 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | expected reference, found struct `std::ops::Range` + | | help: consider borrowing here: `&std::ops::Range { start: 0, end: 1 }` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `std::ops::Range<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-literals.rs:12:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:21:16 | LL | take_range(::std::ops::Range { start: 0, end: 1 }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected reference, found struct `std::ops::Range` - | help: consider borrowing here: `&::std::ops::Range { start: 0, end: 1 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | expected reference, found struct `std::ops::Range` + | | help: consider borrowing here: `&::std::ops::Range { start: 0, end: 1 }` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `std::ops::Range<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-literals.rs:12:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:26:16 | LL | take_range(std::ops::RangeFrom { start: 1 }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected reference, found struct `RangeFrom` - | help: consider borrowing here: `&std::ops::RangeFrom { start: 1 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | expected reference, found struct `RangeFrom` + | | help: consider borrowing here: `&std::ops::RangeFrom { start: 1 }` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeFrom<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-literals.rs:12:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:31:16 | LL | take_range(::std::ops::RangeFrom { start: 1 }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected reference, found struct `RangeFrom` - | help: consider borrowing here: `&::std::ops::RangeFrom { start: 1 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | expected reference, found struct `RangeFrom` + | | help: consider borrowing here: `&::std::ops::RangeFrom { start: 1 }` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeFrom<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-literals.rs:12:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:36:16 | LL | take_range(std::ops::RangeFull {}); - | ^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected reference, found struct `RangeFull` - | help: consider borrowing here: `&std::ops::RangeFull {}` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | expected reference, found struct `RangeFull` + | | help: consider borrowing here: `&std::ops::RangeFull {}` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeFull` +note: function defined here + --> $DIR/issue-54505-no-literals.rs:12:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:41:16 | LL | take_range(::std::ops::RangeFull {}); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected reference, found struct `RangeFull` - | help: consider borrowing here: `&::std::ops::RangeFull {}` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | expected reference, found struct `RangeFull` + | | help: consider borrowing here: `&::std::ops::RangeFull {}` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeFull` +note: function defined here + --> $DIR/issue-54505-no-literals.rs:12:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:46:16 | LL | take_range(std::ops::RangeInclusive::new(0, 1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected reference, found struct `RangeInclusive` - | help: consider borrowing here: `&std::ops::RangeInclusive::new(0, 1)` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | expected reference, found struct `RangeInclusive` + | | help: consider borrowing here: `&std::ops::RangeInclusive::new(0, 1)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeInclusive<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-literals.rs:12:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:51:16 | LL | take_range(::std::ops::RangeInclusive::new(0, 1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected reference, found struct `RangeInclusive` - | help: consider borrowing here: `&::std::ops::RangeInclusive::new(0, 1)` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | expected reference, found struct `RangeInclusive` + | | help: consider borrowing here: `&::std::ops::RangeInclusive::new(0, 1)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeInclusive<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-literals.rs:12:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:56:16 | LL | take_range(std::ops::RangeTo { end: 5 }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected reference, found struct `RangeTo` - | help: consider borrowing here: `&std::ops::RangeTo { end: 5 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | expected reference, found struct `RangeTo` + | | help: consider borrowing here: `&std::ops::RangeTo { end: 5 }` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeTo<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-literals.rs:12:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:61:16 | LL | take_range(::std::ops::RangeTo { end: 5 }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected reference, found struct `RangeTo` - | help: consider borrowing here: `&::std::ops::RangeTo { end: 5 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | expected reference, found struct `RangeTo` + | | help: consider borrowing here: `&::std::ops::RangeTo { end: 5 }` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeTo<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-literals.rs:12:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:66:16 | LL | take_range(std::ops::RangeToInclusive { end: 5 }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected reference, found struct `RangeToInclusive` - | help: consider borrowing here: `&std::ops::RangeToInclusive { end: 5 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | expected reference, found struct `RangeToInclusive` + | | help: consider borrowing here: `&std::ops::RangeToInclusive { end: 5 }` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeToInclusive<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-literals.rs:12:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:71:16 | LL | take_range(::std::ops::RangeToInclusive { end: 5 }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected reference, found struct `RangeToInclusive` - | help: consider borrowing here: `&::std::ops::RangeToInclusive { end: 5 }` + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | | + | | expected reference, found struct `RangeToInclusive` + | | help: consider borrowing here: `&::std::ops::RangeToInclusive { end: 5 }` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeToInclusive<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-literals.rs:12:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error: aborting due to 12 previous errors diff --git a/src/test/ui/range/issue-54505-no-std.stderr b/src/test/ui/range/issue-54505-no-std.stderr index 73507f4836b..c4e36b0b159 100644 --- a/src/test/ui/range/issue-54505-no-std.stderr +++ b/src/test/ui/range/issue-54505-no-std.stderr @@ -4,73 +4,109 @@ error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:27:16 | LL | take_range(0..1); - | ^^^^ - | | - | expected reference, found struct `Range` - | help: consider borrowing here: `&(0..1)` + | ---------- ^^^^ + | | | + | | expected reference, found struct `Range` + | | help: consider borrowing here: `&(0..1)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `Range<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-std.rs:23:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:32:16 | LL | take_range(1..); - | ^^^ - | | - | expected reference, found struct `RangeFrom` - | help: consider borrowing here: `&(1..)` + | ---------- ^^^ + | | | + | | expected reference, found struct `RangeFrom` + | | help: consider borrowing here: `&(1..)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeFrom<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-std.rs:23:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:37:16 | LL | take_range(..); - | ^^ - | | - | expected reference, found struct `RangeFull` - | help: consider borrowing here: `&(..)` + | ---------- ^^ + | | | + | | expected reference, found struct `RangeFull` + | | help: consider borrowing here: `&(..)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeFull` +note: function defined here + --> $DIR/issue-54505-no-std.rs:23:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:42:16 | LL | take_range(0..=1); - | ^^^^^ - | | - | expected reference, found struct `RangeInclusive` - | help: consider borrowing here: `&(0..=1)` + | ---------- ^^^^^ + | | | + | | expected reference, found struct `RangeInclusive` + | | help: consider borrowing here: `&(0..=1)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeInclusive<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-std.rs:23:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:47:16 | LL | take_range(..5); - | ^^^ - | | - | expected reference, found struct `RangeTo` - | help: consider borrowing here: `&(..5)` + | ---------- ^^^ + | | | + | | expected reference, found struct `RangeTo` + | | help: consider borrowing here: `&(..5)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeTo<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-std.rs:23:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:52:16 | LL | take_range(..=42); - | ^^^^^ - | | - | expected reference, found struct `RangeToInclusive` - | help: consider borrowing here: `&(..=42)` + | ---------- ^^^^^ + | | | + | | expected reference, found struct `RangeToInclusive` + | | help: consider borrowing here: `&(..=42)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeToInclusive<{integer}>` +note: function defined here + --> $DIR/issue-54505-no-std.rs:23:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error: aborting due to 7 previous errors diff --git a/src/test/ui/range/issue-54505.stderr b/src/test/ui/range/issue-54505.stderr index 121af29834d..38df6e14496 100644 --- a/src/test/ui/range/issue-54505.stderr +++ b/src/test/ui/range/issue-54505.stderr @@ -2,73 +2,109 @@ error[E0308]: mismatched types --> $DIR/issue-54505.rs:14:16 | LL | take_range(0..1); - | ^^^^ - | | - | expected reference, found struct `std::ops::Range` - | help: consider borrowing here: `&(0..1)` + | ---------- ^^^^ + | | | + | | expected reference, found struct `std::ops::Range` + | | help: consider borrowing here: `&(0..1)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `std::ops::Range<{integer}>` +note: function defined here + --> $DIR/issue-54505.rs:10:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505.rs:19:16 | LL | take_range(1..); - | ^^^ - | | - | expected reference, found struct `RangeFrom` - | help: consider borrowing here: `&(1..)` + | ---------- ^^^ + | | | + | | expected reference, found struct `RangeFrom` + | | help: consider borrowing here: `&(1..)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeFrom<{integer}>` +note: function defined here + --> $DIR/issue-54505.rs:10:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505.rs:24:16 | LL | take_range(..); - | ^^ - | | - | expected reference, found struct `RangeFull` - | help: consider borrowing here: `&(..)` + | ---------- ^^ + | | | + | | expected reference, found struct `RangeFull` + | | help: consider borrowing here: `&(..)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeFull` +note: function defined here + --> $DIR/issue-54505.rs:10:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505.rs:29:16 | LL | take_range(0..=1); - | ^^^^^ - | | - | expected reference, found struct `RangeInclusive` - | help: consider borrowing here: `&(0..=1)` + | ---------- ^^^^^ + | | | + | | expected reference, found struct `RangeInclusive` + | | help: consider borrowing here: `&(0..=1)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeInclusive<{integer}>` +note: function defined here + --> $DIR/issue-54505.rs:10:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505.rs:34:16 | LL | take_range(..5); - | ^^^ - | | - | expected reference, found struct `RangeTo` - | help: consider borrowing here: `&(..5)` + | ---------- ^^^ + | | | + | | expected reference, found struct `RangeTo` + | | help: consider borrowing here: `&(..5)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeTo<{integer}>` +note: function defined here + --> $DIR/issue-54505.rs:10:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error[E0308]: mismatched types --> $DIR/issue-54505.rs:39:16 | LL | take_range(..=42); - | ^^^^^ - | | - | expected reference, found struct `RangeToInclusive` - | help: consider borrowing here: `&(..=42)` + | ---------- ^^^^^ + | | | + | | expected reference, found struct `RangeToInclusive` + | | help: consider borrowing here: `&(..=42)` + | arguments to this function are incorrect | = note: expected reference `&_` found struct `RangeToInclusive<{integer}>` +note: function defined here + --> $DIR/issue-54505.rs:10:4 + | +LL | fn take_range(_r: &impl RangeBounds<i8>) {} + | ^^^^^^^^^^ ------------------------- error: aborting due to 6 previous errors diff --git a/src/test/ui/range/issue-73553-misinterp-range-literal.stderr b/src/test/ui/range/issue-73553-misinterp-range-literal.stderr index 5167b87fd27..6badd998f96 100644 --- a/src/test/ui/range/issue-73553-misinterp-range-literal.stderr +++ b/src/test/ui/range/issue-73553-misinterp-range-literal.stderr @@ -2,25 +2,37 @@ error[E0308]: mismatched types --> $DIR/issue-73553-misinterp-range-literal.rs:12:10 | LL | demo(tell(1)..tell(10)); - | ^^^^^^^^^^^^^^^^^ - | | - | expected reference, found struct `std::ops::Range` - | help: consider borrowing here: `&(tell(1)..tell(10))` + | ---- ^^^^^^^^^^^^^^^^^ + | | | + | | expected reference, found struct `std::ops::Range` + | | help: consider borrowing here: `&(tell(1)..tell(10))` + | arguments to this function are incorrect | = note: expected reference `&std::ops::Range<usize>` found struct `std::ops::Range<usize>` +note: function defined here + --> $DIR/issue-73553-misinterp-range-literal.rs:3:4 + | +LL | fn demo(r: &Range) { + | ^^^^ --------- error[E0308]: mismatched types --> $DIR/issue-73553-misinterp-range-literal.rs:14:10 | LL | demo(1..10); - | ^^^^^ - | | - | expected reference, found struct `std::ops::Range` - | help: consider borrowing here: `&(1..10)` + | ---- ^^^^^ + | | | + | | expected reference, found struct `std::ops::Range` + | | help: consider borrowing here: `&(1..10)` + | arguments to this function are incorrect | = note: expected reference `&std::ops::Range<usize>` found struct `std::ops::Range<{integer}>` +note: function defined here + --> $DIR/issue-73553-misinterp-range-literal.rs:3:4 + | +LL | fn demo(r: &Range) { + | ^^^^ --------- error: aborting due to 2 previous errors diff --git a/src/test/ui/resolve/resolve-primitive-fallback.stderr b/src/test/ui/resolve/resolve-primitive-fallback.stderr index 5af0aefe22b..44631f954df 100644 --- a/src/test/ui/resolve/resolve-primitive-fallback.stderr +++ b/src/test/ui/resolve/resolve-primitive-fallback.stderr @@ -19,15 +19,17 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/resolve-primitive-fallback.rs:3:5 | LL | std::mem::size_of(u16); - | ^^^^^^^^^^^^^^^^^ --- supplied 1 argument - | | - | expected 0 arguments + | ^^^^^^^^^^^^^^^^^ --- argument unexpected | note: function defined here --> $SRC_DIR/core/src/mem/mod.rs:LL:COL | LL | pub const fn size_of<T>() -> usize { | ^^^^^^^ +help: remove the extra argument + | +LL | std::mem::size_of(); + | ~~~~~~~~~~~~~~~~~~~ error: aborting due to 3 previous errors diff --git a/src/test/ui/self/issue-61882.stderr b/src/test/ui/self/issue-61882.stderr index 09ffe8e64b1..dd7194dc2e8 100644 --- a/src/test/ui/self/issue-61882.stderr +++ b/src/test/ui/self/issue-61882.stderr @@ -2,7 +2,15 @@ error[E0308]: mismatched types --> $DIR/issue-61882.rs:4:27 | LL | const B: A<u8> = Self(0); - | ^ expected `bool`, found integer + | ---- ^ expected `bool`, found integer + | | + | arguments to this function are incorrect + | +note: tuple struct defined here + --> $DIR/issue-61882.rs:1:8 + | +LL | struct A<T>(T); + | ^ error[E0308]: mismatched types --> $DIR/issue-61882.rs:4:22 diff --git a/src/test/ui/span/E0057.rs b/src/test/ui/span/E0057.rs new file mode 100644 index 00000000000..83f941f65b9 --- /dev/null +++ b/src/test/ui/span/E0057.rs @@ -0,0 +1,6 @@ +fn main() { + let f = |x| x * 3; + let a = f(); //~ ERROR E0057 + let b = f(4); + let c = f(2, 3); //~ ERROR E0057 +} diff --git a/src/test/ui/span/E0057.stderr b/src/test/ui/span/E0057.stderr new file mode 100644 index 00000000000..a151b20f865 --- /dev/null +++ b/src/test/ui/span/E0057.stderr @@ -0,0 +1,25 @@ +error[E0057]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/E0057.rs:3:13 + | +LL | let a = f(); + | ^-- an argument is missing + | +help: provide the argument + | +LL | let a = f({_}); + | ~~~~~~ + +error[E0057]: this function takes 1 argument but 2 arguments were supplied + --> $DIR/E0057.rs:5:13 + | +LL | let c = f(2, 3); + | ^ - argument unexpected + | +help: remove the extra argument + | +LL | let c = f(2); + | ~~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0057`. diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index 5a964c5d5cc..db784d5fe6c 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -20,19 +20,33 @@ error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:12:10 | LL | test(&y); - | ^^ types differ in mutability + | ---- ^^ types differ in mutability + | | + | arguments to this function are incorrect | = note: expected mutable reference `&mut String` found reference `&String` +note: function defined here + --> $DIR/coerce-suggestions.rs:1:4 + | +LL | fn test(_x: &mut String) {} + | ^^^^ --------------- error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:14:11 | LL | test2(&y); - | ^^ types differ in mutability + | ----- ^^ types differ in mutability + | | + | arguments to this function are incorrect | = note: expected mutable reference `&mut i32` found reference `&String` +note: function defined here + --> $DIR/coerce-suggestions.rs:3:4 + | +LL | fn test2(_x: &mut i32) {} + | ^^^^^ ------------ error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:17:9 diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr index 8d26ca4ac7a..68da9f0dc88 100644 --- a/src/test/ui/span/issue-34264.stderr +++ b/src/test/ui/span/issue-34264.stderr @@ -54,35 +54,47 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/issue-34264.rs:7:5 | LL | foo(Some(42), 2, ""); - | ^^^ -------- - -- supplied 3 arguments - | | - | expected 2 arguments + | ^^^ -- argument unexpected | note: function defined here --> $DIR/issue-34264.rs:1:4 | LL | fn foo(Option<i32>, String) {} | ^^^ ----------- ------ +help: remove the extra argument + | +LL | foo(Some(42), 2); + | ~~~~~~~~~~~~~~~~ error[E0308]: mismatched types --> $DIR/issue-34264.rs:8:13 | LL | bar("", ""); - | ^^ expected `usize`, found `&str` + | --- ^^ expected `usize`, found `&str` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/issue-34264.rs:3:4 + | +LL | fn bar(x, y: usize) {} + | ^^^ - -------- error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/issue-34264.rs:10:5 | LL | bar(1, 2, 3); - | ^^^ - - - supplied 3 arguments - | | - | expected 2 arguments + | ^^^ - argument unexpected | note: function defined here --> $DIR/issue-34264.rs:3:4 | LL | fn bar(x, y: usize) {} | ^^^ - -------- +help: remove the extra argument + | +LL | bar(1, 2); + | ~~~~~~~~~ error: aborting due to 6 previous errors diff --git a/src/test/ui/span/missing-unit-argument.stderr b/src/test/ui/span/missing-unit-argument.stderr index 99c57322d86..c8e1a232887 100644 --- a/src/test/ui/span/missing-unit-argument.stderr +++ b/src/test/ui/span/missing-unit-argument.stderr @@ -2,88 +2,92 @@ error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:11:33 | LL | let _: Result<(), String> = Ok(); - | ^^-- supplied 0 arguments + | ^^-- an argument of type `()` is missing | -help: expected the unit value `()`; create it with empty parentheses +help: provide the argument | LL | let _: Result<(), String> = Ok(()); - | ++ + | ~~~~~~ error[E0061]: this function takes 2 arguments but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:12:5 | LL | foo(); - | ^^^-- supplied 0 arguments - | | - | expected 2 arguments + | ^^^-- two arguments of type `()` and `()` are missing | note: function defined here --> $DIR/missing-unit-argument.rs:1:4 | LL | fn foo(():(), ():()) {} | ^^^ ----- ----- +help: provide the arguments + | +LL | foo((), ()); + | ~~~~~~~~~~~ error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/missing-unit-argument.rs:13:5 | LL | foo(()); - | ^^^ -- supplied 1 argument - | | - | expected 2 arguments + | ^^^---- an argument of type `()` is missing | note: function defined here --> $DIR/missing-unit-argument.rs:1:4 | LL | fn foo(():(), ():()) {} | ^^^ ----- ----- +help: provide the argument + | +LL | foo((), ()); + | ~~~~~~~~~~~ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:14:5 | LL | bar(); - | ^^^-- supplied 0 arguments + | ^^^-- an argument of type `()` is missing | note: function defined here --> $DIR/missing-unit-argument.rs:2:4 | LL | fn bar(():()) {} | ^^^ ----- -help: expected the unit value `()`; create it with empty parentheses +help: provide the argument | LL | bar(()); - | ++ + | ~~~~~~~ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:15:7 | LL | S.baz(); - | ^^^- supplied 0 arguments + | ^^^-- an argument of type `()` is missing | note: associated function defined here --> $DIR/missing-unit-argument.rs:6:8 | LL | fn baz(self, (): ()) { } | ^^^ ---- ------ -help: expected the unit value `()`; create it with empty parentheses +help: provide the argument | LL | S.baz(()); - | ++ + | ~~~~~~~ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:16:7 | LL | S.generic::<()>(); - | ^^^^^^^------ supplied 0 arguments + | ^^^^^^^^^^^^^-- an argument of type `()` is missing | note: associated function defined here --> $DIR/missing-unit-argument.rs:7:8 | LL | fn generic<T>(self, _: T) { } | ^^^^^^^ ---- ---- -help: expected the unit value `()`; create it with empty parentheses +help: provide the argument | LL | S.generic::<()>(()); - | ++ + | ~~~~~~~~~~~~~~~~~ error: aborting due to 6 previous errors diff --git a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr index ddcdfb1c3b3..991dde30629 100644 --- a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr +++ b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr @@ -2,37 +2,55 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied --> $DIR/args-instead-of-tuple-errors.rs:6:34 | LL | let _: Option<(i32, bool)> = Some(1, 2); - | ^^^^ - - supplied 2 arguments - | | - | expected 1 argument + | ^^^^ - - argument unexpected + | | + | expected tuple, found integer + | + = note: expected tuple `(i32, bool)` + found type `{integer}` +help: remove the extra argument + | +LL | let _: Option<(i32, bool)> = Some({(i32, bool)}); + | ~~~~~~~~~~~~~~~~~~~ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/args-instead-of-tuple-errors.rs:8:5 | LL | int_bool(1, 2); - | ^^^^^^^^ - - supplied 2 arguments - | | - | expected 1 argument + | ^^^^^^^^ - - argument unexpected + | | + | expected tuple, found integer | + = note: expected tuple `(i32, bool)` + found type `{integer}` note: function defined here --> $DIR/args-instead-of-tuple-errors.rs:21:4 | LL | fn int_bool(_: (i32, bool)) { | ^^^^^^^^ -------------- +help: remove the extra argument + | +LL | int_bool({(i32, bool)}); + | ~~~~~~~~~~~~~~~~~~~~~~~ error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied --> $DIR/args-instead-of-tuple-errors.rs:11:28 | LL | let _: Option<(i8,)> = Some(); - | ^^^^-- supplied 0 arguments - | | - | expected 1 argument + | ^^^^-- an argument of type `(i8,)` is missing + | +help: provide the argument + | +LL | let _: Option<(i8,)> = Some({(i8,)}); + | ~~~~~~~~~~~~~ error[E0308]: mismatched types --> $DIR/args-instead-of-tuple-errors.rs:14:34 | LL | let _: Option<(i32,)> = Some(5_usize); - | ^^^^^^^ expected tuple, found `usize` + | ---- ^^^^^^^ expected tuple, found `usize` + | | + | arguments to this enum variant are incorrect | = note: expected tuple `(i32,)` found type `usize` @@ -41,7 +59,9 @@ error[E0308]: mismatched types --> $DIR/args-instead-of-tuple-errors.rs:17:34 | LL | let _: Option<(i32,)> = Some((5_usize)); - | ^^^^^^^^^ expected tuple, found `usize` + | ---- ^^^^^^^^^ expected tuple, found `usize` + | | + | arguments to this enum variant are incorrect | = note: expected tuple `(i32,)` found type `usize` diff --git a/src/test/ui/suggestions/args-instead-of-tuple.stderr b/src/test/ui/suggestions/args-instead-of-tuple.stderr index 6a7602c9d0f..7ec10e88142 100644 --- a/src/test/ui/suggestions/args-instead-of-tuple.stderr +++ b/src/test/ui/suggestions/args-instead-of-tuple.stderr @@ -2,7 +2,7 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied --> $DIR/args-instead-of-tuple.rs:7:36 | LL | let _: Result<(i32, i8), ()> = Ok(1, 2); - | ^^ - - supplied 2 arguments + | ^^ | help: use parentheses to construct a tuple | @@ -13,7 +13,7 @@ error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied --> $DIR/args-instead-of-tuple.rs:9:46 | LL | let _: Option<(i32, i8, &'static str)> = Some(1, 2, "hi"); - | ^^^^ - - ---- supplied 3 arguments + | ^^^^ | help: use parentheses to construct a tuple | @@ -24,18 +24,20 @@ error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied --> $DIR/args-instead-of-tuple.rs:11:25 | LL | let _: Option<()> = Some(); - | ^^^^-- supplied 0 arguments + | ^^^^-- an argument of type `()` is missing | -help: expected the unit value `()`; create it with empty parentheses +help: provide the argument | LL | let _: Option<()> = Some(()); - | ++ + | ~~~~~~~~ error[E0308]: mismatched types --> $DIR/args-instead-of-tuple.rs:14:34 | LL | let _: Option<(i32,)> = Some(3); - | ^ expected tuple, found integer + | ---- ^ expected tuple, found integer + | | + | arguments to this enum variant are incorrect | = note: expected tuple `(i32,)` found type `{integer}` @@ -48,7 +50,9 @@ error[E0308]: mismatched types --> $DIR/args-instead-of-tuple.rs:17:34 | LL | let _: Option<(i32,)> = Some((3)); - | ^^^ expected tuple, found integer + | ---- ^^^ expected tuple, found integer + | | + | arguments to this enum variant are incorrect | = note: expected tuple `(i32,)` found type `{integer}` @@ -61,7 +65,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/args-instead-of-tuple.rs:20:5 | LL | two_ints(1, 2); - | ^^^^^^^^ - - supplied 2 arguments + | ^^^^^^^^ | note: function defined here --> $DIR/args-instead-of-tuple.rs:25:4 @@ -77,7 +81,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/args-instead-of-tuple.rs:22:5 | LL | with_generic(3, 4); - | ^^^^^^^^^^^^ - - supplied 2 arguments + | ^^^^^^^^^^^^ | note: function defined here --> $DIR/args-instead-of-tuple.rs:28:4 @@ -93,7 +97,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/args-instead-of-tuple.rs:31:9 | LL | with_generic(a, b); - | ^^^^^^^^^^^^ - - supplied 2 arguments + | ^^^^^^^^^^^^ | note: function defined here --> $DIR/args-instead-of-tuple.rs:28:4 diff --git a/src/test/ui/suggestions/as-ref.stderr b/src/test/ui/suggestions/as-ref.stderr index 8d93ac50796..1efd1b317b7 100644 --- a/src/test/ui/suggestions/as-ref.stderr +++ b/src/test/ui/suggestions/as-ref.stderr @@ -2,33 +2,61 @@ error[E0308]: mismatched types --> $DIR/as-ref.rs:7:29 | LL | opt.map(|arg| takes_ref(arg)); - | --- ^^^ expected `&Foo`, found struct `Foo` - | | + | --- --------- ^^^ expected `&Foo`, found struct `Foo` + | | | + | | arguments to this function are incorrect | help: consider using `as_ref` instead: `as_ref().map` + | +note: function defined here + --> $DIR/as-ref.rs:3:4 + | +LL | fn takes_ref(_: &Foo) {} + | ^^^^^^^^^ ------- error[E0308]: mismatched types --> $DIR/as-ref.rs:8:39 | LL | opt.and_then(|arg| Some(takes_ref(arg))); - | -------- ^^^ expected `&Foo`, found struct `Foo` - | | + | -------- --------- ^^^ expected `&Foo`, found struct `Foo` + | | | + | | arguments to this function are incorrect | help: consider using `as_ref` instead: `as_ref().and_then` + | +note: function defined here + --> $DIR/as-ref.rs:3:4 + | +LL | fn takes_ref(_: &Foo) {} + | ^^^^^^^^^ ------- error[E0308]: mismatched types --> $DIR/as-ref.rs:10:29 | LL | opt.map(|arg| takes_ref(arg)); - | --- ^^^ expected `&Foo`, found struct `Foo` - | | + | --- --------- ^^^ expected `&Foo`, found struct `Foo` + | | | + | | arguments to this function are incorrect | help: consider using `as_ref` instead: `as_ref().map` + | +note: function defined here + --> $DIR/as-ref.rs:3:4 + | +LL | fn takes_ref(_: &Foo) {} + | ^^^^^^^^^ ------- error[E0308]: mismatched types --> $DIR/as-ref.rs:11:37 | LL | opt.and_then(|arg| Ok(takes_ref(arg))); - | -------- ^^^ expected `&Foo`, found struct `Foo` - | | + | -------- --------- ^^^ expected `&Foo`, found struct `Foo` + | | | + | | arguments to this function are incorrect | help: consider using `as_ref` instead: `as_ref().and_then` + | +note: function defined here + --> $DIR/as-ref.rs:3:4 + | +LL | fn takes_ref(_: &Foo) {} + | ^^^^^^^^^ ------- error[E0308]: mismatched types --> $DIR/as-ref.rs:13:29 diff --git a/src/test/ui/suggestions/boxed-variant-field.stderr b/src/test/ui/suggestions/boxed-variant-field.stderr index 9a31dc89197..6dfb73480a2 100644 --- a/src/test/ui/suggestions/boxed-variant-field.stderr +++ b/src/test/ui/suggestions/boxed-variant-field.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/boxed-variant-field.rs:9:31 | LL | Ty::List(elem) => foo(elem), - | ^^^^ expected enum `Ty`, found struct `Box` + | --- ^^^^ expected enum `Ty`, found struct `Box` + | | + | arguments to this function are incorrect | = note: expected enum `Ty` found struct `Box<Ty>` +note: function defined here + --> $DIR/boxed-variant-field.rs:6:4 + | +LL | fn foo(x: Ty) -> Ty { + | ^^^ ----- help: consider unboxing the value | LL | Ty::List(elem) => foo(*elem), diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr index 7ef4895249c..71facf57e8d 100644 --- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr +++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr @@ -34,10 +34,16 @@ LL | fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, LL | Pin::new(x) | -------- ^ expected struct `Box`, found type parameter `F` | | + | arguments to this function are incorrect | help: use `Box::pin` to pin and box this expression: `Box::pin` | = note: expected struct `Box<dyn Future<Output = i32> + Send>` found type parameter `F` +note: associated function defined here + --> $SRC_DIR/core/src/pin.rs:LL:COL + | +LL | pub const fn new(pointer: P) -> Pin<P> { + | ^^^ error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned --> $DIR/expected-boxed-future-isnt-pinned.rs:19:5 diff --git a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr index 0016f192842..8c9a41a2027 100644 --- a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr +++ b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr @@ -17,10 +17,17 @@ error[E0308]: mismatched types --> $DIR/issue-86100-tuple-paren-comma.rs:13:9 | LL | foo((Some(3))); - | ^^^^^^^^^ expected tuple, found enum `Option` + | --- ^^^^^^^^^ expected tuple, found enum `Option` + | | + | arguments to this function are incorrect | = note: expected tuple `(_,)` found enum `Option<{integer}>` +note: function defined here + --> $DIR/issue-86100-tuple-paren-comma.rs:5:4 + | +LL | fn foo<T>(_t: (T,)) {} + | ^^^ -------- help: use a trailing comma to create a tuple with one element | LL | foo((Some(3),)); diff --git a/src/test/ui/suggestions/issue-90213-expected-boxfuture-self-ice.stderr b/src/test/ui/suggestions/issue-90213-expected-boxfuture-self-ice.stderr index c15b772b79c..611f7d5ddda 100644 --- a/src/test/ui/suggestions/issue-90213-expected-boxfuture-self-ice.stderr +++ b/src/test/ui/suggestions/issue-90213-expected-boxfuture-self-ice.stderr @@ -2,11 +2,18 @@ error[E0308]: mismatched types --> $DIR/issue-90213-expected-boxfuture-self-ice.rs:9:19 | LL | Self::foo(None) - | ^^^^ expected struct `Box`, found enum `Option` + | --------- ^^^^ expected struct `Box`, found enum `Option` + | | + | arguments to this function are incorrect | = note: expected struct `Box<Option<S>>` found enum `Option<_>` = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html +note: associated function defined here + --> $DIR/issue-90213-expected-boxfuture-self-ice.rs:7:8 + | +LL | fn foo(_: Box<Option<S>>) {} + | ^^^ ----------------- help: store this in the heap by calling `Box::new` | LL | Self::foo(Box::new(None)) diff --git a/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr b/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr index aa621111c00..9588eedc98b 100644 --- a/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr +++ b/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr @@ -38,7 +38,15 @@ error[E0308]: mismatched types --> $DIR/recover-from-semicolon-trailing-item.rs:14:9 | LL | foo(""); - | ^^ expected `usize`, found `&str` + | --- ^^ expected `usize`, found `&str` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/recover-from-semicolon-trailing-item.rs:6:4 + | +LL | fn foo(a: usize) {}; + | ^^^ -------- error: aborting due to 6 previous errors diff --git a/src/test/ui/suggestions/suggest-ref-macro.stderr b/src/test/ui/suggestions/suggest-ref-macro.stderr index 5c05810e586..b0ac770c06f 100644 --- a/src/test/ui/suggestions/suggest-ref-macro.stderr +++ b/src/test/ui/suggestions/suggest-ref-macro.stderr @@ -2,31 +2,60 @@ error[E0308]: mismatched types --> $DIR/suggest-ref-macro.rs:15:11 | LL | x(123); - | ^^^ - | | - | expected `&mut i32`, found integer - | help: consider mutably borrowing here: `&mut 123` + | - ^^^ + | | | + | | expected `&mut i32`, found integer + | | help: consider mutably borrowing here: `&mut 123` + | arguments to this function are incorrect ... LL | bla!(); | ------ in this macro invocation | +note: function defined here + --> $DIR/suggest-ref-macro.rs:11:4 + | +LL | fn x(_: &mut i32) {} + | ^ ----------- = note: this error originates in the macro `bla` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/suggest-ref-macro.rs:26:10 | +LL | x($v) + | - arguments to this function are incorrect +... LL | bla!(456); | ^^^ | | | expected `&mut i32`, found integer | help: consider mutably borrowing here: `&mut 456` + | +note: function defined here + --> $DIR/suggest-ref-macro.rs:11:4 + | +LL | fn x(_: &mut i32) {} + | ^ ----------- error[E0308]: mismatched types --> $DIR/suggest-ref-macro.rs:8:1 | LL | #[hello] - | ^^^^^^^^ expected `&mut i32`, found integer + | ^^^^^^^^ + | | + | expected `&mut i32`, found integer + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/suggest-ref-macro.rs:8:1 | +LL | #[hello] + | _-^^^^^^^ +LL | | fn abc() {} +LL | | +LL | | fn x(_: &mut i32) {} +LL | | +LL | | macro_rules! bla { + | |_____________- = note: this error originates in the attribute macro `hello` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr index 19fc772544d..ac839ff7eb9 100644 --- a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr +++ b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:13:13 | LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found associated type + | --- ^^^^^^^^ expected `usize`, found associated type + | | + | arguments to this function are incorrect | = note: expected type `usize` found associated type `<impl Trait as Trait>::A` +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- help: consider constraining the associated type `<impl Trait as Trait>::A` to `usize` | LL | fn foo<'a, T: Trait + 'a>(&self, _: impl Trait, x: impl Trait<A = usize>, _: T) { @@ -15,10 +22,17 @@ error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:17:13 | LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found associated type + | --- ^^^^^^^^ expected `usize`, found associated type + | | + | arguments to this function are incorrect | = note: expected type `usize` found associated type `<T as Trait>::A` +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- help: consider constraining the associated type `<T as Trait>::A` to `usize` | LL | fn ban<T>(x: T) where T: Trait<A = usize> { @@ -28,10 +42,17 @@ error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:22:9 | LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found associated type + | --- ^^^^^^^^ expected `usize`, found associated type + | | + | arguments to this function are incorrect | = note: expected type `usize` found associated type `<impl Trait as Trait>::A` +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- help: consider constraining the associated type `<impl Trait as Trait>::A` to `usize` | LL | fn foo<'a, T: Trait + 'a>(_: impl Trait, x: impl Trait<A = usize>, _: T) { @@ -41,10 +62,17 @@ error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:26:9 | LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found associated type + | --- ^^^^^^^^ expected `usize`, found associated type + | | + | arguments to this function are incorrect | = note: expected type `usize` found associated type `<T as Trait>::A` +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- help: consider constraining the associated type `<T as Trait>::A` to `usize` | LL | fn bar<T: Trait<A = usize>>(x: T) { @@ -54,10 +82,17 @@ error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:30:9 | LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found associated type + | --- ^^^^^^^^ expected `usize`, found associated type + | | + | arguments to this function are incorrect | = note: expected type `usize` found associated type `<impl Trait<i32> as Trait<i32>>::A` +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- help: consider constraining the associated type `<impl Trait<i32> as Trait<i32>>::A` to `usize` | LL | fn foo2(x: impl Trait<i32, A = usize>) { @@ -67,10 +102,17 @@ error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:34:9 | LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found associated type + | --- ^^^^^^^^ expected `usize`, found associated type + | | + | arguments to this function are incorrect | = note: expected type `usize` found associated type `<T as Trait<i32>>::A` +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- help: consider constraining the associated type `<T as Trait<i32>>::A` to `usize` | LL | fn bar2<T: Trait<i32, A = usize>>(x: T) { @@ -80,10 +122,17 @@ error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:38:9 | LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found associated type + | --- ^^^^^^^^ expected `usize`, found associated type + | | + | arguments to this function are incorrect | = note: expected type `usize` found associated type `<T as Trait>::A` +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- help: consider constraining the associated type `<T as Trait>::A` to `usize` | LL | fn ban<T>(x: T) where T: Trait<A = usize> { diff --git a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr index 943cbcbc81a..7583c875a1a 100644 --- a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr +++ b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr @@ -16,10 +16,17 @@ error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction.rs:14:9 | LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found associated type + | --- ^^^^^^^^ expected `usize`, found associated type + | | + | arguments to this function are incorrect | = note: expected type `usize` found associated type `<impl Trait as Trait>::A` +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- help: consider constraining the associated type `<impl Trait as Trait>::A` to `usize` | LL | fn foo(_: impl Trait, x: impl Trait<A = usize>) { @@ -29,10 +36,17 @@ error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction.rs:18:9 | LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found associated type + | --- ^^^^^^^^ expected `usize`, found associated type + | | + | arguments to this function are incorrect | = note: expected type `usize` found associated type `<T as Trait>::A` +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- help: consider constraining the associated type `<T as Trait>::A` to `usize` | LL | fn bar<T: Trait<A = usize>>(x: T) { @@ -42,10 +56,17 @@ error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction.rs:22:9 | LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found associated type + | --- ^^^^^^^^ expected `usize`, found associated type + | | + | arguments to this function are incorrect | = note: expected type `usize` found associated type `<impl Trait<i32> as Trait<i32>>::A` +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- help: consider constraining the associated type `<impl Trait<i32> as Trait<i32>>::A` to `usize` | LL | fn foo2(x: impl Trait<i32, A = usize>) { @@ -55,7 +76,9 @@ error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction.rs:26:12 | LL | x.funk(3); - | ^ expected associated type, found integer + | ---- ^ expected associated type, found integer + | | + | arguments to this function are incorrect | = note: expected associated type `<T as Trait<i32>>::A` found type `{integer}` @@ -67,6 +90,11 @@ LL | fn func(&self) -> Self::A; LL | fn funk(&self, _: Self::A); LL | fn funq(&self) -> Self::A {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ consider calling `Trait::funq` +note: associated function defined here + --> $DIR/trait-with-missing-associated-type-restriction.rs:9:8 + | +LL | fn funk(&self, _: Self::A); + | ^^^^ help: consider constraining the associated type `<T as Trait<i32>>::A` to `{integer}` | LL | fn bar2<T: Trait<i32, A = {integer}>>(x: T) { @@ -76,10 +104,17 @@ error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction.rs:27:9 | LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found associated type + | --- ^^^^^^^^ expected `usize`, found associated type + | | + | arguments to this function are incorrect | = note: expected type `usize` found associated type `<T as Trait<i32>>::A` +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- help: consider constraining the associated type `<T as Trait<i32>>::A` to `usize` | LL | fn bar2<T: Trait<i32, A = usize>>(x: T) { @@ -91,25 +126,47 @@ error[E0308]: mismatched types LL | fn baz<D: std::fmt::Debug, T: Trait<A = D>>(x: T) { | - this type parameter LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found type parameter `D` + | --- ^^^^^^^^ expected `usize`, found type parameter `D` + | | + | arguments to this function are incorrect | = note: expected type `usize` found type parameter `D` +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction.rs:35:9 | LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found `()` + | --- ^^^^^^^^ expected `usize`, found `()` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction.rs:39:9 | LL | qux(x.func()) - | ^^^^^^^^ expected `usize`, found associated type + | --- ^^^^^^^^ expected `usize`, found associated type + | | + | arguments to this function are incorrect | = note: expected type `usize` found associated type `<T as Trait>::A` +note: function defined here + --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4 + | +LL | fn qux(_: usize) {} + | ^^^ -------- help: consider constraining the associated type `<T as Trait>::A` to `usize` | LL | fn ban<T>(x: T) where T: Trait<A = usize> { diff --git a/src/test/ui/suggestions/use-placement-typeck.fixed b/src/test/ui/suggestions/use-placement-typeck.fixed index 40c55d1dd06..37335da060e 100644 --- a/src/test/ui/suggestions/use-placement-typeck.fixed +++ b/src/test/ui/suggestions/use-placement-typeck.fixed @@ -7,7 +7,6 @@ #![allow(unused)] use m::Foo; - fn main() { let s = m::S; s.abc(); //~ ERROR no method named `abc` diff --git a/src/test/ui/terminal-width/flag-json.rs b/src/test/ui/terminal-width/flag-json.rs index eabdc59dded..3d2530e204b 100644 --- a/src/test/ui/terminal-width/flag-json.rs +++ b/src/test/ui/terminal-width/flag-json.rs @@ -5,5 +5,5 @@ fn main() { let _: () = 42; - //~^ ERROR mismatched types + //~^ ERROR arguments to this function are incorrect } diff --git a/src/test/ui/terr-in-field.stderr b/src/test/ui/terr-in-field.stderr index 5c6859a0efe..d2fda09c076 100644 --- a/src/test/ui/terr-in-field.stderr +++ b/src/test/ui/terr-in-field.stderr @@ -2,7 +2,15 @@ error[E0308]: mismatched types --> $DIR/terr-in-field.rs:13:14 | LL | want_foo(b); - | ^ expected struct `Foo`, found struct `Bar` + | -------- ^ expected struct `Foo`, found struct `Bar` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/terr-in-field.rs:11:4 + | +LL | fn want_foo(f: Foo) {} + | ^^^^^^^^ ------ error: aborting due to previous error diff --git a/src/test/ui/terr-sorts.stderr b/src/test/ui/terr-sorts.stderr index 34d4d9eaded..5a61a2fab12 100644 --- a/src/test/ui/terr-sorts.stderr +++ b/src/test/ui/terr-sorts.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/terr-sorts.rs:10:14 | LL | want_foo(b); - | ^ expected struct `Foo`, found struct `Box` + | -------- ^ expected struct `Foo`, found struct `Box` + | | + | arguments to this function are incorrect | = note: expected struct `Foo` found struct `Box<Foo>` +note: function defined here + --> $DIR/terr-sorts.rs:8:4 + | +LL | fn want_foo(f: Foo) {} + | ^^^^^^^^ ------ help: consider unboxing the value | LL | want_foo(*b); diff --git a/src/test/ui/traits/bound/sugar.stderr b/src/test/ui/traits/bound/sugar.stderr index feb0c73a09d..b67648c7b04 100644 --- a/src/test/ui/traits/bound/sugar.stderr +++ b/src/test/ui/traits/bound/sugar.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/sugar.rs:12:7 | LL | a(x); - | ^ expected trait `Foo + Send`, found trait `Foo + Sync` + | - ^ expected trait `Foo + Send`, found trait `Foo + Sync` + | | + | arguments to this function are incorrect | = note: expected struct `Box<(dyn Foo + Send + 'static)>` found struct `Box<(dyn Foo + Sync + 'static)>` +note: function defined here + --> $DIR/sugar.rs:5:4 + | +LL | fn a(_x: Box<dyn Foo + Send>) { + | ^ ----------------------- error: aborting due to previous error diff --git a/src/test/ui/traits/issue-52893.stderr b/src/test/ui/traits/issue-52893.stderr index bf732e24915..f0c718c7a16 100644 --- a/src/test/ui/traits/issue-52893.stderr +++ b/src/test/ui/traits/issue-52893.stderr @@ -5,10 +5,17 @@ LL | impl<F, Name, P> AddClass<Name, F> for Class<P> | - this type parameter ... LL | builder.push(output); - | ^^^^^^ expected type parameter `F`, found struct `Class` + | ---- ^^^^^^ expected type parameter `F`, found struct `Class` + | | + | arguments to this function are incorrect | - = note: expected type parameter `F` - found struct `Class<P>` + = note: expected type `F` + found struct `Class<P>` +note: associated function defined here + --> $DIR/issue-52893.rs:11:8 + | +LL | fn push(self, other: T) -> Self::PushRes; + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/traits/issue-95311.rs b/src/test/ui/traits/issue-95311.rs new file mode 100644 index 00000000000..9d40d254ad9 --- /dev/null +++ b/src/test/ui/traits/issue-95311.rs @@ -0,0 +1,19 @@ +// check-pass + +// Test to check that pointee trait doesn't let region variables escape into the cache + +#![feature(ptr_metadata)] + +trait Bar: Sized + 'static {} + +struct Foo<B: Bar> { + marker: std::marker::PhantomData<B>, +} + +impl<B: Bar> Foo<B> { + fn foo<T: ?Sized>(value: &T) { + std::ptr::metadata(value); + } +} + +fn main() {} diff --git a/src/test/ui/traits/multidispatch-bad.stderr b/src/test/ui/traits/multidispatch-bad.stderr index 6caa23d8f49..8b6e610067b 100644 --- a/src/test/ui/traits/multidispatch-bad.stderr +++ b/src/test/ui/traits/multidispatch-bad.stderr @@ -2,8 +2,15 @@ error[E0308]: mismatched types --> $DIR/multidispatch-bad.rs:19:17 | LL | test(22i32, 44i32); - | ^^^^^ expected `u32`, found `i32` + | ---- ^^^^^ expected `u32`, found `i32` + | | + | arguments to this function are incorrect | +note: function defined here + --> $DIR/multidispatch-bad.rs:13:4 + | +LL | fn test<T,U>(_: T, _: U) + | ^^^^ ---- ---- help: change the type of the numeric literal from `i32` to `u32` | LL | test(22i32, 44u32); diff --git a/src/test/ui/tuple/tuple-arity-mismatch.stderr b/src/test/ui/tuple/tuple-arity-mismatch.stderr index 10bcedaf4aa..fff7be987f2 100644 --- a/src/test/ui/tuple/tuple-arity-mismatch.stderr +++ b/src/test/ui/tuple/tuple-arity-mismatch.stderr @@ -2,19 +2,33 @@ error[E0308]: mismatched types --> $DIR/tuple-arity-mismatch.rs:6:20 | LL | let y = first ((1,2.0,3)); - | ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements + | ----- ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements + | | + | arguments to this function are incorrect | = note: expected tuple `(isize, f64)` found tuple `(isize, f64, {integer})` +note: function defined here + --> $DIR/tuple-arity-mismatch.rs:3:4 + | +LL | fn first((value, _): (isize, f64)) -> isize { value } + | ^^^^^ ------------------------ error[E0308]: mismatched types --> $DIR/tuple-arity-mismatch.rs:12:20 | LL | let y = first ((1,)); - | ^^^^ expected a tuple with 2 elements, found one with 1 element + | ----- ^^^^ expected a tuple with 2 elements, found one with 1 element + | | + | arguments to this function are incorrect | = note: expected tuple `(isize, f64)` found tuple `(isize,)` +note: function defined here + --> $DIR/tuple-arity-mismatch.rs:3:4 + | +LL | fn first((value, _): (isize, f64)) -> isize { value } + | ^^^^^ ------------------------ error: aborting due to 2 previous errors diff --git a/src/test/ui/tuple/wrong_argument_ice-2.stderr b/src/test/ui/tuple/wrong_argument_ice-2.stderr index ddafc9763e7..c704ae9934b 100644 --- a/src/test/ui/tuple/wrong_argument_ice-2.stderr +++ b/src/test/ui/tuple/wrong_argument_ice-2.stderr @@ -2,7 +2,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/wrong_argument_ice-2.rs:13:5 | LL | test(x.qux(), x.qux()); - | ^^^^ ------- ------- supplied 2 arguments + | ^^^^ | note: function defined here --> $DIR/wrong_argument_ice-2.rs:1:4 diff --git a/src/test/ui/tuple/wrong_argument_ice-3.stderr b/src/test/ui/tuple/wrong_argument_ice-3.stderr index f0d64d2a4e1..6ea6e670fd6 100644 --- a/src/test/ui/tuple/wrong_argument_ice-3.stderr +++ b/src/test/ui/tuple/wrong_argument_ice-3.stderr @@ -2,15 +2,21 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/wrong_argument_ice-3.rs:9:16 | LL | groups.push(new_group, vec![process]); - | ^^^^ --------- ------------- supplied 2 arguments - | | - | expected 1 argument + | ^^^^ --------- ------------- argument unexpected + | | + | expected tuple, found struct `Vec` | + = note: expected tuple `(Vec<String>, Vec<Process>)` + found struct `Vec<String>` note: associated function defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | LL | pub fn push(&mut self, value: T) { | ^^^^ +help: remove the extra argument + | +LL | groups.push({(Vec<String>, Vec<Process>)}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/tuple/wrong_argument_ice-4.stderr b/src/test/ui/tuple/wrong_argument_ice-4.stderr index fef5dca856d..0c25b6801dc 100644 --- a/src/test/ui/tuple/wrong_argument_ice-4.stderr +++ b/src/test/ui/tuple/wrong_argument_ice-4.stderr @@ -3,12 +3,15 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied | LL | (|| {})(|| { | _____^^^^^^^_- - | | | - | | expected 0 arguments LL | | LL | | let b = 1; LL | | }); - | |_____- supplied 1 argument + | |_____- argument unexpected + | +help: remove the extra argument + | +LL | (|| {})(); + | ~~~~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/tuple/wrong_argument_ice.stderr b/src/test/ui/tuple/wrong_argument_ice.stderr index e96a957350b..2b4cb669f5c 100644 --- a/src/test/ui/tuple/wrong_argument_ice.stderr +++ b/src/test/ui/tuple/wrong_argument_ice.stderr @@ -2,7 +2,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/wrong_argument_ice.rs:11:18 | LL | self.acc.push_back(self.current_provides, self.current_requires); - | ^^^^^^^^^ --------------------- --------------------- supplied 2 arguments + | ^^^^^^^^^ | note: associated function defined here --> $SRC_DIR/alloc/src/collections/vec_deque/mod.rs:LL:COL diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr index a384d5f561c..115ecb01376 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr @@ -5,10 +5,17 @@ LL | impl<T> Enum<T> { | - this type parameter LL | fn ts_variant() { LL | Self::TSVariant(()); - | ^^ expected type parameter `T`, found `()` + | --------------- ^^ expected type parameter `T`, found `()` + | | + | arguments to this function are incorrect | = note: expected type parameter `T` found unit type `()` +note: tuple variant defined here + --> $DIR/enum-variant-generic-args.rs:7:16 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^^^^^^ error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:15:27 @@ -29,10 +36,17 @@ LL | impl<T> Enum<T> { | - this type parameter ... LL | Self::<()>::TSVariant(()); - | ^^ expected type parameter `T`, found `()` + | --------------------- ^^ expected type parameter `T`, found `()` + | | + | arguments to this function are incorrect | = note: expected type parameter `T` found unit type `()` +note: tuple variant defined here + --> $DIR/enum-variant-generic-args.rs:7:16 + | +LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant } + | ^^^^^^^^^ error[E0109]: type arguments are not allowed for this type --> $DIR/enum-variant-generic-args.rs:20:16 diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr index 37543c137f6..3fc5a3594d8 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr @@ -2,15 +2,17 @@ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:21:5 | LL | <E>::V(); - | ^^^^^^-- supplied 0 arguments - | | - | expected 1 argument + | ^^^^^^-- an argument of type `u8` is missing | note: tuple variant defined here --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:5:5 | LL | V(u8) | ^ +help: provide the argument + | +LL | <E>::V({u8}); + | ~~~~~~~~~~~~ error[E0308]: mismatched types --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17 diff --git a/src/test/ui/type/type-ascription-instead-of-initializer.stderr b/src/test/ui/type/type-ascription-instead-of-initializer.stderr index e5666d4fe4f..18ed4986f89 100644 --- a/src/test/ui/type/type-ascription-instead-of-initializer.stderr +++ b/src/test/ui/type/type-ascription-instead-of-initializer.stderr @@ -11,15 +11,17 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/type-ascription-instead-of-initializer.rs:2:12 | LL | let x: Vec::with_capacity(10, 20); - | ^^^^^^^^^^^^^^^^^^ -- -- supplied 2 arguments - | | - | expected 1 argument + | ^^^^^^^^^^^^^^^^^^ -- argument unexpected | note: associated function defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | LL | pub fn with_capacity(capacity: usize) -> Self { | ^^^^^^^^^^^^^ +help: remove the extra argument + | +LL | let x: Vec::with_capacity(10); + | ~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 2 previous errors diff --git a/src/test/ui/type/type-mismatch-same-crate-name.stderr b/src/test/ui/type/type-mismatch-same-crate-name.stderr index 49d40ebed13..783f747fa6d 100644 --- a/src/test/ui/type/type-mismatch-same-crate-name.stderr +++ b/src/test/ui/type/type-mismatch-same-crate-name.stderr @@ -2,19 +2,33 @@ error[E0308]: mismatched types --> $DIR/type-mismatch-same-crate-name.rs:16:20 | 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` + | | + | arguments to this function are incorrect | = note: perhaps two different versions of crate `crate_a1` are being used? +note: function defined here + --> $DIR/auxiliary/crate_a1.rs:10:8 + | +LL | pub fn try_foo(x: Foo){} + | ^^^^^^^ error[E0308]: mismatched types --> $DIR/type-mismatch-same-crate-name.rs:20:20 | 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` + | | + | arguments to this function are incorrect | = note: expected struct `Box<(dyn main::a::Bar + 'static)>` found struct `Box<dyn main::a::Bar>` = note: perhaps two different versions of crate `crate_a1` are being used? +note: function defined here + --> $DIR/auxiliary/crate_a1.rs:11:8 + | +LL | pub fn try_bar(x: Box<Bar>){} + | ^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/type/type-mismatch.stderr b/src/test/ui/type/type-mismatch.stderr index 24c71c63103..6c187bad072 100644 --- a/src/test/ui/type/type-mismatch.stderr +++ b/src/test/ui/type/type-mismatch.stderr @@ -2,418 +2,749 @@ error[E0308]: mismatched types --> $DIR/type-mismatch.rs:17:17 | LL | want::<foo>(f); - | ^ expected struct `foo`, found `usize` + | ----------- ^ expected struct `foo`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:18:17 | LL | want::<bar>(f); - | ^ expected struct `bar`, found `usize` + | ----------- ^ expected struct `bar`, found `usize` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:19:24 | LL | want::<Foo<usize>>(f); - | ^ expected struct `Foo`, found `usize` + | ------------------ ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<usize>` found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:20:27 | LL | want::<Foo<usize, B>>(f); - | ^ expected struct `Foo`, found `usize` + | --------------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<usize, B>` found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:21:22 | LL | want::<Foo<foo>>(f); - | ^ expected struct `Foo`, found `usize` + | ---------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<foo>` found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:22:25 | LL | want::<Foo<foo, B>>(f); - | ^ expected struct `Foo`, found `usize` + | ------------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<foo, B>` found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:23:22 | LL | want::<Foo<bar>>(f); - | ^ expected struct `Foo`, found `usize` + | ---------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<bar>` found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:24:25 | LL | want::<Foo<bar, B>>(f); - | ^ expected struct `Foo`, found `usize` + | ------------------- ^ expected struct `Foo`, found `usize` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<bar, B>` found type `usize` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:28:19 | LL | want::<usize>(f); - | ^ expected `usize`, found struct `foo` + | ------------- ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:29:17 | LL | want::<bar>(f); - | ^ expected struct `bar`, found struct `foo` + | ----------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:30:24 | LL | want::<Foo<usize>>(f); - | ^ expected struct `Foo`, found struct `foo` + | ------------------ ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<usize>` found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:31:27 | LL | want::<Foo<usize, B>>(f); - | ^ expected struct `Foo`, found struct `foo` + | --------------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<usize, B>` found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:32:22 | LL | want::<Foo<foo>>(f); - | ^ expected struct `Foo`, found struct `foo` + | ---------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<foo>` found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:33:25 | LL | want::<Foo<foo, B>>(f); - | ^ expected struct `Foo`, found struct `foo` + | ------------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<foo, B>` found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:34:22 | LL | want::<Foo<bar>>(f); - | ^ expected struct `Foo`, found struct `foo` + | ---------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<bar>` found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:35:25 | LL | want::<Foo<bar, B>>(f); - | ^ expected struct `Foo`, found struct `foo` + | ------------------- ^ expected struct `Foo`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<bar, B>` found struct `foo` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:39:19 | LL | want::<usize>(f); - | ^ expected `usize`, found struct `Foo` + | ------------- ^ expected `usize`, found struct `Foo` + | | + | arguments to this function are incorrect | = note: expected type `usize` found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:40:17 | LL | want::<foo>(f); - | ^ expected struct `foo`, found struct `Foo` + | ----------- ^ expected struct `foo`, found struct `Foo` + | | + | arguments to this function are incorrect | = note: expected struct `foo` found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:41:17 | LL | want::<bar>(f); - | ^ expected struct `bar`, found struct `Foo` + | ----------- ^ expected struct `bar`, found struct `Foo` + | | + | arguments to this function are incorrect | = note: expected struct `bar` found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:42:24 | LL | want::<Foo<usize>>(f); - | ^ expected `usize`, found struct `foo` + | ------------------ ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<usize>` found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:43:27 | LL | want::<Foo<usize, B>>(f); - | ^ expected `usize`, found struct `foo` + | --------------------- ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<usize, B>` found struct `Foo<foo, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:44:25 | LL | want::<Foo<foo, B>>(f); - | ^ expected struct `B`, found struct `A` + | ------------------- ^ expected struct `B`, found struct `A` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<_, B>` found struct `Foo<_, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:45:22 | LL | want::<Foo<bar>>(f); - | ^ expected struct `bar`, found struct `foo` + | ---------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<bar>` found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:46:25 | LL | want::<Foo<bar, B>>(f); - | ^ expected struct `bar`, found struct `foo` + | ------------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<bar, B>` found struct `Foo<foo, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:47:23 | LL | want::<&Foo<foo>>(f); - | ^ - | | - | expected `&Foo<foo>`, found struct `Foo` - | help: consider borrowing here: `&f` + | ----------------- ^ + | | | + | | expected `&Foo<foo>`, found struct `Foo` + | | help: consider borrowing here: `&f` + | arguments to this function are incorrect | = note: expected reference `&Foo<foo>` found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:48:26 | LL | want::<&Foo<foo, B>>(f); - | ^ expected `&Foo<foo, B>`, found struct `Foo` + | -------------------- ^ expected `&Foo<foo, B>`, found struct `Foo` + | | + | arguments to this function are incorrect | = note: expected reference `&Foo<foo, B>` found struct `Foo<foo>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:52:19 | LL | want::<usize>(f); - | ^ expected `usize`, found struct `Foo` + | ------------- ^ expected `usize`, found struct `Foo` + | | + | arguments to this function are incorrect | = note: expected type `usize` found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:53:17 | LL | want::<foo>(f); - | ^ expected struct `foo`, found struct `Foo` + | ----------- ^ expected struct `foo`, found struct `Foo` + | | + | arguments to this function are incorrect | = note: expected struct `foo` found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:54:17 | LL | want::<bar>(f); - | ^ expected struct `bar`, found struct `Foo` + | ----------- ^ expected struct `bar`, found struct `Foo` + | | + | arguments to this function are incorrect | = note: expected struct `bar` found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:55:24 | LL | want::<Foo<usize>>(f); - | ^ expected `usize`, found struct `foo` + | ------------------ ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<usize, A>` found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:56:27 | LL | want::<Foo<usize, B>>(f); - | ^ expected `usize`, found struct `foo` + | --------------------- ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<usize, _>` found struct `Foo<foo, _>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:57:22 | LL | want::<Foo<foo>>(f); - | ^ expected struct `A`, found struct `B` + | ---------------- ^ expected struct `A`, found struct `B` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<_, A>` found struct `Foo<_, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:58:22 | LL | want::<Foo<bar>>(f); - | ^ expected struct `bar`, found struct `foo` + | ---------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<bar, A>` found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:59:25 | LL | want::<Foo<bar, B>>(f); - | ^ expected struct `bar`, found struct `foo` + | ------------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<bar, _>` found struct `Foo<foo, _>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:60:23 | LL | want::<&Foo<foo>>(f); - | ^ expected `&Foo<foo>`, found struct `Foo` + | ----------------- ^ expected `&Foo<foo>`, found struct `Foo` + | | + | arguments to this function are incorrect | = note: expected reference `&Foo<foo>` found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:61:26 | LL | want::<&Foo<foo, B>>(f); - | ^ - | | - | expected `&Foo<foo, B>`, found struct `Foo` - | help: consider borrowing here: `&f` + | -------------------- ^ + | | | + | | expected `&Foo<foo, B>`, found struct `Foo` + | | help: consider borrowing here: `&f` + | arguments to this function are incorrect | = note: expected reference `&Foo<foo, B>` found struct `Foo<foo, B>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:65:19 | LL | want::<usize>(f); - | ^ expected `usize`, found struct `Foo` + | ------------- ^ expected `usize`, found struct `Foo` + | | + | arguments to this function are incorrect | = note: expected type `usize` found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:66:17 | LL | want::<foo>(f); - | ^ expected struct `foo`, found struct `Foo` + | ----------- ^ expected struct `foo`, found struct `Foo` + | | + | arguments to this function are incorrect | = note: expected struct `foo` found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:67:17 | LL | want::<bar>(f); - | ^ expected struct `bar`, found struct `Foo` + | ----------- ^ expected struct `bar`, found struct `Foo` + | | + | arguments to this function are incorrect | = note: expected struct `bar` found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:68:24 | LL | want::<Foo<usize>>(f); - | ^ expected `usize`, found struct `foo` + | ------------------ ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<usize, A, B>` found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:69:27 | LL | want::<Foo<usize, B>>(f); - | ^ expected `usize`, found struct `foo` + | --------------------- ^ expected `usize`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<usize, _, B>` found struct `Foo<foo, _, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:70:22 | LL | want::<Foo<foo>>(f); - | ^ expected struct `A`, found struct `B` + | ---------------- ^ expected struct `A`, found struct `B` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<_, A, B>` found struct `Foo<_, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:71:25 | LL | want::<Foo<foo, B>>(f); - | ^ expected struct `B`, found struct `A` + | ------------------- ^ expected struct `B`, found struct `A` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<_, _, B>` found struct `Foo<_, _, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:72:22 | LL | want::<Foo<bar>>(f); - | ^ expected struct `bar`, found struct `foo` + | ---------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<bar, A, B>` found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:73:25 | LL | want::<Foo<bar, B>>(f); - | ^ expected struct `bar`, found struct `foo` + | ------------------- ^ expected struct `bar`, found struct `foo` + | | + | arguments to this function are incorrect | = note: expected struct `Foo<bar, _, B>` found struct `Foo<foo, _, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:74:23 | LL | want::<&Foo<foo>>(f); - | ^ expected `&Foo<foo>`, found struct `Foo` + | ----------------- ^ expected `&Foo<foo>`, found struct `Foo` + | | + | arguments to this function are incorrect | = note: expected reference `&Foo<foo>` found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error[E0308]: mismatched types --> $DIR/type-mismatch.rs:75:26 | LL | want::<&Foo<foo, B>>(f); - | ^ expected `&Foo<foo, B>`, found struct `Foo` + | -------------------- ^ expected `&Foo<foo, B>`, found struct `Foo` + | | + | arguments to this function are incorrect | = note: expected reference `&Foo<foo, B>` found struct `Foo<foo, B, A>` +note: function defined here + --> $DIR/type-mismatch.rs:14:4 + | +LL | fn want<T>(t: T) {} + | ^^^^ ---- error: aborting due to 47 previous errors diff --git a/src/test/ui/typeck/autoderef-with-param-env-error.rs b/src/test/ui/typeck/autoderef-with-param-env-error.rs new file mode 100644 index 00000000000..ec96c61c63e --- /dev/null +++ b/src/test/ui/typeck/autoderef-with-param-env-error.rs @@ -0,0 +1,9 @@ +fn foo() +where + T: Send, + //~^ cannot find type `T` in this scope +{ + let s = "abc".to_string(); +} + +fn main() {} diff --git a/src/test/ui/typeck/autoderef-with-param-env-error.stderr b/src/test/ui/typeck/autoderef-with-param-env-error.stderr new file mode 100644 index 00000000000..cde800336dd --- /dev/null +++ b/src/test/ui/typeck/autoderef-with-param-env-error.stderr @@ -0,0 +1,12 @@ +error[E0412]: cannot find type `T` in this scope + --> $DIR/autoderef-with-param-env-error.rs:3:5 + | +LL | fn foo() + | - help: you might be missing a type parameter: `<T>` +LL | where +LL | T: Send, + | ^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/typeck/issue-46112.stderr b/src/test/ui/typeck/issue-46112.stderr index 39bff88e7f8..93461507501 100644 --- a/src/test/ui/typeck/issue-46112.stderr +++ b/src/test/ui/typeck/issue-46112.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/issue-46112.rs:9:21 | LL | fn main() { test(Ok(())); } - | ^^ expected enum `Option`, found `()` + | -- ^^ expected enum `Option`, found `()` + | | + | arguments to this enum variant are incorrect | = note: expected enum `Option<()>` found unit type `()` diff --git a/src/test/ui/typeck/issue-84768.stderr b/src/test/ui/typeck/issue-84768.stderr index 0a79d539ea9..04dc0e36520 100644 --- a/src/test/ui/typeck/issue-84768.stderr +++ b/src/test/ui/typeck/issue-84768.stderr @@ -8,10 +8,17 @@ error[E0308]: mismatched types --> $DIR/issue-84768.rs:7:42 | LL | <F as FnOnce(&mut u8)>::call_once(f, 1) - | ^ expected tuple, found integer + | --------------------------------- ^ expected tuple, found integer + | | + | arguments to this function are incorrect | = note: expected tuple `(&mut u8,)` found type `{integer}` +note: associated function defined here + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; + | ^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/typeck/issue-89856.stderr b/src/test/ui/typeck/issue-89856.stderr index 4cb46a34a07..5fa1ae1a54f 100644 --- a/src/test/ui/typeck/issue-89856.stderr +++ b/src/test/ui/typeck/issue-89856.stderr @@ -2,10 +2,17 @@ error[E0308]: mismatched types --> $DIR/issue-89856.rs:6:20 | LL | take_str_maybe(option); - | ^^^^^^ expected `str`, found struct `String` + | -------------- ^^^^^^ expected `str`, found struct `String` + | | + | arguments to this function are incorrect | = note: expected enum `Option<&str>` found enum `Option<&String>` +note: function defined here + --> $DIR/issue-89856.rs:1:4 + | +LL | fn take_str_maybe(x: Option<&str>) -> Option<&str> { None } + | ^^^^^^^^^^^^^^ --------------- help: try converting the passed type into a `&str` | LL | take_str_maybe(option.map(|x| &**x)); diff --git a/src/test/ui/typeck/struct-enum-wrong-args.stderr b/src/test/ui/typeck/struct-enum-wrong-args.stderr index 6e99feed33f..721b2c821ef 100644 --- a/src/test/ui/typeck/struct-enum-wrong-args.stderr +++ b/src/test/ui/typeck/struct-enum-wrong-args.stderr @@ -2,95 +2,116 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:6:13 | LL | let _ = Some(3, 2); - | ^^^^ - - supplied 2 arguments - | | - | expected 1 argument + | ^^^^ - argument unexpected + | +help: remove the extra argument + | +LL | let _ = Some(3); + | ~~~~~~~ error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:7:13 | LL | let _ = Ok(3, 6, 2); - | ^^ - - - supplied 3 arguments - | | - | expected 1 argument + | ^^ - - argument unexpected + | | + | argument unexpected + | +help: remove the extra arguments + | +LL | let _ = Ok(3); + | ~~~~~ error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:8:13 | LL | let _ = Ok(); - | ^^-- supplied 0 arguments - | | - | expected 1 argument + | ^^-- an argument is missing + | +help: provide the argument + | +LL | let _ = Ok({_}); + | ~~~~~~~ error[E0061]: this struct takes 1 argument but 0 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:9:13 | LL | let _ = Wrapper(); - | ^^^^^^^-- supplied 0 arguments - | | - | expected 1 argument + | ^^^^^^^-- an argument of type `i32` is missing | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:2:8 | LL | struct Wrapper(i32); | ^^^^^^^ +help: provide the argument + | +LL | let _ = Wrapper({i32}); + | ~~~~~~~~~~~~~~ error[E0061]: this struct takes 1 argument but 2 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:10:13 | LL | let _ = Wrapper(5, 2); - | ^^^^^^^ - - supplied 2 arguments - | | - | expected 1 argument + | ^^^^^^^ - argument unexpected | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:2:8 | LL | struct Wrapper(i32); | ^^^^^^^ +help: remove the extra argument + | +LL | let _ = Wrapper(5); + | ~~~~~~~~~~ error[E0061]: this struct takes 2 arguments but 0 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:11:13 | LL | let _ = DoubleWrapper(); - | ^^^^^^^^^^^^^-- supplied 0 arguments - | | - | expected 2 arguments + | ^^^^^^^^^^^^^-- two arguments of type `i32` and `i32` are missing | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:3:8 | LL | struct DoubleWrapper(i32, i32); | ^^^^^^^^^^^^^ +help: provide the arguments + | +LL | let _ = DoubleWrapper({i32}, {i32}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0061]: this struct takes 2 arguments but 1 argument was supplied --> $DIR/struct-enum-wrong-args.rs:12:13 | LL | let _ = DoubleWrapper(5); - | ^^^^^^^^^^^^^ - supplied 1 argument - | | - | expected 2 arguments + | ^^^^^^^^^^^^^--- an argument of type `i32` is missing | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:3:8 | LL | struct DoubleWrapper(i32, i32); | ^^^^^^^^^^^^^ +help: provide the argument + | +LL | let _ = DoubleWrapper(5, {i32}); + | ~~~~~~~~~~~~~~~~~~~~~~~ error[E0061]: this struct takes 2 arguments but 3 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:13:13 | LL | let _ = DoubleWrapper(5, 2, 7); - | ^^^^^^^^^^^^^ - - - supplied 3 arguments - | | - | expected 2 arguments + | ^^^^^^^^^^^^^ - argument unexpected | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:3:8 | LL | struct DoubleWrapper(i32, i32); | ^^^^^^^^^^^^^ +help: remove the extra argument + | +LL | let _ = DoubleWrapper(5, 2); + | ~~~~~~~~~~~~~~~~~~~ error: aborting due to 8 previous errors diff --git a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr index 74766d9fdd1..c6f9b3661a2 100644 --- a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr +++ b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr @@ -20,8 +20,15 @@ error[E0308]: mismatched types --> $DIR/ufcs-qpath-self-mismatch.rs:6:28 | LL | <i32 as Add<i32>>::add(1u32, 2); - | ^^^^ expected `i32`, found `u32` + | ---------------------- ^^^^ expected `i32`, found `u32` + | | + | arguments to this function are incorrect | +note: associated function defined here + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | fn add(self, rhs: Rhs) -> Self::Output; + | ^^^ help: change the type of the numeric literal from `u32` to `i32` | LL | <i32 as Add<i32>>::add(1i32, 2); @@ -31,8 +38,15 @@ error[E0308]: mismatched types --> $DIR/ufcs-qpath-self-mismatch.rs:8:31 | LL | <i32 as Add<i32>>::add(1, 2u32); - | ^^^^ expected `i32`, found `u32` + | ---------------------- ^^^^ expected `i32`, found `u32` + | | + | arguments to this function are incorrect + | +note: associated function defined here + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | +LL | fn add(self, rhs: Rhs) -> Self::Output; + | ^^^ help: change the type of the numeric literal from `u32` to `i32` | LL | <i32 as Add<i32>>::add(1, 2i32); diff --git a/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr b/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr index f791ea62ceb..ea1ca380b1c 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/unboxed-closures-type-mismatch.rs:5:15 | LL | let z = f(1_usize, 2); - | ^^^^^^^ expected `isize`, found `usize` + | - ^^^^^^^ expected `isize`, found `usize` + | | + | arguments to this function are incorrect | help: change the type of the numeric literal from `usize` to `isize` | diff --git a/src/test/ui/unterminated-nested-comment.rs b/src/test/ui/unterminated-nested-comment.rs new file mode 100644 index 00000000000..db5f2f3ba13 --- /dev/null +++ b/src/test/ui/unterminated-nested-comment.rs @@ -0,0 +1,4 @@ +/* //~ ERROR E0758 +/* */ +/* +*/ diff --git a/src/test/ui/unterminated-nested-comment.stderr b/src/test/ui/unterminated-nested-comment.stderr new file mode 100644 index 00000000000..3653e76c9cb --- /dev/null +++ b/src/test/ui/unterminated-nested-comment.stderr @@ -0,0 +1,21 @@ +error[E0758]: unterminated block comment + --> $DIR/unterminated-nested-comment.rs:1:1 + | +LL | /* + | ^- + | | + | _unterminated block comment + | | +LL | | /* */ +LL | | /* + | | -- + | | | + | | ...as last nested comment starts here, maybe you want to close this instead? +LL | | */ + | |_--^ + | | + | ...and last nested comment terminates here. + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0758`. diff --git a/src/test/ui/use/use-super-global-path.rs b/src/test/ui/use/use-super-global-path.rs index 27a4a653b49..64bfd14b7e7 100644 --- a/src/test/ui/use/use-super-global-path.rs +++ b/src/test/ui/use/use-super-global-path.rs @@ -9,7 +9,7 @@ mod foo { pub fn g() { use ::super::main; //~ ERROR global paths cannot start with `super` - main(); //~ ERROR cannot find function `main` in this scope + main(); } } diff --git a/src/test/ui/use/use-super-global-path.stderr b/src/test/ui/use/use-super-global-path.stderr index edde26c1fc1..7014a12e9dd 100644 --- a/src/test/ui/use/use-super-global-path.stderr +++ b/src/test/ui/use/use-super-global-path.stderr @@ -16,18 +16,6 @@ error[E0433]: failed to resolve: global paths cannot start with `super` LL | use ::super::main; | ^^^^^ global paths cannot start with `super` -error[E0425]: cannot find function `main` in this scope - --> $DIR/use-super-global-path.rs:12:9 - | -LL | main(); - | ^^^^ not found in this scope - | -help: consider importing this function - | -LL | use main; - | - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0425, E0433. -For more information about an error, try `rustc --explain E0425`. +For more information about this error, try `rustc --explain E0433`. diff --git a/src/tools/cargo b/src/tools/cargo -Subproject e2e2dddebe66dfc1403a312653557e332445308 +Subproject dba5baf4345858c591517b24801902a062c399f diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs index 72e86804ed2..6ed141fa4a5 100644 --- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs @@ -59,7 +59,7 @@ pub(super) fn check<'tcx>( if let Some(indexed_extent) = indexed_extent { let parent_def_id = cx.tcx.hir().get_parent_item(expr.hir_id); let region_scope_tree = cx.tcx.region_scope_tree(parent_def_id); - let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id); + let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id).unwrap(); if region_scope_tree.is_subscope_of(indexed_extent, pat_extent) { return; } @@ -262,7 +262,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> { match res { Res::Local(hir_id) => { let parent_def_id = self.cx.tcx.hir().get_parent_item(expr.hir_id); - let extent = self.cx.tcx.region_scope_tree(parent_def_id).var_scope(hir_id.local_id); + let extent = self.cx.tcx.region_scope_tree(parent_def_id).var_scope(hir_id.local_id).unwrap(); if index_used_directly { self.indexed_directly.insert( seqvar.segments[0].ident.name, diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs index a0b2302662e..9ba9642fcc8 100644 --- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs @@ -169,13 +169,14 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult { .iter() .map(|(o, _)| match o { InlineAsmOperand::In { expr, .. } - | InlineAsmOperand::InOut { expr, .. } - | InlineAsmOperand::Sym { expr } => never_loop_expr(expr, main_loop_id), + | InlineAsmOperand::InOut { expr, .. } => never_loop_expr(expr, main_loop_id), InlineAsmOperand::Out { expr, .. } => never_loop_expr_all(&mut expr.iter(), main_loop_id), InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => { never_loop_expr_all(&mut once(in_expr).chain(out_expr.iter()), main_loop_id) }, - InlineAsmOperand::Const { .. } => NeverLoopResult::Otherwise, + InlineAsmOperand::Const { .. } + | InlineAsmOperand::SymFn { .. } + | InlineAsmOperand::SymStatic { .. } => NeverLoopResult::Otherwise, }) .fold(NeverLoopResult::Otherwise, combine_both), ExprKind::Struct(_, _, None) diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index 11882585044..1ab7f52110c 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -160,8 +160,8 @@ impl<'tcx> LateLintPass<'tcx> for Shadow { fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool { let scope_tree = cx.tcx.region_scope_tree(owner.to_def_id()); - let first_scope = scope_tree.var_scope(first); - let second_scope = scope_tree.var_scope(second); + let first_scope = scope_tree.var_scope(first).unwrap(); + let second_scope = scope_tree.var_scope(second).unwrap(); scope_tree.is_subscope_of(second_scope, first_scope) } diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs index dc48ea3f4f9..a04288e0a41 100644 --- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs @@ -281,8 +281,9 @@ fn print_expr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, indent: usize) { for (op, _op_sp) in asm.operands { match op { hir::InlineAsmOperand::In { expr, .. } - | hir::InlineAsmOperand::InOut { expr, .. } - | hir::InlineAsmOperand::Sym { expr } => print_expr(cx, expr, indent + 1), + | hir::InlineAsmOperand::InOut { expr, .. } => { + print_expr(cx, expr, indent + 1); + } hir::InlineAsmOperand::Out { expr, .. } => { if let Some(expr) = expr { print_expr(cx, expr, indent + 1); @@ -294,10 +295,26 @@ fn print_expr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, indent: usize) { print_expr(cx, out_expr, indent + 1); } }, - hir::InlineAsmOperand::Const { anon_const } => { + hir::InlineAsmOperand::Const { anon_const } + | hir::InlineAsmOperand::SymFn { anon_const } => { println!("{}anon_const:", ind); print_expr(cx, &cx.tcx.hir().body(anon_const.body).value, indent + 1); }, + hir::InlineAsmOperand::SymStatic { path, .. } => { + match path { + hir::QPath::Resolved(ref ty, path) => { + println!("{}Resolved Path, {:?}", ind, ty); + println!("{}path: {:?}", ind, path); + }, + hir::QPath::TypeRelative(ty, seg) => { + println!("{}Relative Path, {:?}", ind, ty); + println!("{}seg: {:?}", ind, seg); + }, + hir::QPath::LangItem(lang_item, ..) => { + println!("{}Lang Item Path, {:?}", ind, lang_item.name()); + }, + } + } } } }, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 00594f4d42a..c05317f59b7 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -675,7 +675,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } }, InlineAsmOperand::Const { anon_const } => self.hash_body(anon_const.body), - InlineAsmOperand::Sym { expr } => self.hash_expr(expr), + InlineAsmOperand::SymFn { anon_const } => self.hash_body(anon_const.body), + InlineAsmOperand::SymStatic { path, def_id: _ } => self.hash_qpath(path), } } }, diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs index 79e6e92dc0a..e5fa6deefc5 100644 --- a/src/tools/clippy/clippy_utils/src/paths.rs +++ b/src/tools/clippy/clippy_utils/src/paths.rs @@ -23,7 +23,7 @@ pub const BTREEMAP_ENTRY: [&str; 6] = ["alloc", "collections", "btree", "map", " pub const BTREEMAP_INSERT: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "insert"]; pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"]; pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"]; -pub const CSTRING_AS_C_STR: [&str; 5] = ["std", "ffi", "c_str", "CString", "as_c_str"]; +pub const CSTRING_AS_C_STR: [&str; 5] = ["alloc", "ffi", "c_str", "CString", "as_c_str"]; pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"]; pub const DEREF_MUT_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "DerefMut", "deref_mut"]; /// Preferably use the diagnostic item `sym::deref_method` where possible diff --git a/src/tools/rustfmt/src/bin/main.rs b/src/tools/rustfmt/src/bin/main.rs index ad10b9ede60..8e871e61f26 100644 --- a/src/tools/rustfmt/src/bin/main.rs +++ b/src/tools/rustfmt/src/bin/main.rs @@ -693,6 +693,7 @@ fn edition_from_edition_str(edition_str: &str) -> Result<Edition> { "2015" => Ok(Edition::Edition2015), "2018" => Ok(Edition::Edition2018), "2021" => Ok(Edition::Edition2021), + "2024" => Ok(Edition::Edition2024), _ => Err(format_err!("Invalid value for `--edition`")), } } diff --git a/src/tools/rustfmt/src/config/options.rs b/src/tools/rustfmt/src/config/options.rs index d857c29be29..257a17b2703 100644 --- a/src/tools/rustfmt/src/config/options.rs +++ b/src/tools/rustfmt/src/config/options.rs @@ -423,6 +423,10 @@ pub enum Edition { #[doc_hint = "2021"] /// Edition 2021. Edition2021, + #[value = "2024"] + #[doc_hint = "2024"] + /// Edition 2024. + Edition2024, } impl Default for Edition { @@ -437,6 +441,7 @@ impl From<Edition> for rustc_span::edition::Edition { Edition::Edition2015 => Self::Edition2015, Edition::Edition2018 => Self::Edition2018, Edition::Edition2021 => Self::Edition2021, + Edition::Edition2024 => Self::Edition2024, } } } |
