diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index f71bc586b4847..25209e20e9939 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -14,7 +14,7 @@ use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable}; use rustc_mir_dataflow::impls::MaybeStorageLive; use rustc_mir_dataflow::storage::AlwaysLiveLocals; use rustc_mir_dataflow::{Analysis, ResultsCursor}; -use rustc_target::abi::Size; +use rustc_target::abi::{Size, VariantIdx}; #[derive(Copy, Clone, Debug)] enum EdgeKind { @@ -244,6 +244,60 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.fail(location, format!("bad index ({:?} != usize)", index_ty)) } } + if let ProjectionElem::Field(f, ty) = elem { + let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) }; + let parent_ty = parent.ty(&self.body.local_decls, self.tcx); + let fail_out_of_bounds = |this: &Self, location| { + this.fail(location, format!("Out of bounds field {:?} for {:?}", f, parent_ty)); + }; + let check_equal = |this: &Self, location, f_ty| { + if !this.mir_assign_valid_types(ty, f_ty) { + this.fail( + location, + format!( + "Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is {:?}", + parent, f, ty, f_ty + ) + ) + } + }; + match parent_ty.ty.kind() { + ty::Tuple(fields) => { + let Some(f_ty) = fields.get(f.as_usize()) else { + fail_out_of_bounds(self, location); + return; + }; + check_equal(self, location, *f_ty); + } + ty::Adt(adt_def, substs) => { + let var = parent_ty.variant_index.unwrap_or(VariantIdx::from_u32(0)); + let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else { + fail_out_of_bounds(self, location); + return; + }; + check_equal(self, location, field.ty(self.tcx, substs)); + } + ty::Closure(_, substs) => { + let substs = substs.as_closure(); + let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else { + fail_out_of_bounds(self, location); + return; + }; + check_equal(self, location, f_ty); + } + ty::Generator(_, substs, _) => { + let substs = substs.as_generator(); + let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else { + fail_out_of_bounds(self, location); + return; + }; + check_equal(self, location, f_ty); + } + _ => { + self.fail(location, format!("{:?} does not have fields", parent_ty.ty)); + } + } + } self.super_projection_elem(local, proj_base, elem, context, location); } @@ -291,7 +345,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty::Array(..) | ty::Slice(..) ); } - Rvalue::BinaryOp(op, vals) | Rvalue::CheckedBinaryOp(op, vals) => { + Rvalue::BinaryOp(op, vals) => { use BinOp::*; let a = vals.0.ty(&self.body.local_decls, self.tcx); let b = vals.1.ty(&self.body.local_decls, self.tcx); @@ -355,17 +409,55 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { for x in [a, b] { check_kinds!( x, - "Cannot perform op on type {:?}", + "Cannot perform arithmetic on type {:?}", ty::Uint(..) | ty::Int(..) | ty::Float(..) ) } if a != b { self.fail( location, - format!("Cannot perform op on unequal types {:?} and {:?}", a, b), + format!( + "Cannot perform arithmetic on unequal types {:?} and {:?}", + a, b + ), + ); + } + } + } + } + Rvalue::CheckedBinaryOp(op, vals) => { + use BinOp::*; + let a = vals.0.ty(&self.body.local_decls, self.tcx); + let b = vals.1.ty(&self.body.local_decls, self.tcx); + match op { + Add | Sub | Mul => { + for x in [a, b] { + check_kinds!( + x, + "Cannot perform checked arithmetic on type {:?}", + ty::Uint(..) | ty::Int(..) + ) + } + if a != b { + self.fail( + location, + format!( + "Cannot perform checked arithmetic on unequal types {:?} and {:?}", + a, b + ), ); } } + Shl | Shr => { + for x in [a, b] { + check_kinds!( + x, + "Cannot perform checked shift on non-integer type {:?}", + ty::Uint(..) | ty::Int(..) + ) + } + } + _ => self.fail(location, format!("There is no checked version of {:?}", op)), } } Rvalue::UnaryOp(op, operand) => { diff --git a/compiler/rustc_error_messages/locales/en-US/typeck.ftl b/compiler/rustc_error_messages/locales/en-US/typeck.ftl index 6a3235fc7728c..aef18fcafaa05 100644 --- a/compiler/rustc_error_messages/locales/en-US/typeck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/typeck.ftl @@ -90,3 +90,14 @@ typeck-add-return-type-missing-here = a return type might be missing here typeck-expected-default-return-type = expected `()` because of default return type typeck-expected-return-type = expected `{$expected}` because of return type + +typeck-unconstrained-opaque-type = unconstrained opaque type + .note = `{$name}` must be used in combination with a concrete type within the same module + +typeck-explicit-generic-args-with-impl-trait = + cannot provide explicit generic arguments when `impl Trait` is used in argument position + .label = explicit generic argument not allowed + .note = see issue #83701 for more information + +typeck-explicit-generic-args-with-impl-trait-feature = + add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index f83fa68ced00d..21914dd7a8c7d 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -426,6 +426,13 @@ struct HandlerInner { future_breakage_diagnostics: Vec, + /// The [`unstable_expect_diagnostics`] should be empty when this struct is + /// dropped. However, it can have values if the compilation is stopped early + /// or is only partially executed. To avoid ICEs, like in rust#94953 we only + /// check if [`unstable_expect_diagnostics`] is empty, if the expectation ids + /// have been converted. + check_unstable_expect_diagnostics: bool, + /// Expected [`Diagnostic`]s store a [`LintExpectationId`] as part of /// the lint level. [`LintExpectationId`]s created early during the compilation /// (before `HirId`s have been defined) are not stable and can therefore not be @@ -497,10 +504,12 @@ impl Drop for HandlerInner { ); } - assert!( - self.unstable_expect_diagnostics.is_empty(), - "all diagnostics with unstable expectations should have been converted", - ); + if self.check_unstable_expect_diagnostics { + assert!( + self.unstable_expect_diagnostics.is_empty(), + "all diagnostics with unstable expectations should have been converted", + ); + } } } @@ -574,6 +583,7 @@ impl Handler { emitted_diagnostics: Default::default(), stashed_diagnostics: Default::default(), future_breakage_diagnostics: Vec::new(), + check_unstable_expect_diagnostics: false, unstable_expect_diagnostics: Vec::new(), fulfilled_expectations: Default::default(), }), @@ -988,12 +998,13 @@ impl Handler { &self, unstable_to_stable: &FxHashMap, ) { - let diags = std::mem::take(&mut self.inner.borrow_mut().unstable_expect_diagnostics); + let mut inner = self.inner.borrow_mut(); + let diags = std::mem::take(&mut inner.unstable_expect_diagnostics); + inner.check_unstable_expect_diagnostics = true; if diags.is_empty() { return; } - let mut inner = self.inner.borrow_mut(); for mut diag in diags.into_iter() { diag.update_unstable_expectation_id(unstable_to_stable); diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index ccd860ce2428a..af81f5cde2c41 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1584,9 +1584,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { Variable(ty::error::ExpectedFound>), Fixed(&'static str), } - let (expected_found, exp_found, is_simple_error) = match values { - None => (None, Mismatch::Fixed("type"), false), + let (expected_found, exp_found, is_simple_error, values) = match values { + None => (None, Mismatch::Fixed("type"), false, None), Some(values) => { + let values = self.resolve_vars_if_possible(values); let (is_simple_error, exp_found) = match values { ValuePairs::Terms(infer::ExpectedFound { expected: ty::Term::Ty(expected), @@ -1614,7 +1615,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { return; } }; - (vals, exp_found, is_simple_error) + (vals, exp_found, is_simple_error, Some(values)) } }; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 08987dff660a4..00119267e8561 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1009,6 +1009,10 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { }); } ); + + // This check has to be run after all lints are done processing. We don't + // define a lint filter, as all lint checks should have finished at this point. + sess.time("check_lint_expectations", || tcx.check_expectations(None)); }); Ok(()) diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index 67f5aa0540fbe..dc48ac0a618e7 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -1,10 +1,16 @@ use crate::builtin; use rustc_hir::HirId; +use rustc_middle::ty::query::Providers; use rustc_middle::{lint::LintExpectation, ty::TyCtxt}; use rustc_session::lint::LintExpectationId; use rustc_span::symbol::sym; +use rustc_span::Symbol; -pub fn check_expectations(tcx: TyCtxt<'_>) { +pub(crate) fn provide(providers: &mut Providers) { + *providers = Providers { check_expectations, ..*providers }; +} + +fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option) { if !tcx.sess.features_untracked().enabled(sym::lint_reasons) { return; } @@ -13,7 +19,9 @@ pub fn check_expectations(tcx: TyCtxt<'_>) { let lint_expectations = &tcx.lint_levels(()).lint_expectations; for (id, expectation) in lint_expectations { - if !fulfilled_expectations.contains(id) { + if !fulfilled_expectations.contains(id) + && tool_filter.map_or(true, |filter| expectation.lint_tool == Some(filter)) + { // This check will always be true, since `lint_expectations` only // holds stable ids if let LintExpectationId::Stable { hir_id, .. } = id { diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 0ac636b878e0d..0ce760b64d9ca 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -503,7 +503,4 @@ pub fn check_crate<'tcx, T: LateLintPass<'tcx>>( }); }, ); - - // This check has to be run after all lints are done processing for this crate - tcx.sess.time("check_lint_expectations", || crate::expect::check_expectations(tcx)); } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 01f1d1e79ac6c..257549bf1a1a4 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -371,7 +371,12 @@ impl<'s> LintLevelsBuilder<'s> { }; self.lint_expectations.push(( expect_id, - LintExpectation::new(reason, sp, is_unfulfilled_lint_expectations), + LintExpectation::new( + reason, + sp, + is_unfulfilled_lint_expectations, + tool_name, + ), )); } let src = LintLevelSource::Node( @@ -400,8 +405,10 @@ impl<'s> LintLevelsBuilder<'s> { self.insert_spec(*id, (level, src)); } if let Level::Expect(expect_id) = level { - self.lint_expectations - .push((expect_id, LintExpectation::new(reason, sp, false))); + self.lint_expectations.push(( + expect_id, + LintExpectation::new(reason, sp, false, tool_name), + )); } } Err((Some(ids), ref new_lint_name)) => { @@ -444,8 +451,10 @@ impl<'s> LintLevelsBuilder<'s> { self.insert_spec(*id, (level, src)); } if let Level::Expect(expect_id) = level { - self.lint_expectations - .push((expect_id, LintExpectation::new(reason, sp, false))); + self.lint_expectations.push(( + expect_id, + LintExpectation::new(reason, sp, false, tool_name), + )); } } Err((None, _)) => { @@ -550,8 +559,10 @@ impl<'s> LintLevelsBuilder<'s> { } } if let Level::Expect(expect_id) = level { - self.lint_expectations - .push((expect_id, LintExpectation::new(reason, sp, false))); + self.lint_expectations.push(( + expect_id, + LintExpectation::new(reason, sp, false, tool_name), + )); } } else { panic!("renamed lint does not exist: {}", new_name); diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 028c14366c6ad..a965587afb715 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -109,6 +109,7 @@ pub use rustc_session::lint::{LintArray, LintPass}; pub fn provide(providers: &mut Providers) { levels::provide(providers); + expect::provide(providers); *providers = Providers { lint_mod, ..*providers }; } diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index f49166433faad..83fc7bcde8ab4 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -5,8 +5,8 @@ use crate::diagnostics::error::{ SessionDiagnosticDeriveError, }; use crate::diagnostics::utils::{ - option_inner_ty, report_error_if_not_applied_to_span, type_matches_path, Applicability, - FieldInfo, HasFieldMap, SetOnce, + report_error_if_not_applied_to_span, type_matches_path, Applicability, FieldInfo, FieldInnerTy, + HasFieldMap, SetOnce, }; use proc_macro2::TokenStream; use quote::{format_ident, quote}; @@ -353,35 +353,40 @@ impl SessionDiagnosticDeriveBuilder { info: FieldInfo<'_>, ) -> Result { let field_binding = &info.binding.binding; - let option_ty = option_inner_ty(&info.ty); - let generated_code = self.generate_non_option_field_code( + + let inner_ty = FieldInnerTy::from_type(&info.ty); + let name = attr.path.segments.last().unwrap().ident.to_string(); + let (binding, needs_destructure) = match (name.as_str(), &inner_ty) { + // `primary_span` can accept a `Vec` so don't destructure that. + ("primary_span", FieldInnerTy::Vec(_)) => (quote! { #field_binding.clone() }, false), + _ => (quote! { *#field_binding }, true), + }; + + let generated_code = self.generate_inner_field_code( attr, FieldInfo { vis: info.vis, binding: info.binding, - ty: option_ty.unwrap_or(&info.ty), + ty: inner_ty.inner_type().unwrap_or(&info.ty), span: info.span, }, + binding, )?; - if option_ty.is_none() { - Ok(quote! { #generated_code }) + if needs_destructure { + Ok(inner_ty.with(field_binding, generated_code)) } else { - Ok(quote! { - if let Some(#field_binding) = #field_binding { - #generated_code - } - }) + Ok(generated_code) } } - fn generate_non_option_field_code( + fn generate_inner_field_code( &mut self, attr: &Attribute, info: FieldInfo<'_>, + binding: TokenStream, ) -> Result { let diag = &self.diag; - let field_binding = &info.binding.binding; let name = attr.path.segments.last().unwrap().ident.to_string(); let name = name.as_str(); @@ -397,14 +402,14 @@ impl SessionDiagnosticDeriveBuilder { "primary_span" => { report_error_if_not_applied_to_span(attr, &info)?; Ok(quote! { - #diag.set_span(*#field_binding); + #diag.set_span(#binding); }) } "label" | "note" | "help" => { report_error_if_not_applied_to_span(attr, &info)?; - Ok(self.add_subdiagnostic(field_binding, name, name)) + Ok(self.add_subdiagnostic(binding, name, name)) } - "subdiagnostic" => Ok(quote! { #diag.subdiagnostic(*#field_binding); }), + "subdiagnostic" => Ok(quote! { #diag.subdiagnostic(#binding); }), _ => throw_invalid_attr!(attr, &meta, |diag| { diag .help("only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` are valid field attributes") @@ -413,7 +418,7 @@ impl SessionDiagnosticDeriveBuilder { Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(ref s), .. }) => match name { "label" | "note" | "help" => { report_error_if_not_applied_to_span(attr, &info)?; - Ok(self.add_subdiagnostic(field_binding, name, &s.value())) + Ok(self.add_subdiagnostic(binding, name, &s.value())) } _ => throw_invalid_attr!(attr, &meta, |diag| { diag.help("only `label`, `note` and `help` are valid field attributes") @@ -509,7 +514,7 @@ impl SessionDiagnosticDeriveBuilder { /// `fluent_attr_identifier`. fn add_subdiagnostic( &self, - field_binding: &proc_macro2::Ident, + field_binding: TokenStream, kind: &str, fluent_attr_identifier: &str, ) -> TokenStream { @@ -520,7 +525,7 @@ impl SessionDiagnosticDeriveBuilder { let fn_name = format_ident!("span_{}", kind); quote! { #diag.#fn_name( - *#field_binding, + #field_binding, rustc_errors::DiagnosticMessage::fluent_attr(#slug, #fluent_attr_identifier) ); } diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index 961b42f424fd1..65b1328682f82 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -5,8 +5,8 @@ use crate::diagnostics::error::{ SessionDiagnosticDeriveError, }; use crate::diagnostics::utils::{ - option_inner_ty, report_error_if_not_applied_to_applicability, - report_error_if_not_applied_to_span, Applicability, FieldInfo, HasFieldMap, SetOnce, + report_error_if_not_applied_to_applicability, report_error_if_not_applied_to_span, + Applicability, FieldInfo, FieldInnerTy, HasFieldMap, SetOnce, }; use proc_macro2::TokenStream; use quote::{format_ident, quote}; @@ -301,11 +301,11 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> { ) -> Result { let ast = binding.ast(); - let option_ty = option_inner_ty(&ast.ty); + let inner_ty = FieldInnerTy::from_type(&ast.ty); let info = FieldInfo { vis: &ast.vis, binding: binding, - ty: option_ty.unwrap_or(&ast.ty), + ty: inner_ty.inner_type().unwrap_or(&ast.ty), span: &ast.span(), }; @@ -353,15 +353,7 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> { ); }; - if option_ty.is_none() { - Ok(quote! { #generated }) - } else { - Ok(quote! { - if let Some(#binding) = #binding { - #generated - } - }) - } + Ok(inner_ty.with(binding, generated)) } fn into_tokens(&mut self) -> Result { diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index 1f36af0a20bcd..aba861fc6aafa 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -1,7 +1,7 @@ use crate::diagnostics::error::{span_err, throw_span_err, SessionDiagnosticDeriveError}; use proc_macro::Span; use proc_macro2::TokenStream; -use quote::{format_ident, quote}; +use quote::{format_ident, quote, ToTokens}; use std::collections::BTreeSet; use std::str::FromStr; use syn::{spanned::Spanned, Attribute, Meta, Type, Visibility}; @@ -76,22 +76,71 @@ pub(crate) fn report_error_if_not_applied_to_span( report_error_if_not_applied_to_ty(attr, info, &["rustc_span", "Span"], "Span") } -/// If `ty` is an Option, returns `Some(inner type)`, otherwise returns `None`. -pub(crate) fn option_inner_ty(ty: &Type) -> Option<&Type> { - if type_matches_path(ty, &["std", "option", "Option"]) { +/// Inner type of a field and type of wrapper. +pub(crate) enum FieldInnerTy<'ty> { + /// Field is wrapped in a `Option<$inner>`. + Option(&'ty Type), + /// Field is wrapped in a `Vec<$inner>`. + Vec(&'ty Type), + /// Field isn't wrapped in an outer type. + None, +} + +impl<'ty> FieldInnerTy<'ty> { + /// Returns inner type for a field, if there is one. + /// + /// - If `ty` is an `Option`, returns `FieldInnerTy::Option { inner: (inner type) }`. + /// - If `ty` is a `Vec`, returns `FieldInnerTy::Vec { inner: (inner type) }`. + /// - Otherwise returns `None`. + pub(crate) fn from_type(ty: &'ty Type) -> Self { + let variant: &dyn Fn(&'ty Type) -> FieldInnerTy<'ty> = + if type_matches_path(ty, &["std", "option", "Option"]) { + &FieldInnerTy::Option + } else if type_matches_path(ty, &["std", "vec", "Vec"]) { + &FieldInnerTy::Vec + } else { + return FieldInnerTy::None; + }; + if let Type::Path(ty_path) = ty { let path = &ty_path.path; let ty = path.segments.iter().last().unwrap(); if let syn::PathArguments::AngleBracketed(bracketed) = &ty.arguments { if bracketed.args.len() == 1 { if let syn::GenericArgument::Type(ty) = &bracketed.args[0] { - return Some(ty); + return variant(ty); } } } } + + unreachable!(); + } + + /// Returns `Option` containing inner type if there is one. + pub(crate) fn inner_type(&self) -> Option<&'ty Type> { + match self { + FieldInnerTy::Option(inner) | FieldInnerTy::Vec(inner) => Some(inner), + FieldInnerTy::None => None, + } + } + + /// Surrounds `inner` with destructured wrapper type, exposing inner type as `binding`. + pub(crate) fn with(&self, binding: impl ToTokens, inner: impl ToTokens) -> TokenStream { + match self { + FieldInnerTy::Option(..) => quote! { + if let Some(#binding) = #binding { + #inner + } + }, + FieldInnerTy::Vec(..) => quote! { + for #binding in #binding { + #inner + } + }, + FieldInnerTy::None => quote! { #inner }, + } } - None } /// Field information passed to the builder. Deliberately omits attrs to discourage the diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index e55b0454eefc7..c7c5f56867a5d 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -210,6 +210,10 @@ pub struct LintExpectation { /// adjusted to include an additional note. Therefore, we have to track if /// the expectation is for the lint. pub is_unfulfilled_lint_expectations: bool, + /// This will hold the name of the tool that this lint belongs to. For + /// the lint `clippy::some_lint` the tool would be `clippy`, the same + /// goes for `rustdoc`. This will be `None` for rustc lints + pub lint_tool: Option, } impl LintExpectation { @@ -217,8 +221,9 @@ impl LintExpectation { reason: Option, emission_span: Span, is_unfulfilled_lint_expectations: bool, + lint_tool: Option, ) -> Self { - Self { reason, emission_span, is_unfulfilled_lint_expectations } + Self { reason, emission_span, is_unfulfilled_lint_expectations, lint_tool } } } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index b7f695da544f1..8111409b8bc0e 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -448,6 +448,12 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { self.push(&format!("+ user_ty: {:?}", user_ty)); } + let fmt_val = |val: &ConstValue<'tcx>| match val { + ConstValue::Scalar(s) => format!("Scalar({:?})", s), + ConstValue::Slice { .. } => format!("Slice(..)"), + ConstValue::ByRef { .. } => format!("ByRef(..)"), + }; + let val = match literal { ConstantKind::Ty(ct) => match ct.val() { ty::ConstKind::Param(p) => format!("Param({})", p), @@ -457,7 +463,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { uv.substs, uv.promoted, ), - ty::ConstKind::Value(val) => format!("Value({:?})", val), + ty::ConstKind::Value(val) => format!("Value({})", fmt_val(&val)), ty::ConstKind::Error(_) => "Error".to_string(), // These variants shouldn't exist in the MIR. ty::ConstKind::Placeholder(_) @@ -467,7 +473,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { // To keep the diffs small, we render this like we render `ty::Const::Value`. // // This changes once `ty::Const::Value` is represented using valtrees. - ConstantKind::Val(val, _) => format!("Value({:?})", val), + ConstantKind::Val(val, _) => format!("Value({})", fmt_val(&val)), }; self.push(&format!("+ literal: Const {{ ty: {}, val: {} }}", literal.ty(), val)); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index e439d128dbc77..3eb8bb0feb12e 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -157,6 +157,25 @@ rustc_queries! { desc { "running analysis passes on this crate" } } + /// This query checks the fulfillment of collected lint expectations. + /// All lint emitting queries have to be done before this is executed + /// to ensure that all expectations can be fulfilled. + /// + /// This is an extra query to enable other drivers (like rustdoc) to + /// only execute a small subset of the [`analysis`] query, while allowing + /// lints to be expected. In rustc, this query will be executed as part of + /// the [`analysis`] query and doesn't have to be called a second time. + /// + /// Tools can additionally pass in a tool filter. That will restrict the + /// expectations to only trigger for lints starting with the listed tool + /// name. This is useful for cases were not all linting code from rustc + /// was called. With the default `None` all registered lints will also + /// be checked for expectation fulfillment. + query check_expectations(key: Option) -> () { + eval_always + desc { "checking lint expectations (RFC 2383)" } + } + /// Maps from the `DefId` of an item (trait/struct/enum/fn) to its /// associated generics. query generics_of(key: DefId) -> ty::Generics { diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs index 3f0f856b5dd7c..6fbafeb1d32b3 100644 --- a/compiler/rustc_query_impl/src/keys.rs +++ b/compiler/rustc_query_impl/src/keys.rs @@ -435,6 +435,16 @@ impl Key for Symbol { } } +impl Key for Option { + #[inline(always)] + fn query_crate_is_local(&self) -> bool { + true + } + fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { + DUMMY_SP + } +} + /// Canonical query goals correspond to abstract trait operations that /// are not tied to any crate in particular. impl<'tcx, T> Key for Canonical<'tcx, T> { diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index e933fe1cb2412..6fb87e15a3303 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -289,12 +289,26 @@ impl ParseSess { self.proc_macro_quoted_spans.lock().clone() } + pub fn create_err<'a>( + &'a self, + err: impl SessionDiagnostic<'a>, + ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + err.into_diagnostic(self) + } + pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed { - err.into_diagnostic(self).emit() + self.create_err(err).emit() + } + + pub fn create_warning<'a>( + &'a self, + warning: impl SessionDiagnostic<'a, ()>, + ) -> DiagnosticBuilder<'a, ()> { + warning.into_diagnostic(self) } pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) { - warning.into_diagnostic(self).emit() + self.create_warning(warning).emit() } pub fn struct_err( diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index e8279f6fed24f..b2c23cda6aae5 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -413,9 +413,21 @@ impl Session { pub fn err(&self, msg: impl Into) -> ErrorGuaranteed { self.diagnostic().err(msg) } + pub fn create_err<'a>( + &'a self, + err: impl SessionDiagnostic<'a>, + ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + self.parse_sess.create_err(err) + } pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed { self.parse_sess.emit_err(err) } + pub fn create_warning<'a>( + &'a self, + err: impl SessionDiagnostic<'a, ()>, + ) -> DiagnosticBuilder<'a, ()> { + self.parse_sess.create_warning(err) + } pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) { self.parse_sess.emit_warning(warning) } diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 0e8fd9cc93fd1..a2cd3c4c46816 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -276,12 +276,19 @@ impl ToJson for Endian { } /// Size of a type in bytes. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] #[derive(HashStable_Generic)] pub struct Size { raw: u64, } +// This is debug-printed a lot in larger structs, don't waste too much space there +impl fmt::Debug for Size { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Size({} bytes)", self.bytes()) + } +} + impl Size { pub const ZERO: Size = Size { raw: 0 }; @@ -485,12 +492,19 @@ impl Step for Size { } /// Alignment of a type in bytes (always a power of two). -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] #[derive(HashStable_Generic)] pub struct Align { pow2: u8, } +// This is debug-printed a lot in larger structs, don't waste too much space there +impl fmt::Debug for Align { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Align({} bytes)", self.bytes()) + } +} + impl Align { pub const ONE: Align = Align { pow2: 0 }; diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 794e711b6c831..38c29d3874c9e 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -3,7 +3,10 @@ use crate::astconv::{ AstConv, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition, }; -use crate::errors::AssocTypeBindingNotAllowed; +use crate::errors::{ + AssocTypeBindingNotAllowed, ExplicitGenericArgsWithImplTrait, + ExplicitGenericArgsWithImplTraitFeature, +}; use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs}; use rustc_ast::ast::ParamKindOrd; use rustc_errors::{struct_span_err, Applicability, Diagnostic, MultiSpan}; @@ -636,29 +639,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }) .collect::>(); - let mut err = struct_span_err! { - tcx.sess, - spans.clone(), - E0632, - "cannot provide explicit generic arguments when `impl Trait` is \ - used in argument position" - }; - - for span in spans { - err.span_label(span, "explicit generic argument not allowed"); - } - - err.note( - "see issue #83701 \ - for more information", - ); + let mut err = tcx.sess.create_err(ExplicitGenericArgsWithImplTrait { spans }); if tcx.sess.is_nightly_build() { - err.help( - "add `#![feature(explicit_generic_args_with_impl_trait)]` \ - to the crate attributes to enable", - ); + err.subdiagnostic(ExplicitGenericArgsWithImplTraitFeature); } - err.emit(); } diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index 580fb7c3e0f06..90b59df472cad 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -59,7 +59,7 @@ pub fn check_legal_trait_for_method_call( enum CallStep<'tcx> { Builtin(Ty<'tcx>), - DeferredClosure(ty::FnSig<'tcx>), + DeferredClosure(DefId, ty::FnSig<'tcx>), /// E.g., enum variant constructors. Overloaded(MethodCallee<'tcx>), } @@ -107,8 +107,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.confirm_builtin_call(call_expr, callee_expr, callee_ty, arg_exprs, expected) } - Some(CallStep::DeferredClosure(fn_sig)) => { - self.confirm_deferred_closure_call(call_expr, arg_exprs, expected, fn_sig) + Some(CallStep::DeferredClosure(def_id, fn_sig)) => { + self.confirm_deferred_closure_call(call_expr, arg_exprs, expected, def_id, fn_sig) } Some(CallStep::Overloaded(method_callee)) => { @@ -171,7 +171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { closure_substs: substs, }, ); - return Some(CallStep::DeferredClosure(closure_sig)); + return Some(CallStep::DeferredClosure(def_id, closure_sig)); } } @@ -533,6 +533,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_expr: &'tcx hir::Expr<'tcx>, arg_exprs: &'tcx [hir::Expr<'tcx>], expected: Expectation<'tcx>, + closure_def_id: DefId, fn_sig: ty::FnSig<'tcx>, ) -> Ty<'tcx> { // `fn_sig` is the *signature* of the closure being called. We @@ -555,7 +556,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { arg_exprs, fn_sig.c_variadic, TupleArgumentsFlag::TupleArguments, - None, + Some(closure_def_id), ); fn_sig.output() diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 97d256cab685d..277743e4a46c1 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -24,7 +24,7 @@ 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_middle::ty::{self, Ty, TyCtxt}; use rustc_session::Session; use rustc_span::symbol::Ident; use rustc_span::{self, Span}; @@ -394,6 +394,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { break 'errors; } + self.set_tainted_by_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 @@ -502,6 +504,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { TupleMatchFound::Single => { let expected_ty = expected_input_tys[0]; let provided_ty = final_arg_types[0].map(|ty| ty.0).unwrap(); + let expected_ty = self.resolve_vars_if_possible(expected_ty); + let provided_ty = self.resolve_vars_if_possible(provided_ty); let cause = &self.misc(provided_args[0].span); let compatibility = demand_compatible(0, &mut final_arg_types); let type_error = match compatibility { @@ -523,24 +527,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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))); - } + label_fn_like(tcx, &mut err, fn_def_id); err.emit(); break 'errors; } @@ -558,24 +545,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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))); - } + label_fn_like(tcx, &mut err, fn_def_id); err.multipart_suggestion( "use parentheses to construct a tuple", vec![(start, '('.to_string()), (end, ')'.to_string())], @@ -597,13 +567,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let expected_ty = expected_input_tys[*input_idx]; let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap(); + let expected_ty = self.resolve_vars_if_possible(expected_ty); + let provided_ty = self.resolve_vars_if_possible(provided_ty); 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(), + provided_ty, final_arg_types[*input_idx].map(|ty| ty.1).unwrap(), None, None, @@ -613,24 +585,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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))); - } + label_fn_like(tcx, &mut err, fn_def_id); err.emit(); break 'errors; } @@ -678,12 +633,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match error { Error::Invalid(input_idx, compatibility) => { let expected_ty = expected_input_tys[input_idx]; + let provided_ty = final_arg_types + .get(input_idx) + .and_then(|x| x.as_ref()) + .map(|ty| ty.0) + .unwrap_or(tcx.ty_error()); + let expected_ty = self.resolve_vars_if_possible(expected_ty); + let provided_ty = self.resolve_vars_if_possible(provided_ty); if let Compatibility::Incompatible(error) = &compatibility { - let provided_ty = final_arg_types - .get(input_idx) - .and_then(|x| x.as_ref()) - .map(|ty| ty.0) - .unwrap_or(tcx.ty_error()); let cause = &self.misc( provided_args.get(input_idx).map(|i| i.span).unwrap_or(call_span), ); @@ -948,24 +905,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // 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() - .flat_map(|id| tcx.hir().body(id).params) - ; - - 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))); - } + label_fn_like(tcx, &mut err, fn_def_id); // And add a suggestion block for all of the parameters let suggestion_text = match suggestion_text { @@ -1790,3 +1730,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } + +fn label_fn_like<'tcx>( + tcx: TyCtxt<'tcx>, + err: &mut rustc_errors::DiagnosticBuilder<'tcx, rustc_errors::ErrorGuaranteed>, + def_id: Option, +) { + let Some(def_id) = def_id else { + return; + }; + + if 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))); + } else { + match tcx.hir().get_if_local(def_id) { + Some(hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(_, _, _, span, ..), + .. + })) => { + let spans: MultiSpan = (*span).into(); + + // Note: We don't point to param spans here because they overlap + // with the closure span itself + + err.span_note(spans, "closure defined here"); + } + _ => {} + } + } +} diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 5330d4d74cb07..4b6f80ce57a83 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -14,6 +14,7 @@ use rustc_span::{Span, DUMMY_SP}; use super::ItemCtxt; use super::{bad_placeholder, is_suggestable_infer_ty}; +use crate::errors::UnconstrainedOpaqueType; /// Computes the relevant generic parameter for a potential generic const argument. /// @@ -682,13 +683,10 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { match locator.found { Some(hidden) => hidden.ty, None => { - let span = tcx.def_span(def_id); - let name = tcx.item_name(tcx.local_parent(def_id).to_def_id()); - let label = format!( - "`{}` must be used in combination with a concrete type within the same module", - name - ); - tcx.sess.struct_span_err(span, "unconstrained opaque type").note(&label).emit(); + tcx.sess.emit_err(UnconstrainedOpaqueType { + span: tcx.def_span(def_id), + name: tcx.item_name(tcx.local_parent(def_id).to_def_id()), + }); tcx.ty_error() } } diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index 3d2f93537e4e8..a3e7108caae00 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -228,3 +228,25 @@ pub enum ExpectedReturnTypeLabel<'tcx> { expected: Ty<'tcx>, }, } + +#[derive(SessionDiagnostic)] +#[error(slug = "typeck-unconstrained-opaque-type")] +#[note] +pub struct UnconstrainedOpaqueType { + #[primary_span] + pub span: Span, + pub name: Symbol, +} + +#[derive(SessionDiagnostic)] +#[error(code = "E0632", slug = "typeck-explicit-generic-args-with-impl-trait")] +#[note] +pub struct ExplicitGenericArgsWithImplTrait { + #[primary_span] + #[label] + pub spans: Vec, +} + +#[derive(SessionSubdiagnostic)] +#[help(slug = "typeck-explicit-generic-args-with-impl-trait-feature")] +pub struct ExplicitGenericArgsWithImplTraitFeature; diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile index 66333e2b99214..7a34a7daaec5b 100644 --- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile +++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile @@ -41,4 +41,4 @@ ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \ /scripts/validate-error-codes.sh && \ # Runs checks to ensure that there are no ES5 issues in our JS code. es-check es6 ../src/librustdoc/html/static/js/*.js && \ - eslint ../src/librustdoc/html/static/js/*.js + eslint -c ../src/librustdoc/html/static/.eslintrc.js ../src/librustdoc/html/static/js/*.js diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 537ab48bbfc12..30b3d6defb4b8 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -567,3 +567,10 @@ $ rustdoc src/lib.rs -Z unstable-options \ The example above check every well known names (`target_os`, `doc`, `test`, ... via `names()`) and check the values of `feature`: `foo` and `bar`. + +### `--generate-link-to-definition`: Generate links on types in source code + + * Tracking issue: [#89095](https://github.com/rust-lang/rust/issues/89095) + +This flag enables the generation of links in the source code pages which allow the reader +to jump to a type definition. diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 1db6064551cae..17644aeed8569 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -232,6 +232,8 @@ crate fn create_config( rustc_lint::builtin::RENAMED_AND_REMOVED_LINTS.name.to_string(), rustc_lint::builtin::UNKNOWN_LINTS.name.to_string(), rustc_lint::builtin::UNEXPECTED_CFGS.name.to_string(), + // this lint is needed to support `#[expect]` attributes + rustc_lint::builtin::UNFULFILLED_LINT_EXPECTATIONS.name.to_string(), ]; lints_to_show.extend(crate::lint::RUSTDOC_LINTS.iter().map(|lint| lint.name.to_string())); @@ -463,6 +465,8 @@ crate fn run_global_ctxt( } } + tcx.sess.time("check_lint_expectations", || tcx.check_expectations(Some(sym::rustdoc))); + if tcx.sess.diagnostic().has_errors_or_lint_errors().is_some() { rustc_errors::FatalError.raise(); } diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index b5502309560ee..1ae888d059dc6 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{ExprKind, GenericParam, HirId, Mod, Node}; +use rustc_hir::{ExprKind, HirId, Mod, Node}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; use rustc_span::Span; @@ -100,8 +100,6 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { self.tcx.hir() } - fn visit_generic_param(&mut self, _: &'tcx GenericParam<'tcx>) {} - fn visit_path(&mut self, path: &'tcx rustc_hir::Path<'tcx>, _id: HirId) { self.handle_path(path, None); intravisit::walk_path(self, path); diff --git a/src/librustdoc/html/static/.eslintrc.js b/src/librustdoc/html/static/.eslintrc.js index c7af41ac969ce..e118ee5d5edc5 100644 --- a/src/librustdoc/html/static/.eslintrc.js +++ b/src/librustdoc/html/static/.eslintrc.js @@ -16,6 +16,9 @@ module.exports = { "semi": [ "error", "always" - ] + ], + "no-var": ["error"], + "prefer-const": ["error"], + "prefer-arrow-callback": ["error"], } }; diff --git a/src/librustdoc/html/static/js/externs.js b/src/librustdoc/html/static/js/externs.js index de881dbd0812a..defdc20132e67 100644 --- a/src/librustdoc/html/static/js/externs.js +++ b/src/librustdoc/html/static/js/externs.js @@ -1,9 +1,6 @@ // This file contains type definitions that are processed by the Closure Compiler but are // not put into the JavaScript we include as part of the documentation. It is used for // type checking. See README.md in this directory for more info. -/* eslint-env es6 */ -/* eslint no-var: "error" */ -/* eslint prefer-const: "error" */ /* eslint-disable */ let searchState; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 2d8339e839424..ea20f6e28ecd6 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1,7 +1,3 @@ -/* eslint-env es6 */ -/* eslint no-var: "error" */ -/* eslint prefer-const: "error" */ -/* eslint prefer-arrow-callback: "error" */ // Local js definitions: /* global addClass, getSettingValue, hasClass, searchState */ /* global onEach, onEachLazy, removeClass */ diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js index 70fcef522129e..544bced4c5afd 100644 --- a/src/librustdoc/html/static/js/scrape-examples.js +++ b/src/librustdoc/html/static/js/scrape-examples.js @@ -1,7 +1,3 @@ -/* eslint-env es6 */ -/* eslint no-var: "error" */ -/* eslint prefer-const: "error" */ -/* eslint prefer-arrow-callback: "error" */ /* global addClass, hasClass, removeClass, onEachLazy */ "use strict"; diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 2eafa540a1aa2..3d8cfeecbed6d 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1,7 +1,3 @@ -/* eslint-env es6 */ -/* eslint no-var: "error" */ -/* eslint prefer-const: "error" */ -/* eslint prefer-arrow-callback: "error" */ /* global addClass, getNakedUrl, getSettingValue, hasOwnPropertyRustdoc, initSearch, onEach */ /* global onEachLazy, removeClass, searchState, browserSupportsHistoryApi */ diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index e447d09ab6b97..a7b60a496890c 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -1,7 +1,3 @@ -/* eslint-env es6 */ -/* eslint no-var: "error" */ -/* eslint prefer-const: "error" */ -/* eslint prefer-arrow-callback: "error" */ // Local js definitions: /* global getSettingValue, getVirtualKey, updateLocalStorage, updateSystemTheme */ /* global addClass, removeClass, onEach, onEachLazy, NOT_DISPLAYED_ID */ diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index f788d41d2ded4..92ecd200081b9 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -1,8 +1,3 @@ -/* eslint-env es6 */ -/* eslint no-var: "error" */ -/* eslint prefer-const: "error" */ -/* eslint prefer-arrow-callback: "error" */ - // From rust: /* global search, sourcesIndex */ diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index 052731e99aed2..69940bb89df21 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -1,8 +1,3 @@ -/* eslint-env es6 */ -/* eslint no-var: "error" */ -/* eslint prefer-const: "error" */ -/* eslint prefer-arrow-callback: "error" */ - "use strict"; const darkThemes = ["dark", "ayu"]; diff --git a/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff index 7dd420e41ceff..bbde6ad4b637d 100644 --- a/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff +++ b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff @@ -77,7 +77,7 @@ _9 = const "hello, world!"; // scope 4 at $DIR/const_debuginfo.rs:14:13: 14:28 // mir::Constant // + span: $DIR/const_debuginfo.rs:14:13: 14:28 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [8191], len: Size { raw: 13 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 13 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } StorageLive(_10); // scope 5 at $DIR/const_debuginfo.rs:16:9: 16:10 Deinit(_10); // scope 5 at $DIR/const_debuginfo.rs:16:13: 16:34 (_10.0: bool) = const true; // scope 5 at $DIR/const_debuginfo.rs:16:13: 16:34 diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff index 49f6c10415763..cb4273ba6bd6e 100644 --- a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff +++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff @@ -22,7 +22,7 @@ // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(Scalar()) } // mir::Constant // + span: $SRC_DIR/std/src/panic.rs:LL:COL - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [101, 120, 112, 108, 105, 99, 105, 116, 32, 112, 97, 110, 105, 99], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [16383], len: Size { raw: 14 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 14 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } } bb2: { diff --git a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff index 3b9d5e727b8a3..31719b435d694 100644 --- a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff @@ -43,7 +43,7 @@ + // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(Scalar()) } + // mir::Constant + // + span: $SRC_DIR/std/src/panic.rs:LL:COL -+ // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [101, 120, 112, 108, 105, 99, 105, 116, 32, 112, 97, 110, 105, 99], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [16383], len: Size { raw: 14 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 14 }) } ++ // + literal: Const { ty: &str, val: Value(Slice(..)) } } } diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff index 7613afdf4fef5..c19cbe3e5b0df 100644 --- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff @@ -46,7 +46,7 @@ - bb2: { + // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + // + user_ty: UserType(0) -+ // + literal: Const { ty: alloc::raw_vec::RawVec, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } ++ // + literal: Const { ty: alloc::raw_vec::RawVec, val: Value(ByRef(..)) } + Deinit((*_7)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + ((*_7).0: alloc::raw_vec::RawVec) = move _8; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + ((*_7).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff index a2f70f61cac9d..c19cbe3e5b0df 100644 --- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff @@ -46,7 +46,7 @@ - bb2: { + // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + // + user_ty: UserType(0) -+ // + literal: Const { ty: alloc::raw_vec::RawVec, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [65535], len: Size { raw: 16 } }, align: Align { pow2: 3 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } ++ // + literal: Const { ty: alloc::raw_vec::RawVec, val: Value(ByRef(..)) } + Deinit((*_7)); // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + ((*_7).0: alloc::raw_vec::RawVec) = move _8; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + ((*_7).1: usize) = const 0_usize; // scope 3 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL diff --git a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff index c1a4fc301d7cd..f9e11439dd9d2 100644 --- a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff @@ -73,7 +73,7 @@ // + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value(Scalar()) } // mir::Constant // + span: $SRC_DIR/core/src/panic.rs:LL:COL - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [105, 110, 116, 101, 114, 110, 97, 108, 32, 101, 114, 114, 111, 114, 58, 32, 101, 110, 116, 101, 114, 101, 100, 32, 117, 110, 114, 101, 97, 99, 104, 97, 98, 108, 101, 32, 99, 111, 100, 101], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1099511627775], len: Size { raw: 40 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 40 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } } bb2: { diff --git a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir index e2051c85af215..a617417484978 100644 --- a/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir +++ b/src/test/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir @@ -92,7 +92,7 @@ fn num_to_digit(_1: char) -> u32 { // + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value(Scalar()) } // mir::Constant // + span: $SRC_DIR/core/src/option.rs:LL:COL - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [99, 97, 108, 108, 101, 100, 32, 96, 79, 112, 116, 105, 111, 110, 58, 58, 117, 110, 119, 114, 97, 112, 40, 41, 96, 32, 111, 110, 32, 97, 32, 96, 78, 111, 110, 101, 96, 32, 118, 97, 108, 117, 101], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [8796093022207], len: Size { raw: 43 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 43 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } } bb7: { diff --git a/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir index d562f04560c34..2044d34a3db7b 100644 --- a/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/no_drop_for_inactive_variant.unwrap.SimplifyCfg-elaborate-drops.after.mir @@ -26,7 +26,7 @@ fn unwrap(_1: Option) -> T { // + literal: Const { ty: fn(&str) -> ! {begin_panic::<&str>}, val: Value(Scalar()) } // mir::Constant // + span: $SRC_DIR/std/src/panic.rs:LL:COL - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [101, 120, 112, 108, 105, 99, 105, 116, 32, 112, 97, 110, 105, 99], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [16383], len: Size { raw: 14 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 14 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } } bb2: { diff --git a/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir b/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir index 22bf1acc57d72..bdab2d9322210 100644 --- a/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir +++ b/src/test/mir-opt/no_spurious_drop_after_call.main.ElaborateDrops.before.mir @@ -15,7 +15,7 @@ fn main() -> () { _4 = const ""; // scope 0 at $DIR/no-spurious-drop-after-call.rs:9:20: 9:22 // mir::Constant // + span: $DIR/no-spurious-drop-after-call.rs:9:20: 9:22 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [], len: Size { raw: 0 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 0 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _3 = &(*_4); // scope 0 at $DIR/no-spurious-drop-after-call.rs:9:20: 9:34 _2 = ::to_string(move _3) -> bb1; // scope 0 at $DIR/no-spurious-drop-after-call.rs:9:20: 9:34 // mir::Constant diff --git a/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir b/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir index 62fbcaaa28938..e0875ab0069e7 100644 --- a/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir +++ b/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir @@ -192,7 +192,7 @@ static XXX: &Foo = { _2 = Foo { tup: const "hi", data: move _3 }; // scope 0 at $DIR/storage_live_dead_in_statics.rs:5:29: 23:2 // mir::Constant // + span: $DIR/storage_live_dead_in_statics.rs:6:10: 6:14 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [104, 105], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 2 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } StorageDead(_3); // scope 0 at $DIR/storage_live_dead_in_statics.rs:23:1: 23:2 _1 = &_2; // scope 0 at $DIR/storage_live_dead_in_statics.rs:5:28: 23:2 _0 = &(*_1); // scope 0 at $DIR/storage_live_dead_in_statics.rs:5:28: 23:2 diff --git a/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir index 2b79a69b93b3e..16fd328b6f966 100644 --- a/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +++ b/src/test/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -22,7 +22,7 @@ fn main() -> () { _5 = const "C"; // scope 0 at $DIR/uninhabited_enum_branching.rs:23:21: 23:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching.rs:23:21: 23:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _1 = &(*_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:23:21: 23:24 StorageDead(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:23:23: 23:24 StorageDead(_2); // scope 0 at $DIR/uninhabited_enum_branching.rs:24:6: 24:7 @@ -40,7 +40,7 @@ fn main() -> () { _9 = const "E"; // scope 0 at $DIR/uninhabited_enum_branching.rs:28:21: 28:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching.rs:28:21: 28:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [69], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _6 = &(*_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:28:21: 28:24 StorageDead(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:28:23: 28:24 goto -> bb3; // scope 0 at $DIR/uninhabited_enum_branching.rs:28:23: 28:24 @@ -50,7 +50,7 @@ fn main() -> () { _6 = const "D"; // scope 0 at $DIR/uninhabited_enum_branching.rs:27:21: 27:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching.rs:27:21: 27:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } goto -> bb3; // scope 0 at $DIR/uninhabited_enum_branching.rs:27:21: 27:24 } diff --git a/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff index fe87bbd8c0b87..c499e5c59dbeb 100644 --- a/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff +++ b/src/test/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff @@ -28,7 +28,7 @@ _5 = const "C"; // scope 0 at $DIR/uninhabited_enum_branching.rs:23:21: 23:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching.rs:23:21: 23:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _1 = &(*_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:23:21: 23:24 StorageDead(_5); // scope 0 at $DIR/uninhabited_enum_branching.rs:23:23: 23:24 goto -> bb4; // scope 0 at $DIR/uninhabited_enum_branching.rs:23:23: 23:24 @@ -38,7 +38,7 @@ _1 = const "A(Empty)"; // scope 0 at $DIR/uninhabited_enum_branching.rs:21:24: 21:34 // mir::Constant // + span: $DIR/uninhabited_enum_branching.rs:21:24: 21:34 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [65, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } goto -> bb4; // scope 0 at $DIR/uninhabited_enum_branching.rs:21:24: 21:34 } @@ -47,7 +47,7 @@ _4 = const "B(Empty)"; // scope 0 at $DIR/uninhabited_enum_branching.rs:22:24: 22:34 // mir::Constant // + span: $DIR/uninhabited_enum_branching.rs:22:24: 22:34 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [66, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _1 = &(*_4); // scope 0 at $DIR/uninhabited_enum_branching.rs:22:24: 22:34 StorageDead(_4); // scope 0 at $DIR/uninhabited_enum_branching.rs:22:33: 22:34 goto -> bb4; // scope 0 at $DIR/uninhabited_enum_branching.rs:22:33: 22:34 @@ -69,7 +69,7 @@ _9 = const "E"; // scope 0 at $DIR/uninhabited_enum_branching.rs:28:21: 28:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching.rs:28:21: 28:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [69], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _6 = &(*_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:28:21: 28:24 StorageDead(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:28:23: 28:24 goto -> bb7; // scope 0 at $DIR/uninhabited_enum_branching.rs:28:23: 28:24 @@ -79,7 +79,7 @@ _6 = const "D"; // scope 0 at $DIR/uninhabited_enum_branching.rs:27:21: 27:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching.rs:27:21: 27:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } goto -> bb7; // scope 0 at $DIR/uninhabited_enum_branching.rs:27:21: 27:24 } diff --git a/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir index 27f9c8b7f8fea..77951bc8d7b67 100644 --- a/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +++ b/src/test/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -40,7 +40,7 @@ fn main() -> () { _8 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:21: 25:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching2.rs:25:21: 25:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _3 = &(*_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:21: 25:24 StorageDead(_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:23: 25:24 goto -> bb3; // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:23: 25:24 @@ -51,7 +51,7 @@ fn main() -> () { _7 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:21: 24:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching2.rs:24:21: 24:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _3 = &(*_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:21: 24:24 StorageDead(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:23: 24:24 goto -> bb3; // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:23: 24:24 @@ -70,7 +70,7 @@ fn main() -> () { _13 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:21: 32:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching2.rs:32:21: 32:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _9 = &(*_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:21: 32:24 StorageDead(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:23: 32:24 goto -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:23: 32:24 @@ -81,7 +81,7 @@ fn main() -> () { _12 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:21: 31:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching2.rs:31:21: 31:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _9 = &(*_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:21: 31:24 StorageDead(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:23: 31:24 goto -> bb6; // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:23: 31:24 diff --git a/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff index 8622fccec888a..1b06c730cdab6 100644 --- a/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff +++ b/src/test/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff @@ -42,7 +42,7 @@ _8 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:21: 25:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching2.rs:25:21: 25:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _3 = &(*_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:21: 25:24 StorageDead(_8); // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:23: 25:24 goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:25:23: 25:24 @@ -52,7 +52,7 @@ _3 = const "A(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:22:24: 22:34 // mir::Constant // + span: $DIR/uninhabited_enum_branching2.rs:22:24: 22:34 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [65, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:22:24: 22:34 } @@ -61,7 +61,7 @@ _6 = const "B(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:23:24: 23:34 // mir::Constant // + span: $DIR/uninhabited_enum_branching2.rs:23:24: 23:34 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [66, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _3 = &(*_6); // scope 1 at $DIR/uninhabited_enum_branching2.rs:23:24: 23:34 StorageDead(_6); // scope 1 at $DIR/uninhabited_enum_branching2.rs:23:33: 23:34 goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:23:33: 23:34 @@ -72,7 +72,7 @@ _7 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:21: 24:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching2.rs:24:21: 24:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _3 = &(*_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:21: 24:24 StorageDead(_7); // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:23: 24:24 goto -> bb5; // scope 1 at $DIR/uninhabited_enum_branching2.rs:24:23: 24:24 @@ -92,7 +92,7 @@ _13 = const "D"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:21: 32:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching2.rs:32:21: 32:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [68], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _9 = &(*_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:21: 32:24 StorageDead(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:23: 32:24 goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:32:23: 32:24 @@ -102,7 +102,7 @@ _9 = const "A(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:29:24: 29:34 // mir::Constant // + span: $DIR/uninhabited_enum_branching2.rs:29:24: 29:34 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [65, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:29:24: 29:34 } @@ -111,7 +111,7 @@ _11 = const "B(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:30:24: 30:34 // mir::Constant // + span: $DIR/uninhabited_enum_branching2.rs:30:24: 30:34 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [66, 40, 69, 109, 112, 116, 121, 41], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 8 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _9 = &(*_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:30:24: 30:34 StorageDead(_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:30:33: 30:34 goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:30:33: 30:34 @@ -122,7 +122,7 @@ _12 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:21: 31:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching2.rs:31:21: 31:24 - // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [67], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1], len: Size { raw: 1 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 1 }) } + // + literal: Const { ty: &str, val: Value(Slice(..)) } _9 = &(*_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:21: 31:24 StorageDead(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:23: 31:24 goto -> bb10; // scope 1 at $DIR/uninhabited_enum_branching2.rs:31:23: 31:24 diff --git a/src/test/rustdoc-ui/expect-tool-lint-rfc-2383.rs b/src/test/rustdoc-ui/expect-tool-lint-rfc-2383.rs new file mode 100644 index 0000000000000..0901ac3640fdd --- /dev/null +++ b/src/test/rustdoc-ui/expect-tool-lint-rfc-2383.rs @@ -0,0 +1,157 @@ +// check-pass +#![feature(lint_reasons)] + +//! This file tests the `#[expect]` attribute implementation for tool lints. The same +//! file is used to test clippy and rustdoc. Any changes to this file should be synced +//! to the other test files as well. +//! +//! Expectations: +//! * rustc: only rustc lint expectations are emitted +//! * clippy: rustc and Clippy's expectations are emitted +//! * rustdoc: only rustdoc lint expectations are emitted +//! +//! This test can't cover every lint from Clippy, rustdoc and potentially other +//! tools that will be developed. This therefore only tests a small subset of lints + +#![expect(rustdoc::missing_crate_level_docs)] +//~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations] +//~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default + +mod rustc_ok { + //! See + + #[expect(dead_code)] + pub fn rustc_lints() { + let x = 42.0; + + #[expect(illegal_floating_point_literal_pattern)] + match x { + 5.0 => {} + 6.0 => {} + _ => {} + } + } +} + +mod rustc_warn { + //! See + + #[expect(dead_code)] + pub fn rustc_lints() { + let x = 42; + + #[expect(illegal_floating_point_literal_pattern)] + match x { + 5 => {} + 6 => {} + _ => {} + } + } +} + +pub mod rustdoc_ok { + //! See + + #[expect(rustdoc::broken_intra_doc_links)] + /// I want to link to [`Nonexistent`] but it doesn't exist! + pub fn foo() {} + + #[expect(rustdoc::invalid_html_tags)] + ///

+ pub fn bar() {} + + #[expect(rustdoc::bare_urls)] + /// http://example.org + pub fn baz() {} +} + +pub mod rustdoc_warn { + //! See + + #[expect(rustdoc::broken_intra_doc_links)] + //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations] + /// I want to link to [`bar`] but it doesn't exist! + pub fn foo() {} + + #[expect(rustdoc::invalid_html_tags)] + //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations] + ///

+ pub fn bar() {} + + #[expect(rustdoc::bare_urls)] + //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations] + /// + pub fn baz() {} +} + +mod clippy_ok { + //! See + + #[expect(clippy::almost_swapped)] + fn foo() { + let mut a = 0; + let mut b = 9; + a = b; + b = a; + } + + #[expect(clippy::bytes_nth)] + fn bar() { + let _ = "Hello".bytes().nth(3); + } + + #[expect(clippy::if_same_then_else)] + fn baz() { + let _ = if true { + 42 + } else { + 42 + }; + } + + #[expect(clippy::logic_bug)] + fn burger() { + let a = false; + let b = true; + + if a && b || a {} + } +} + +mod clippy_warn { + //! See + + #[expect(clippy::almost_swapped)] + fn foo() { + let mut a = 0; + let mut b = 9; + a = b; + } + + #[expect(clippy::bytes_nth)] + fn bar() { + let _ = "Hello".as_bytes().get(3); + } + + #[expect(clippy::if_same_then_else)] + fn baz() { + let _ = if true { + 33 + } else { + 42 + }; + } + + #[expect(clippy::logic_bug)] + fn burger() { + let a = false; + let b = true; + let c = false; + + if a && b || c {} + } +} + +fn main() { + rustc_warn::rustc_lints(); +} diff --git a/src/test/rustdoc-ui/expect-tool-lint-rfc-2383.stderr b/src/test/rustdoc-ui/expect-tool-lint-rfc-2383.stderr new file mode 100644 index 0000000000000..efc5f349f4f44 --- /dev/null +++ b/src/test/rustdoc-ui/expect-tool-lint-rfc-2383.stderr @@ -0,0 +1,28 @@ +warning: this lint expectation is unfulfilled + --> $DIR/expect-tool-lint-rfc-2383.rs:16:11 + | +LL | #![expect(rustdoc::missing_crate_level_docs)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unfulfilled_lint_expectations)]` on by default + +warning: this lint expectation is unfulfilled + --> $DIR/expect-tool-lint-rfc-2383.rs:71:14 + | +LL | #[expect(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: this lint expectation is unfulfilled + --> $DIR/expect-tool-lint-rfc-2383.rs:76:14 + | +LL | #[expect(rustdoc::invalid_html_tags)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: this lint expectation is unfulfilled + --> $DIR/expect-tool-lint-rfc-2383.rs:81:14 + | +LL | #[expect(rustdoc::bare_urls)] + | ^^^^^^^^^^^^^^^^^^ + +warning: 4 warnings emitted + diff --git a/src/test/rustdoc/check-source-code-urls-to-def.rs b/src/test/rustdoc/check-source-code-urls-to-def.rs index ca4179d403d69..12c5df2871cf5 100644 --- a/src/test/rustdoc/check-source-code-urls-to-def.rs +++ b/src/test/rustdoc/check-source-code-urls-to-def.rs @@ -46,6 +46,24 @@ pub fn foo(a: u32, b: &str, c: String, d: Foo, e: bar::Bar, f: source_code::Sour // @has - '//a[@href="../../src/foo/auxiliary/source-code-bar.rs.html#14-16"]' 'Trait' pub fn foo2(t: &T, v: &V, b: bool) {} +pub trait AnotherTrait {} +pub trait WhyNot {} + +// @has - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#49"]' 'AnotherTrait' +// @has - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#50"]' 'WhyNot' +pub fn foo3(t: &T, v: &V) +where + T: AnotherTrait, + V: WhyNot +{} + +pub trait AnotherTrait2 {} + +// @has - '//a[@href="../../src/foo/check-source-code-urls-to-def.rs.html#60"]' 'AnotherTrait2' +pub fn foo4() { + let x: Vec = Vec::new(); +} + // @has - '//a[@href="../../foo/primitive.bool.html"]' 'bool' #[doc(primitive = "bool")] mod whatever {} diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index efbf78ac87d73..c63410fa35bde 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -474,3 +474,11 @@ struct Subdiagnostic { #[subdiagnostic] note: Note, } + +#[derive(SessionDiagnostic)] +#[error(code = "E0123", slug = "foo")] +struct VecField { + #[primary_span] + #[label] + spans: Vec, +} diff --git a/src/test/ui/argument-suggestions/basic.rs b/src/test/ui/argument-suggestions/basic.rs index 765b2d5d68e4a..3e96322d67efb 100644 --- a/src/test/ui/argument-suggestions/basic.rs +++ b/src/test/ui/argument-suggestions/basic.rs @@ -22,4 +22,7 @@ fn main() { 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 + + let closure = |x| x; + closure(); //~ ERROR this function takes } diff --git a/src/test/ui/argument-suggestions/basic.stderr b/src/test/ui/argument-suggestions/basic.stderr index 78f82b076198a..8300a22c5483d 100644 --- a/src/test/ui/argument-suggestions/basic.stderr +++ b/src/test/ui/argument-suggestions/basic.stderr @@ -81,7 +81,23 @@ help: reorder these arguments LL | permuted(X {}, Y {}, Z {}); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: aborting due to 5 previous errors +error[E0057]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/basic.rs:27:5 + | +LL | closure(); + | ^^^^^^^-- an argument is missing + | +note: closure defined here + --> $DIR/basic.rs:26:19 + | +LL | let closure = |x| x; + | ^^^ +help: provide the argument + | +LL | closure({_}); + | ~~~~~~~~~~~~ + +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0061, E0308. -For more information about an error, try `rustc --explain E0061`. +Some errors have detailed explanations: E0057, E0061, E0308. +For more information about an error, try `rustc --explain E0057`. diff --git a/src/test/ui/associated-types/associated-types-issue-20346.stderr b/src/test/ui/associated-types/associated-types-issue-20346.stderr index 516057e53d25e..a67cf99283cfa 100644 --- a/src/test/ui/associated-types/associated-types-issue-20346.stderr +++ b/src/test/ui/associated-types/associated-types-issue-20346.stderr @@ -12,8 +12,8 @@ note: expected this to be `Option` | LL | type Item = T; | ^ - = note: expected enum `Option` - found type `T` + = note: expected enum `Option` + found type parameter `T` note: required by a bound in `is_iterator_of` --> $DIR/associated-types-issue-20346.rs:15:34 | diff --git a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr index 1ac72e4b90c75..65533f93c9413 100644 --- a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr +++ b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr @@ -5,7 +5,7 @@ LL | foo(()); | ^^^ lifetime mismatch | = note: expected reference `&'a ()` - found type `&()` + found reference `&()` note: the lifetime requirement is introduced here --> $DIR/higher-ranked-projection.rs:15:33 | diff --git a/src/test/ui/async-await/generator-desc.stderr b/src/test/ui/async-await/generator-desc.stderr index b205fd619155e..3be8c552063e7 100644 --- a/src/test/ui/async-await/generator-desc.stderr +++ b/src/test/ui/async-await/generator-desc.stderr @@ -24,13 +24,18 @@ LL | fun(one(), two()); | | | arguments to this function are incorrect | +note: while checking the return type of the `async fn` + --> $DIR/generator-desc.rs:5:16 + | +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 type `impl Future` (opaque type at <$DIR/generator-desc.rs:5:16>) - found opaque type `impl Future` (opaque type at <$DIR/generator-desc.rs:6:16>) + = note: expected opaque type `impl Future` (opaque type at <$DIR/generator-desc.rs:5:16>) + found opaque type `impl Future` (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 @@ -43,26 +48,26 @@ error[E0308]: mismatched types --> $DIR/generator-desc.rs:14:26 | LL | fun((async || {})(), (async || {})()); - | --- ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body - | | + | --- -- ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body + | | | + | | the expected `async` closure body | arguments to this function are incorrect | ::: $SRC_DIR/core/src/future/mod.rs:LL:COL | LL | pub const fn from_generator(gen: T) -> impl Future - | ------------------------------- the found opaque type + | ------------------------------- + | | + | the expected opaque type + | the found opaque type | - = note: expected type `impl Future` (`async` closure body) - found opaque type `impl Future` (`async` closure body) + = note: expected opaque type `impl Future` (`async` closure body) + found opaque type `impl Future` (`async` closure body) note: function defined here --> $DIR/generator-desc.rs:8:4 | LL | fn fun>(f1: F, f2: F) {} | ^^^ ----- ----- -help: consider `await`ing on the `Future` - | -LL | fun((async || {})(), (async || {})().await); - | ++++++ error: aborting due to 3 previous errors diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index ba9ed5cb65fc9..1196601ace090 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -60,8 +60,13 @@ LL | | LL | | }; | |_____- `if` and `else` have incompatible types | - = note: expected type `impl Future` - found unit type `()` +note: while checking the return type of the `async fn` + --> $DIR/suggest-missing-await.rs:18:18 + | +LL | async fn dummy() {} + | ^ checked the `Output` of this `async fn`, expected opaque type + = note: expected opaque type `impl Future` + found unit type `()` help: consider `await`ing on the `Future` | LL | dummy().await diff --git a/src/test/ui/borrowck/suggest-local-var-imm-and-mut.nll.stderr b/src/test/ui/borrowck/suggest-local-var-imm-and-mut.nll.stderr deleted file mode 100644 index eb934e7b72b08..0000000000000 --- a/src/test/ui/borrowck/suggest-local-var-imm-and-mut.nll.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable - --> $DIR/suggest-local-var-imm-and-mut.rs:12:22 - | -LL | self.foo(self.bar()); - | ---------^^^^^^^^^^- - | | | | - | | | mutable borrow occurs here - | | immutable borrow later used by call - | immutable borrow occurs here - -error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable - --> $DIR/suggest-local-var-imm-and-mut.rs:24:29 - | -LL | Self::foo(self, Self::bar(self)); - | --------- ---- ^^^^^^^^^^^^^^^ mutable borrow occurs here - | | | - | | immutable borrow occurs here - | immutable borrow later used by call - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/closures/closure_cap_coerce_many_fail.stderr b/src/test/ui/closures/closure_cap_coerce_many_fail.stderr index bd2e31648cc5f..e25b33bbcdb06 100644 --- a/src/test/ui/closures/closure_cap_coerce_many_fail.stderr +++ b/src/test/ui/closures/closure_cap_coerce_many_fail.stderr @@ -11,8 +11,8 @@ LL | | _ => unimplemented!(), LL | | }; | |_____- `match` arms have incompatible types | - = note: expected type `fn(i32, i32) -> i32 {add}` - found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:9:16: 9:43]` + = note: expected fn item `fn(i32, i32) -> i32 {add}` + found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:9:16: 9:43]` error[E0308]: `match` arms have incompatible types --> $DIR/closure_cap_coerce_many_fail.rs:18:16 @@ -20,15 +20,18 @@ error[E0308]: `match` arms have incompatible types LL | let _ = match "+" { | _____________- LL | | "+" => |a, b| (a + b) as i32, - | | --------------------- this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:17:16: 17:37]` + | | --------------------- + | | | + | | the expected closure + | | this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:17:16: 17:37]` LL | | "-" => |a, b| (a - b + cap) as i32, | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure LL | | _ => unimplemented!(), LL | | }; | |_____- `match` arms have incompatible types | - = note: expected type `[closure@$DIR/closure_cap_coerce_many_fail.rs:17:16: 17:37]` - found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:18:16: 18:43]` + = note: expected closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:17:16: 17:37]` + found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:18:16: 18:43]` = note: no two closures, even if identical, have the same type = help: consider boxing your closure and/or using it as a trait object @@ -38,15 +41,18 @@ error[E0308]: `match` arms have incompatible types LL | let _ = match "+" { | _____________- LL | | "+" => |a, b| (a + b + cap) as i32, - | | --------------------------- this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:26:16: 26:43]` + | | --------------------------- + | | | + | | the expected closure + | | this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:26:16: 26:43]` LL | | "-" => |a, b| (a - b) as i32, | | ^^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure LL | | _ => unimplemented!(), LL | | }; | |_____- `match` arms have incompatible types | - = note: expected type `[closure@$DIR/closure_cap_coerce_many_fail.rs:26:16: 26:43]` - found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:27:16: 27:37]` + = note: expected closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:26:16: 26:43]` + found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:27:16: 27:37]` = note: no two closures, even if identical, have the same type = help: consider boxing your closure and/or using it as a trait object @@ -56,15 +62,18 @@ error[E0308]: `match` arms have incompatible types LL | let _ = match "+" { | _____________- LL | | "+" => |a, b| (a + b + cap) as i32, - | | --------------------------- this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:34:16: 34:43]` + | | --------------------------- + | | | + | | the expected closure + | | this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:34:16: 34:43]` LL | | "-" => |a, b| (a - b + cap) as i32, | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure LL | | _ => unimplemented!(), LL | | }; | |_____- `match` arms have incompatible types | - = note: expected type `[closure@$DIR/closure_cap_coerce_many_fail.rs:34:16: 34:43]` - found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:35:16: 35:43]` + = note: expected closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:34:16: 34:43]` + found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:35:16: 35:43]` = note: no two closures, even if identical, have the same type = help: consider boxing your closure and/or using it as a trait object 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 4f266b166d698..36551e5afc6c6 100644 --- a/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr +++ b/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr @@ -6,8 +6,8 @@ LL | test(&mut 7, &7); | | | arguments to this function are incorrect | - = note: expected type `&mut {integer}` - found reference `&{integer}` + = note: expected mutable reference `&mut {integer}` + found reference `&{integer}` note: function defined here --> $DIR/coerce-reborrow-multi-arg-fail.rs:1:4 | 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 deleted file mode 100644 index e9854f0b9b53b..0000000000000 --- a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr +++ /dev/null @@ -1,29 +0,0 @@ -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/destructuring-assignment/default-match-bindings-forbidden.stderr b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr index 3d472bf63094d..950e0223e2201 100644 --- a/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr +++ b/src/test/ui/destructuring-assignment/default-match-bindings-forbidden.stderr @@ -6,8 +6,8 @@ LL | (x, y) = &(1, 2); | | | expected reference, found tuple | - = note: expected type `&({integer}, {integer})` - found tuple `(_, _)` + = note: expected reference `&({integer}, {integer})` + found tuple `(_, _)` error: aborting due to previous error diff --git a/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr index 55b08b74af062..a3004cbbe1067 100644 --- a/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr +++ b/src/test/ui/destructuring-assignment/tuple_destructure_fail.stderr @@ -14,8 +14,8 @@ LL | (a, a, b) = (1, 2); | | | expected a tuple with 2 elements, found one with 3 elements | - = note: expected type `({integer}, {integer})` - found tuple `(_, _, _)` + = note: expected tuple `({integer}, {integer})` + found tuple `(_, _, _)` error[E0070]: invalid left-hand side of assignment --> $DIR/tuple_destructure_fail.rs:7:13 @@ -33,8 +33,8 @@ LL | (_,) = (1, 2); | | | expected a tuple with 2 elements, found one with 1 element | - = note: expected type `({integer}, {integer})` - found tuple `(_,)` + = note: expected tuple `({integer}, {integer})` + found tuple `(_,)` error: aborting due to 4 previous errors diff --git a/src/test/ui/error-codes/E0057.stderr b/src/test/ui/error-codes/E0057.stderr index a151b20f865b2..4b4d30a8387fe 100644 --- a/src/test/ui/error-codes/E0057.stderr +++ b/src/test/ui/error-codes/E0057.stderr @@ -4,6 +4,11 @@ error[E0057]: this function takes 1 argument but 0 arguments were supplied LL | let a = f(); | ^-- an argument is missing | +note: closure defined here + --> $DIR/E0057.rs:2:13 + | +LL | let f = |x| x * 3; + | ^^^ help: provide the argument | LL | let a = f({_}); @@ -15,6 +20,11 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied LL | let c = f(2, 3); | ^ - argument unexpected | +note: closure defined here + --> $DIR/E0057.rs:2:13 + | +LL | let f = |x| x * 3; + | ^^^ help: remove the extra argument | LL | let c = f(2); diff --git a/src/test/ui/error-codes/E0502.nll.stderr b/src/test/ui/error-codes/E0502.nll.stderr deleted file mode 100644 index 94cc89754db5f..0000000000000 --- a/src/test/ui/error-codes/E0502.nll.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0502]: cannot borrow `*a` as mutable because it is also borrowed as immutable - --> $DIR/E0502.rs:4:5 - | -LL | let ref y = a; - | ----- immutable borrow occurs here -LL | bar(a); - | ^^^^^^ mutable borrow occurs here -LL | y.use_ref(); - | ----------- immutable borrow later used here - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/estr-subtyping.rs b/src/test/ui/estr-subtyping.rs deleted file mode 100644 index 9c5825fff8552..0000000000000 --- a/src/test/ui/estr-subtyping.rs +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index adebb7d1e63ab..0000000000000 --- a/src/test/ui/estr-subtyping.stderr +++ /dev/null @@ -1,18 +0,0 @@ -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/fn/fn-item-type.rs b/src/test/ui/fn/fn-item-type.rs index 16a0c10ea3a3a..1831e6cbf1050 100644 --- a/src/test/ui/fn/fn-item-type.rs +++ b/src/test/ui/fn/fn-item-type.rs @@ -12,7 +12,7 @@ impl Foo for T { /* `foo` is still default here */ } fn main() { eq(foo::, bar::); //~^ ERROR mismatched types - //~| expected type `fn(_) -> _ {foo::}` + //~| expected fn item `fn(_) -> _ {foo::}` //~| found fn item `fn(_) -> _ {bar::}` //~| 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,6 @@ fn main() { eq(bar::, bar::>); //~^ ERROR mismatched types - //~| expected type `fn(_) -> _ {bar::}` //~| found fn item `fn(_) -> _ {bar::>}` //~| expected struct `String`, found struct `Vec` //~| different `fn` items always have unique types, even if their signatures are the same @@ -45,7 +44,6 @@ fn main() { eq(foo::, bar:: as fn(isize) -> isize); //~^ ERROR mismatched types - //~| expected type `fn(_) -> _ {foo::}` //~| 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 1fb120eb7a778..ecc6485d6d2b5 100644 --- a/src/test/ui/fn/fn-item-type.stderr +++ b/src/test/ui/fn/fn-item-type.stderr @@ -6,8 +6,8 @@ LL | eq(foo::, bar::); | | | arguments to this function are incorrect | - = note: expected type `fn(_) -> _ {foo::}` - found fn item `fn(_) -> _ {bar::}` + = note: expected fn item `fn(_) -> _ {foo::}` + found fn item `fn(_) -> _ {bar::}` = 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:: as fn(isize) -> isize` @@ -25,8 +25,8 @@ LL | eq(foo::, foo::); | | | arguments to this function are incorrect | - = note: expected type `fn(_) -> _ {foo::}` - found fn item `fn(_) -> _ {foo::}` + = note: expected fn item `fn(_) -> _ {foo::}` + found fn item `fn(_) -> _ {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(isize) -> isize` = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `foo:: as fn(isize) -> isize` @@ -44,8 +44,8 @@ LL | eq(bar::, bar::>); | | | arguments to this function are incorrect | - = note: expected type `fn(_) -> _ {bar::}` - found fn item `fn(_) -> _ {bar::>}` + = note: expected fn item `fn(_) -> _ {bar::}` + found fn item `fn(_) -> _ {bar::>}` = 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:: as fn(isize) -> isize` @@ -56,15 +56,15 @@ LL | fn eq(x: T, y: T) { } | ^^ ---- ---- error[E0308]: mismatched types - --> $DIR/fn-item-type.rs:39:26 + --> $DIR/fn-item-type.rs:38:26 | LL | eq(::foo, ::foo); | -- ^^^^^^^^^^^^^^^^^ expected `u8`, found `u16` | | | arguments to this function are incorrect | - = note: expected type `fn() {::foo}` - found fn item `fn() {::foo}` + = note: expected fn item `fn() {::foo}` + found fn item `fn() {::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: `::foo as fn()` @@ -75,14 +75,14 @@ LL | fn eq(x: T, y: T) { } | ^^ ---- ---- error[E0308]: mismatched types - --> $DIR/fn-item-type.rs:46:19 + --> $DIR/fn-item-type.rs:45:19 | LL | eq(foo::, bar:: as fn(isize) -> isize); | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found fn pointer | | | arguments to this function are incorrect | - = note: expected type `fn(_) -> _ {foo::}` + = note: expected fn item `fn(_) -> _ {foo::}` 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:: as fn(isize) -> isize` diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.stderr b/src/test/ui/generator/type-mismatch-signature-deduction.stderr index f05faedf21b82..d78a5929a896d 100644 --- a/src/test/ui/generator/type-mismatch-signature-deduction.stderr +++ b/src/test/ui/generator/type-mismatch-signature-deduction.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | 5 | ^ expected enum `Result`, found integer | - = note: expected type `Result<{integer}, _>` + = note: expected enum `Result<{integer}, _>` found type `{integer}` note: return type inferred to be `Result<{integer}, _>` here --> $DIR/type-mismatch-signature-deduction.rs:9:20 diff --git a/src/test/ui/indexing-requires-a-uint.stderr b/src/test/ui/indexing-requires-a-uint.stderr index a9adff4faded9..0a24855a6a79c 100644 --- a/src/test/ui/indexing-requires-a-uint.stderr +++ b/src/test/ui/indexing-requires-a-uint.stderr @@ -21,6 +21,10 @@ note: function defined here | LL | fn bar(_: T) {} | ^^^ ---- +help: you can convert a `usize` to an `isize` and panic if the converted value doesn't fit + | +LL | bar::(i.try_into().unwrap()); // i should not be re-coerced back to an isize + | ++++++++++++++++++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-13359.stderr b/src/test/ui/issues/issue-13359.stderr index db6283ea11f50..fef63680a8676 100644 --- a/src/test/ui/issues/issue-13359.stderr +++ b/src/test/ui/issues/issue-13359.stderr @@ -11,6 +11,10 @@ note: function defined here | LL | fn foo(_s: i16) { } | ^^^ ------- +help: you can convert an `isize` to an `i16` and panic if the converted value doesn't fit + | +LL | foo((1*(1 as isize)).try_into().unwrap()); + | + +++++++++++++++++++++ error[E0308]: mismatched types --> $DIR/issue-13359.rs:10:9 @@ -25,6 +29,10 @@ note: function defined here | LL | fn bar(_s: u32) { } | ^^^ ------- +help: you can convert a `usize` to a `u32` and panic if the converted value doesn't fit + | +LL | bar((1*(1 as usize)).try_into().unwrap()); + | + +++++++++++++++++++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/layout/debug.rs b/src/test/ui/layout/debug.rs index 299151df66493..a282e71235c31 100644 --- a/src/test/ui/layout/debug.rs +++ b/src/test/ui/layout/debug.rs @@ -1,4 +1,4 @@ -// normalize-stderr-test "pref: Align \{\n *pow2: [1-3],\n *\}" -> "pref: $$PREF_ALIGN" +// normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" #![feature(never_type, rustc_attrs, type_alias_impl_trait)] #![crate_type = "lib"] diff --git a/src/test/ui/layout/debug.stderr b/src/test/ui/layout/debug.stderr index 25f7febfef9df..56a1337e6a5ea 100644 --- a/src/test/ui/layout/debug.stderr +++ b/src/test/ui/layout/debug.stderr @@ -1,9 +1,7 @@ error: layout_of(E) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -33,27 +31,17 @@ error: layout_of(E) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 4, - }, + size: Size(4 bytes), }, Layout { fields: Arbitrary { offsets: [ - Size { - raw: 4, - }, - Size { - raw: 4, - }, - Size { - raw: 8, - }, + Size(4 bytes), + Size(4 bytes), + Size(8 bytes), ], memory_index: [ 0, @@ -67,14 +55,10 @@ error: layout_of(E) = Layout { abi: Uninhabited, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, + abi: Align(4 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 12, - }, + size: Size(12 bytes), }, ], }, @@ -83,9 +67,7 @@ error: layout_of(E) = Layout { }, largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I32, false, @@ -94,14 +76,10 @@ error: layout_of(E) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, + abi: Align(4 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 12, - }, + size: Size(12 bytes), } --> $DIR/debug.rs:6:1 | @@ -111,15 +89,9 @@ LL | enum E { Foo, Bar(!, i32, i32) } error: layout_of(S) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, - Size { - raw: 0, - }, - Size { - raw: 4, - }, + Size(0 bytes), + Size(0 bytes), + Size(4 bytes), ], memory_index: [ 1, @@ -148,14 +120,10 @@ error: layout_of(S) = Layout { ), largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, + abi: Align(4 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 8, - }, + size: Size(8 bytes), } --> $DIR/debug.rs:9:1 | @@ -174,14 +142,10 @@ error: layout_of(U) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, + abi: Align(4 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 8, - }, + size: Size(8 bytes), } --> $DIR/debug.rs:12:1 | @@ -191,9 +155,7 @@ LL | union U { f1: (i32, i32), f3: i32 } error: layout_of(std::result::Result) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -213,9 +175,7 @@ error: layout_of(std::result::Result) = Layout { Layout { fields: Arbitrary { offsets: [ - Size { - raw: 4, - }, + Size(4 bytes), ], memory_index: [ 0, @@ -229,21 +189,15 @@ error: layout_of(std::result::Result) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, + abi: Align(4 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 8, - }, + size: Size(8 bytes), }, Layout { fields: Arbitrary { offsets: [ - Size { - raw: 4, - }, + Size(4 bytes), ], memory_index: [ 0, @@ -257,14 +211,10 @@ error: layout_of(std::result::Result) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, + abi: Align(4 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 8, - }, + size: Size(8 bytes), }, ], }, @@ -286,9 +236,7 @@ error: layout_of(std::result::Result) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I32, false, @@ -297,14 +245,10 @@ error: layout_of(std::result::Result) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, + abi: Align(4 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 8, - }, + size: Size(8 bytes), } --> $DIR/debug.rs:15:1 | @@ -327,14 +271,10 @@ error: layout_of(i32) = Layout { ), largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, + abi: Align(4 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 4, - }, + size: Size(4 bytes), } --> $DIR/debug.rs:18:1 | diff --git a/src/test/ui/layout/hexagon-enum.stderr b/src/test/ui/layout/hexagon-enum.stderr index 4db8162b16bb2..ba919df771fca 100644 --- a/src/test/ui/layout/hexagon-enum.stderr +++ b/src/test/ui/layout/hexagon-enum.stderr @@ -1,9 +1,7 @@ error: layout_of(A) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -33,16 +31,10 @@ error: layout_of(A) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, - pref: Align { - pow2: 0, - }, - }, - size: Size { - raw: 1, + abi: Align(1 bytes), + pref: Align(1 bytes), }, + size: Size(1 bytes), }, ], }, @@ -57,9 +49,7 @@ error: layout_of(A) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I8, false, @@ -68,16 +58,10 @@ error: layout_of(A) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, - pref: Align { - pow2: 0, - }, - }, - size: Size { - raw: 1, + abi: Align(1 bytes), + pref: Align(1 bytes), }, + size: Size(1 bytes), } --> $DIR/hexagon-enum.rs:16:1 | @@ -87,9 +71,7 @@ LL | enum A { Apple } error: layout_of(B) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -119,16 +101,10 @@ error: layout_of(B) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, - pref: Align { - pow2: 0, - }, - }, - size: Size { - raw: 1, + abi: Align(1 bytes), + pref: Align(1 bytes), }, + size: Size(1 bytes), }, ], }, @@ -143,9 +119,7 @@ error: layout_of(B) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I8, false, @@ -154,16 +128,10 @@ error: layout_of(B) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, - pref: Align { - pow2: 0, - }, - }, - size: Size { - raw: 1, + abi: Align(1 bytes), + pref: Align(1 bytes), }, + size: Size(1 bytes), } --> $DIR/hexagon-enum.rs:20:1 | @@ -173,9 +141,7 @@ LL | enum B { Banana = 255, } error: layout_of(C) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -205,16 +171,10 @@ error: layout_of(C) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 1, - }, - pref: Align { - pow2: 1, - }, - }, - size: Size { - raw: 2, + abi: Align(2 bytes), + pref: Align(2 bytes), }, + size: Size(2 bytes), }, ], }, @@ -229,9 +189,7 @@ error: layout_of(C) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I16, false, @@ -240,16 +198,10 @@ error: layout_of(C) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 1, - }, - pref: Align { - pow2: 1, - }, - }, - size: Size { - raw: 2, + abi: Align(2 bytes), + pref: Align(2 bytes), }, + size: Size(2 bytes), } --> $DIR/hexagon-enum.rs:24:1 | @@ -259,9 +211,7 @@ LL | enum C { Chaenomeles = 256, } error: layout_of(P) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -291,16 +241,10 @@ error: layout_of(P) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 4, + abi: Align(4 bytes), + pref: Align(4 bytes), }, + size: Size(4 bytes), }, ], }, @@ -315,9 +259,7 @@ error: layout_of(P) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I32, false, @@ -326,16 +268,10 @@ error: layout_of(P) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 4, + abi: Align(4 bytes), + pref: Align(4 bytes), }, + size: Size(4 bytes), } --> $DIR/hexagon-enum.rs:28:1 | @@ -345,9 +281,7 @@ LL | enum P { Peach = 0x1000_0000isize, } error: layout_of(T) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -377,16 +311,10 @@ error: layout_of(T) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 4, + abi: Align(4 bytes), + pref: Align(4 bytes), }, + size: Size(4 bytes), }, ], }, @@ -401,9 +329,7 @@ error: layout_of(T) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I32, true, @@ -412,16 +338,10 @@ error: layout_of(T) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 4, + abi: Align(4 bytes), + pref: Align(4 bytes), }, + size: Size(4 bytes), } --> $DIR/hexagon-enum.rs:34:1 | diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr index cd3fb5ca5ea40..6c97a09b0c666 100644 --- a/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr +++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.stderr @@ -1,10 +1,10 @@ -error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) --> $DIR/homogeneous-aggr-zero-sized-c-struct.rs:22:1 | LL | pub type TestMiddle = Middle; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) --> $DIR/homogeneous-aggr-zero-sized-c-struct.rs:33:1 | LL | pub type TestFinal = Final; diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs index ec2c9b70224b5..a473c5c97c0b2 100644 --- a/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs +++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs @@ -17,8 +17,7 @@ pub struct WithPhantomData { pub _unit: std::marker::PhantomData<()>, } -pub struct EmptyRustStruct { -} +pub struct EmptyRustStruct {} #[repr(C)] pub struct WithEmptyRustStruct { @@ -52,22 +51,22 @@ pub struct WithEmptyRustEnum { #[rustc_layout(homogeneous_aggregate)] pub type Test1 = BaseCase; -//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) #[rustc_layout(homogeneous_aggregate)] pub type Test2 = WithPhantomData; -//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) #[rustc_layout(homogeneous_aggregate)] pub type Test3 = WithEmptyRustStruct; -//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) #[rustc_layout(homogeneous_aggregate)] pub type Test4 = WithTransitivelyEmptyRustStruct; -//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) #[rustc_layout(homogeneous_aggregate)] pub type Test5 = WithEmptyRustEnum; -//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) -fn main() { } +fn main() {} diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr index ec2b08bf02d65..322948ff78399 100644 --- a/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr +++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-repr-rust.stderr @@ -1,29 +1,29 @@ -error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) - --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:54:1 +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:53:1 | LL | pub type Test1 = BaseCase; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) - --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:58:1 +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:57:1 | LL | pub type Test2 = WithPhantomData; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) - --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:62:1 +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:61:1 | LL | pub type Test3 = WithEmptyRustStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) - --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:66:1 +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:65:1 | LL | pub type Test4 = WithTransitivelyEmptyRustStruct; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) - --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:70:1 +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-zero-sized-repr-rust.rs:69:1 | LL | pub type Test5 = WithEmptyRustEnum; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs b/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs index 89387e01ba572..af5f5885d67c5 100644 --- a/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs +++ b/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs @@ -1,4 +1,4 @@ -// normalize-stderr-test "pref: Align \{\n *pow2: [1-3],\n *\}" -> "pref: $$PREF_ALIGN" +// normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index 46187aae30445..1a724e6f59be1 100644 --- a/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -1,9 +1,7 @@ error: layout_of(MissingPayloadField) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -23,9 +21,7 @@ error: layout_of(MissingPayloadField) = Layout { Layout { fields: Arbitrary { offsets: [ - Size { - raw: 1, - }, + Size(1 bytes), ], memory_index: [ 0, @@ -39,14 +35,10 @@ error: layout_of(MissingPayloadField) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 2, - }, + size: Size(2 bytes), }, Layout { fields: Arbitrary { @@ -61,14 +53,10 @@ error: layout_of(MissingPayloadField) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 1, - }, + size: Size(1 bytes), }, ], }, @@ -89,9 +77,7 @@ error: layout_of(MissingPayloadField) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I8, false, @@ -100,14 +86,10 @@ error: layout_of(MissingPayloadField) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 2, - }, + size: Size(2 bytes), } --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:16:1 | @@ -120,9 +102,7 @@ LL | | } error: layout_of(CommonPayloadField) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -142,9 +122,7 @@ error: layout_of(CommonPayloadField) = Layout { Layout { fields: Arbitrary { offsets: [ - Size { - raw: 1, - }, + Size(1 bytes), ], memory_index: [ 0, @@ -158,21 +136,15 @@ error: layout_of(CommonPayloadField) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 2, - }, + size: Size(2 bytes), }, Layout { fields: Arbitrary { offsets: [ - Size { - raw: 1, - }, + Size(1 bytes), ], memory_index: [ 0, @@ -186,14 +158,10 @@ error: layout_of(CommonPayloadField) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 2, - }, + size: Size(2 bytes), }, ], }, @@ -215,9 +183,7 @@ error: layout_of(CommonPayloadField) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I8, false, @@ -226,14 +192,10 @@ error: layout_of(CommonPayloadField) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 2, - }, + size: Size(2 bytes), } --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:25:1 | @@ -246,9 +208,7 @@ LL | | } error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -268,9 +228,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { Layout { fields: Arbitrary { offsets: [ - Size { - raw: 1, - }, + Size(1 bytes), ], memory_index: [ 0, @@ -284,21 +242,15 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 2, - }, + size: Size(2 bytes), }, Layout { fields: Arbitrary { offsets: [ - Size { - raw: 1, - }, + Size(1 bytes), ], memory_index: [ 0, @@ -312,14 +264,10 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 2, - }, + size: Size(2 bytes), }, ], }, @@ -340,9 +288,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I8, false, @@ -351,14 +297,10 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 2, - }, + size: Size(2 bytes), } --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:33:1 | @@ -371,9 +313,7 @@ LL | | } error: layout_of(NicheFirst) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -397,12 +337,8 @@ error: layout_of(NicheFirst) = Layout { Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, - Size { - raw: 1, - }, + Size(0 bytes), + Size(1 bytes), ], memory_index: [ 0, @@ -430,9 +366,7 @@ error: layout_of(NicheFirst) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I8, false, @@ -441,14 +375,10 @@ error: layout_of(NicheFirst) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 2, - }, + size: Size(2 bytes), }, Layout { fields: Arbitrary { @@ -463,14 +393,10 @@ error: layout_of(NicheFirst) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 0, - }, + size: Size(0 bytes), }, Layout { fields: Arbitrary { @@ -485,14 +411,10 @@ error: layout_of(NicheFirst) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 0, - }, + size: Size(0 bytes), }, ], }, @@ -513,9 +435,7 @@ error: layout_of(NicheFirst) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I8, false, @@ -524,14 +444,10 @@ error: layout_of(NicheFirst) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 2, - }, + size: Size(2 bytes), } --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:41:1 | @@ -545,9 +461,7 @@ LL | | } error: layout_of(NicheSecond) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 1, - }, + Size(1 bytes), ], memory_index: [ 0, @@ -571,12 +485,8 @@ error: layout_of(NicheSecond) = Layout { Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, - Size { - raw: 1, - }, + Size(0 bytes), + Size(1 bytes), ], memory_index: [ 0, @@ -604,9 +514,7 @@ error: layout_of(NicheSecond) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 1, - }, + offset: Size(1 bytes), value: Int( I8, false, @@ -615,14 +523,10 @@ error: layout_of(NicheSecond) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 2, - }, + size: Size(2 bytes), }, Layout { fields: Arbitrary { @@ -637,14 +541,10 @@ error: layout_of(NicheSecond) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 0, - }, + size: Size(0 bytes), }, Layout { fields: Arbitrary { @@ -659,14 +559,10 @@ error: layout_of(NicheSecond) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 0, - }, + size: Size(0 bytes), }, ], }, @@ -687,9 +583,7 @@ error: layout_of(NicheSecond) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 1, - }, + offset: Size(1 bytes), value: Int( I8, false, @@ -698,14 +592,10 @@ error: layout_of(NicheSecond) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, + abi: Align(1 bytes), pref: $PREF_ALIGN, }, - size: Size { - raw: 2, - }, + size: Size(2 bytes), } --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:50:1 | diff --git a/src/test/ui/layout/thumb-enum.stderr b/src/test/ui/layout/thumb-enum.stderr index 9d1f234f31ad5..9db9ad5a78486 100644 --- a/src/test/ui/layout/thumb-enum.stderr +++ b/src/test/ui/layout/thumb-enum.stderr @@ -1,9 +1,7 @@ error: layout_of(A) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -33,16 +31,10 @@ error: layout_of(A) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 1, + abi: Align(1 bytes), + pref: Align(4 bytes), }, + size: Size(1 bytes), }, ], }, @@ -57,9 +49,7 @@ error: layout_of(A) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I8, false, @@ -68,16 +58,10 @@ error: layout_of(A) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 1, + abi: Align(1 bytes), + pref: Align(4 bytes), }, + size: Size(1 bytes), } --> $DIR/thumb-enum.rs:16:1 | @@ -87,9 +71,7 @@ LL | enum A { Apple } error: layout_of(B) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -119,16 +101,10 @@ error: layout_of(B) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 1, + abi: Align(1 bytes), + pref: Align(4 bytes), }, + size: Size(1 bytes), }, ], }, @@ -143,9 +119,7 @@ error: layout_of(B) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I8, false, @@ -154,16 +128,10 @@ error: layout_of(B) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 0, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 1, + abi: Align(1 bytes), + pref: Align(4 bytes), }, + size: Size(1 bytes), } --> $DIR/thumb-enum.rs:20:1 | @@ -173,9 +141,7 @@ LL | enum B { Banana = 255, } error: layout_of(C) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -205,16 +171,10 @@ error: layout_of(C) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 1, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 2, + abi: Align(2 bytes), + pref: Align(4 bytes), }, + size: Size(2 bytes), }, ], }, @@ -229,9 +189,7 @@ error: layout_of(C) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I16, false, @@ -240,16 +198,10 @@ error: layout_of(C) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 1, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 2, + abi: Align(2 bytes), + pref: Align(4 bytes), }, + size: Size(2 bytes), } --> $DIR/thumb-enum.rs:24:1 | @@ -259,9 +211,7 @@ LL | enum C { Chaenomeles = 256, } error: layout_of(P) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -291,16 +241,10 @@ error: layout_of(P) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 4, + abi: Align(4 bytes), + pref: Align(4 bytes), }, + size: Size(4 bytes), }, ], }, @@ -315,9 +259,7 @@ error: layout_of(P) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I32, false, @@ -326,16 +268,10 @@ error: layout_of(P) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 4, + abi: Align(4 bytes), + pref: Align(4 bytes), }, + size: Size(4 bytes), } --> $DIR/thumb-enum.rs:28:1 | @@ -345,9 +281,7 @@ LL | enum P { Peach = 0x1000_0000isize, } error: layout_of(T) = Layout { fields: Arbitrary { offsets: [ - Size { - raw: 0, - }, + Size(0 bytes), ], memory_index: [ 0, @@ -377,16 +311,10 @@ error: layout_of(T) = Layout { }, largest_niche: None, align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 4, + abi: Align(4 bytes), + pref: Align(4 bytes), }, + size: Size(4 bytes), }, ], }, @@ -401,9 +329,7 @@ error: layout_of(T) = Layout { ), largest_niche: Some( Niche { - offset: Size { - raw: 0, - }, + offset: Size(0 bytes), value: Int( I32, true, @@ -412,16 +338,10 @@ error: layout_of(T) = Layout { }, ), align: AbiAndPrefAlign { - abi: Align { - pow2: 2, - }, - pref: Align { - pow2: 2, - }, - }, - size: Size { - raw: 4, + abi: Align(4 bytes), + pref: Align(4 bytes), }, + size: Size(4 bytes), } --> $DIR/thumb-enum.rs:34:1 | diff --git a/src/test/ui/layout/zero-sized-array-union.stderr b/src/test/ui/layout/zero-sized-array-union.stderr index 43b1588266bb7..8faf8593294cc 100644 --- a/src/test/ui/layout/zero-sized-array-union.stderr +++ b/src/test/ui/layout/zero-sized-array-union.stderr @@ -1,22 +1,22 @@ -error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) --> $DIR/zero-sized-array-union.rs:59:1 | LL | type TestBaz1 = Baz1; | ^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) --> $DIR/zero-sized-array-union.rs:70:1 | LL | type TestBaz2 = Baz2; | ^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) --> $DIR/zero-sized-array-union.rs:81:1 | LL | type TestBaz3 = Baz3; | ^^^^^^^^^^^^^^^^^^^^^ -error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size { raw: 4 } })) +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) --> $DIR/zero-sized-array-union.rs:92:1 | LL | type TestBaz4 = Baz4; diff --git a/src/test/ui/let-else/let-else-non-diverging.stderr b/src/test/ui/let-else/let-else-non-diverging.stderr index fd5a18ce7ea51..b961b16b6f6ef 100644 --- a/src/test/ui/let-else/let-else-non-diverging.stderr +++ b/src/test/ui/let-else/let-else-non-diverging.stderr @@ -5,7 +5,7 @@ LL | let Some(x) = Some(1) else { Some(2) }; | ^^^^^^^^^^^ expected `!`, found enum `Option` | = note: expected type `!` - found type `Option<{integer}>` + found enum `Option<{integer}>` = help: try adding a diverging expression, such as `return` or `panic!(..)` = help: ...or use `match` instead of `let...else` @@ -20,8 +20,8 @@ LL | | } LL | | }; | |_____^ expected `!`, found `()` | - = note: expected type `!` - found type `()` + = note: expected type `!` + found unit type `()` = help: try adding a diverging expression, such as `return` or `panic!(..)` = help: ...or use `match` instead of `let...else` @@ -35,7 +35,7 @@ LL | | }; | |_____^ expected `!`, found enum `Option` | = note: expected type `!` - found type `Option<{integer}>` + found enum `Option<{integer}>` = help: try adding a diverging expression, such as `return` or `panic!(..)` = help: ...or use `match` instead of `let...else` diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.rs b/src/test/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.rs new file mode 100644 index 0000000000000..f80fe88cbb97e --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.rs @@ -0,0 +1,155 @@ +// check-pass +#![feature(lint_reasons)] + +//! This file tests the `#[expect]` attribute implementation for tool lints. The same +//! file is used to test clippy and rustdoc. Any changes to this file should be synced +//! to the other test files. +//! +//! Expectations: +//! * rustc: only rustc lint expectations are emitted +//! * clippy: rustc and Clippy's expectations are emitted +//! * rustdoc: only rustdoc lint expectations are emitted +//! +//! This test can't cover every lint from Clippy, rustdoc and potentially other +//! tools that will be developed. This therefore only tests a small subset of lints + +#![expect(rustdoc::missing_crate_level_docs)] + +mod rustc_ok { + //! See + + #[expect(dead_code)] + pub fn rustc_lints() { + let x = 42.0; + + #[expect(illegal_floating_point_literal_pattern)] + match x { + 5.0 => {} + 6.0 => {} + _ => {} + } + } +} + +mod rustc_warn { + //! See + + #[expect(dead_code)] + //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations] + //~| NOTE `#[warn(unfulfilled_lint_expectations)]` on by default + pub fn rustc_lints() { + let x = 42; + + #[expect(illegal_floating_point_literal_pattern)] + //~^ WARNING this lint expectation is unfulfilled [unfulfilled_lint_expectations] + match x { + 5 => {} + 6 => {} + _ => {} + } + } +} + +pub mod rustdoc_ok { + //! See + + #[expect(rustdoc::broken_intra_doc_links)] + /// I want to link to [`Nonexistent`] but it doesn't exist! + pub fn foo() {} + + #[expect(rustdoc::invalid_html_tags)] + ///

+ pub fn bar() {} + + #[expect(rustdoc::bare_urls)] + /// http://example.org + pub fn baz() {} +} + +pub mod rustdoc_warn { + //! See + + #[expect(rustdoc::broken_intra_doc_links)] + /// I want to link to [`bar`] but it doesn't exist! + pub fn foo() {} + + #[expect(rustdoc::invalid_html_tags)] + ///

+ pub fn bar() {} + + #[expect(rustdoc::bare_urls)] + /// + pub fn baz() {} +} + +mod clippy_ok { + //! See + + #[expect(clippy::almost_swapped)] + fn foo() { + let mut a = 0; + let mut b = 9; + a = b; + b = a; + } + + #[expect(clippy::bytes_nth)] + fn bar() { + let _ = "Hello".bytes().nth(3); + } + + #[expect(clippy::if_same_then_else)] + fn baz() { + let _ = if true { + 42 + } else { + 42 + }; + } + + #[expect(clippy::logic_bug)] + fn burger() { + let a = false; + let b = true; + + if a && b || a {} + } +} + +mod clippy_warn { + //! See + + #[expect(clippy::almost_swapped)] + fn foo() { + let mut a = 0; + let mut b = 9; + a = b; + } + + #[expect(clippy::bytes_nth)] + fn bar() { + let _ = "Hello".as_bytes().get(3); + } + + #[expect(clippy::if_same_then_else)] + fn baz() { + let _ = if true { + 33 + } else { + 42 + }; + } + + #[expect(clippy::logic_bug)] + fn burger() { + let a = false; + let b = true; + let c = false; + + if a && b || c {} + } +} + +fn main() { + rustc_warn::rustc_lints(); +} diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.stderr b/src/test/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.stderr new file mode 100644 index 0000000000000..6d49e7543dc59 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_tool_lint_rfc_2383.stderr @@ -0,0 +1,16 @@ +warning: this lint expectation is unfulfilled + --> $DIR/expect_tool_lint_rfc_2383.rs:37:14 + | +LL | #[expect(dead_code)] + | ^^^^^^^^^ + | + = note: `#[warn(unfulfilled_lint_expectations)]` on by default + +warning: this lint expectation is unfulfilled + --> $DIR/expect_tool_lint_rfc_2383.rs:43:18 + | +LL | #[expect(illegal_floating_point_literal_pattern)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 2 warnings emitted + diff --git a/src/test/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.rs b/src/test/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.rs new file mode 100644 index 0000000000000..2b6c3c6a1fdf6 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.rs @@ -0,0 +1,16 @@ +// This ensures that ICEs like rust#94953 don't happen +// check-pass +// compile-flags: -Z unpretty=expanded + +#![feature(lint_reasons)] + +// This `expect` will create an expectation with an unstable expectation id +#[expect(while_true)] +fn create_early_lint_pass_expectation() { + // `while_true` is an early lint + while true {} +} + +fn main() { + create_early_lint_pass_expectation(); +} diff --git a/src/test/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout b/src/test/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout new file mode 100644 index 0000000000000..0ee3a03c38847 --- /dev/null +++ b/src/test/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout @@ -0,0 +1,20 @@ +#![feature(prelude_import)] +#![no_std] +// This ensures that ICEs like rust#94953 don't happen +// check-pass +// compile-flags: -Z unpretty=expanded + +#![feature(lint_reasons)] +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; + +// This `expect` will create an expectation with an unstable expectation id +#[expect(while_true)] +fn create_early_lint_pass_expectation() { + // `while_true` is an early lint + while true {} +} + +fn main() { create_early_lint_pass_expectation(); } diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index 579a5b7ecb98c..ae10a00671e61 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -15,6 +15,10 @@ note: function defined here 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) +help: you can convert a `usize` to a `u64` and panic if the converted value doesn't fit + | +LL | ($arr.len() * size_of($arr[0])).try_into().unwrap()); + | + +++++++++++++++++++++ error[E0605]: non-primitive cast: `{integer}` as `()` --> $DIR/issue-26480.rs:22:19 diff --git a/src/test/ui/or-patterns/already-bound-name.stderr b/src/test/ui/or-patterns/already-bound-name.stderr index 66112165622b9..368782c1e0d01 100644 --- a/src/test/ui/or-patterns/already-bound-name.stderr +++ b/src/test/ui/or-patterns/already-bound-name.stderr @@ -92,7 +92,7 @@ LL | let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1)); | first introduced with type `{integer}` here | = note: expected type `{integer}` - found type `E<{integer}>` + found enum `E<{integer}>` = note: a binding must have the same type in all alternatives error: aborting due to 15 previous errors diff --git a/src/test/ui/or-patterns/inconsistent-modes.stderr b/src/test/ui/or-patterns/inconsistent-modes.stderr index dae6bb41e74e2..f6367ef823405 100644 --- a/src/test/ui/or-patterns/inconsistent-modes.stderr +++ b/src/test/ui/or-patterns/inconsistent-modes.stderr @@ -57,8 +57,8 @@ LL | let (Ok(ref a) | Err(ref mut a)): Result<&u8, &mut u8> = Ok(&0); | | types differ in mutability | first introduced with type `&&u8` here | - = note: expected type `&&u8` - found type `&mut &mut u8` + = note: expected reference `&&u8` + found mutable reference `&mut &mut u8` = note: a binding must have the same type in all alternatives error[E0308]: mismatched types @@ -70,8 +70,8 @@ LL | let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0)); | | types differ in mutability | first introduced with type `&{integer}` here | - = note: expected type `&{integer}` - found type `&mut _` + = note: expected reference `&{integer}` + found mutable reference `&mut _` = note: a binding must have the same type in all alternatives error: aborting due to 9 previous errors diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr index 8063ba8e9f7bd..d0979b23f60cd 100644 --- a/src/test/ui/parser/recover-range-pats.stderr +++ b/src/test/ui/parser/recover-range-pats.stderr @@ -316,6 +316,9 @@ LL | if let X.. .0 = 0 {} | | | | | expected integer, found floating-point number | this is of type `u8` + | + = note: expected type `u8` + found type `{float}` error[E0029]: only `char` and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:33:12 @@ -350,6 +353,9 @@ LL | if let X..=.0 = 0 {} | | | | | expected integer, found floating-point number | this is of type `u8` + | + = note: expected type `u8` + found type `{float}` error[E0029]: only `char` and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:54:12 @@ -384,6 +390,9 @@ LL | if let X... .0 = 0 {} | | | | | expected integer, found floating-point number | this is of type `u8` + | + = note: expected type `u8` + found type `{float}` error[E0029]: only `char` and numeric types are allowed in range patterns --> $DIR/recover-range-pats.rs:73:12 diff --git a/src/test/ui/reify-intrinsic.stderr b/src/test/ui/reify-intrinsic.stderr index dff4ca68d3103..70a64446f6a7d 100644 --- a/src/test/ui/reify-intrinsic.stderr +++ b/src/test/ui/reify-intrinsic.stderr @@ -25,8 +25,8 @@ error[E0308]: cannot coerce intrinsics to function pointers LL | std::intrinsics::unlikely, | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers | - = note: expected type `extern "rust-intrinsic" fn(_) -> _ {likely}` - found fn item `extern "rust-intrinsic" fn(_) -> _ {unlikely}` + = note: expected fn item `extern "rust-intrinsic" fn(_) -> _ {likely}` + found fn item `extern "rust-intrinsic" fn(_) -> _ {unlikely}` error: aborting due to 3 previous errors diff --git a/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr b/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr index c14dfa3601a8c..96c1869b4e726 100644 --- a/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr +++ b/src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr @@ -54,8 +54,8 @@ LL | Opts::A(ref mut i) | Opts::B(ref i) => {} | | | first introduced with type `&mut isize` here | - = note: expected type `&mut isize` - found type `&isize` + = note: expected mutable reference `&mut isize` + found reference `&isize` = note: in the same arm, a binding must have the same type in all alternatives error: aborting due to 6 previous errors diff --git a/src/test/ui/rfc-2005-default-binding-mode/lit.stderr b/src/test/ui/rfc-2005-default-binding-mode/lit.stderr index 6d18a39606ccf..11bc170cdfa1b 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/lit.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/lit.stderr @@ -6,8 +6,8 @@ LL | match &s { LL | "abc" => true, | ^^^^^ expected `&str`, found `str` | - = note: expected type `&&str` - found reference `&'static str` + = note: expected reference `&&str` + found reference `&'static str` error[E0308]: mismatched types --> $DIR/lit.rs:16:9 @@ -17,8 +17,8 @@ LL | match &s { LL | b"abc" => true, | ^^^^^^ expected `&[u8]`, found array `[u8; 3]` | - = note: expected type `&&[u8]` - found reference `&'static [u8; 3]` + = note: expected reference `&&[u8]` + found reference `&'static [u8; 3]` error: aborting due to 2 previous errors diff --git a/src/test/ui/span/E0057.rs b/src/test/ui/span/E0057.rs deleted file mode 100644 index 83f941f65b988..0000000000000 --- a/src/test/ui/span/E0057.rs +++ /dev/null @@ -1,6 +0,0 @@ -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 deleted file mode 100644 index a151b20f865b2..0000000000000 --- a/src/test/ui/span/E0057.stderr +++ /dev/null @@ -1,25 +0,0 @@ -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/suggestions/issue-81839.stderr b/src/test/ui/suggestions/issue-81839.stderr index 0b1c41b837f6a..fae474cedb886 100644 --- a/src/test/ui/suggestions/issue-81839.stderr +++ b/src/test/ui/suggestions/issue-81839.stderr @@ -19,8 +19,8 @@ note: while checking the return type of the `async fn` | LL | pub async fn answer_str(&self, _s: &str) -> Test { | ^^^^ checked the `Output` of this `async fn`, found opaque type - = note: expected type `()` - found opaque type `impl Future` + = note: expected unit type `()` + found opaque type `impl Future` error: aborting due to previous error diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.rs b/src/test/ui/suggestions/match-prev-arm-needing-semi.rs index 6aa93a24d2f04..8c8abe047c2ab 100644 --- a/src/test/ui/suggestions/match-prev-arm-needing-semi.rs +++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.rs @@ -16,6 +16,9 @@ fn extra_semicolon() { async fn async_dummy() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type //~| NOTE while checking the return type of the `async fn` //~| NOTE in this expansion of desugaring of `async` block or function +//~| NOTE checked the `Output` of this `async fn`, expected opaque type +//~| NOTE while checking the return type of the `async fn` +//~| NOTE in this expansion of desugaring of `async` block or function async fn async_dummy2() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type //~| NOTE checked the `Output` of this `async fn`, found opaque type //~| NOTE while checking the return type of the `async fn` @@ -31,7 +34,7 @@ async fn async_extra_semicolon_same() { } false => async_dummy(), //~ ERROR `match` arms have incompatible types //~^ NOTE expected `()`, found opaque type - //~| NOTE expected type `()` + //~| NOTE expected unit type `()` //~| HELP consider `await`ing on the `Future` }; } @@ -44,7 +47,7 @@ async fn async_extra_semicolon_different() { } false => async_dummy2(), //~ ERROR `match` arms have incompatible types //~^ NOTE expected `()`, found opaque type - //~| NOTE expected type `()` + //~| NOTE expected unit type `()` //~| HELP consider `await`ing on the `Future` }; } @@ -55,7 +58,7 @@ async fn async_different_futures() { //~| HELP consider `await`ing on both `Future`s false => async_dummy2(), //~ ERROR `match` arms have incompatible types //~^ NOTE expected opaque type, found a different opaque type - //~| NOTE expected type `impl Future` + //~| NOTE expected opaque type `impl Future` //~| NOTE distinct uses of `impl Trait` result in different opaque types }; } diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr index b55c51b92809a..4c4b782bd6fb1 100644 --- a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr +++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr @@ -1,5 +1,5 @@ error[E0308]: `match` arms have incompatible types - --> $DIR/match-prev-arm-needing-semi.rs:32:18 + --> $DIR/match-prev-arm-needing-semi.rs:35:18 | LL | let _ = match true { | _____________- @@ -20,8 +20,8 @@ note: while checking the return type of the `async fn` | LL | async fn async_dummy() {} | ^ checked the `Output` of this `async fn`, found opaque type - = note: expected type `()` - found opaque type `impl Future` + = note: expected unit type `()` + found opaque type `impl Future` help: consider `await`ing on the `Future` | LL | false => async_dummy().await, @@ -33,7 +33,7 @@ LL + async_dummy() | error[E0308]: `match` arms have incompatible types - --> $DIR/match-prev-arm-needing-semi.rs:45:18 + --> $DIR/match-prev-arm-needing-semi.rs:48:18 | LL | let _ = match true { | _____________- @@ -50,12 +50,12 @@ LL | | }; | |_____- `match` arms have incompatible types | note: while checking the return type of the `async fn` - --> $DIR/match-prev-arm-needing-semi.rs:19:25 + --> $DIR/match-prev-arm-needing-semi.rs:22:25 | LL | async fn async_dummy2() {} | ^ checked the `Output` of this `async fn`, found opaque type - = note: expected type `()` - found opaque type `impl Future` + = note: expected unit type `()` + found opaque type `impl Future` help: consider `await`ing on the `Future` | LL | false => async_dummy2().await, @@ -69,7 +69,7 @@ LL ~ false => Box::new(async_dummy2()), | error[E0308]: `match` arms have incompatible types - --> $DIR/match-prev-arm-needing-semi.rs:56:18 + --> $DIR/match-prev-arm-needing-semi.rs:59:18 | LL | let _ = match true { | _____________- @@ -84,12 +84,17 @@ LL | | }; | |_____- `match` arms have incompatible types | note: while checking the return type of the `async fn` - --> $DIR/match-prev-arm-needing-semi.rs:19:25 + --> $DIR/match-prev-arm-needing-semi.rs:16:24 + | +LL | async fn async_dummy() {} + | ^ checked the `Output` of this `async fn`, expected opaque type +note: while checking the return type of the `async fn` + --> $DIR/match-prev-arm-needing-semi.rs:22:25 | LL | async fn async_dummy2() {} | ^ checked the `Output` of this `async fn`, found opaque type - = note: expected type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>) - found opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:19:25>) + = note: expected opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>) + found opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:22:25>) = note: distinct uses of `impl Trait` result in different opaque types help: consider `await`ing on both `Future`s | diff --git a/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr b/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr index 60f423a116317..be6fc261562eb 100644 --- a/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr +++ b/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr @@ -20,8 +20,8 @@ LL | | _ => Box::new(Bar), LL | | }; | |_____- `match` arms have incompatible types | - = note: expected type `Box` - found struct `Box` + = note: expected struct `Box` + found struct `Box` note: you might have meant to return the `match` expression --> $DIR/match-with-different-arm-types-as-stmt-instead-of-expr.rs:27:6 | diff --git a/src/test/ui/suggestions/opaque-type-error.stderr b/src/test/ui/suggestions/opaque-type-error.stderr index e065e0aaa8e06..133ffb0587392 100644 --- a/src/test/ui/suggestions/opaque-type-error.stderr +++ b/src/test/ui/suggestions/opaque-type-error.stderr @@ -1,6 +1,9 @@ error[E0308]: `if` and `else` have incompatible types --> $DIR/opaque-type-error.rs:20:9 | +LL | fn thing_one() -> impl Future> { + | ------------------------------------ the expected opaque type +... LL | fn thing_two() -> impl Future> { | ------------------------------------ the found opaque type ... @@ -13,8 +16,8 @@ LL | | thing_two() LL | | }.await | |_____- `if` and `else` have incompatible types | - = note: expected type `impl Future>` (opaque type at <$DIR/opaque-type-error.rs:8:19>) - found opaque type `impl Future>` (opaque type at <$DIR/opaque-type-error.rs:12:19>) + = note: expected opaque type `impl Future>` (opaque type at <$DIR/opaque-type-error.rs:8:19>) + found opaque type `impl Future>` (opaque type at <$DIR/opaque-type-error.rs:12:19>) = note: distinct uses of `impl Trait` result in different opaque types help: consider `await`ing on both `Future`s | diff --git a/src/test/ui/traits/issue-52893.stderr b/src/test/ui/traits/issue-52893.stderr index f0c718c7a16db..0ee44921bf5f8 100644 --- a/src/test/ui/traits/issue-52893.stderr +++ b/src/test/ui/traits/issue-52893.stderr @@ -9,8 +9,8 @@ LL | builder.push(output); | | | arguments to this function are incorrect | - = note: expected type `F` - found struct `Class

` + = note: expected type parameter `F` + found struct `Class

` note: associated function defined here --> $DIR/issue-52893.rs:11:8 | diff --git a/src/test/ui/tuple/wrong_argument_ice-4.stderr b/src/test/ui/tuple/wrong_argument_ice-4.stderr index 0c25b6801dc8e..f8dfc4cd043cd 100644 --- a/src/test/ui/tuple/wrong_argument_ice-4.stderr +++ b/src/test/ui/tuple/wrong_argument_ice-4.stderr @@ -8,6 +8,11 @@ LL | | let b = 1; LL | | }); | |_____- argument unexpected | +note: closure defined here + --> $DIR/wrong_argument_ice-4.rs:2:6 + | +LL | (|| {})(|| { + | ^^ help: remove the extra argument | LL | (|| {})(); 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 ea1ca380b1c7a..3241c9f8521c0 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr @@ -6,6 +6,11 @@ LL | let z = f(1_usize, 2); | | | arguments to this function are incorrect | +note: closure defined here + --> $DIR/unboxed-closures-type-mismatch.rs:4:17 + | +LL | let mut f = |x: isize, y: isize| -> isize { x + y }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: change the type of the numeric literal from `usize` to `isize` | LL | let z = f(1_isize, 2); diff --git a/src/test/ui/unsized/box-instead-of-dyn-fn.stderr b/src/test/ui/unsized/box-instead-of-dyn-fn.stderr index 80f61cb3eae11..b9d51d21e9af2 100644 --- a/src/test/ui/unsized/box-instead-of-dyn-fn.stderr +++ b/src/test/ui/unsized/box-instead-of-dyn-fn.stderr @@ -3,7 +3,10 @@ error[E0308]: `if` and `else` have incompatible types | LL | / if a % 2 == 0 { LL | | move || println!("{a}") - | | ----------------------- expected because of this + | | ----------------------- + | | | + | | the expected closure + | | expected because of this LL | | } else { LL | | Box::new(move || println!("{}", b)) | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected closure, found struct `Box` @@ -11,8 +14,8 @@ LL | | LL | | } | |_____- `if` and `else` have incompatible types | - = note: expected type `[closure@$DIR/box-instead-of-dyn-fn.rs:8:9: 8:32]` - found struct `Box<[closure@$DIR/box-instead-of-dyn-fn.rs:10:18: 10:43]>` + = note: expected closure `[closure@$DIR/box-instead-of-dyn-fn.rs:8:9: 8:32]` + found struct `Box<[closure@$DIR/box-instead-of-dyn-fn.rs:10:18: 10:43]>` error[E0746]: return type cannot have an unboxed trait object --> $DIR/box-instead-of-dyn-fn.rs:5:56 diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr index 9dbd41ca368a1..3f297d222dce7 100644 --- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr +++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -9,8 +9,8 @@ LL | | None => &R, LL | | } | |_____- `match` arms have incompatible types | - = note: expected type `&S` - found reference `&R` + = note: expected reference `&S` + found reference `&R` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:26:21 diff --git a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs new file mode 100644 index 0000000000000..28b37f96e9118 --- /dev/null +++ b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.rs @@ -0,0 +1,142 @@ +// check-pass +#![feature(lint_reasons)] +//! This file tests the `#[expect]` attribute implementation for tool lints. The same +//! file is used to test clippy and rustdoc. Any changes to this file should be synced +//! to the other test files as well. +//! +//! Expectations: +//! * rustc: only rustc lint expectations are emitted +//! * clippy: rustc and Clippy's expectations are emitted +//! * rustdoc: only rustdoc lint expectations are emitted +//! +//! This test can't cover every lint from Clippy, rustdoc and potentially other +//! tools that will be developed. This therefore only tests a small subset of lints +#![expect(rustdoc::missing_crate_level_docs)] + +mod rustc_ok { + //! See + + #[expect(dead_code)] + pub fn rustc_lints() { + let x = 42.0; + + #[expect(illegal_floating_point_literal_pattern)] + match x { + 5.0 => {} + 6.0 => {} + _ => {} + } + } +} + +mod rustc_warn { + //! See + + #[expect(dead_code)] + pub fn rustc_lints() { + let x = 42; + + #[expect(illegal_floating_point_literal_pattern)] + match x { + 5 => {} + 6 => {} + _ => {} + } + } +} + +pub mod rustdoc_ok { + //! See + + #[expect(rustdoc::broken_intra_doc_links)] + /// I want to link to [`Nonexistent`] but it doesn't exist! + pub fn foo() {} + + #[expect(rustdoc::invalid_html_tags)] + ///

+ pub fn bar() {} + + #[expect(rustdoc::bare_urls)] + /// http://example.org + pub fn baz() {} +} + +pub mod rustdoc_warn { + //! See + + #[expect(rustdoc::broken_intra_doc_links)] + /// I want to link to [`bar`] but it doesn't exist! + pub fn foo() {} + + #[expect(rustdoc::invalid_html_tags)] + ///

+ pub fn bar() {} + + #[expect(rustdoc::bare_urls)] + /// + pub fn baz() {} +} + +mod clippy_ok { + //! See + + #[expect(clippy::almost_swapped)] + fn foo() { + let mut a = 0; + let mut b = 9; + a = b; + b = a; + } + + #[expect(clippy::bytes_nth)] + fn bar() { + let _ = "Hello".bytes().nth(3); + } + + #[expect(clippy::if_same_then_else)] + fn baz() { + let _ = if true { 42 } else { 42 }; + } + + #[expect(clippy::logic_bug)] + fn burger() { + let a = false; + let b = true; + + if a && b || a {} + } +} + +mod clippy_warn { + //! See + + #[expect(clippy::almost_swapped)] + fn foo() { + let mut a = 0; + let mut b = 9; + a = b; + } + + #[expect(clippy::bytes_nth)] + fn bar() { + let _ = "Hello".as_bytes().get(3); + } + + #[expect(clippy::if_same_then_else)] + fn baz() { + let _ = if true { 33 } else { 42 }; + } + + #[expect(clippy::logic_bug)] + fn burger() { + let a = false; + let b = true; + let c = false; + + if a && b || c {} + } +} + +fn main() { + rustc_warn::rustc_lints(); +} diff --git a/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr new file mode 100644 index 0000000000000..db29e85a82191 --- /dev/null +++ b/src/tools/clippy/tests/ui/expect_tool_lint_rfc_2383.stderr @@ -0,0 +1,40 @@ +error: this lint expectation is unfulfilled + --> $DIR/expect_tool_lint_rfc_2383.rs:35:14 + | +LL | #[expect(dead_code)] + | ^^^^^^^^^ + | + = note: `-D unfulfilled-lint-expectations` implied by `-D warnings` + +error: this lint expectation is unfulfilled + --> $DIR/expect_tool_lint_rfc_2383.rs:39:18 + | +LL | #[expect(illegal_floating_point_literal_pattern)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this lint expectation is unfulfilled + --> $DIR/expect_tool_lint_rfc_2383.rs:113:14 + | +LL | #[expect(clippy::almost_swapped)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: this lint expectation is unfulfilled + --> $DIR/expect_tool_lint_rfc_2383.rs:120:14 + | +LL | #[expect(clippy::bytes_nth)] + | ^^^^^^^^^^^^^^^^^ + +error: this lint expectation is unfulfilled + --> $DIR/expect_tool_lint_rfc_2383.rs:125:14 + | +LL | #[expect(clippy::if_same_then_else)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: this lint expectation is unfulfilled + --> $DIR/expect_tool_lint_rfc_2383.rs:130:14 + | +LL | #[expect(clippy::logic_bug)] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/src/tools/miri b/src/tools/miri index a71a008393767..3b8b6aa8b6899 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit a71a0083937671d79e16bfac4c7b8cab9c8ab9bb +Subproject commit 3b8b6aa8b689971d3b8776cefe3d809501e1b8ff