diff options
87 files changed, 687 insertions, 362 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 0b1cb124080..85b599902b9 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -760,10 +760,28 @@ impl<'hir> LoweringContext<'_, 'hir> { Some(hir::CoroutineKind::Coroutine(_)) | Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) | None => { - return hir::ExprKind::Err(self.dcx().emit_err(AwaitOnlyInAsyncFnAndBlocks { - await_kw_span, - item_span: self.current_item, - })); + // Lower to a block `{ EXPR; <error> }` so that the awaited expr + // is not accidentally orphaned. + let stmt_id = self.next_id(); + let expr_err = self.expr( + expr.span, + hir::ExprKind::Err(self.dcx().emit_err(AwaitOnlyInAsyncFnAndBlocks { + await_kw_span, + item_span: self.current_item, + })), + ); + return hir::ExprKind::Block( + self.block_all( + expr.span, + arena_vec![self; hir::Stmt { + hir_id: stmt_id, + kind: hir::StmtKind::Semi(expr), + span: expr.span, + }], + Some(self.arena.alloc(expr_err)), + ), + None, + ); } }; @@ -1496,12 +1514,31 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind<'hir> { + let yielded = + opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span)); + let is_async_gen = match self.coroutine_kind { Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) => false, Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true, Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => { - return hir::ExprKind::Err( - self.dcx().emit_err(AsyncCoroutinesNotSupported { span }), + // Lower to a block `{ EXPR; <error> }` so that the awaited expr + // is not accidentally orphaned. + let stmt_id = self.next_id(); + let expr_err = self.expr( + yielded.span, + hir::ExprKind::Err(self.dcx().emit_err(AsyncCoroutinesNotSupported { span })), + ); + return hir::ExprKind::Block( + self.block_all( + yielded.span, + arena_vec![self; hir::Stmt { + hir_id: stmt_id, + kind: hir::StmtKind::Semi(yielded), + span: yielded.span, + }], + Some(self.arena.alloc(expr_err)), + ), + None, ); } Some(hir::CoroutineKind::Coroutine(_)) => { @@ -1531,9 +1568,6 @@ impl<'hir> LoweringContext<'_, 'hir> { } }; - let yielded = - opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span)); - if is_async_gen { // `yield $expr` is transformed into `task_context = yield async_gen_ready($expr)`. // This ensures that we store our resumed `ResumeContext` correctly, and also that diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index a88e130cd4b..2cebea9d145 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -182,13 +182,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> { use rustc_type_ir::TyKind::*; - let val = match src.layout.ty.kind() { - // Floating point - Float(FloatTy::F32) => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty), - Float(FloatTy::F64) => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty), - _ => { - bug!("Can't cast 'Float' type into {}", cast_to.ty); - } + let Float(fty) = src.layout.ty.kind() else { + bug!("FloatToFloat/FloatToInt cast: source type {} is not a float type", src.layout.ty) + }; + let val = match fty { + FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F32 => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty), + FloatTy::F64 => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty), + FloatTy::F128 => unimplemented!("f16_f128"), }; Ok(ImmTy::from_scalar(val, cast_to)) } @@ -275,6 +276,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { trace!("cast_from_scalar: {}, {} -> {}", v, src_layout.ty, cast_ty); Ok(match *cast_ty.kind() { + // int -> int Int(_) | Uint(_) => { let size = match *cast_ty.kind() { Int(t) => Integer::from_int_ty(self, t).size(), @@ -285,15 +287,26 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Scalar::from_uint(v, size) } - Float(FloatTy::F32) if signed => Scalar::from_f32(Single::from_i128(v as i128).value), - Float(FloatTy::F64) if signed => Scalar::from_f64(Double::from_i128(v as i128).value), - Float(FloatTy::F32) => Scalar::from_f32(Single::from_u128(v).value), - Float(FloatTy::F64) => Scalar::from_f64(Double::from_u128(v).value), - - Char => { - // `u8` to `char` cast - Scalar::from_u32(u8::try_from(v).unwrap().into()) + // signed int -> float + Float(fty) if signed => { + let v = v as i128; + match fty { + FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F32 => Scalar::from_f32(Single::from_i128(v).value), + FloatTy::F64 => Scalar::from_f64(Double::from_i128(v).value), + FloatTy::F128 => unimplemented!("f16_f128"), + } } + // unsigned int -> float + Float(fty) => match fty { + FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F32 => Scalar::from_f32(Single::from_u128(v).value), + FloatTy::F64 => Scalar::from_f64(Double::from_u128(v).value), + FloatTy::F128 => unimplemented!("f16_f128"), + }, + + // u8 -> char + Char => Scalar::from_u32(u8::try_from(v).unwrap().into()), // Casts to bool are not permitted by rustc, no need to handle them here. _ => span_bug!(self.cur_span(), "invalid int to {} cast", cast_ty), @@ -339,14 +352,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let v = f.to_i128(size.bits_usize()).value; Scalar::from_int(v, size) } - // float -> f32 - Float(FloatTy::F32) => { - Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)) - } - // float -> f64 - Float(FloatTy::F64) => { - Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)) - } + // float -> float + Float(fty) => match fty { + FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F32 => Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)), + FloatTy::F64 => Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)), + FloatTy::F128 => unimplemented!("f16_f128"), + }, // That's it. _ => span_bug!(self.cur_span(), "invalid float to {} cast", dest_ty), } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 440d0ad1140..893b3f9534d 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -166,7 +166,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } - match ty.kind() { + match ty.peel_refs().kind() { ty::Param(param) => { let generics = self.tcx.generics_of(self.body_id); let generic_param = generics.type_param(¶m, self.tcx); @@ -184,7 +184,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - ty::Alias(ty::AliasKind::Opaque, _) => { + ty::Slice(..) | ty::Adt(..) | ty::Alias(ty::AliasKind::Opaque, _) => { for unsatisfied in unsatisfied_predicates.iter() { if is_iterator_predicate(unsatisfied.0, self.tcx) { return true; diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index a0aa252bcdf..a58a37bf3ac 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -12,6 +12,43 @@ use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::symbol::{sym, Symbol}; use rustc_span::BytePos; +const MAX_CHECK_CFG_NAMES_OR_VALUES: usize = 35; + +fn check_cfg_expected_note( + sess: &Session, + possibilities: &[Symbol], + type_: &str, + name: Option<Symbol>, + suffix: &str, +) -> String { + use std::fmt::Write; + + let n_possibilities = if sess.opts.unstable_opts.check_cfg_all_expected { + possibilities.len() + } else { + std::cmp::min(possibilities.len(), MAX_CHECK_CFG_NAMES_OR_VALUES) + }; + + let mut possibilities = possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>(); + possibilities.sort(); + + let and_more = possibilities.len().saturating_sub(n_possibilities); + let possibilities = possibilities[..n_possibilities].join("`, `"); + + let mut note = String::with_capacity(50 + possibilities.len()); + + write!(&mut note, "expected {type_}").unwrap(); + if let Some(name) = name { + write!(&mut note, " for `{name}`").unwrap(); + } + write!(&mut note, " are: {suffix}`{possibilities}`").unwrap(); + if and_more > 0 { + write!(&mut note, " and {and_more} more").unwrap(); + } + + note +} + pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) { match diagnostic { BuiltinLintDiag::UnicodeTextFlow(span, content) => { @@ -286,16 +323,13 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di } } if !possibilities.is_empty() { - let mut possibilities = - possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>(); - possibilities.sort(); - let possibilities = possibilities.join("`, `"); - - // The list of expected names can be long (even by default) and - // so the diagnostic produced can take a lot of space. To avoid - // cloging the user output we only want to print that diagnostic - // once. - diag.help_once(format!("expected names are: `{possibilities}`")); + diag.help_once(check_cfg_expected_note( + sess, + &possibilities, + "names", + None, + "", + )); } } @@ -338,16 +372,13 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di // Show the full list if all possible values for a given name, but don't do it // for names as the possibilities could be very long if !possibilities.is_empty() { - { - let mut possibilities = - possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>(); - possibilities.sort(); - - let possibilities = possibilities.join("`, `"); - let none = if have_none_possibility { "(none), " } else { "" }; - - diag.note(format!("expected values for `{name}` are: {none}`{possibilities}`")); - } + diag.note(check_cfg_expected_note( + sess, + &possibilities, + "values", + Some(name), + if have_none_possibility { "(none), " } else { "" }, + )); if let Some((value, value_span)) = value { // Suggest the most probable if we found one diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index 0261768d916..c518844cc5e 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -1001,19 +1001,26 @@ impl<'p, Cx: TypeCx> PatStack<'p, Cx> { /// Only call if `ctor.is_covered_by(self.head().ctor())` is true. fn pop_head_constructor( &self, + cx: &Cx, ctor: &Constructor<Cx>, ctor_arity: usize, ctor_is_relevant: bool, - ) -> PatStack<'p, Cx> { + ) -> Result<PatStack<'p, Cx>, Cx::Error> { // We pop the head pattern and push the new fields extracted from the arguments of // `self.head()`. let mut new_pats = self.head().specialize(ctor, ctor_arity); + if new_pats.len() != ctor_arity { + return Err(cx.bug(format_args!( + "uncaught type error: pattern {:?} has inconsistent arity (expected arity {ctor_arity})", + self.head().as_pat().unwrap() + ))); + } new_pats.extend_from_slice(&self.pats[1..]); // `ctor` is relevant for this row if it is the actual constructor of this row, or if the // row has a wildcard and `ctor` is relevant for wildcards. let ctor_is_relevant = !matches!(self.head().ctor(), Constructor::Wildcard) || ctor_is_relevant; - PatStack { pats: new_pats, relevant: self.relevant && ctor_is_relevant } + Ok(PatStack { pats: new_pats, relevant: self.relevant && ctor_is_relevant }) } } @@ -1083,18 +1090,19 @@ impl<'p, Cx: TypeCx> MatrixRow<'p, Cx> { /// Only call if `ctor.is_covered_by(self.head().ctor())` is true. fn pop_head_constructor( &self, + cx: &Cx, ctor: &Constructor<Cx>, ctor_arity: usize, ctor_is_relevant: bool, parent_row: usize, - ) -> MatrixRow<'p, Cx> { - MatrixRow { - pats: self.pats.pop_head_constructor(ctor, ctor_arity, ctor_is_relevant), + ) -> Result<MatrixRow<'p, Cx>, Cx::Error> { + Ok(MatrixRow { + pats: self.pats.pop_head_constructor(cx, ctor, ctor_arity, ctor_is_relevant)?, parent_row, is_under_guard: self.is_under_guard, useful: false, intersects: BitSet::new_empty(0), // Initialized in `Matrix::expand_and_push`. - } + }) } } @@ -1217,7 +1225,7 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> { }; for (i, row) in self.rows().enumerate() { if ctor.is_covered_by(pcx.cx, row.head().ctor())? { - let new_row = row.pop_head_constructor(ctor, arity, ctor_is_relevant, i); + let new_row = row.pop_head_constructor(pcx.cx, ctor, arity, ctor_is_relevant, i)?; matrix.expand_and_push(new_row); } } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 1b546bf9103..b06d75be390 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -17,6 +17,7 @@ use rustc_middle::dep_graph::{ use rustc_middle::query::on_disk_cache::AbsoluteBytePos; use rustc_middle::query::on_disk_cache::{CacheDecoder, CacheEncoder, EncodedDepNodeIndex}; use rustc_middle::query::Key; +use rustc_middle::ty::print::with_reduced_queries; use rustc_middle::ty::tls::{self, ImplicitCtxt}; use rustc_middle::ty::{self, TyCtxt}; use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext}; @@ -304,6 +305,10 @@ pub(crate) fn create_query_frame< kind: DepKind, name: &'static str, ) -> QueryStackFrame { + // If reduced queries are requested, we may be printing a query stack due + // to a panic. Avoid using `default_span` and `def_kind` in that case. + let reduce_queries = with_reduced_queries(); + // Avoid calling queries while formatting the description let description = ty::print::with_no_queries!(do_describe(tcx, key)); let description = if tcx.sess.verbose_internals() { @@ -311,7 +316,7 @@ pub(crate) fn create_query_frame< } else { description }; - let span = if kind == dep_graph::dep_kinds::def_span { + let span = if kind == dep_graph::dep_kinds::def_span || reduce_queries { // The `def_span` query is used to calculate `default_span`, // so exit to avoid infinite recursion. None @@ -319,7 +324,7 @@ pub(crate) fn create_query_frame< Some(key.default_span(tcx)) }; let def_id = key.key_as_def_id(); - let def_kind = if kind == dep_graph::dep_kinds::def_kind { + let def_kind = if kind == dep_graph::dep_kinds::def_kind || reduce_queries { // Try to avoid infinite recursion. None } else { diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 40517407ee6..3d9848395a2 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -285,9 +285,8 @@ where let lock = query.query_state(qcx).active.get_shard_by_value(&key).lock(); match lock.get(&key) { - Some(QueryResult::Poisoned) => { - panic!("query '{}' not cached due to poisoning", query.name()) - } + // The query we waited on panicked. Continue unwinding here. + Some(QueryResult::Poisoned) => FatalError.raise(), _ => panic!( "query '{}' result must be in the cache or the query must be poisoned after a wait", query.name() diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 42c9d5e10eb..55e1556cdf8 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1565,6 +1565,8 @@ options! { "set options for branch target identification and pointer authentication on AArch64"), cf_protection: CFProtection = (CFProtection::None, parse_cfprotection, [TRACKED], "instrument control-flow architecture protection"), + check_cfg_all_expected: bool = (false, parse_bool, [UNTRACKED], + "show all expected values in check-cfg diagnostics (default: no)"), codegen_backend: Option<String> = (None, parse_opt_string, [TRACKED], "the backend to use"), collapse_macro_debuginfo: CollapseMacroDebuginfo = (CollapseMacroDebuginfo::Unspecified, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 62933bce76b..7a930937255 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -416,9 +416,59 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => { let trait_predicate = bound_predicate.rebind(trait_predicate); let trait_predicate = self.resolve_vars_if_possible(trait_predicate); - let trait_ref = trait_predicate.to_poly_trait_ref(); - if let Some(guar) = self.emit_specialized_closure_kind_error(&obligation, trait_ref) { + // Let's use the root obligation as the main message, when we care about the + // most general case ("X doesn't implement Pattern<'_>") over the case that + // happened to fail ("char doesn't implement Fn(&mut char)"). + // + // We rely on a few heuristics to identify cases where this root + // obligation is more important than the leaf obligation: + let (main_trait_predicate, o) = if let ty::PredicateKind::Clause( + ty::ClauseKind::Trait(root_pred) + ) = root_obligation.predicate.kind().skip_binder() + && !trait_predicate.self_ty().skip_binder().has_escaping_bound_vars() + && !root_pred.self_ty().has_escaping_bound_vars() + // The type of the leaf predicate is (roughly) the same as the type + // from the root predicate, as a proxy for "we care about the root" + // FIXME: this doesn't account for trivial derefs, but works as a first + // approximation. + && ( + // `T: Trait` && `&&T: OtherTrait`, we want `OtherTrait` + self.can_eq( + obligation.param_env, + trait_predicate.self_ty().skip_binder(), + root_pred.self_ty().peel_refs(), + ) + // `&str: Iterator` && `&str: IntoIterator`, we want `IntoIterator` + || self.can_eq( + obligation.param_env, + trait_predicate.self_ty().skip_binder(), + root_pred.self_ty(), + ) + ) + // The leaf trait and the root trait are different, so as to avoid + // talking about `&mut T: Trait` and instead remain talking about + // `T: Trait` instead + && trait_predicate.def_id() != root_pred.def_id() + // The root trait is not `Unsize`, as to avoid talking about it in + // `tests/ui/coercion/coerce-issue-49593-box-never.rs`. + && Some(root_pred.def_id()) != self.tcx.lang_items().unsize_trait() + { + ( + self.resolve_vars_if_possible( + root_obligation.predicate.kind().rebind(root_pred), + ), + root_obligation, + ) + } else { + (trait_predicate, &obligation) + }; + let trait_ref = main_trait_predicate.to_poly_trait_ref(); + + if let Some(guar) = self.emit_specialized_closure_kind_error( + &obligation, + trait_ref, + ) { return guar; } @@ -459,8 +509,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { notes, parent_label, append_const_msg, - } = self.on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file); - + } = self.on_unimplemented_note(trait_ref, o, &mut long_ty_file); let have_alt_message = message.is_some() || label.is_some(); let is_try_conversion = self.is_try_conversion(span, trait_ref.def_id()); let is_unsize = @@ -483,7 +532,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; let err_msg = self.get_standard_error_message( - &trait_predicate, + &main_trait_predicate, message, predicate_is_const, append_const_msg, diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 86c7551882a..28259516973 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -22,11 +22,20 @@ struct OpaqueTypeCollector<'tcx> { seen: FxHashSet<LocalDefId>, span: Option<Span>, + + mode: CollectionMode, +} + +enum CollectionMode { + /// For impl trait in assoc types we only permit collecting them from + /// associated types of the same impl block. + ImplTraitInAssocTypes, + TypeAliasImplTraitTransition, } impl<'tcx> OpaqueTypeCollector<'tcx> { - fn new(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self { - Self { tcx, opaques: Vec::new(), item, seen: Default::default(), span: None } + fn new(tcx: TyCtxt<'tcx>, item: LocalDefId, mode: CollectionMode) -> Self { + Self { tcx, opaques: Vec::new(), item, seen: Default::default(), span: None, mode } } fn span(&self) -> Span { @@ -251,6 +260,9 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { } } ty::Adt(def, _) if def.did().is_local() => { + if let CollectionMode::ImplTraitInAssocTypes = self.mode { + return ControlFlow::Continue(()); + } if !self.seen.insert(def.did().expect_local()) { return ControlFlow::Continue(()); } @@ -275,89 +287,13 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> { } } -struct ImplTraitInAssocTypeCollector<'tcx>(OpaqueTypeCollector<'tcx>); - -impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for ImplTraitInAssocTypeCollector<'tcx> { - #[instrument(skip(self), ret, level = "trace")] - fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> ControlFlow<!> { - let old = self.0.span; - self.0.span = Some(span); - value.visit_with(self); - self.0.span = old; - - ControlFlow::Continue(()) - } -} - -impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInAssocTypeCollector<'tcx> { - #[instrument(skip(self), ret, level = "trace")] - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<!> { - t.super_visit_with(self)?; - match t.kind() { - ty::Alias(ty::Opaque, alias_ty) if alias_ty.def_id.is_local() => { - self.0.visit_opaque_ty(alias_ty); - } - ty::Alias(ty::Projection, alias_ty) => { - // This avoids having to do normalization of `Self::AssocTy` by only - // supporting the case of a method defining opaque types from assoc types - // in the same impl block. - let parent_trait_ref = self - .0 - .parent_trait_ref() - .expect("impl trait in assoc type collector used on non-assoc item"); - // If the trait ref of the associated item and the impl differs, - // then we can't use the impl's identity args below, so - // just skip. - if alias_ty.trait_ref(self.0.tcx) == parent_trait_ref { - let parent = self.0.parent().expect("we should have a parent here"); - - for &assoc in self.0.tcx.associated_items(parent).in_definition_order() { - trace!(?assoc); - if assoc.trait_item_def_id != Some(alias_ty.def_id) { - continue; - } - - // If the type is further specializable, then the type_of - // is not actually correct below. - if !assoc.defaultness(self.0.tcx).is_final() { - continue; - } - - let impl_args = alias_ty.args.rebase_onto( - self.0.tcx, - parent_trait_ref.def_id, - ty::GenericArgs::identity_for_item(self.0.tcx, parent), - ); - - if check_args_compatible(self.0.tcx, assoc, impl_args) { - return self - .0 - .tcx - .type_of(assoc.def_id) - .instantiate(self.0.tcx, impl_args) - .visit_with(self); - } else { - self.0.tcx.dcx().span_bug( - self.0.tcx.def_span(assoc.def_id), - "item had incorrect args", - ); - } - } - } - } - _ => trace!(kind=?t.kind()), - } - ControlFlow::Continue(()) - } -} - fn impl_trait_in_assoc_types_defined_by<'tcx>( tcx: TyCtxt<'tcx>, item: LocalDefId, ) -> &'tcx ty::List<LocalDefId> { - let mut collector = ImplTraitInAssocTypeCollector(OpaqueTypeCollector::new(tcx, item)); + let mut collector = OpaqueTypeCollector::new(tcx, item, CollectionMode::ImplTraitInAssocTypes); super::sig_types::walk_types(tcx, item, &mut collector); - tcx.mk_local_def_ids(&collector.0.opaques) + tcx.mk_local_def_ids(&collector.opaques) } fn opaque_types_defined_by<'tcx>( @@ -366,7 +302,8 @@ fn opaque_types_defined_by<'tcx>( ) -> &'tcx ty::List<LocalDefId> { let kind = tcx.def_kind(item); trace!(?kind); - let mut collector = OpaqueTypeCollector::new(tcx, item); + let mut collector = + OpaqueTypeCollector::new(tcx, item, CollectionMode::TypeAliasImplTraitTransition); super::sig_types::walk_types(tcx, item, &mut collector); match kind { DefKind::AssocFn diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 084157b97ab..facfc9d208e 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -944,6 +944,21 @@ impl<T, A: Allocator> Rc<T, A> { /// is in fact equivalent to <code>[Rc::try_unwrap]\(this).[ok][Result::ok]()</code>. /// (Note that the same kind of equivalence does **not** hold true for /// [`Arc`](crate::sync::Arc), due to race conditions that do not apply to `Rc`!) + /// + /// # Examples + /// + /// ``` + /// use std::rc::Rc; + /// + /// let x = Rc::new(3); + /// assert_eq!(Rc::into_inner(x), Some(3)); + /// + /// let x = Rc::new(4); + /// let y = Rc::clone(&x); + /// + /// assert_eq!(Rc::into_inner(y), None); + /// assert_eq!(Rc::into_inner(x), Some(4)); + /// ``` #[inline] #[stable(feature = "rc_into_inner", since = "1.70.0")] pub fn into_inner(this: Self) -> Option<T> { @@ -1329,6 +1344,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> { /// let x_ptr = Rc::into_raw(x); /// assert_eq!(unsafe { &*x_ptr }, "hello"); /// ``` + #[must_use = "losing the pointer will leak memory"] #[stable(feature = "rc_raw", since = "1.17.0")] #[rustc_never_returns_null_ptr] pub fn into_raw(this: Self) -> *const T { @@ -2970,7 +2986,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> { /// /// [`from_raw`]: Weak::from_raw /// [`as_ptr`]: Weak::as_ptr - #[must_use = "`self` will be dropped if the result is not used"] + #[must_use = "losing the pointer will leak memory"] #[stable(feature = "weak_into_raw", since = "1.45.0")] pub fn into_raw(self) -> *const T { let result = self.as_ptr(); diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 00f47f5c6e0..80f0f2acc99 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2719,7 +2719,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> { /// /// [`from_raw`]: Weak::from_raw /// [`as_ptr`]: Weak::as_ptr - #[must_use = "`self` will be dropped if the result is not used"] + #[must_use = "losing the pointer will leak memory"] #[stable(feature = "weak_into_raw", since = "1.45.0")] pub fn into_raw(self) -> *const T { let result = self.as_ptr(); diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 7bd19875584..c0e934b3b1f 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1490,6 +1490,12 @@ impl<T, A: Allocator> Vec<T, A> { /// vec.insert(4, 5); /// assert_eq!(vec, [1, 4, 2, 3, 5]); /// ``` + /// + /// # Time complexity + /// + /// Takes *O*([`Vec::len`]) time. All items after the insertion index must be + /// shifted to the right. In the worst case, all elements are shifted when + /// the insertion index is 0. #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] pub fn insert(&mut self, index: usize, element: T) { @@ -1913,6 +1919,13 @@ impl<T, A: Allocator> Vec<T, A> { /// vec.push(3); /// assert_eq!(vec, [1, 2, 3]); /// ``` + /// + /// # Time complexity + /// + /// Takes amortized *O*(1) time. If the vector's length would exceed its + /// capacity after the push, *O*(*capacity*) time is taken to copy the + /// vector's elements to a larger allocation. This expensive operation is + /// offset by the *capacity* *O*(1) insertions it allows. #[cfg(not(no_global_oom_handling))] #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -1961,6 +1974,10 @@ impl<T, A: Allocator> Vec<T, A> { /// } /// assert_eq!(from_iter_fallible(0..100), Ok(Vec::from_iter(0..100))); /// ``` + /// + /// # Time complexity + /// + /// Takes *O*(1) time. #[inline] #[unstable(feature = "vec_push_within_capacity", issue = "100486")] pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> { @@ -1990,6 +2007,10 @@ impl<T, A: Allocator> Vec<T, A> { /// assert_eq!(vec.pop(), Some(3)); /// assert_eq!(vec, [1, 2]); /// ``` + /// + /// # Time complexity + /// + /// Takes *O*(1) time. #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn pop(&mut self) -> Option<T> { diff --git a/library/core/benches/lib.rs b/library/core/benches/lib.rs index fdefc9a714e..4d14b930e41 100644 --- a/library/core/benches/lib.rs +++ b/library/core/benches/lib.rs @@ -16,6 +16,7 @@ mod char; mod fmt; mod hash; mod iter; +mod net; mod num; mod ops; mod pattern; diff --git a/library/core/benches/net/addr_parser.rs b/library/core/benches/net/addr_parser.rs new file mode 100644 index 00000000000..b9406a9779d --- /dev/null +++ b/library/core/benches/net/addr_parser.rs @@ -0,0 +1,78 @@ +use core::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; +use core::str::FromStr; + +use test::{black_box, Bencher}; + +const IPV4_STR: &str = "192.168.0.1"; +const IPV4_STR_PORT: &str = "192.168.0.1:8080"; + +const IPV6_STR_FULL: &str = "2001:db8:0:0:0:0:c0a8:1"; +const IPV6_STR_COMPRESS: &str = "2001:db8::c0a8:1"; +const IPV6_STR_V4: &str = "2001:db8::192.168.0.1"; +const IPV6_STR_PORT: &str = "[2001:db8::c0a8:1]:8080"; +const IPV6_STR_PORT_SCOPE_ID: &str = "[2001:db8::c0a8:1%1337]:8080"; + +#[bench] +fn bench_parse_ipv4(b: &mut Bencher) { + b.iter(|| Ipv4Addr::from_str(black_box(IPV4_STR))); +} + +#[bench] +fn bench_parse_ipv6_full(b: &mut Bencher) { + b.iter(|| Ipv6Addr::from_str(black_box(IPV6_STR_FULL))); +} + +#[bench] +fn bench_parse_ipv6_compress(b: &mut Bencher) { + b.iter(|| Ipv6Addr::from_str(black_box(IPV6_STR_COMPRESS))); +} + +#[bench] +fn bench_parse_ipv6_v4(b: &mut Bencher) { + b.iter(|| Ipv6Addr::from_str(black_box(IPV6_STR_V4))); +} + +#[bench] +fn bench_parse_ipaddr_v4(b: &mut Bencher) { + b.iter(|| IpAddr::from_str(black_box(IPV4_STR))); +} + +#[bench] +fn bench_parse_ipaddr_v6_full(b: &mut Bencher) { + b.iter(|| IpAddr::from_str(black_box(IPV6_STR_FULL))); +} + +#[bench] +fn bench_parse_ipaddr_v6_compress(b: &mut Bencher) { + b.iter(|| IpAddr::from_str(black_box(IPV6_STR_COMPRESS))); +} + +#[bench] +fn bench_parse_ipaddr_v6_v4(b: &mut Bencher) { + b.iter(|| IpAddr::from_str(black_box(IPV6_STR_V4))); +} + +#[bench] +fn bench_parse_socket_v4(b: &mut Bencher) { + b.iter(|| SocketAddrV4::from_str(black_box(IPV4_STR_PORT))); +} + +#[bench] +fn bench_parse_socket_v6(b: &mut Bencher) { + b.iter(|| SocketAddrV6::from_str(black_box(IPV6_STR_PORT))); +} + +#[bench] +fn bench_parse_socket_v6_scope_id(b: &mut Bencher) { + b.iter(|| SocketAddrV6::from_str(black_box(IPV6_STR_PORT_SCOPE_ID))); +} + +#[bench] +fn bench_parse_socketaddr_v4(b: &mut Bencher) { + b.iter(|| SocketAddr::from_str(black_box(IPV4_STR_PORT))); +} + +#[bench] +fn bench_parse_socketaddr_v6(b: &mut Bencher) { + b.iter(|| SocketAddr::from_str(black_box(IPV6_STR_PORT))); +} diff --git a/library/core/benches/net/mod.rs b/library/core/benches/net/mod.rs new file mode 100644 index 00000000000..c29aed46ccd --- /dev/null +++ b/library/core/benches/net/mod.rs @@ -0,0 +1 @@ +mod addr_parser; diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index a93b94867ce..65ae4831839 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -927,7 +927,7 @@ impl char { #[must_use] #[inline] pub(crate) fn is_grapheme_extended(self) -> bool { - unicode::Grapheme_Extend(self) + self > '\x7f' && unicode::Grapheme_Extend(self) } /// Returns `true` if this `char` has one of the general categories for numbers. diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs index af2e422e8a0..6dd3069034d 100644 --- a/library/core/src/future/future.rs +++ b/library/core/src/future/future.rs @@ -30,8 +30,7 @@ use crate::task::{Context, Poll}; #[lang = "future_trait"] #[diagnostic::on_unimplemented( label = "`{Self}` is not a future", - message = "`{Self}` is not a future", - note = "{Self} must be a future or must implement `IntoFuture` to be awaited" + message = "`{Self}` is not a future" )] pub trait Future { /// The type of value produced on completion. diff --git a/library/core/src/future/into_future.rs b/library/core/src/future/into_future.rs index 38c654e76b4..eb5a9b72dd0 100644 --- a/library/core/src/future/into_future.rs +++ b/library/core/src/future/into_future.rs @@ -100,6 +100,11 @@ use crate::future::Future; /// ``` #[stable(feature = "into_future", since = "1.64.0")] #[rustc_diagnostic_item = "IntoFuture"] +#[diagnostic::on_unimplemented( + label = "`{Self}` is not a future", + message = "`{Self}` is not a future", + note = "{Self} must be a future or must implement `IntoFuture` to be awaited" +)] pub trait IntoFuture { /// The output that the future will produce on completion. #[stable(feature = "into_future", since = "1.64.0")] diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 0d1cf7941fb..d89801bce2b 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -236,6 +236,49 @@ pub trait FromIterator<A>: Sized { /// ``` #[rustc_diagnostic_item = "IntoIterator"] #[rustc_skip_array_during_method_dispatch] +#[rustc_on_unimplemented( + on( + _Self = "core::ops::range::RangeTo<Idx>", + label = "if you meant to iterate until a value, add a starting value", + note = "`..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a \ + bounded `Range`: `0..end`" + ), + on( + _Self = "core::ops::range::RangeToInclusive<Idx>", + label = "if you meant to iterate until a value (including it), add a starting value", + note = "`..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant \ + to have a bounded `RangeInclusive`: `0..=end`" + ), + on( + _Self = "[]", + label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`" + ), + on(_Self = "&[]", label = "`{Self}` is not an iterator; try calling `.iter()`"), + on( + _Self = "alloc::vec::Vec<T, A>", + label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`" + ), + on( + _Self = "&str", + label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" + ), + on( + _Self = "alloc::string::String", + label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" + ), + on( + _Self = "{integral}", + note = "if you want to iterate between `start` until a value `end`, use the exclusive range \ + syntax `start..end` or the inclusive range syntax `start..=end`" + ), + on( + _Self = "{float}", + note = "if you want to iterate between `start` until a value `end`, use the exclusive range \ + syntax `start..end` or the inclusive range syntax `start..=end`" + ), + label = "`{Self}` is not an iterator", + message = "`{Self}` is not an iterator" +)] #[stable(feature = "rust1", since = "1.0.0")] pub trait IntoIterator { /// The type of the elements being iterated over. diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 3267cea38b7..e1904ed220c 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -28,42 +28,11 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {} #[rustc_on_unimplemented( on( _Self = "core::ops::range::RangeTo<Idx>", - label = "if you meant to iterate until a value, add a starting value", - note = "`..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a \ - bounded `Range`: `0..end`" + note = "you might have meant to use a bounded `Range`" ), on( _Self = "core::ops::range::RangeToInclusive<Idx>", - label = "if you meant to iterate until a value (including it), add a starting value", - note = "`..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant \ - to have a bounded `RangeInclusive`: `0..=end`" - ), - on( - _Self = "[]", - label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`" - ), - on(_Self = "&[]", label = "`{Self}` is not an iterator; try calling `.iter()`"), - on( - _Self = "alloc::vec::Vec<T, A>", - label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`" - ), - on( - _Self = "&str", - label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" - ), - on( - _Self = "alloc::string::String", - label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" - ), - on( - _Self = "{integral}", - note = "if you want to iterate between `start` until a value `end`, use the exclusive range \ - syntax `start..end` or the inclusive range syntax `start..=end`" - ), - on( - _Self = "{float}", - note = "if you want to iterate between `start` until a value `end`, use the exclusive range \ - syntax `start..end` or the inclusive range syntax `start..=end`" + note = "you might have meant to use a bounded `RangeInclusive`" ), label = "`{Self}` is not an iterator", message = "`{Self}` is not an iterator" diff --git a/library/core/src/net/parser.rs b/library/core/src/net/parser.rs index b9a1924d668..835ab9d73af 100644 --- a/library/core/src/net/parser.rs +++ b/library/core/src/net/parser.rs @@ -3,7 +3,7 @@ //! This module is "publicly exported" through the `FromStr` implementations //! below. -use crate::convert::TryInto; +use crate::convert::{TryFrom, TryInto}; use crate::error::Error; use crate::fmt; use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; @@ -104,36 +104,66 @@ impl<'a> Parser<'a> { // Read a number off the front of the input in the given radix, stopping // at the first non-digit character or eof. Fails if the number has more // digits than max_digits or if there is no number. - fn read_number<T: ReadNumberHelper>( + // + // INVARIANT: `max_digits` must be less than the number of digits that `u32` + // can represent. + fn read_number<T: ReadNumberHelper + TryFrom<u32>>( &mut self, radix: u32, max_digits: Option<usize>, allow_zero_prefix: bool, ) -> Option<T> { - self.read_atomically(move |p| { - let mut result = T::ZERO; - let mut digit_count = 0; - let has_leading_zero = p.peek_char() == Some('0'); - - while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) { - result = result.checked_mul(radix)?; - result = result.checked_add(digit)?; - digit_count += 1; - if let Some(max_digits) = max_digits { + // If max_digits.is_some(), then we are parsing a `u8` or `u16` and + // don't need to use checked arithmetic since it fits within a `u32`. + if let Some(max_digits) = max_digits { + // u32::MAX = 4_294_967_295u32, which is 10 digits long. + // `max_digits` must be less than 10 to not overflow a `u32`. + debug_assert!(max_digits < 10); + + self.read_atomically(move |p| { + let mut result = 0_u32; + let mut digit_count = 0; + let has_leading_zero = p.peek_char() == Some('0'); + + while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) { + result *= radix; + result += digit; + digit_count += 1; + if digit_count > max_digits { return None; } } - } - if digit_count == 0 { - None - } else if !allow_zero_prefix && has_leading_zero && digit_count > 1 { - None - } else { - Some(result) - } - }) + if digit_count == 0 { + None + } else if !allow_zero_prefix && has_leading_zero && digit_count > 1 { + None + } else { + result.try_into().ok() + } + }) + } else { + self.read_atomically(move |p| { + let mut result = T::ZERO; + let mut digit_count = 0; + let has_leading_zero = p.peek_char() == Some('0'); + + while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) { + result = result.checked_mul(radix)?; + result = result.checked_add(digit)?; + digit_count += 1; + } + + if digit_count == 0 { + None + } else if !allow_zero_prefix && has_leading_zero && digit_count > 1 { + None + } else { + Some(result) + } + }) + } } /// Read an IPv4 address. diff --git a/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs b/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs index 394f95e9144..a0773c85bef 100644 --- a/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs +++ b/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs @@ -84,10 +84,16 @@ pub fn check(tests_path: impl AsRef<Path>, bad: &mut bool) { } }); - let Some((test_name, _)) = test.to_str().map(|s| s.split_once('.')).flatten() else { + let Some(test_name) = test.file_stem().map(OsStr::to_str).flatten() else { continue; }; + assert!( + !test_name.contains('.'), + "test name cannot contain dots '.': `{}`", + test.display() + ); + test_info.insert(test_name.to_string(), (test, expected_revisions)); } @@ -98,14 +104,20 @@ pub fn check(tests_path: impl AsRef<Path>, bad: &mut bool) { for sibling in files_under_inspection.iter().filter(|f| { f.extension().map(OsStr::to_str).flatten().is_some_and(|ext| EXTENSIONS.contains(&ext)) }) { - let filename_components = sibling.to_str().unwrap().split('.').collect::<Vec<_>>(); - let file_prefix = filename_components[0]; + let Some(filename) = sibling.file_name().map(OsStr::to_str).flatten() else { + continue; + }; + + let filename_components = filename.split('.').collect::<Vec<_>>(); + let [file_prefix, ..] = &filename_components[..] else { + continue; + }; - let Some((test_path, expected_revisions)) = test_info.get(file_prefix) else { + let Some((test_path, expected_revisions)) = test_info.get(*file_prefix) else { continue; }; - match filename_components[..] { + match &filename_components[..] { // Cannot have a revision component, skip. [] | [_] => return, [_, _] if !expected_revisions.is_empty() => { @@ -120,9 +132,9 @@ pub fn check(tests_path: impl AsRef<Path>, bad: &mut bool) { [_, _] => return, [_, found_revision, .., extension] => { if !IGNORES.contains(&found_revision) - && !expected_revisions.contains(found_revision) + && !expected_revisions.contains(*found_revision) // This is from `//@ stderr-per-bitwidth` - && !(extension == "stderr" && ["32bit", "64bit"].contains(&found_revision)) + && !(*extension == "stderr" && ["32bit", "64bit"].contains(&found_revision)) { // Found some unexpected revision-esque component that is not a known // compare-mode or expected revision. diff --git a/tests/rustdoc/invalid.crate.name.rs b/tests/rustdoc/invalid$crate$name.rs index 189a6c92124..189a6c92124 100644 --- a/tests/rustdoc/invalid.crate.name.rs +++ b/tests/rustdoc/invalid$crate$name.rs diff --git a/tests/ui/associated-types/substs-ppaux.normal.stderr b/tests/ui/associated-types/substs-ppaux.normal.stderr index 93118616f02..a2647f66835 100644 --- a/tests/ui/associated-types/substs-ppaux.normal.stderr +++ b/tests/ui/associated-types/substs-ppaux.normal.stderr @@ -70,13 +70,12 @@ help: use parentheses to call this function LL | let x: () = foo::<'static>(); | ++ -error[E0277]: the size for values of type `str` cannot be known at compilation time +error[E0277]: the trait bound `str: Foo<'_, '_, u8>` is not satisfied --> $DIR/substs-ppaux.rs:49:6 | LL | <str as Foo<u8>>::bar; - | ^^^ doesn't have a size known at compile-time + | ^^^ the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'_, '_, u8>` | - = help: the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'_, '_, u8>` note: required for `str` to implement `Foo<'_, '_, u8>` --> $DIR/substs-ppaux.rs:11:17 | diff --git a/tests/ui/associated-types/substs-ppaux.rs b/tests/ui/associated-types/substs-ppaux.rs index d32cdd24658..077ca764e24 100644 --- a/tests/ui/associated-types/substs-ppaux.rs +++ b/tests/ui/associated-types/substs-ppaux.rs @@ -47,6 +47,6 @@ fn foo<'z>() where &'z (): Sized { //[normal]~| found fn item `fn() {foo::<'static>}` <str as Foo<u8>>::bar; - //[verbose]~^ ERROR the size for values of type - //[normal]~^^ ERROR the size for values of type + //[verbose]~^ ERROR the trait bound `str: Foo<'?0, '?1, u8>` is not satisfied + //[normal]~^^ ERROR the trait bound `str: Foo<'_, '_, u8>` is not satisfied } diff --git a/tests/ui/associated-types/substs-ppaux.verbose.stderr b/tests/ui/associated-types/substs-ppaux.verbose.stderr index 13d3156fb80..d32f44ccd64 100644 --- a/tests/ui/associated-types/substs-ppaux.verbose.stderr +++ b/tests/ui/associated-types/substs-ppaux.verbose.stderr @@ -70,13 +70,12 @@ help: use parentheses to call this function LL | let x: () = foo::<'static>(); | ++ -error[E0277]: the size for values of type `str` cannot be known at compilation time +error[E0277]: the trait bound `str: Foo<'?0, '?1, u8>` is not satisfied --> $DIR/substs-ppaux.rs:49:6 | LL | <str as Foo<u8>>::bar; - | ^^^ doesn't have a size known at compile-time + | ^^^ the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'?0, '?1, u8>` | - = help: the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'?0, '?1, u8>` note: required for `str` to implement `Foo<'?0, '?1, u8>` --> $DIR/substs-ppaux.rs:11:17 | diff --git a/tests/ui/async-await/async-error-span.stderr b/tests/ui/async-await/async-error-span.stderr index 2ec968ffc03..44f1583f4cc 100644 --- a/tests/ui/async-await/async-error-span.stderr +++ b/tests/ui/async-await/async-error-span.stderr @@ -5,7 +5,6 @@ LL | fn get_future() -> impl Future<Output = ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future | = help: the trait `Future` is not implemented for `()` - = note: () must be a future or must implement `IntoFuture` to be awaited error[E0282]: type annotations needed --> $DIR/async-error-span.rs:13:9 diff --git a/tests/ui/async-await/async-outside-of-await-issue-121096.rs b/tests/ui/async-await/async-outside-of-await-issue-121096.rs new file mode 100644 index 00000000000..e3999035ef9 --- /dev/null +++ b/tests/ui/async-await/async-outside-of-await-issue-121096.rs @@ -0,0 +1,9 @@ +//@ edition:2021 + +fn main() { + async { + use std::ops::Add; + let _ = 1.add(3); + }.await + //~^ ERROR `await` is only allowed inside `async` functions and blocks +} diff --git a/tests/ui/async-await/async-outside-of-await-issue-121096.stderr b/tests/ui/async-await/async-outside-of-await-issue-121096.stderr new file mode 100644 index 00000000000..b0677a83864 --- /dev/null +++ b/tests/ui/async-await/async-outside-of-await-issue-121096.stderr @@ -0,0 +1,12 @@ +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/async-outside-of-await-issue-121096.rs:7:7 + | +LL | fn main() { + | ---- this is not `async` +... +LL | }.await + | ^^^^^ only allowed inside `async` functions and blocks + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0728`. diff --git a/tests/ui/async-await/coroutine-not-future.stderr b/tests/ui/async-await/coroutine-not-future.stderr index 130c5ef526b..580217fb4f8 100644 --- a/tests/ui/async-await/coroutine-not-future.stderr +++ b/tests/ui/async-await/coroutine-not-future.stderr @@ -49,7 +49,6 @@ LL | takes_future(returns_coroutine()); | required by a bound introduced by this call | = help: the trait `Future` is not implemented for `impl Coroutine<Yield = (), Return = ()>` - = note: impl Coroutine<Yield = (), Return = ()> must be a future or must implement `IntoFuture` to be awaited note: required by a bound in `takes_future` --> $DIR/coroutine-not-future.rs:17:26 | @@ -69,7 +68,6 @@ LL | | }); | |_____^ `{coroutine@$DIR/coroutine-not-future.rs:41:18: 41:23}` is not a future | = help: the trait `Future` is not implemented for `{coroutine@$DIR/coroutine-not-future.rs:41:18: 41:23}` - = note: {coroutine@$DIR/coroutine-not-future.rs:41:18: 41:23} must be a future or must implement `IntoFuture` to be awaited note: required by a bound in `takes_future` --> $DIR/coroutine-not-future.rs:17:26 | diff --git a/tests/ui/auto-traits/typeck-default-trait-impl-precedence.rs b/tests/ui/auto-traits/typeck-default-trait-impl-precedence.rs index 2bbe82270bd..5baa4f10c44 100644 --- a/tests/ui/auto-traits/typeck-default-trait-impl-precedence.rs +++ b/tests/ui/auto-traits/typeck-default-trait-impl-precedence.rs @@ -17,5 +17,5 @@ impl Signed for i32 { } fn main() { is_defaulted::<&'static i32>(); is_defaulted::<&'static u32>(); - //~^ ERROR `u32: Signed` is not satisfied + //~^ ERROR the trait bound `&'static u32: Defaulted` is not satisfied } diff --git a/tests/ui/auto-traits/typeck-default-trait-impl-precedence.stderr b/tests/ui/auto-traits/typeck-default-trait-impl-precedence.stderr index e699422ae2b..47bb1a059be 100644 --- a/tests/ui/auto-traits/typeck-default-trait-impl-precedence.stderr +++ b/tests/ui/auto-traits/typeck-default-trait-impl-precedence.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `u32: Signed` is not satisfied +error[E0277]: the trait bound `&'static u32: Defaulted` is not satisfied --> $DIR/typeck-default-trait-impl-precedence.rs:19:20 | LL | is_defaulted::<&'static u32>(); - | ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`, which is required by `&'static u32: Defaulted` + | ^^^^^^^^^^^^ the trait `Signed` is not implemented for `&'static u32`, which is required by `&'static u32: Defaulted` | note: required for `&'static u32` to implement `Defaulted` --> $DIR/typeck-default-trait-impl-precedence.rs:10:19 diff --git a/tests/ui/check-cfg/mix.rs b/tests/ui/check-cfg/mix.rs index ba30bc1e69b..69156ab6763 100644 --- a/tests/ui/check-cfg/mix.rs +++ b/tests/ui/check-cfg/mix.rs @@ -74,6 +74,8 @@ fn test_cfg_macro() { //~^ WARNING unexpected `cfg` condition value //~| WARNING unexpected `cfg` condition value //~| WARNING unexpected `cfg` condition value + cfg!(target_feature = "zebra"); + //~^ WARNING unexpected `cfg` condition value } fn main() {} diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr index 77643f227d9..93333e5ef2a 100644 --- a/tests/ui/check-cfg/mix.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -245,5 +245,14 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration -warning: 26 warnings emitted +warning: unexpected `cfg` condition value: `zebra` + --> $DIR/mix.rs:77:10 + | +LL | cfg!(target_feature = "zebra"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2` and 186 more + = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + +warning: 27 warnings emitted diff --git a/tests/ui/check-cfg/well-known-values.rs b/tests/ui/check-cfg/well-known-values.rs index 859a36c604c..fa062a3fe2e 100644 --- a/tests/ui/check-cfg/well-known-values.rs +++ b/tests/ui/check-cfg/well-known-values.rs @@ -6,6 +6,7 @@ // //@ check-pass //@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: -Zcheck-cfg-all-expected #![feature(cfg_overflow_checks)] #![feature(cfg_relocation_model)] diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 01fc3f83f16..86df829fe72 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:25:5 + --> $DIR/well-known-values.rs:26:5 | LL | clippy = "_UNEXPECTED_VALUE", | ^^^^^^---------------------- @@ -11,7 +11,7 @@ LL | clippy = "_UNEXPECTED_VALUE", = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:27:5 + --> $DIR/well-known-values.rs:28:5 | LL | debug_assertions = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^---------------------- @@ -22,7 +22,7 @@ LL | debug_assertions = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:29:5 + --> $DIR/well-known-values.rs:30:5 | LL | doc = "_UNEXPECTED_VALUE", | ^^^---------------------- @@ -33,7 +33,7 @@ LL | doc = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:31:5 + --> $DIR/well-known-values.rs:32:5 | LL | doctest = "_UNEXPECTED_VALUE", | ^^^^^^^---------------------- @@ -44,7 +44,7 @@ LL | doctest = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:33:5 + --> $DIR/well-known-values.rs:34:5 | LL | miri = "_UNEXPECTED_VALUE", | ^^^^---------------------- @@ -55,7 +55,7 @@ LL | miri = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:35:5 + --> $DIR/well-known-values.rs:36:5 | LL | overflow_checks = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^---------------------- @@ -66,7 +66,7 @@ LL | overflow_checks = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:37:5 + --> $DIR/well-known-values.rs:38:5 | LL | panic = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -75,7 +75,7 @@ LL | panic = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:39:5 + --> $DIR/well-known-values.rs:40:5 | LL | proc_macro = "_UNEXPECTED_VALUE", | ^^^^^^^^^^---------------------- @@ -86,7 +86,7 @@ LL | proc_macro = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:41:5 + --> $DIR/well-known-values.rs:42:5 | LL | relocation_model = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -95,7 +95,7 @@ LL | relocation_model = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:43:5 + --> $DIR/well-known-values.rs:44:5 | LL | sanitize = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -104,7 +104,7 @@ LL | sanitize = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:45:5 + --> $DIR/well-known-values.rs:46:5 | LL | target_abi = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -113,7 +113,7 @@ LL | target_abi = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:47:5 + --> $DIR/well-known-values.rs:48:5 | LL | target_arch = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | target_arch = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:49:5 + --> $DIR/well-known-values.rs:50:5 | LL | target_endian = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -131,7 +131,7 @@ LL | target_endian = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:51:5 + --> $DIR/well-known-values.rs:52:5 | LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -140,7 +140,7 @@ LL | target_env = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:53:5 + --> $DIR/well-known-values.rs:54:5 | LL | target_family = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -149,7 +149,7 @@ LL | target_family = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:55:5 + --> $DIR/well-known-values.rs:56:5 | LL | target_feature = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -158,7 +158,7 @@ LL | target_feature = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:57:5 + --> $DIR/well-known-values.rs:58:5 | LL | target_has_atomic = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -167,7 +167,7 @@ LL | target_has_atomic = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:59:5 + --> $DIR/well-known-values.rs:60:5 | LL | target_has_atomic_equal_alignment = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -176,7 +176,7 @@ LL | target_has_atomic_equal_alignment = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:61:5 + --> $DIR/well-known-values.rs:62:5 | LL | target_has_atomic_load_store = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -185,7 +185,7 @@ LL | target_has_atomic_load_store = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:63:5 + --> $DIR/well-known-values.rs:64:5 | LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -194,7 +194,7 @@ LL | target_os = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:65:5 + --> $DIR/well-known-values.rs:66:5 | LL | target_pointer_width = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -203,7 +203,7 @@ LL | target_pointer_width = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:67:5 + --> $DIR/well-known-values.rs:68:5 | LL | target_thread_local = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^---------------------- @@ -214,7 +214,7 @@ LL | target_thread_local = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:69:5 + --> $DIR/well-known-values.rs:70:5 | LL | target_vendor = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -223,7 +223,7 @@ LL | target_vendor = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:71:5 + --> $DIR/well-known-values.rs:72:5 | LL | test = "_UNEXPECTED_VALUE", | ^^^^---------------------- @@ -234,7 +234,7 @@ LL | test = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:73:5 + --> $DIR/well-known-values.rs:74:5 | LL | unix = "_UNEXPECTED_VALUE", | ^^^^---------------------- @@ -245,7 +245,7 @@ LL | unix = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` - --> $DIR/well-known-values.rs:75:5 + --> $DIR/well-known-values.rs:76:5 | LL | windows = "_UNEXPECTED_VALUE", | ^^^^^^^---------------------- @@ -256,7 +256,7 @@ LL | windows = "_UNEXPECTED_VALUE", = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `linuz` - --> $DIR/well-known-values.rs:81:7 + --> $DIR/well-known-values.rs:82:7 | LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | ^^^^^^^^^^^^------- diff --git a/tests/ui/command/need-crate-arg-ignore-tidy.x.rs b/tests/ui/command/need-crate-arg-ignore-tidy$x.rs index b1ac4a4ae21..b1ac4a4ae21 100644 --- a/tests/ui/command/need-crate-arg-ignore-tidy.x.rs +++ b/tests/ui/command/need-crate-arg-ignore-tidy$x.rs diff --git a/tests/ui/command/need-crate-arg-ignore-tidy.x.stderr b/tests/ui/command/need-crate-arg-ignore-tidy$x.stderr index 89f7210c048..28f6d31b1ce 100644 --- a/tests/ui/command/need-crate-arg-ignore-tidy.x.stderr +++ b/tests/ui/command/need-crate-arg-ignore-tidy$x.stderr @@ -1,4 +1,4 @@ -error: invalid character `'.'` in crate name: `need_crate_arg_ignore_tidy.x` +error: invalid character `'$'` in crate name: `need_crate_arg_ignore_tidy$x` | = help: you can either pass `--crate-name` on the command line or add `#![crate_name="…"]` to set the crate name diff --git a/tests/ui/coroutine/gen_block_is_no_future.stderr b/tests/ui/coroutine/gen_block_is_no_future.stderr index f9e23e45b44..fb2f2ba5597 100644 --- a/tests/ui/coroutine/gen_block_is_no_future.stderr +++ b/tests/ui/coroutine/gen_block_is_no_future.stderr @@ -5,7 +5,6 @@ LL | fn foo() -> impl std::future::Future { | ^^^^^^^^^^^^^^^^^^^^^^^^ `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21}` is not a future | = help: the trait `Future` is not implemented for `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21}` - = note: {gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21} must be a future or must implement `IntoFuture` to be awaited error: aborting due to 1 previous error diff --git a/tests/ui/feature-gates/feature-gate-trivial_bounds.stderr b/tests/ui/feature-gates/feature-gate-trivial_bounds.stderr index 7fc726409ce..5e62221628d 100644 --- a/tests/ui/feature-gates/feature-gate-trivial_bounds.stderr +++ b/tests/ui/feature-gates/feature-gate-trivial_bounds.stderr @@ -74,7 +74,6 @@ LL | fn use_for() where i32: Iterator { | ^^^^^^^^^^^^^ `i32` is not an iterator | = help: the trait `Iterator` is not implemented for `i32` - = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = help: see issue #48214 = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable diff --git a/tests/ui/for/issue-20605.current.stderr b/tests/ui/for/issue-20605.current.stderr index c8d39afdeb9..9e706601ef5 100644 --- a/tests/ui/for/issue-20605.current.stderr +++ b/tests/ui/for/issue-20605.current.stderr @@ -1,4 +1,4 @@ -error[E0277]: the size for values of type `dyn Iterator<Item = &'a mut u8>` cannot be known at compilation time +error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator --> $DIR/issue-20605.rs:5:17 | LL | for item in *things { *item = 0 } diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr index a44faa5491d..f9c3848476c 100644 --- a/tests/ui/for/issue-20605.next.stderr +++ b/tests/ui/for/issue-20605.next.stderr @@ -1,8 +1,10 @@ -error[E0277]: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied +error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator --> $DIR/issue-20605.rs:5:17 | LL | for item in *things { *item = 0 } - | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>` + | ^^^^^^^ `dyn Iterator<Item = &'a mut u8>` is not an iterator + | + = help: the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>` error: the type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed --> $DIR/issue-20605.rs:5:17 diff --git a/tests/ui/for/issue-20605.rs b/tests/ui/for/issue-20605.rs index 4a9f62b6612..1c01de967cc 100644 --- a/tests/ui/for/issue-20605.rs +++ b/tests/ui/for/issue-20605.rs @@ -3,8 +3,8 @@ fn changer<'a>(mut things: Box<dyn Iterator<Item=&'a mut u8>>) { for item in *things { *item = 0 } - //[current]~^ ERROR the size for values of type - //[next]~^^ ERROR the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied + //[current]~^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator + //[next]~^^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator //[next]~| ERROR the type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed //[next]~| ERROR the type `&mut <dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed //[next]~| ERROR the type `Option<<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed diff --git a/tests/ui/impl-trait/issues/issue-83919.stderr b/tests/ui/impl-trait/issues/issue-83919.stderr index 200257235fe..b0bd6ed116b 100644 --- a/tests/ui/impl-trait/issues/issue-83919.stderr +++ b/tests/ui/impl-trait/issues/issue-83919.stderr @@ -5,7 +5,6 @@ LL | fn get_fut(&self) -> Self::Fut { | ^^^^^^^^^ `{integer}` is not a future | = help: the trait `Future` is not implemented for `{integer}` - = note: {integer} must be a future or must implement `IntoFuture` to be awaited error: aborting due to 1 previous error diff --git a/tests/ui/issues-71798.stderr b/tests/ui/issues-71798.stderr index 829d0a02ec9..52dd14ccb0a 100644 --- a/tests/ui/issues-71798.stderr +++ b/tests/ui/issues-71798.stderr @@ -14,7 +14,6 @@ LL | *x | -- return type was inferred to be `u32` here | = help: the trait `Future` is not implemented for `u32` - = note: u32 must be a future or must implement `IntoFuture` to be awaited error: aborting due to 2 previous errors diff --git a/tests/ui/iterators/bound.stderr b/tests/ui/iterators/bound.stderr index e5ed19f3731..915f0496716 100644 --- a/tests/ui/iterators/bound.stderr +++ b/tests/ui/iterators/bound.stderr @@ -5,7 +5,6 @@ LL | struct T(S<u8>); | ^^^^^ `u8` is not an iterator | = help: the trait `Iterator` is not implemented for `u8` - = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` note: required by a bound in `S` --> $DIR/bound.rs:1:13 | diff --git a/tests/ui/iterators/vec-on-unimplemented.fixed b/tests/ui/iterators/vec-on-unimplemented.fixed new file mode 100644 index 00000000000..cc46bd67f9a --- /dev/null +++ b/tests/ui/iterators/vec-on-unimplemented.fixed @@ -0,0 +1,5 @@ +//@ run-rustfix +fn main() { + let _ = vec![true, false].into_iter().map(|v| !v).collect::<Vec<_>>(); + //~^ ERROR no method named `map` found for struct `Vec<bool>` in the current scope +} diff --git a/tests/ui/iterators/vec-on-unimplemented.rs b/tests/ui/iterators/vec-on-unimplemented.rs index 42b5d36bfad..7367fd4c9cd 100644 --- a/tests/ui/iterators/vec-on-unimplemented.rs +++ b/tests/ui/iterators/vec-on-unimplemented.rs @@ -1,4 +1,5 @@ +//@ run-rustfix fn main() { - vec![true, false].map(|v| !v).collect::<Vec<_>>(); - //~^ ERROR `Vec<bool>` is not an iterator + let _ = vec![true, false].map(|v| !v).collect::<Vec<_>>(); + //~^ ERROR no method named `map` found for struct `Vec<bool>` in the current scope } diff --git a/tests/ui/iterators/vec-on-unimplemented.stderr b/tests/ui/iterators/vec-on-unimplemented.stderr index 29b19d5e3b4..d6f4bfa1cde 100644 --- a/tests/ui/iterators/vec-on-unimplemented.stderr +++ b/tests/ui/iterators/vec-on-unimplemented.stderr @@ -1,14 +1,13 @@ -error[E0599]: `Vec<bool>` is not an iterator - --> $DIR/vec-on-unimplemented.rs:2:23 +error[E0599]: no method named `map` found for struct `Vec<bool>` in the current scope + --> $DIR/vec-on-unimplemented.rs:3:31 | -LL | vec![true, false].map(|v| !v).collect::<Vec<_>>(); - | ^^^ `Vec<bool>` is not an iterator; try calling `.into_iter()` or `.iter()` +LL | let _ = vec![true, false].map(|v| !v).collect::<Vec<_>>(); + | ^^^ `Vec<bool>` is not an iterator | - = note: the following trait bounds were not satisfied: - `Vec<bool>: Iterator` - which is required by `&mut Vec<bool>: Iterator` - `[bool]: Iterator` - which is required by `&mut [bool]: Iterator` +help: call `.into_iter()` first + | +LL | let _ = vec![true, false].into_iter().map(|v| !v).collect::<Vec<_>>(); + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/kindck/kindck-impl-type-params-2.rs b/tests/ui/kindck/kindck-impl-type-params-2.rs index 8950fc51e64..8b0771985dc 100644 --- a/tests/ui/kindck/kindck-impl-type-params-2.rs +++ b/tests/ui/kindck/kindck-impl-type-params-2.rs @@ -11,5 +11,5 @@ fn take_param<T:Foo>(foo: &T) { } fn main() { let x: Box<_> = Box::new(3); take_param(&x); - //~^ ERROR the trait bound `Box<{integer}>: Copy` is not satisfied + //~^ ERROR the trait bound `Box<{integer}>: Foo` is not satisfied } diff --git a/tests/ui/kindck/kindck-impl-type-params-2.stderr b/tests/ui/kindck/kindck-impl-type-params-2.stderr index 46c0bda9535..a7d169d3ac4 100644 --- a/tests/ui/kindck/kindck-impl-type-params-2.stderr +++ b/tests/ui/kindck/kindck-impl-type-params-2.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied +error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied --> $DIR/kindck-impl-type-params-2.rs:13:16 | LL | take_param(&x); diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr index a85815d8cc4..979525ff407 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied +error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied --> $DIR/kindck-inherited-copy-bound.rs:21:16 | LL | take_param(&x); diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr index 687660fe7ee..30f90b88160 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr +++ b/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied +error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied --> $DIR/kindck-inherited-copy-bound.rs:21:16 | LL | take_param(&x); diff --git a/tests/ui/kindck/kindck-send-object.rs b/tests/ui/kindck/kindck-send-object.rs index 6411e688b4a..f5d44246efe 100644 --- a/tests/ui/kindck/kindck-send-object.rs +++ b/tests/ui/kindck/kindck-send-object.rs @@ -10,7 +10,7 @@ trait Message : Send { } fn object_ref_with_static_bound_not_ok() { assert_send::<&'static (dyn Dummy + 'static)>(); - //~^ ERROR `(dyn Dummy + 'static)` cannot be shared between threads safely [E0277] + //~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277] } fn box_object_with_no_bound_not_ok<'a>() { diff --git a/tests/ui/kindck/kindck-send-object.stderr b/tests/ui/kindck/kindck-send-object.stderr index 0fc9cb14c7d..9f1ff4f3644 100644 --- a/tests/ui/kindck/kindck-send-object.stderr +++ b/tests/ui/kindck/kindck-send-object.stderr @@ -1,10 +1,10 @@ -error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely +error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads safely --> $DIR/kindck-send-object.rs:12:19 | LL | assert_send::<&'static (dyn Dummy + 'static)>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely | - = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send` + = help: the trait `Sync` is not implemented for `&'static (dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send` = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` note: required by a bound in `assert_send` --> $DIR/kindck-send-object.rs:5:18 diff --git a/tests/ui/kindck/kindck-send-object1.rs b/tests/ui/kindck/kindck-send-object1.rs index 0ce3995dccc..76a9fc6019a 100644 --- a/tests/ui/kindck/kindck-send-object1.rs +++ b/tests/ui/kindck/kindck-send-object1.rs @@ -8,7 +8,7 @@ trait Dummy { } // careful with object types, who knows what they close over... fn test51<'a>() { assert_send::<&'a dyn Dummy>(); - //~^ ERROR `(dyn Dummy + 'a)` cannot be shared between threads safely [E0277] + //~^ ERROR `&'a (dyn Dummy + 'a)` cannot be sent between threads safely [E0277] } fn test52<'a>() { assert_send::<&'a (dyn Dummy + Sync)>(); diff --git a/tests/ui/kindck/kindck-send-object1.stderr b/tests/ui/kindck/kindck-send-object1.stderr index 39343b9993b..f2aa814676f 100644 --- a/tests/ui/kindck/kindck-send-object1.stderr +++ b/tests/ui/kindck/kindck-send-object1.stderr @@ -1,10 +1,10 @@ -error[E0277]: `(dyn Dummy + 'a)` cannot be shared between threads safely +error[E0277]: `&'a (dyn Dummy + 'a)` cannot be sent between threads safely --> $DIR/kindck-send-object1.rs:10:19 | LL | assert_send::<&'a dyn Dummy>(); - | ^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely + | ^^^^^^^^^^^^^ `&'a (dyn Dummy + 'a)` cannot be sent between threads safely | - = help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)`, which is required by `&'a (dyn Dummy + 'a): Send` + = help: the trait `Sync` is not implemented for `&'a (dyn Dummy + 'a)`, which is required by `&'a (dyn Dummy + 'a): Send` = note: required for `&'a (dyn Dummy + 'a)` to implement `Send` note: required by a bound in `assert_send` --> $DIR/kindck-send-object1.rs:5:18 diff --git a/tests/ui/kindck/kindck-send-object2.rs b/tests/ui/kindck/kindck-send-object2.rs index b797588e446..d37074e6574 100644 --- a/tests/ui/kindck/kindck-send-object2.rs +++ b/tests/ui/kindck/kindck-send-object2.rs @@ -5,7 +5,7 @@ trait Dummy { } fn test50() { assert_send::<&'static dyn Dummy>(); - //~^ ERROR `(dyn Dummy + 'static)` cannot be shared between threads safely [E0277] + //~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277] } fn test53() { diff --git a/tests/ui/kindck/kindck-send-object2.stderr b/tests/ui/kindck/kindck-send-object2.stderr index 758a517e128..cd4d74360f8 100644 --- a/tests/ui/kindck/kindck-send-object2.stderr +++ b/tests/ui/kindck/kindck-send-object2.stderr @@ -1,10 +1,10 @@ -error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely +error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads safely --> $DIR/kindck-send-object2.rs:7:19 | LL | assert_send::<&'static dyn Dummy>(); - | ^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely + | ^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely | - = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send` + = help: the trait `Sync` is not implemented for `&'static (dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send` = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` note: required by a bound in `assert_send` --> $DIR/kindck-send-object2.rs:3:18 diff --git a/tests/ui/meta/dir.with.dots/test.rs b/tests/ui/meta/dir.with.dots/test.rs new file mode 100644 index 00000000000..4d663e994f5 --- /dev/null +++ b/tests/ui/meta/dir.with.dots/test.rs @@ -0,0 +1,7 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/121986>. +// Check that `tests_revision_unpaired_stdout_stderr` don't accidentally get confused by +// paths containing periods. + +//@ check-pass + +fn main() {} diff --git a/tests/ui/methods/issues/issue-94581.fixed b/tests/ui/methods/issues/issue-94581.fixed new file mode 100644 index 00000000000..ff2bbeba27c --- /dev/null +++ b/tests/ui/methods/issues/issue-94581.fixed @@ -0,0 +1,8 @@ +//@ run-rustfix +fn get_slice() -> &'static [i32] { + &[1, 2, 3, 4] +} + +fn main() { + let _sqsum: i32 = get_slice().into_iter().map(|i| i * i).sum(); //~ ERROR [E0599] +} diff --git a/tests/ui/methods/issues/issue-94581.rs b/tests/ui/methods/issues/issue-94581.rs index df393e91db0..535d3249eb9 100644 --- a/tests/ui/methods/issues/issue-94581.rs +++ b/tests/ui/methods/issues/issue-94581.rs @@ -1,7 +1,8 @@ +//@ run-rustfix fn get_slice() -> &'static [i32] { &[1, 2, 3, 4] } fn main() { - let sqsum = get_slice().map(|i| i * i).sum(); //~ ERROR [E0599] + let _sqsum: i32 = get_slice().map(|i| i * i).sum(); //~ ERROR [E0599] } diff --git a/tests/ui/methods/issues/issue-94581.stderr b/tests/ui/methods/issues/issue-94581.stderr index ae7446d4833..d04d6ca5e3c 100644 --- a/tests/ui/methods/issues/issue-94581.stderr +++ b/tests/ui/methods/issues/issue-94581.stderr @@ -1,14 +1,13 @@ -error[E0599]: `&'static [i32]` is not an iterator - --> $DIR/issue-94581.rs:6:29 +error[E0599]: no method named `map` found for reference `&'static [i32]` in the current scope + --> $DIR/issue-94581.rs:7:35 | -LL | let sqsum = get_slice().map(|i| i * i).sum(); - | ^^^ `&'static [i32]` is not an iterator; try calling `.iter()` +LL | let _sqsum: i32 = get_slice().map(|i| i * i).sum(); + | ^^^ `&'static [i32]` is not an iterator | - = note: the following trait bounds were not satisfied: - `&'static [i32]: Iterator` - which is required by `&mut &'static [i32]: Iterator` - `[i32]: Iterator` - which is required by `&mut [i32]: Iterator` +help: call `.into_iter()` first + | +LL | let _sqsum: i32 = get_slice().into_iter().map(|i| i * i).sum(); + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs index 8567d812e4f..29793e9f734 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs @@ -14,7 +14,7 @@ struct PriorityQueueEntry<T> { //~^ ERROR can't compare `PriorityQueue<T>` with `PriorityQueue<T>` //~| ERROR the trait bound `PriorityQueue<T>: Eq` is not satisfied //~| ERROR can't compare `T` with `T` -//~| ERROR `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator +//~| ERROR no method named `cmp` found for struct `BinaryHeap<PriorityQueueEntry<T>>` //~| ERROR no field `height` on type `&PriorityQueue<T>` struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>); diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr index 6fa639877d3..0fe560afcb5 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr @@ -46,15 +46,12 @@ LL | struct PriorityQueue<T>(BinaryHeap<PriorityQueueEntry<T>>); = help: the trait `PartialOrd<_>` is not implemented for `BinaryHeap<PriorityQueueEntry<T>>` = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0599]: `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator +error[E0599]: no method named `cmp` found for struct `BinaryHeap<PriorityQueueEntry<T>>` in the current scope --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22 | LL | #[derive(PartialOrd, AddImpl)] | ^^^^^^^ `BinaryHeap<PriorityQueueEntry<T>>` is not an iterator | - = note: the following trait bounds were not satisfied: - `BinaryHeap<PriorityQueueEntry<T>>: Iterator` - which is required by `&mut BinaryHeap<PriorityQueueEntry<T>>: Iterator` = note: this error originates in the derive macro `AddImpl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0609]: no field `height` on type `&PriorityQueue<T>` diff --git a/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.rs b/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.rs index 5053c115b45..c9dc1c6e649 100644 --- a/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.rs +++ b/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.rs @@ -17,5 +17,5 @@ fn stuff<T: Bar>(_: T) {} fn main() { stuff(1u8); - //~^ the trait bound `u8: Foo` is not satisfied + //~^ the trait bound `u8: Bar` is not satisfied } diff --git a/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr b/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr index 99d318a7933..284dacf7000 100644 --- a/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr +++ b/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `u8: Foo` is not satisfied +error[E0277]: the trait bound `u8: Bar` is not satisfied --> $DIR/feature-gate-do_not_recommend.rs:19:11 | LL | stuff(1u8); diff --git a/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr index ec9826819c0..05e087fd9f9 100644 --- a/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr +++ b/tests/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr @@ -7,7 +7,6 @@ LL | bar(foo); | required by a bound introduced by this call | = help: the trait `Future` is not implemented for fn item `fn() -> impl Future<Output = ()> {foo}` - = note: fn() -> impl Future<Output = ()> {foo} must be a future or must implement `IntoFuture` to be awaited note: required by a bound in `bar` --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:7:16 | @@ -27,7 +26,6 @@ LL | bar(async_closure); | required by a bound introduced by this call | = help: the trait `Future` is not implemented for `{async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33}` - = note: {async closure@$DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:11:25: 11:33} must be a future or must implement `IntoFuture` to be awaited note: required by a bound in `bar` --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:7:16 | diff --git a/tests/ui/suggestions/issue-104961.fixed b/tests/ui/suggestions/issue-104961.fixed index a4047def341..5def21b506e 100644 --- a/tests/ui/suggestions/issue-104961.fixed +++ b/tests/ui/suggestions/issue-104961.fixed @@ -2,12 +2,12 @@ fn foo(x: &str) -> bool { x.starts_with(&("hi".to_string() + " you")) - //~^ ERROR expected a `FnMut(char)` closure, found `String` + //~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277] } fn foo2(x: &str) -> bool { x.starts_with(&"hi".to_string()) - //~^ ERROR expected a `FnMut(char)` closure, found `String` + //~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277] } fn main() { diff --git a/tests/ui/suggestions/issue-104961.rs b/tests/ui/suggestions/issue-104961.rs index 9d02f570c84..a09b8a88711 100644 --- a/tests/ui/suggestions/issue-104961.rs +++ b/tests/ui/suggestions/issue-104961.rs @@ -2,12 +2,12 @@ fn foo(x: &str) -> bool { x.starts_with("hi".to_string() + " you") - //~^ ERROR expected a `FnMut(char)` closure, found `String` + //~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277] } fn foo2(x: &str) -> bool { x.starts_with("hi".to_string()) - //~^ ERROR expected a `FnMut(char)` closure, found `String` + //~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277] } fn main() { diff --git a/tests/ui/suggestions/issue-104961.stderr b/tests/ui/suggestions/issue-104961.stderr index 7e795a74c90..3c5f86817f3 100644 --- a/tests/ui/suggestions/issue-104961.stderr +++ b/tests/ui/suggestions/issue-104961.stderr @@ -1,4 +1,4 @@ -error[E0277]: expected a `FnMut(char)` closure, found `String` +error[E0277]: the trait bound `String: Pattern<'_>` is not satisfied --> $DIR/issue-104961.rs:4:19 | LL | x.starts_with("hi".to_string() + " you") @@ -6,7 +6,6 @@ LL | x.starts_with("hi".to_string() + " you") | | | required by a bound introduced by this call | - = note: the trait bound `String: Pattern<'_>` is not satisfied = note: required for `String` to implement `Pattern<'_>` note: required by a bound in `core::str::<impl str>::starts_with` --> $SRC_DIR/core/src/str/mod.rs:LL:COL @@ -15,7 +14,7 @@ help: consider borrowing here LL | x.starts_with(&("hi".to_string() + " you")) | ++ + -error[E0277]: expected a `FnMut(char)` closure, found `String` +error[E0277]: the trait bound `String: Pattern<'_>` is not satisfied --> $DIR/issue-104961.rs:9:19 | LL | x.starts_with("hi".to_string()) @@ -23,7 +22,6 @@ LL | x.starts_with("hi".to_string()) | | | required by a bound introduced by this call | - = note: the trait bound `String: Pattern<'_>` is not satisfied = note: required for `String` to implement `Pattern<'_>` note: required by a bound in `core::str::<impl str>::starts_with` --> $SRC_DIR/core/src/str/mod.rs:LL:COL diff --git a/tests/ui/suggestions/issue-62843.stderr b/tests/ui/suggestions/issue-62843.stderr index f3a9f6b7913..84ab4a0edd3 100644 --- a/tests/ui/suggestions/issue-62843.stderr +++ b/tests/ui/suggestions/issue-62843.stderr @@ -1,4 +1,4 @@ -error[E0277]: expected a `FnMut(char)` closure, found `String` +error[E0277]: the trait bound `String: Pattern<'_>` is not satisfied --> $DIR/issue-62843.rs:4:32 | LL | println!("{:?}", line.find(pattern)); @@ -6,7 +6,6 @@ LL | println!("{:?}", line.find(pattern)); | | | required by a bound introduced by this call | - = note: the trait bound `String: Pattern<'_>` is not satisfied = note: required for `String` to implement `Pattern<'_>` note: required by a bound in `core::str::<impl str>::find` --> $SRC_DIR/core/src/str/mod.rs:LL:COL diff --git a/tests/ui/suggestions/slice-issue-87994.rs b/tests/ui/suggestions/slice-issue-87994.rs index ecb7f54ea25..5a2574fff8a 100644 --- a/tests/ui/suggestions/slice-issue-87994.rs +++ b/tests/ui/suggestions/slice-issue-87994.rs @@ -1,16 +1,16 @@ fn main() { let v = vec![1i32, 2, 3]; for _ in v[1..] { - //~^ ERROR [i32]` is not an iterator [E0277] - //~^^ ERROR known at compilation time + //~^ ERROR `[i32]` is not an iterator [E0277] + //~| ERROR `[i32]` is not an iterator [E0277] } struct K { n: i32, } let mut v2 = vec![K { n: 1 }, K { n: 1 }, K { n: 1 }]; for i2 in v2[1..] { - //~^ ERROR [K]` is not an iterator [E0277] - //~^^ ERROR known at compilation time + //~^ ERROR `[K]` is not an iterator [E0277] + //~| ERROR `[K]` is not an iterator [E0277] i2.n = 2; } } diff --git a/tests/ui/suggestions/slice-issue-87994.stderr b/tests/ui/suggestions/slice-issue-87994.stderr index 656f71eb877..22ad5d35212 100644 --- a/tests/ui/suggestions/slice-issue-87994.stderr +++ b/tests/ui/suggestions/slice-issue-87994.stderr @@ -13,7 +13,7 @@ LL | for _ in &v[1..] { LL | for _ in &mut v[1..] { | ++++ -error[E0277]: the size for values of type `[i32]` cannot be known at compilation time +error[E0277]: `[i32]` is not an iterator --> $DIR/slice-issue-87994.rs:3:12 | LL | for _ in v[1..] { @@ -21,6 +21,7 @@ LL | for _ in v[1..] { | = note: the trait bound `[i32]: IntoIterator` is not satisfied = note: required for `[i32]` to implement `IntoIterator` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider borrowing here | LL | for _ in &v[1..] { @@ -43,7 +44,7 @@ LL | for i2 in &v2[1..] { LL | for i2 in &mut v2[1..] { | ++++ -error[E0277]: the size for values of type `[K]` cannot be known at compilation time +error[E0277]: `[K]` is not an iterator --> $DIR/slice-issue-87994.rs:11:13 | LL | for i2 in v2[1..] { @@ -51,6 +52,7 @@ LL | for i2 in v2[1..] { | = note: the trait bound `[K]: IntoIterator` is not satisfied = note: required for `[K]` to implement `IntoIterator` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider borrowing here | LL | for i2 in &v2[1..] { diff --git a/tests/ui/suggestions/suggest-remove-refs-5.stderr b/tests/ui/suggestions/suggest-remove-refs-5.stderr index 6b2f330e1a3..3b6994b45d1 100644 --- a/tests/ui/suggestions/suggest-remove-refs-5.stderr +++ b/tests/ui/suggestions/suggest-remove-refs-5.stderr @@ -1,10 +1,10 @@ -error[E0277]: `Vec<i32>` is not an iterator +error[E0277]: `&mut &mut &mut &mut Vec<i32>` is not an iterator --> $DIR/suggest-remove-refs-5.rs:4:14 | LL | for _ in &mut &mut v {} - | ^^^^^^^^^^^ `Vec<i32>` is not an iterator; try calling `.into_iter()` or `.iter()` + | ^^^^^^^^^^^ `&mut &mut &mut &mut Vec<i32>` is not an iterator | - = help: the trait `Iterator` is not implemented for `Vec<i32>`, which is required by `&mut &mut &mut &mut Vec<i32>: IntoIterator` + = help: the trait `Iterator` is not implemented for `&mut &mut &mut &mut Vec<i32>`, which is required by `&mut &mut &mut &mut Vec<i32>: IntoIterator` = note: required for `&mut Vec<i32>` to implement `Iterator` = note: 3 redundant requirements hidden = note: required for `&mut &mut &mut &mut Vec<i32>` to implement `Iterator` @@ -15,13 +15,13 @@ LL ~ let v = &mut Vec::<i32>::new(); LL ~ for _ in v {} | -error[E0277]: `[u8; 1]` is not an iterator +error[E0277]: `&mut &mut &mut [u8; 1]` is not an iterator --> $DIR/suggest-remove-refs-5.rs:7:14 | LL | for _ in &mut v {} - | ^^^^^^ `[u8; 1]` is not an iterator; try calling `.into_iter()` or `.iter()` + | ^^^^^^ `&mut &mut &mut [u8; 1]` is not an iterator | - = help: the trait `Iterator` is not implemented for `[u8; 1]`, which is required by `&mut &mut &mut [u8; 1]: IntoIterator` + = help: the trait `Iterator` is not implemented for `&mut &mut &mut [u8; 1]`, which is required by `&mut &mut &mut [u8; 1]: IntoIterator` = note: required for `&mut [u8; 1]` to implement `Iterator` = note: 2 redundant requirements hidden = note: required for `&mut &mut &mut [u8; 1]` to implement `Iterator` diff --git a/tests/ui/traits/alias/cross-crate.rs b/tests/ui/traits/alias/cross-crate.rs index 207216f73bf..37681948548 100644 --- a/tests/ui/traits/alias/cross-crate.rs +++ b/tests/ui/traits/alias/cross-crate.rs @@ -12,6 +12,6 @@ fn use_alias<T: SendSync>() {} fn main() { use_alias::<u32>(); use_alias::<Rc<u32>>(); - //~^ ERROR `Rc<u32>` cannot be sent between threads safely [E0277] - //~^^ ERROR `Rc<u32>` cannot be shared between threads safely [E0277] + //~^ ERROR the trait bound `Rc<u32>: SendSync` is not satisfied [E0277] + //~| ERROR the trait bound `Rc<u32>: SendSync` is not satisfied [E0277] } diff --git a/tests/ui/traits/alias/cross-crate.stderr b/tests/ui/traits/alias/cross-crate.stderr index fd614b4bcd5..52eb7e44f44 100644 --- a/tests/ui/traits/alias/cross-crate.stderr +++ b/tests/ui/traits/alias/cross-crate.stderr @@ -1,10 +1,9 @@ -error[E0277]: `Rc<u32>` cannot be sent between threads safely +error[E0277]: the trait bound `Rc<u32>: SendSync` is not satisfied --> $DIR/cross-crate.rs:14:17 | LL | use_alias::<Rc<u32>>(); - | ^^^^^^^ `Rc<u32>` cannot be sent between threads safely + | ^^^^^^^ the trait `Send` is not implemented for `Rc<u32>`, which is required by `Rc<u32>: SendSync` | - = help: the trait `Send` is not implemented for `Rc<u32>`, which is required by `Rc<u32>: SendSync` = note: required for `Rc<u32>` to implement `SendSync` note: required by a bound in `use_alias` --> $DIR/cross-crate.rs:10:17 @@ -12,13 +11,12 @@ note: required by a bound in `use_alias` LL | fn use_alias<T: SendSync>() {} | ^^^^^^^^ required by this bound in `use_alias` -error[E0277]: `Rc<u32>` cannot be shared between threads safely +error[E0277]: the trait bound `Rc<u32>: SendSync` is not satisfied --> $DIR/cross-crate.rs:14:17 | LL | use_alias::<Rc<u32>>(); - | ^^^^^^^ `Rc<u32>` cannot be shared between threads safely + | ^^^^^^^ the trait `Sync` is not implemented for `Rc<u32>`, which is required by `Rc<u32>: SendSync` | - = help: the trait `Sync` is not implemented for `Rc<u32>`, which is required by `Rc<u32>: SendSync` = note: required for `Rc<u32>` to implement `SendSync` note: required by a bound in `use_alias` --> $DIR/cross-crate.rs:10:17 diff --git a/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.rs b/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.rs index d254c0ae3ef..bffa856bbee 100644 --- a/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.rs +++ b/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.rs @@ -7,5 +7,5 @@ trait IteratorAlias = Iterator; fn f(_: impl IteratorAlias) {} fn main() { - f(()) //~ `()` is not an iterator + f(()) //~ ERROR the trait bound `(): IteratorAlias` is not satisfied } diff --git a/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.stderr b/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.stderr index 1e4f4cb7046..c73c2f68032 100644 --- a/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.stderr +++ b/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.stderr @@ -1,12 +1,11 @@ -error[E0277]: `()` is not an iterator +error[E0277]: the trait bound `(): IteratorAlias` is not satisfied --> $DIR/issue-108072-unmet-trait-alias-bound.rs:10:7 | LL | f(()) - | - ^^ `()` is not an iterator + | - ^^ the trait `Iterator` is not implemented for `()`, which is required by `(): IteratorAlias` | | | required by a bound introduced by this call | - = help: the trait `Iterator` is not implemented for `()`, which is required by `(): IteratorAlias` = note: required for `()` to implement `IteratorAlias` note: required by a bound in `f` --> $DIR/issue-108072-unmet-trait-alias-bound.rs:7:14 diff --git a/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr b/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr index 629ccac49c5..17fced307ed 100644 --- a/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr +++ b/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr @@ -6,7 +6,7 @@ LL | auto trait Magic: Copy {} | | | auto traits cannot have super traits or lifetime bounds -error[E0277]: the trait bound `NoClone: Copy` is not satisfied +error[E0277]: the trait bound `NoClone: Magic` is not satisfied --> $DIR/supertrait-auto-trait.rs:16:23 | LL | let (a, b) = copy(NoClone); diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr index 6c019f59b09..5bc79d9cee8 100644 --- a/tests/ui/traits/issue-50480.stderr +++ b/tests/ui/traits/issue-50480.stderr @@ -93,7 +93,6 @@ LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator | = help: the trait `Iterator` is not implemented for `i32` - = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` error[E0277]: `i32` is not an iterator --> $DIR/issue-50480.rs:14:33 @@ -102,7 +101,6 @@ LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator | = help: the trait `Iterator` is not implemented for `i32` - = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` error[E0277]: `i32` is not an iterator --> $DIR/issue-50480.rs:3:28 @@ -111,7 +109,6 @@ LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); | ^^^ `i32` is not an iterator | = help: the trait `Iterator` is not implemented for `i32` - = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` error[E0277]: `i32` is not an iterator --> $DIR/issue-50480.rs:11:10 @@ -120,7 +117,6 @@ LL | #[derive(Clone, Copy)] | ^^^^^ `i32` is not an iterator | = help: the trait `Iterator` is not implemented for `i32` - = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `i32` is not an iterator @@ -133,7 +129,6 @@ LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String); | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator | = help: the trait `Iterator` is not implemented for `i32` - = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 13 previous errors diff --git a/tests/ui/traits/suggest-dereferences/root-obligation.fixed b/tests/ui/traits/suggest-dereferences/root-obligation.fixed index eecd52304ff..072296c6b15 100644 --- a/tests/ui/traits/suggest-dereferences/root-obligation.fixed +++ b/tests/ui/traits/suggest-dereferences/root-obligation.fixed @@ -4,7 +4,7 @@ fn get_vowel_count(string: &str) -> usize { string .chars() .filter(|c| "aeiou".contains(*c)) - //~^ ERROR expected a `Fn(char)` closure, found `char` + //~^ ERROR the trait bound `&char: Pattern<'_>` is not satisfied .count() } diff --git a/tests/ui/traits/suggest-dereferences/root-obligation.rs b/tests/ui/traits/suggest-dereferences/root-obligation.rs index d58193f1213..e7025fe0825 100644 --- a/tests/ui/traits/suggest-dereferences/root-obligation.rs +++ b/tests/ui/traits/suggest-dereferences/root-obligation.rs @@ -4,7 +4,7 @@ fn get_vowel_count(string: &str) -> usize { string .chars() .filter(|c| "aeiou".contains(c)) - //~^ ERROR expected a `Fn(char)` closure, found `char` + //~^ ERROR the trait bound `&char: Pattern<'_>` is not satisfied .count() } diff --git a/tests/ui/traits/suggest-dereferences/root-obligation.stderr b/tests/ui/traits/suggest-dereferences/root-obligation.stderr index a41330373be..56f95e20715 100644 --- a/tests/ui/traits/suggest-dereferences/root-obligation.stderr +++ b/tests/ui/traits/suggest-dereferences/root-obligation.stderr @@ -1,12 +1,11 @@ -error[E0277]: expected a `Fn(char)` closure, found `char` +error[E0277]: the trait bound `&char: Pattern<'_>` is not satisfied --> $DIR/root-obligation.rs:6:38 | LL | .filter(|c| "aeiou".contains(c)) - | -------- ^ expected an `Fn(char)` closure, found `char` + | -------- ^ the trait `Fn<(char,)>` is not implemented for `&char`, which is required by `&char: Pattern<'_>` | | | required by a bound introduced by this call | - = help: the trait `Fn<(char,)>` is not implemented for `char`, which is required by `&char: Pattern<'_>` = note: required for `&char` to implement `FnOnce<(char,)>` = note: required for `&char` to implement `Pattern<'_>` note: required by a bound in `core::str::<impl str>::contains` diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.rs b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.rs new file mode 100644 index 00000000000..1278563a92c --- /dev/null +++ b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.rs @@ -0,0 +1,28 @@ +//! This test demonstrates a bug where we accidentally +//! detected opaque types in struct fields, but only if nested +//! in projections of another opaque type. + +#![feature(impl_trait_in_assoc_type)] + +struct Bar; + +trait Trait: Sized { + type Assoc2; + type Assoc; + fn foo() -> Self::Assoc; +} + +impl Trait for Bar { + type Assoc2 = impl std::fmt::Debug; + type Assoc = impl Iterator<Item = Foo>; + fn foo() -> Self::Assoc { + vec![Foo { field: () }].into_iter() + //~^ ERROR item constrains opaque type that is not in its signature + } +} + +struct Foo { + field: <Bar as Trait>::Assoc2, +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.stderr b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.stderr new file mode 100644 index 00000000000..0570e0303c6 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/hidden_behind_struct_field3.stderr @@ -0,0 +1,15 @@ +error: item constrains opaque type that is not in its signature + --> $DIR/hidden_behind_struct_field3.rs:19:27 + | +LL | vec![Foo { field: () }].into_iter() + | ^^ + | + = note: this item must mention the opaque type in its signature in order to be able to register hidden types +note: this item must mention the opaque type in its signature in order to be able to register hidden types + --> $DIR/hidden_behind_struct_field3.rs:18:8 + | +LL | fn foo() -> Self::Assoc { + | ^^^ + +error: aborting due to 1 previous error + |
